aboutsummaryrefslogtreecommitdiff
path: root/providers/common
diff options
context:
space:
mode:
Diffstat (limited to 'providers/common')
-rw-r--r--providers/common/bio_prov.c244
-rw-r--r--providers/common/build.info10
-rw-r--r--providers/common/capabilities.c225
-rw-r--r--providers/common/der/DIGESTS.asn143
-rw-r--r--providers/common/der/DSA.asn136
-rw-r--r--providers/common/der/EC.asn190
-rw-r--r--providers/common/der/ECX.asn117
-rw-r--r--providers/common/der/NIST.asn115
-rw-r--r--providers/common/der/RSA.asn189
-rw-r--r--providers/common/der/SM2.asn118
-rw-r--r--providers/common/der/build.info119
-rw-r--r--providers/common/der/der_digests_gen.c.in20
-rw-r--r--providers/common/der/der_dsa_gen.c.in25
-rw-r--r--providers/common/der/der_dsa_key.c27
-rw-r--r--providers/common/der/der_dsa_sig.c50
-rw-r--r--providers/common/der/der_ec_gen.c.in19
-rw-r--r--providers/common/der/der_ec_key.c21
-rw-r--r--providers/common/der/der_ec_sig.c51
-rw-r--r--providers/common/der/der_ecx_gen.c.in19
-rw-r--r--providers/common/der/der_ecx_key.c48
-rw-r--r--providers/common/der/der_rsa_gen.c.in20
-rw-r--r--providers/common/der/der_rsa_key.c400
-rw-r--r--providers/common/der/der_rsa_sig.c73
-rw-r--r--providers/common/der/der_sm2_gen.c.in19
-rw-r--r--providers/common/der/der_sm2_key.c23
-rw-r--r--providers/common/der/der_sm2_sig.c39
-rw-r--r--providers/common/der/der_wrap_gen.c.in19
-rw-r--r--providers/common/der/oids_to_c.pm113
-rw-r--r--providers/common/der/wrap.asn126
-rw-r--r--providers/common/digest_to_nid.c57
-rw-r--r--providers/common/include/prov/__DECC_INCLUDE_EPILOGUE.H22
-rw-r--r--providers/common/include/prov/__DECC_INCLUDE_PROLOGUE.H26
-rw-r--r--providers/common/include/prov/bio.h32
-rw-r--r--providers/common/include/prov/der_digests.h.in20
-rw-r--r--providers/common/include/prov/der_dsa.h.in25
-rw-r--r--providers/common/include/prov/der_ec.h.in26
-rw-r--r--providers/common/include/prov/der_ecx.h.in25
-rw-r--r--providers/common/include/prov/der_rsa.h.in33
-rw-r--r--providers/common/include/prov/der_sm2.h.in26
-rw-r--r--providers/common/include/prov/der_wrap.h.in19
-rw-r--r--providers/common/include/prov/proverr.h27
-rw-r--r--providers/common/include/prov/provider_ctx.h40
-rw-r--r--providers/common/include/prov/provider_util.h138
-rw-r--r--providers/common/include/prov/providercommon.h24
-rw-r--r--providers/common/include/prov/securitycheck.h30
-rw-r--r--providers/common/provider_ctx.c61
-rw-r--r--providers/common/provider_err.c229
-rw-r--r--providers/common/provider_seeding.c77
-rw-r--r--providers/common/provider_util.c353
-rw-r--r--providers/common/securitycheck.c256
-rw-r--r--providers/common/securitycheck_default.c43
-rw-r--r--providers/common/securitycheck_fips.c41
52 files changed, 3548 insertions, 0 deletions
diff --git a/providers/common/bio_prov.c b/providers/common/bio_prov.c
new file mode 100644
index 000000000000..baf923c7b3c6
--- /dev/null
+++ b/providers/common/bio_prov.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <assert.h>
+#include <openssl/core_dispatch.h>
+#include "internal/cryptlib.h"
+#include "prov/bio.h"
+
+static OSSL_FUNC_BIO_new_file_fn *c_bio_new_file = NULL;
+static OSSL_FUNC_BIO_new_membuf_fn *c_bio_new_membuf = NULL;
+static OSSL_FUNC_BIO_read_ex_fn *c_bio_read_ex = NULL;
+static OSSL_FUNC_BIO_write_ex_fn *c_bio_write_ex = NULL;
+static OSSL_FUNC_BIO_gets_fn *c_bio_gets = NULL;
+static OSSL_FUNC_BIO_puts_fn *c_bio_puts = NULL;
+static OSSL_FUNC_BIO_ctrl_fn *c_bio_ctrl = NULL;
+static OSSL_FUNC_BIO_up_ref_fn *c_bio_up_ref = NULL;
+static OSSL_FUNC_BIO_free_fn *c_bio_free = NULL;
+static OSSL_FUNC_BIO_vprintf_fn *c_bio_vprintf = NULL;
+
+int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns)
+{
+ for (; fns->function_id != 0; fns++) {
+ switch (fns->function_id) {
+ case OSSL_FUNC_BIO_NEW_FILE:
+ if (c_bio_new_file == NULL)
+ c_bio_new_file = OSSL_FUNC_BIO_new_file(fns);
+ break;
+ case OSSL_FUNC_BIO_NEW_MEMBUF:
+ if (c_bio_new_membuf == NULL)
+ c_bio_new_membuf = OSSL_FUNC_BIO_new_membuf(fns);
+ break;
+ case OSSL_FUNC_BIO_READ_EX:
+ if (c_bio_read_ex == NULL)
+ c_bio_read_ex = OSSL_FUNC_BIO_read_ex(fns);
+ break;
+ case OSSL_FUNC_BIO_WRITE_EX:
+ if (c_bio_write_ex == NULL)
+ c_bio_write_ex = OSSL_FUNC_BIO_write_ex(fns);
+ break;
+ case OSSL_FUNC_BIO_GETS:
+ if (c_bio_gets == NULL)
+ c_bio_gets = OSSL_FUNC_BIO_gets(fns);
+ break;
+ case OSSL_FUNC_BIO_PUTS:
+ if (c_bio_puts == NULL)
+ c_bio_puts = OSSL_FUNC_BIO_puts(fns);
+ break;
+ case OSSL_FUNC_BIO_CTRL:
+ if (c_bio_ctrl == NULL)
+ c_bio_ctrl = OSSL_FUNC_BIO_ctrl(fns);
+ break;
+ case OSSL_FUNC_BIO_UP_REF:
+ if (c_bio_up_ref == NULL)
+ c_bio_up_ref = OSSL_FUNC_BIO_up_ref(fns);
+ break;
+ case OSSL_FUNC_BIO_FREE:
+ if (c_bio_free == NULL)
+ c_bio_free = OSSL_FUNC_BIO_free(fns);
+ break;
+ case OSSL_FUNC_BIO_VPRINTF:
+ if (c_bio_vprintf == NULL)
+ c_bio_vprintf = OSSL_FUNC_BIO_vprintf(fns);
+ break;
+ }
+ }
+
+ return 1;
+}
+
+OSSL_CORE_BIO *ossl_prov_bio_new_file(const char *filename, const char *mode)
+{
+ if (c_bio_new_file == NULL)
+ return NULL;
+ return c_bio_new_file(filename, mode);
+}
+
+OSSL_CORE_BIO *ossl_prov_bio_new_membuf(const char *filename, int len)
+{
+ if (c_bio_new_membuf == NULL)
+ return NULL;
+ return c_bio_new_membuf(filename, len);
+}
+
+int ossl_prov_bio_read_ex(OSSL_CORE_BIO *bio, void *data, size_t data_len,
+ size_t *bytes_read)
+{
+ if (c_bio_read_ex == NULL)
+ return 0;
+ return c_bio_read_ex(bio, data, data_len, bytes_read);
+}
+
+int ossl_prov_bio_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len,
+ size_t *written)
+{
+ if (c_bio_write_ex == NULL)
+ return 0;
+ return c_bio_write_ex(bio, data, data_len, written);
+}
+
+int ossl_prov_bio_gets(OSSL_CORE_BIO *bio, char *buf, int size)
+{
+ if (c_bio_gets == NULL)
+ return -1;
+ return c_bio_gets(bio, buf, size);
+}
+
+int ossl_prov_bio_puts(OSSL_CORE_BIO *bio, const char *str)
+{
+ if (c_bio_puts == NULL)
+ return -1;
+ return c_bio_puts(bio, str);
+}
+
+int ossl_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr)
+{
+ if (c_bio_ctrl == NULL)
+ return -1;
+ return c_bio_ctrl(bio, cmd, num, ptr);
+}
+
+int ossl_prov_bio_up_ref(OSSL_CORE_BIO *bio)
+{
+ if (c_bio_up_ref == NULL)
+ return 0;
+ return c_bio_up_ref(bio);
+}
+
+int ossl_prov_bio_free(OSSL_CORE_BIO *bio)
+{
+ if (c_bio_free == NULL)
+ return 0;
+ return c_bio_free(bio);
+}
+
+int ossl_prov_bio_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list ap)
+{
+ if (c_bio_vprintf == NULL)
+ return -1;
+ return c_bio_vprintf(bio, format, ap);
+}
+
+int ossl_prov_bio_printf(OSSL_CORE_BIO *bio, const char *format, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, format);
+ ret = ossl_prov_bio_vprintf(bio, format, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+#ifndef FIPS_MODULE
+
+/* No direct BIO support in the FIPS module */
+
+static int bio_core_read_ex(BIO *bio, char *data, size_t data_len,
+ size_t *bytes_read)
+{
+ return ossl_prov_bio_read_ex(BIO_get_data(bio), data, data_len, bytes_read);
+}
+
+static int bio_core_write_ex(BIO *bio, const char *data, size_t data_len,
+ size_t *written)
+{
+ return ossl_prov_bio_write_ex(BIO_get_data(bio), data, data_len, written);
+}
+
+static long bio_core_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+ return ossl_prov_bio_ctrl(BIO_get_data(bio), cmd, num, ptr);
+}
+
+static int bio_core_gets(BIO *bio, char *buf, int size)
+{
+ return ossl_prov_bio_gets(BIO_get_data(bio), buf, size);
+}
+
+static int bio_core_puts(BIO *bio, const char *str)
+{
+ return ossl_prov_bio_puts(BIO_get_data(bio), str);
+}
+
+static int bio_core_new(BIO *bio)
+{
+ BIO_set_init(bio, 1);
+
+ return 1;
+}
+
+static int bio_core_free(BIO *bio)
+{
+ BIO_set_init(bio, 0);
+ ossl_prov_bio_free(BIO_get_data(bio));
+
+ return 1;
+}
+
+BIO_METHOD *ossl_bio_prov_init_bio_method(void)
+{
+ BIO_METHOD *corebiometh = NULL;
+
+ corebiometh = BIO_meth_new(BIO_TYPE_CORE_TO_PROV, "BIO to Core filter");
+ if (corebiometh == NULL
+ || !BIO_meth_set_write_ex(corebiometh, bio_core_write_ex)
+ || !BIO_meth_set_read_ex(corebiometh, bio_core_read_ex)
+ || !BIO_meth_set_puts(corebiometh, bio_core_puts)
+ || !BIO_meth_set_gets(corebiometh, bio_core_gets)
+ || !BIO_meth_set_ctrl(corebiometh, bio_core_ctrl)
+ || !BIO_meth_set_create(corebiometh, bio_core_new)
+ || !BIO_meth_set_destroy(corebiometh, bio_core_free)) {
+ BIO_meth_free(corebiometh);
+ return NULL;
+ }
+
+ return corebiometh;
+}
+
+BIO *ossl_bio_new_from_core_bio(PROV_CTX *provctx, OSSL_CORE_BIO *corebio)
+{
+ BIO *outbio;
+ BIO_METHOD *corebiometh = ossl_prov_ctx_get0_core_bio_method(provctx);
+
+ if (corebiometh == NULL)
+ return NULL;
+
+ if ((outbio = BIO_new(corebiometh)) == NULL)
+ return NULL;
+ if (!ossl_prov_bio_up_ref(corebio)) {
+ BIO_free(outbio);
+ return NULL;
+ }
+ BIO_set_data(outbio, corebio);
+ return outbio;
+}
+
+#endif
diff --git a/providers/common/build.info b/providers/common/build.info
new file mode 100644
index 000000000000..a14bf0903771
--- /dev/null
+++ b/providers/common/build.info
@@ -0,0 +1,10 @@
+SUBDIRS=der
+
+SOURCE[../libcommon.a]=provider_err.c provider_ctx.c
+$FIPSCOMMON=provider_util.c capabilities.c bio_prov.c digest_to_nid.c\
+ securitycheck.c provider_seeding.c
+SOURCE[../libdefault.a]=$FIPSCOMMON securitycheck_default.c
+IF[{- !$disabled{module} && !$disabled{shared} -}]
+ SOURCE[../liblegacy.a]=provider_util.c
+ENDIF
+SOURCE[../libfips.a]=$FIPSCOMMON securitycheck_fips.c
diff --git a/providers/common/capabilities.c b/providers/common/capabilities.c
new file mode 100644
index 000000000000..7223d55164cd
--- /dev/null
+++ b/providers/common/capabilities.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+/* For TLS1_VERSION etc */
+#include <openssl/prov_ssl.h>
+#include <openssl/params.h>
+#include "internal/nelem.h"
+#include "internal/tlsgroups.h"
+#include "prov/providercommon.h"
+#include "e_os.h"
+
+/* If neither ec or dh is available then we have no TLS-GROUP capabilities */
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
+typedef struct tls_group_constants_st {
+ unsigned int group_id; /* Group ID */
+ unsigned int secbits; /* Bits of security */
+ int mintls; /* Minimum TLS version, -1 unsupported */
+ int maxtls; /* Maximum TLS version (or 0 for undefined) */
+ int mindtls; /* Minimum DTLS version, -1 unsupported */
+ int maxdtls; /* Maximum DTLS version (or 0 for undefined) */
+} TLS_GROUP_CONSTANTS;
+
+static const TLS_GROUP_CONSTANTS group_list[35] = {
+ { OSSL_TLS_GROUP_ID_sect163k1, 80, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_sect163r1, 80, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_sect163r2, 80, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_sect193r1, 80, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_sect193r2, 80, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_sect233k1, 112, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_sect233r1, 112, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_sect239k1, 112, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_sect283k1, 128, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_sect283r1, 128, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_sect409k1, 192, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_sect409r1, 192, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_sect571k1, 256, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_sect571r1, 256, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_secp160k1, 80, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_secp160r1, 80, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_secp160r2, 80, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_secp192k1, 80, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_secp192r1, 80, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_secp224k1, 112, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_secp224r1, 112, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_secp256k1, 128, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_secp256r1, 128, TLS1_VERSION, 0, DTLS1_VERSION, 0 },
+ { OSSL_TLS_GROUP_ID_secp384r1, 192, TLS1_VERSION, 0, DTLS1_VERSION, 0 },
+ { OSSL_TLS_GROUP_ID_secp521r1, 256, TLS1_VERSION, 0, DTLS1_VERSION, 0 },
+ { OSSL_TLS_GROUP_ID_brainpoolP256r1, 128, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_brainpoolP384r1, 192, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_brainpoolP512r1, 256, TLS1_VERSION, TLS1_2_VERSION,
+ DTLS1_VERSION, DTLS1_2_VERSION },
+ { OSSL_TLS_GROUP_ID_x25519, 128, TLS1_VERSION, 0, DTLS1_VERSION, 0 },
+ { OSSL_TLS_GROUP_ID_x448, 224, TLS1_VERSION, 0, DTLS1_VERSION, 0 },
+ /* Security bit values as given by BN_security_bits() */
+ { OSSL_TLS_GROUP_ID_ffdhe2048, 112, TLS1_3_VERSION, 0, -1, -1 },
+ { OSSL_TLS_GROUP_ID_ffdhe3072, 128, TLS1_3_VERSION, 0, -1, -1 },
+ { OSSL_TLS_GROUP_ID_ffdhe4096, 128, TLS1_3_VERSION, 0, -1, -1 },
+ { OSSL_TLS_GROUP_ID_ffdhe6144, 128, TLS1_3_VERSION, 0, -1, -1 },
+ { OSSL_TLS_GROUP_ID_ffdhe8192, 192, TLS1_3_VERSION, 0, -1, -1 },
+};
+
+#define TLS_GROUP_ENTRY(tlsname, realname, algorithm, idx) \
+ { \
+ OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME, \
+ tlsname, \
+ sizeof(tlsname)), \
+ OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL, \
+ realname, \
+ sizeof(realname)), \
+ OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_ALG, \
+ algorithm, \
+ sizeof(algorithm)), \
+ OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_ID, \
+ (unsigned int *)&group_list[idx].group_id), \
+ OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS, \
+ (unsigned int *)&group_list[idx].secbits), \
+ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_TLS, \
+ (unsigned int *)&group_list[idx].mintls), \
+ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, \
+ (unsigned int *)&group_list[idx].maxtls), \
+ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, \
+ (unsigned int *)&group_list[idx].mindtls), \
+ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, \
+ (unsigned int *)&group_list[idx].maxdtls), \
+ OSSL_PARAM_END \
+ }
+
+static const OSSL_PARAM param_group_list[][10] = {
+# ifndef OPENSSL_NO_EC
+# ifndef OPENSSL_NO_EC2M
+ TLS_GROUP_ENTRY("sect163k1", "sect163k1", "EC", 0),
+ TLS_GROUP_ENTRY("K-163", "sect163k1", "EC", 0), /* Alias of above */
+# endif
+# ifndef FIPS_MODULE
+ TLS_GROUP_ENTRY("sect163r1", "sect163r1", "EC", 1),
+# endif
+# ifndef OPENSSL_NO_EC2M
+ TLS_GROUP_ENTRY("sect163r2", "sect163r2", "EC", 2),
+ TLS_GROUP_ENTRY("B-163", "sect163r2", "EC", 2), /* Alias of above */
+# endif
+# ifndef FIPS_MODULE
+ TLS_GROUP_ENTRY("sect193r1", "sect193r1", "EC", 3),
+ TLS_GROUP_ENTRY("sect193r2", "sect193r2", "EC", 4),
+# endif
+# ifndef OPENSSL_NO_EC2M
+ TLS_GROUP_ENTRY("sect233k1", "sect233k1", "EC", 5),
+ TLS_GROUP_ENTRY("K-233", "sect233k1", "EC", 5), /* Alias of above */
+ TLS_GROUP_ENTRY("sect233r1", "sect233r1", "EC", 6),
+ TLS_GROUP_ENTRY("B-233", "sect233r1", "EC", 6), /* Alias of above */
+# endif
+# ifndef FIPS_MODULE
+ TLS_GROUP_ENTRY("sect239k1", "sect239k1", "EC", 7),
+# endif
+# ifndef OPENSSL_NO_EC2M
+ TLS_GROUP_ENTRY("sect283k1", "sect283k1", "EC", 8),
+ TLS_GROUP_ENTRY("K-283", "sect283k1", "EC", 8), /* Alias of above */
+ TLS_GROUP_ENTRY("sect283r1", "sect283r1", "EC", 9),
+ TLS_GROUP_ENTRY("B-283", "sect283r1", "EC", 9), /* Alias of above */
+ TLS_GROUP_ENTRY("sect409k1", "sect409k1", "EC", 10),
+ TLS_GROUP_ENTRY("K-409", "sect409k1", "EC", 10), /* Alias of above */
+ TLS_GROUP_ENTRY("sect409r1", "sect409r1", "EC", 11),
+ TLS_GROUP_ENTRY("B-409", "sect409r1", "EC", 11), /* Alias of above */
+ TLS_GROUP_ENTRY("sect571k1", "sect571k1", "EC", 12),
+ TLS_GROUP_ENTRY("K-571", "sect571k1", "EC", 12), /* Alias of above */
+ TLS_GROUP_ENTRY("sect571r1", "sect571r1", "EC", 13),
+ TLS_GROUP_ENTRY("B-571", "sect571r1", "EC", 13), /* Alias of above */
+# endif
+# ifndef FIPS_MODULE
+ TLS_GROUP_ENTRY("secp160k1", "secp160k1", "EC", 14),
+ TLS_GROUP_ENTRY("secp160r1", "secp160r1", "EC", 15),
+ TLS_GROUP_ENTRY("secp160r2", "secp160r2", "EC", 16),
+ TLS_GROUP_ENTRY("secp192k1", "secp192k1", "EC", 17),
+# endif
+ TLS_GROUP_ENTRY("secp192r1", "prime192v1", "EC", 18),
+ TLS_GROUP_ENTRY("P-192", "prime192v1", "EC", 18), /* Alias of above */
+# ifndef FIPS_MODULE
+ TLS_GROUP_ENTRY("secp224k1", "secp224k1", "EC", 19),
+# endif
+ TLS_GROUP_ENTRY("secp224r1", "secp224r1", "EC", 20),
+ TLS_GROUP_ENTRY("P-224", "secp224r1", "EC", 20), /* Alias of above */
+# ifndef FIPS_MODULE
+ TLS_GROUP_ENTRY("secp256k1", "secp256k1", "EC", 21),
+# endif
+ TLS_GROUP_ENTRY("secp256r1", "prime256v1", "EC", 22),
+ TLS_GROUP_ENTRY("P-256", "prime256v1", "EC", 22), /* Alias of above */
+ TLS_GROUP_ENTRY("secp384r1", "secp384r1", "EC", 23),
+ TLS_GROUP_ENTRY("P-384", "secp384r1", "EC", 23), /* Alias of above */
+ TLS_GROUP_ENTRY("secp521r1", "secp521r1", "EC", 24),
+ TLS_GROUP_ENTRY("P-521", "secp521r1", "EC", 24), /* Alias of above */
+# ifndef FIPS_MODULE
+ TLS_GROUP_ENTRY("brainpoolP256r1", "brainpoolP256r1", "EC", 25),
+ TLS_GROUP_ENTRY("brainpoolP384r1", "brainpoolP384r1", "EC", 26),
+ TLS_GROUP_ENTRY("brainpoolP512r1", "brainpoolP512r1", "EC", 27),
+# endif
+ TLS_GROUP_ENTRY("x25519", "X25519", "X25519", 28),
+ TLS_GROUP_ENTRY("x448", "X448", "X448", 29),
+# endif /* OPENSSL_NO_EC */
+# ifndef OPENSSL_NO_DH
+ /* Security bit values for FFDHE groups are as per RFC 7919 */
+ TLS_GROUP_ENTRY("ffdhe2048", "ffdhe2048", "DH", 30),
+ TLS_GROUP_ENTRY("ffdhe3072", "ffdhe3072", "DH", 31),
+ TLS_GROUP_ENTRY("ffdhe4096", "ffdhe4096", "DH", 32),
+ TLS_GROUP_ENTRY("ffdhe6144", "ffdhe6144", "DH", 33),
+ TLS_GROUP_ENTRY("ffdhe8192", "ffdhe8192", "DH", 34),
+# endif
+};
+#endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */
+
+static int tls_group_capability(OSSL_CALLBACK *cb, void *arg)
+{
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
+ size_t i;
+
+ for (i = 0; i < OSSL_NELEM(param_group_list); i++)
+ if (!cb(param_group_list[i], arg))
+ return 0;
+#endif
+
+ return 1;
+}
+
+int ossl_prov_get_capabilities(void *provctx, const char *capability,
+ OSSL_CALLBACK *cb, void *arg)
+{
+ if (OPENSSL_strcasecmp(capability, "TLS-GROUP") == 0)
+ return tls_group_capability(cb, arg);
+
+ /* We don't support this capability */
+ return 0;
+}
diff --git a/providers/common/der/DIGESTS.asn1 b/providers/common/der/DIGESTS.asn1
new file mode 100644
index 000000000000..7251a9e1367e
--- /dev/null
+++ b/providers/common/der/DIGESTS.asn1
@@ -0,0 +1,43 @@
+-- Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+--
+-- Licensed under the Apache License 2.0 (the "License"). You may not use
+-- this file except in compliance with the License. You can obtain a copy
+-- in the file LICENSE in the source distribution or at
+-- https://www.openssl.org/source/license.html
+
+-- -------------------------------------------------------------------
+-- From https://tools.ietf.org/html/rfc4055#section-2.1
+
+id-sha1 OBJECT IDENTIFIER ::= { iso(1)
+ identified-organization(3) oiw(14)
+ secsig(3) algorithms(2) 26 }
+
+-- -------------------------------------------------------------------
+-- From https://tools.ietf.org/html/rfc5480#appendix-A
+-- (OIDs for MD2 and MD5 are allowed only in EMSA-PKCS1-v1_5)
+
+id-md2 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 }
+
+id-md5 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 }
+
+-- -------------------------------------------------------------------
+-- From https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration
+
+id-sha256 OBJECT IDENTIFIER ::= { hashAlgs 1 }
+id-sha384 OBJECT IDENTIFIER ::= { hashAlgs 2 }
+id-sha512 OBJECT IDENTIFIER ::= { hashAlgs 3 }
+id-sha224 OBJECT IDENTIFIER ::= { hashAlgs 4 }
+id-sha512-224 OBJECT IDENTIFIER ::= { hashAlgs 5 }
+id-sha512-256 OBJECT IDENTIFIER ::= { hashAlgs 6 }
+id-sha3-224 OBJECT IDENTIFIER ::= { hashAlgs 7 }
+id-sha3-256 OBJECT IDENTIFIER ::= { hashAlgs 8 }
+id-sha3-384 OBJECT IDENTIFIER ::= { hashAlgs 9 }
+id-sha3-512 OBJECT IDENTIFIER ::= { hashAlgs 10 }
+id-shake128 OBJECT IDENTIFIER ::= { hashAlgs 11 }
+id-shake256 OBJECT IDENTIFIER ::= { hashAlgs 12 }
+id-shake128-len OBJECT IDENTIFIER ::= { hashAlgs 17 }
+id-shake256-len OBJECT IDENTIFIER ::= { hashAlgs 18 }
+id-KMACWithSHAKE128 OBJECT IDENTIFIER ::={hashAlgs 19}
+id-KMACWithSHAKE256 OBJECT IDENTIFIER ::={ hashAlgs 20}
diff --git a/providers/common/der/DSA.asn1 b/providers/common/der/DSA.asn1
new file mode 100644
index 000000000000..2c90294aefad
--- /dev/null
+++ b/providers/common/der/DSA.asn1
@@ -0,0 +1,36 @@
+-- Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+--
+-- Licensed under the Apache License 2.0 (the "License"). You may not use
+-- this file except in compliance with the License. You can obtain a copy
+-- in the file LICENSE in the source distribution or at
+-- https://www.openssl.org/source/license.html
+
+-- -------------------------------------------------------------------
+-- Taken from RFC 3279, 3 ASN.1 Module
+-- (https://www.rfc-editor.org/rfc/rfc3279.html#section-3)
+
+-- OID for DSA public key
+
+id-dsa OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 }
+
+-- OID for DSA signature generated with SHA-1 hash
+
+id-dsa-with-sha1 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) x9-57 (10040) x9algorithm(4) 3 }
+
+
+-- -------------------------------------------------------------------
+-- Taken from https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration
+
+sigAlgs OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 4 3 }
+
+id-dsa-with-sha224 OBJECT IDENTIFIER ::= { sigAlgs 1 }
+id-dsa-with-sha256 OBJECT IDENTIFIER ::= { sigAlgs 2 }
+id-dsa-with-sha384 OBJECT IDENTIFIER ::= { sigAlgs 3 }
+id-dsa-with-sha512 OBJECT IDENTIFIER ::= { sigAlgs 4 }
+
+id-dsa-with-sha3-224 OBJECT IDENTIFIER ::= { sigAlgs 5 }
+id-dsa-with-sha3-256 OBJECT IDENTIFIER ::= { sigAlgs 6 }
+id-dsa-with-sha3-384 OBJECT IDENTIFIER ::= { sigAlgs 7 }
+id-dsa-with-sha3-512 OBJECT IDENTIFIER ::= { sigAlgs 8 }
diff --git a/providers/common/der/EC.asn1 b/providers/common/der/EC.asn1
new file mode 100644
index 000000000000..417103b81b83
--- /dev/null
+++ b/providers/common/der/EC.asn1
@@ -0,0 +1,90 @@
+-- Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+--
+-- Licensed under the Apache License 2.0 (the "License"). You may not use
+-- this file except in compliance with the License. You can obtain a copy
+-- in the file LICENSE in the source distribution or at
+-- https://www.openssl.org/source/license.html
+
+-- -------------------------------------------------------------------
+-- Taken from RFC 3279, 3 ASN.1 Module
+-- (https://www.rfc-editor.org/rfc/rfc3279.html#section-3)
+
+ansi-X9-62 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) 10045 }
+
+-- Arc for ECDSA signature OIDS
+
+id-ecSigType OBJECT IDENTIFIER ::= { ansi-X9-62 signatures(4) }
+
+-- OID for ECDSA signatures with SHA-1
+
+ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { id-ecSigType 1 }
+
+id-publicKeyType OBJECT IDENTIFIER ::= { ansi-X9-62 keyType(2) }
+
+id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 }
+
+-- Named Elliptic Curves in ANSI X9.62.
+
+ellipticCurve OBJECT IDENTIFIER ::= { ansi-X9-62 curves(3) }
+
+c-TwoCurve OBJECT IDENTIFIER ::= {
+ ellipticCurve characteristicTwo(0) }
+
+c2pnb163v1 OBJECT IDENTIFIER ::= { c-TwoCurve 1 }
+c2pnb163v2 OBJECT IDENTIFIER ::= { c-TwoCurve 2 }
+c2pnb163v3 OBJECT IDENTIFIER ::= { c-TwoCurve 3 }
+c2pnb176w1 OBJECT IDENTIFIER ::= { c-TwoCurve 4 }
+c2tnb191v1 OBJECT IDENTIFIER ::= { c-TwoCurve 5 }
+c2tnb191v2 OBJECT IDENTIFIER ::= { c-TwoCurve 6 }
+c2tnb191v3 OBJECT IDENTIFIER ::= { c-TwoCurve 7 }
+c2onb191v4 OBJECT IDENTIFIER ::= { c-TwoCurve 8 }
+c2onb191v5 OBJECT IDENTIFIER ::= { c-TwoCurve 9 }
+c2pnb208w1 OBJECT IDENTIFIER ::= { c-TwoCurve 10 }
+c2tnb239v1 OBJECT IDENTIFIER ::= { c-TwoCurve 11 }
+c2tnb239v2 OBJECT IDENTIFIER ::= { c-TwoCurve 12 }
+c2tnb239v3 OBJECT IDENTIFIER ::= { c-TwoCurve 13 }
+c2onb239v4 OBJECT IDENTIFIER ::= { c-TwoCurve 14 }
+c2onb239v5 OBJECT IDENTIFIER ::= { c-TwoCurve 15 }
+c2pnb272w1 OBJECT IDENTIFIER ::= { c-TwoCurve 16 }
+c2pnb304w1 OBJECT IDENTIFIER ::= { c-TwoCurve 17 }
+c2tnb359v1 OBJECT IDENTIFIER ::= { c-TwoCurve 18 }
+c2pnb368w1 OBJECT IDENTIFIER ::= { c-TwoCurve 19 }
+c2tnb431r1 OBJECT IDENTIFIER ::= { c-TwoCurve 20 }
+
+primeCurve OBJECT IDENTIFIER ::= { ellipticCurve prime(1) }
+
+prime192v1 OBJECT IDENTIFIER ::= { primeCurve 1 }
+prime192v2 OBJECT IDENTIFIER ::= { primeCurve 2 }
+prime192v3 OBJECT IDENTIFIER ::= { primeCurve 3 }
+prime239v1 OBJECT IDENTIFIER ::= { primeCurve 4 }
+prime239v2 OBJECT IDENTIFIER ::= { primeCurve 5 }
+prime239v3 OBJECT IDENTIFIER ::= { primeCurve 6 }
+prime256v1 OBJECT IDENTIFIER ::= { primeCurve 7 }
+
+-- -------------------------------------------------------------------
+-- Taken from RFC 5758, 3.2. ECDSA Signature Algorithm
+-- (https://www.rfc-editor.org/rfc/rfc5758.html#section-3.2)
+
+ecdsa-with-SHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 1 }
+
+ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
+
+ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
+
+ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+ us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
+
+-- -------------------------------------------------------------------
+-- Taken from https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration
+
+sigAlgs OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 4 3 }
+
+id-ecdsa-with-sha3-224 OBJECT IDENTIFIER ::= { sigAlgs 9 }
+id-ecdsa-with-sha3-256 OBJECT IDENTIFIER ::= { sigAlgs 10 }
+id-ecdsa-with-sha3-384 OBJECT IDENTIFIER ::= { sigAlgs 11 }
+id-ecdsa-with-sha3-512 OBJECT IDENTIFIER ::= { sigAlgs 12 }
+
diff --git a/providers/common/der/ECX.asn1 b/providers/common/der/ECX.asn1
new file mode 100644
index 000000000000..be258044be97
--- /dev/null
+++ b/providers/common/der/ECX.asn1
@@ -0,0 +1,17 @@
+-- Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+--
+-- Licensed under the Apache License 2.0 (the "License"). You may not use
+-- this file except in compliance with the License. You can obtain a copy
+-- in the file LICENSE in the source distribution or at
+-- https://www.openssl.org/source/license.html
+
+-- -------------------------------------------------------------------
+-- Taken from RFC 8410, 9 ASN.1 Module
+-- (https://tools.ietf.org/html/rfc8410#section-9)
+
+id-edwards-curve-algs OBJECT IDENTIFIER ::= { 1 3 101 }
+
+id-X25519 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 110 }
+id-X448 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 111 }
+id-Ed25519 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 112 }
+id-Ed448 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 113 }
diff --git a/providers/common/der/NIST.asn1 b/providers/common/der/NIST.asn1
new file mode 100644
index 000000000000..eafac3879347
--- /dev/null
+++ b/providers/common/der/NIST.asn1
@@ -0,0 +1,15 @@
+-- Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+--
+-- Licensed under the Apache License 2.0 (the "License"). You may not use
+-- this file except in compliance with the License. You can obtain a copy
+-- in the file LICENSE in the source distribution or at
+-- https://www.openssl.org/source/license.html
+
+-- -------------------------------------------------------------------
+-- Taken from https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration
+
+-- Copies of common OIDs used by other ASN.1 files.
+csor OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 }
+nistAlgorithms OBJECT IDENTIFIER ::= { csor nistAlgorithm(4) }
+hashAlgs OBJECT IDENTIFIER ::= { nistAlgorithms 2 }
+sigAlgs OBJECT IDENTIFIER ::= { nistAlgorithms 3 }
diff --git a/providers/common/der/RSA.asn1 b/providers/common/der/RSA.asn1
new file mode 100644
index 000000000000..3695ee7ad14a
--- /dev/null
+++ b/providers/common/der/RSA.asn1
@@ -0,0 +1,89 @@
+-- Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+--
+-- Licensed under the Apache License 2.0 (the "License"). You may not use
+-- this file except in compliance with the License. You can obtain a copy
+-- in the file LICENSE in the source distribution or at
+-- https://www.openssl.org/source/license.html
+
+-- -------------------------------------------------------------------
+-- Taken from RFC 8017, Appendix C
+-- (https://www.rfc-editor.org/rfc/rfc8017.html#appendix-C)
+
+-- ============================
+-- Basic object identifiers
+-- ============================
+
+-- The DER encoding of this in hexadecimal is:
+-- (0x)06 08
+-- 2A 86 48 86 F7 0D 01 01
+--
+pkcs-1 OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1
+}
+
+--
+-- When rsaEncryption is used in an AlgorithmIdentifier,
+-- the parameters MUST be present and MUST be NULL.
+--
+rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
+
+--
+-- When id-RSAES-OAEP is used in an AlgorithmIdentifier, the
+-- parameters MUST be present and MUST be RSAES-OAEP-params.
+--
+id-RSAES-OAEP OBJECT IDENTIFIER ::= { pkcs-1 7 }
+
+--
+-- When id-pSpecified is used in an AlgorithmIdentifier, the
+-- parameters MUST be an OCTET STRING.
+--
+id-pSpecified OBJECT IDENTIFIER ::= { pkcs-1 9 }
+
+--
+-- When id-RSASSA-PSS is used in an AlgorithmIdentifier, the
+-- parameters MUST be present and MUST be RSASSA-PSS-params.
+--
+id-RSASSA-PSS OBJECT IDENTIFIER ::= { pkcs-1 10 }
+
+--
+-- When the following OIDs are used in an AlgorithmIdentifier,
+-- the parameters MUST be present and MUST be NULL.
+--
+md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
+md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
+sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
+sha224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 14 }
+sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
+sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
+sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
+sha512-224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 15 }
+sha512-256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 16 }
+
+--
+-- When id-mgf1 is used in an AlgorithmIdentifier, the parameters
+-- MUST be present and MUST be a HashAlgorithm, for example, sha1.
+--
+id-mgf1 OBJECT IDENTIFIER ::= { pkcs-1 8 }
+
+-- -------------------------------------------------------------------
+-- Taken from https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration
+
+id-rsassa-pkcs1-v1_5-with-sha3-224 OBJECT IDENTIFIER ::= { sigAlgs 13 }
+id-rsassa-pkcs1-v1_5-with-sha3-256 OBJECT IDENTIFIER ::= { sigAlgs 14 }
+id-rsassa-pkcs1-v1_5-with-sha3-384 OBJECT IDENTIFIER ::= { sigAlgs 15 }
+id-rsassa-pkcs1-v1_5-with-sha3-512 OBJECT IDENTIFIER ::= { sigAlgs 16 }
+
+
+-- -------------------------------------------------------------------
+-- These OID's exist in the codebase but may need to be deprecated at some point.
+-- md5_sha1 has been omitted as it does not look like valid entry.
+
+md4WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 3 }
+
+ripemd160WithRSAEncryption OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) teletrust(36) algorithm(3) signatureAlgorithm(3) rsaSignature(1) 2
+}
+
+mdc2WithRSASignature OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) mdc2WithRSASignature(14)
+}
diff --git a/providers/common/der/SM2.asn1 b/providers/common/der/SM2.asn1
new file mode 100644
index 000000000000..f3f173c42c94
--- /dev/null
+++ b/providers/common/der/SM2.asn1
@@ -0,0 +1,18 @@
+-- Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+--
+-- Licensed under the Apache License 2.0 (the "License"). You may not use
+-- this file except in compliance with the License. You can obtain a copy
+-- in the file LICENSE in the source distribution or at
+-- https://www.openssl.org/source/license.html
+
+oscca OBJECT IDENTIFIER ::= { iso(1) member-body(2) cn(156) 10197 }
+
+sm-scheme OBJECT IDENTIFIER ::= { oscca 1 }
+
+-- OID for SM2 signatures with SM3
+
+sm2-with-SM3 OBJECT IDENTIFIER ::= { sm-scheme 501 }
+
+-- Named Elliptic Curves of SM2
+
+curveSM2 OBJECT IDENTIFIER ::= { sm-scheme 301 }
diff --git a/providers/common/der/build.info b/providers/common/der/build.info
new file mode 100644
index 000000000000..b81413e11beb
--- /dev/null
+++ b/providers/common/der/build.info
@@ -0,0 +1,119 @@
+$INCDIR=../include/prov
+
+#----- Digests
+$DER_DIGESTS_H=$INCDIR/der_digests.h
+$DER_DIGESTS_GEN=der_digests_gen.c
+
+GENERATE[$DER_DIGESTS_GEN]=der_digests_gen.c.in
+DEPEND[$DER_DIGESTS_GEN]=oids_to_c.pm NIST.asn1 DIGESTS.asn1
+
+DEPEND[${DER_DIGESTS_GEN/.c/.o}]=$DER_DIGESTS_H
+GENERATE[$DER_DIGESTS_H]=$INCDIR/der_digests.h.in
+DEPEND[$DER_DIGESTS_H]=oids_to_c.pm NIST.asn1 DIGESTS.asn1
+
+#----- RSA
+$DER_RSA_H=$INCDIR/der_rsa.h
+$DER_RSA_GEN=der_rsa_gen.c
+$DER_RSA_AUX=der_rsa_key.c der_rsa_sig.c
+$DER_RSA_COMMON=$DER_RSA_GEN der_rsa_key.c
+$DER_RSA_FIPSABLE=der_rsa_sig.c
+
+GENERATE[$DER_RSA_GEN]=der_rsa_gen.c.in
+DEPEND[$DER_RSA_GEN]=oids_to_c.pm NIST.asn1 RSA.asn1
+
+DEPEND[${DER_RSA_AUX/.c/.o}]=$DER_RSA_H $DER_DIGESTS_H
+DEPEND[${DER_RSA_GEN/.c/.o}]=$DER_RSA_H
+GENERATE[$DER_RSA_H]=$INCDIR/der_rsa.h.in
+DEPEND[$DER_RSA_H]=oids_to_c.pm NIST.asn1 RSA.asn1
+
+#----- DSA
+IF[{- !$disabled{dsa} -}]
+ $DER_DSA_H=$INCDIR/der_dsa.h
+ $DER_DSA_GEN=der_dsa_gen.c
+ $DER_DSA_AUX=der_dsa_key.c der_dsa_sig.c
+
+ GENERATE[$DER_DSA_GEN]=der_dsa_gen.c.in
+ DEPEND[$DER_DSA_GEN]=oids_to_c.pm DSA.asn1
+
+ DEPEND[${DER_DSA_AUX/.c/.o}]=$DER_DSA_H $DER_DIGESTS_H
+ DEPEND[${DER_DSA_GEN/.c/.o}]=$DER_DSA_H
+ GENERATE[$DER_DSA_H]=$INCDIR/der_dsa.h.in
+ DEPEND[$DER_DSA_H]=oids_to_c.pm DSA.asn1
+ENDIF
+
+#----- EC
+IF[{- !$disabled{ec} -}]
+ $DER_EC_H=$INCDIR/der_ec.h
+ $DER_EC_GEN=der_ec_gen.c
+ $DER_EC_AUX=der_ec_key.c der_ec_sig.c
+
+ GENERATE[$DER_EC_GEN]=der_ec_gen.c.in
+ DEPEND[$DER_EC_GEN]=oids_to_c.pm EC.asn1
+
+ DEPEND[${DER_EC_AUX/.c/.o}]=$DER_EC_H $DER_DIGESTS_H
+ DEPEND[${DER_EC_GEN/.c/.o}]=$DER_EC_H
+ GENERATE[$DER_EC_H]=$INCDIR/der_ec.h.in
+ DEPEND[$DER_EC_H]=oids_to_c.pm EC.asn1
+ENDIF
+
+#----- ECX
+IF[{- !$disabled{ec} -}]
+ $DER_ECX_H=$INCDIR/der_ecx.h
+ $DER_ECX_GEN=der_ecx_gen.c
+ $DER_ECX_AUX=der_ecx_key.c
+
+ GENERATE[$DER_ECX_GEN]=der_ecx_gen.c.in
+ DEPEND[$DER_ECX_GEN]=oids_to_c.pm ECX.asn1
+
+ DEPEND[${DER_ECX_AUX/.c/.o}]=$DER_ECX_H
+ DEPEND[${DER_ECX_GEN/.c/.o}]=$DER_ECX_H
+ GENERATE[$DER_ECX_H]=$INCDIR/der_ecx.h.in
+ DEPEND[$DER_ECX_H]=oids_to_c.pm ECX.asn1
+ENDIF
+
+#----- KEY WRAP
+$DER_WRAP_H=$INCDIR/der_wrap.h
+$DER_WRAP_GEN=der_wrap_gen.c
+
+GENERATE[$DER_WRAP_GEN]=der_wrap_gen.c.in
+DEPEND[$DER_WRAP_GEN]=oids_to_c.pm wrap.asn1
+
+DEPEND[${DER_WRAP_GEN/.c/.o}]=$DER_WRAP_H
+GENERATE[$DER_WRAP_H]=$INCDIR/der_wrap.h.in
+DEPEND[$DER_WRAP_H]=oids_to_c.pm wrap.asn1
+
+#----- SM2
+IF[{- !$disabled{sm2} -}]
+ $DER_SM2_H=$INCDIR/der_sm2.h
+ $DER_SM2_GEN=der_sm2_gen.c
+ $DER_SM2_AUX=der_sm2_key.c der_sm2_sig.c
+
+ GENERATE[$DER_SM2_GEN]=der_sm2_gen.c.in
+ DEPEND[$DER_SM2_GEN]=oids_to_c.pm SM2.asn1
+
+ DEPEND[${DER_SM2_AUX/.c/.o}]=$DER_SM2_H $DER_EC_H
+ DEPEND[${DER_SM2_GEN/.c/.o}]=$DER_SM2_H
+ GENERATE[$DER_SM2_H]=$INCDIR/der_sm2.h.in
+ DEPEND[$DER_SM2_H]=oids_to_c.pm SM2.asn1
+ENDIF
+
+#----- Conclusion
+
+$COMMON= $DER_RSA_COMMON $DER_DIGESTS_GEN $DER_WRAP_GEN
+
+IF[{- !$disabled{dsa} -}]
+ $COMMON = $COMMON $DER_DSA_GEN $DER_DSA_AUX
+ENDIF
+
+IF[{- !$disabled{ec} -}]
+ $COMMON = $COMMON $DER_EC_GEN $DER_EC_AUX
+ $COMMON = $COMMON $DER_ECX_GEN $DER_ECX_AUX
+ENDIF
+
+IF[{- !$disabled{sm2} -}]
+ $NONFIPS = $NONFIPS $DER_SM2_GEN $DER_SM2_AUX
+ENDIF
+
+SOURCE[../../libcommon.a]= $COMMON
+SOURCE[../../libfips.a]= $DER_RSA_FIPSABLE
+SOURCE[../../libdefault.a]= $DER_RSA_FIPSABLE $NONFIPS
diff --git a/providers/common/der/der_digests_gen.c.in b/providers/common/der/der_digests_gen.c.in
new file mode 100644
index 000000000000..9b6da1dafb1c
--- /dev/null
+++ b/providers/common/der/der_digests_gen.c.in
@@ -0,0 +1,20 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "prov/der_digests.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/NIST.asn1',
+ 'providers/common/der/DIGESTS.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_C });
+-}
diff --git a/providers/common/der/der_dsa_gen.c.in b/providers/common/der/der_dsa_gen.c.in
new file mode 100644
index 000000000000..dd581567e87a
--- /dev/null
+++ b/providers/common/der/der_dsa_gen.c.in
@@ -0,0 +1,25 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * DSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
+#include "prov/der_dsa.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/DSA.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_C });
+-}
diff --git a/providers/common/der/der_dsa_key.c b/providers/common/der/der_dsa_key.c
new file mode 100644
index 000000000000..dc7b2fe8faa6
--- /dev/null
+++ b/providers/common/der/der_dsa_key.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * DSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
+#include <openssl/obj_mac.h>
+#include "internal/packet.h"
+#include "prov/der_dsa.h"
+
+int ossl_DER_w_algorithmIdentifier_DSA(WPACKET *pkt, int tag, DSA *dsa)
+{
+ return ossl_DER_w_begin_sequence(pkt, tag)
+ /* No parameters (yet?) */
+ && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_dsa,
+ sizeof(ossl_der_oid_id_dsa))
+ && ossl_DER_w_end_sequence(pkt, tag);
+}
diff --git a/providers/common/der/der_dsa_sig.c b/providers/common/der/der_dsa_sig.c
new file mode 100644
index 000000000000..07225b7b119b
--- /dev/null
+++ b/providers/common/der/der_dsa_sig.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * DSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
+#include <openssl/obj_mac.h>
+#include "internal/packet.h"
+#include "prov/der_dsa.h"
+
+#define MD_CASE(name) \
+ case NID_##name: \
+ precompiled = ossl_der_oid_id_dsa_with_##name; \
+ precompiled_sz = sizeof(ossl_der_oid_id_dsa_with_##name); \
+ break;
+
+int ossl_DER_w_algorithmIdentifier_DSA_with_MD(WPACKET *pkt, int tag,
+ DSA *dsa, int mdnid)
+{
+ const unsigned char *precompiled = NULL;
+ size_t precompiled_sz = 0;
+
+ switch (mdnid) {
+ MD_CASE(sha1);
+ MD_CASE(sha224);
+ MD_CASE(sha256);
+ MD_CASE(sha384);
+ MD_CASE(sha512);
+ MD_CASE(sha3_224);
+ MD_CASE(sha3_256);
+ MD_CASE(sha3_384);
+ MD_CASE(sha3_512);
+ default:
+ return 0;
+ }
+
+ return ossl_DER_w_begin_sequence(pkt, tag)
+ /* No parameters (yet?) */
+ && ossl_DER_w_precompiled(pkt, -1, precompiled, precompiled_sz)
+ && ossl_DER_w_end_sequence(pkt, tag);
+}
diff --git a/providers/common/der/der_ec_gen.c.in b/providers/common/der/der_ec_gen.c.in
new file mode 100644
index 000000000000..ec47686ebe2b
--- /dev/null
+++ b/providers/common/der/der_ec_gen.c.in
@@ -0,0 +1,19 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "prov/der_ec.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/EC.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_C });
+-}
diff --git a/providers/common/der/der_ec_key.c b/providers/common/der/der_ec_key.c
new file mode 100644
index 000000000000..ae0775af5340
--- /dev/null
+++ b/providers/common/der/der_ec_key.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/obj_mac.h>
+#include "internal/packet.h"
+#include "prov/der_ec.h"
+
+int ossl_DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec)
+{
+ return ossl_DER_w_begin_sequence(pkt, cont)
+ /* No parameters (yet?) */
+ && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_ecPublicKey,
+ sizeof(ossl_der_oid_id_ecPublicKey))
+ && ossl_DER_w_end_sequence(pkt, cont);
+}
diff --git a/providers/common/der/der_ec_sig.c b/providers/common/der/der_ec_sig.c
new file mode 100644
index 000000000000..25b672dab2f1
--- /dev/null
+++ b/providers/common/der/der_ec_sig.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/obj_mac.h>
+#include "internal/packet.h"
+#include "prov/der_ec.h"
+
+/* Aliases so we can have a uniform MD_CASE */
+#define ossl_der_oid_id_ecdsa_with_sha1 ossl_der_oid_ecdsa_with_SHA1
+#define ossl_der_oid_id_ecdsa_with_sha224 ossl_der_oid_ecdsa_with_SHA224
+#define ossl_der_oid_id_ecdsa_with_sha256 ossl_der_oid_ecdsa_with_SHA256
+#define ossl_der_oid_id_ecdsa_with_sha384 ossl_der_oid_ecdsa_with_SHA384
+#define ossl_der_oid_id_ecdsa_with_sha512 ossl_der_oid_ecdsa_with_SHA512
+
+#define MD_CASE(name) \
+ case NID_##name: \
+ precompiled = ossl_der_oid_id_ecdsa_with_##name; \
+ precompiled_sz = sizeof(ossl_der_oid_id_ecdsa_with_##name); \
+ break;
+
+int ossl_DER_w_algorithmIdentifier_ECDSA_with_MD(WPACKET *pkt, int cont,
+ EC_KEY *ec, int mdnid)
+{
+ const unsigned char *precompiled = NULL;
+ size_t precompiled_sz = 0;
+
+ switch (mdnid) {
+ MD_CASE(sha1);
+ MD_CASE(sha224);
+ MD_CASE(sha256);
+ MD_CASE(sha384);
+ MD_CASE(sha512);
+ MD_CASE(sha3_224);
+ MD_CASE(sha3_256);
+ MD_CASE(sha3_384);
+ MD_CASE(sha3_512);
+ default:
+ return 0;
+ }
+
+ return ossl_DER_w_begin_sequence(pkt, cont)
+ /* No parameters (yet?) */
+ && ossl_DER_w_precompiled(pkt, -1, precompiled, precompiled_sz)
+ && ossl_DER_w_end_sequence(pkt, cont);
+}
diff --git a/providers/common/der/der_ecx_gen.c.in b/providers/common/der/der_ecx_gen.c.in
new file mode 100644
index 000000000000..bcd45b6e4d52
--- /dev/null
+++ b/providers/common/der/der_ecx_gen.c.in
@@ -0,0 +1,19 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "prov/der_ecx.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/ECX.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_C });
+-}
diff --git a/providers/common/der/der_ecx_key.c b/providers/common/der/der_ecx_key.c
new file mode 100644
index 000000000000..c00a11cac8ee
--- /dev/null
+++ b/providers/common/der/der_ecx_key.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/obj_mac.h>
+#include "internal/packet.h"
+#include "prov/der_ecx.h"
+
+int ossl_DER_w_algorithmIdentifier_X25519(WPACKET *pkt, int cont, ECX_KEY *ec)
+{
+ return ossl_DER_w_begin_sequence(pkt, cont)
+ /* No parameters (yet?) */
+ && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_X25519,
+ sizeof(ossl_der_oid_id_X25519))
+ && ossl_DER_w_end_sequence(pkt, cont);
+}
+
+int ossl_DER_w_algorithmIdentifier_X448(WPACKET *pkt, int cont, ECX_KEY *ec)
+{
+ return ossl_DER_w_begin_sequence(pkt, cont)
+ /* No parameters (yet?) */
+ && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_X448,
+ sizeof(ossl_der_oid_id_X448))
+ && ossl_DER_w_end_sequence(pkt, cont);
+}
+
+int ossl_DER_w_algorithmIdentifier_ED25519(WPACKET *pkt, int cont, ECX_KEY *ec)
+{
+ return ossl_DER_w_begin_sequence(pkt, cont)
+ /* No parameters (yet?) */
+ && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_Ed25519,
+ sizeof(ossl_der_oid_id_Ed25519))
+ && ossl_DER_w_end_sequence(pkt, cont);
+}
+
+int ossl_DER_w_algorithmIdentifier_ED448(WPACKET *pkt, int cont, ECX_KEY *ec)
+{
+ return ossl_DER_w_begin_sequence(pkt, cont)
+ /* No parameters (yet?) */
+ && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_Ed448,
+ sizeof(ossl_der_oid_id_Ed448))
+ && ossl_DER_w_end_sequence(pkt, cont);
+}
diff --git a/providers/common/der/der_rsa_gen.c.in b/providers/common/der/der_rsa_gen.c.in
new file mode 100644
index 000000000000..0560f649e8e0
--- /dev/null
+++ b/providers/common/der/der_rsa_gen.c.in
@@ -0,0 +1,20 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "prov/der_rsa.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/NIST.asn1',
+ 'providers/common/der/RSA.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_C });
+-}
diff --git a/providers/common/der/der_rsa_key.c b/providers/common/der/der_rsa_key.c
new file mode 100644
index 000000000000..771150d893da
--- /dev/null
+++ b/providers/common/der/der_rsa_key.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * RSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
+#include <openssl/obj_mac.h>
+#include "internal/cryptlib.h"
+#include "prov/der_rsa.h"
+#include "prov/der_digests.h"
+
+/* More complex pre-compiled sequences. */
+
+/*-
+ * From https://tools.ietf.org/html/rfc8017#appendix-A.2.1
+ *
+ * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-sha1 PARAMETERS NULL }|
+ * { OID id-sha224 PARAMETERS NULL }|
+ * { OID id-sha256 PARAMETERS NULL }|
+ * { OID id-sha384 PARAMETERS NULL }|
+ * { OID id-sha512 PARAMETERS NULL }|
+ * { OID id-sha512-224 PARAMETERS NULL }|
+ * { OID id-sha512-256 PARAMETERS NULL },
+ * ... -- Allows for future expansion --
+ * }
+ */
+#define DER_V_NULL DER_P_NULL, 0
+#define DER_SZ_NULL 2
+
+/*
+ * The names for the hash function AlgorithmIdentifiers are borrowed and
+ * expanded from https://tools.ietf.org/html/rfc4055#section-2.1
+ *
+ * sha1Identifier AlgorithmIdentifier ::= { id-sha1, NULL }
+ * sha224Identifier AlgorithmIdentifier ::= { id-sha224, NULL }
+ * sha256Identifier AlgorithmIdentifier ::= { id-sha256, NULL }
+ * sha384Identifier AlgorithmIdentifier ::= { id-sha384, NULL }
+ * sha512Identifier AlgorithmIdentifier ::= { id-sha512, NULL }
+ */
+/*
+ * NOTE: Some of the arrays aren't used other than inside sizeof(), which
+ * clang complains about (-Wno-unneeded-internal-declaration). To get
+ * around that, we make them non-static, and declare them an extra time to
+ * avoid compilers complaining about definitions without declarations.
+ */
+#define DER_AID_V_sha1Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_sha1 + DER_SZ_NULL, \
+ DER_OID_V_id_sha1, \
+ DER_V_NULL
+extern const unsigned char ossl_der_aid_sha1Identifier[];
+const unsigned char ossl_der_aid_sha1Identifier[] = {
+ DER_AID_V_sha1Identifier
+};
+#define DER_AID_SZ_sha1Identifier sizeof(ossl_der_aid_sha1Identifier)
+
+#define DER_AID_V_sha224Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_sha224 + DER_SZ_NULL, \
+ DER_OID_V_id_sha224, \
+ DER_V_NULL
+extern const unsigned char ossl_der_aid_sha224Identifier[];
+const unsigned char ossl_der_aid_sha224Identifier[] = {
+ DER_AID_V_sha224Identifier
+};
+#define DER_AID_SZ_sha224Identifier sizeof(ossl_der_aid_sha224Identifier)
+
+#define DER_AID_V_sha256Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_sha256 + DER_SZ_NULL, \
+ DER_OID_V_id_sha256, \
+ DER_V_NULL
+extern const unsigned char ossl_der_aid_sha256Identifier[];
+const unsigned char ossl_der_aid_sha256Identifier[] = {
+ DER_AID_V_sha256Identifier
+};
+#define DER_AID_SZ_sha256Identifier sizeof(ossl_der_aid_sha256Identifier)
+
+#define DER_AID_V_sha384Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_sha384 + DER_SZ_NULL, \
+ DER_OID_V_id_sha384, \
+ DER_V_NULL
+extern const unsigned char ossl_der_aid_sha384Identifier[];
+const unsigned char ossl_der_aid_sha384Identifier[] = {
+ DER_AID_V_sha384Identifier
+};
+#define DER_AID_SZ_sha384Identifier sizeof(ossl_der_aid_sha384Identifier)
+
+#define DER_AID_V_sha512Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_sha512 + DER_SZ_NULL, \
+ DER_OID_V_id_sha512, \
+ DER_V_NULL
+extern const unsigned char ossl_der_aid_sha512Identifier[];
+const unsigned char ossl_der_aid_sha512Identifier[] = {
+ DER_AID_V_sha512Identifier
+};
+#define DER_AID_SZ_sha512Identifier sizeof(ossl_der_aid_sha512Identifier)
+
+#define DER_AID_V_sha512_224Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_sha512_224 + DER_SZ_NULL, \
+ DER_OID_V_id_sha512_224, \
+ DER_V_NULL
+extern const unsigned char ossl_der_aid_sha512_224Identifier[];
+const unsigned char ossl_der_aid_sha512_224Identifier[] = {
+ DER_AID_V_sha512_224Identifier
+};
+#define DER_AID_SZ_sha512_224Identifier sizeof(ossl_der_aid_sha512_224Identifier)
+
+#define DER_AID_V_sha512_256Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_sha512_256 + DER_SZ_NULL, \
+ DER_OID_V_id_sha512_256, \
+ DER_V_NULL
+extern const unsigned char ossl_der_aid_sha512_256Identifier[];
+const unsigned char ossl_der_aid_sha512_256Identifier[] = {
+ DER_AID_V_sha512_256Identifier
+};
+#define DER_AID_SZ_sha512_256Identifier sizeof(ossl_der_aid_sha512_256Identifier)
+
+/*-
+ * From https://tools.ietf.org/html/rfc8017#appendix-A.2.1
+ *
+ * HashAlgorithm ::= AlgorithmIdentifier {
+ * {OAEP-PSSDigestAlgorithms}
+ * }
+ *
+ * ...
+ *
+ * PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-mgf1 PARAMETERS HashAlgorithm },
+ * ... -- Allows for future expansion --
+ * }
+ */
+
+/*
+ * The names for the MGF1 AlgorithmIdentifiers are borrowed and expanded
+ * from https://tools.ietf.org/html/rfc4055#section-2.1
+ *
+ * mgf1SHA1Identifier AlgorithmIdentifier ::=
+ * { id-mgf1, sha1Identifier }
+ * mgf1SHA224Identifier AlgorithmIdentifier ::=
+ * { id-mgf1, sha224Identifier }
+ * mgf1SHA256Identifier AlgorithmIdentifier ::=
+ * { id-mgf1, sha256Identifier }
+ * mgf1SHA384Identifier AlgorithmIdentifier ::=
+ * { id-mgf1, sha384Identifier }
+ * mgf1SHA512Identifier AlgorithmIdentifier ::=
+ * { id-mgf1, sha512Identifier }
+ */
+#if 0 /* Currently unused */
+#define DER_AID_V_mgf1SHA1Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha1Identifier, \
+ DER_OID_V_id_mgf1, \
+ DER_AID_V_sha1Identifier
+static const unsigned char der_aid_mgf1SHA1Identifier[] = {
+ DER_AID_V_mgf1SHA1Identifier
+};
+#define DER_AID_SZ_mgf1SHA1Identifier sizeof(der_aid_mgf1SHA1Identifier)
+#endif
+
+#define DER_AID_V_mgf1SHA224Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha224Identifier, \
+ DER_OID_V_id_mgf1, \
+ DER_AID_V_sha224Identifier
+static const unsigned char der_aid_mgf1SHA224Identifier[] = {
+ DER_AID_V_mgf1SHA224Identifier
+};
+#define DER_AID_SZ_mgf1SHA224Identifier sizeof(der_aid_mgf1SHA224Identifier)
+
+#define DER_AID_V_mgf1SHA256Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha256Identifier, \
+ DER_OID_V_id_mgf1, \
+ DER_AID_V_sha256Identifier
+static const unsigned char der_aid_mgf1SHA256Identifier[] = {
+ DER_AID_V_mgf1SHA256Identifier
+};
+#define DER_AID_SZ_mgf1SHA256Identifier sizeof(der_aid_mgf1SHA256Identifier)
+
+#define DER_AID_V_mgf1SHA384Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha384Identifier, \
+ DER_OID_V_id_mgf1, \
+ DER_AID_V_sha384Identifier
+static const unsigned char der_aid_mgf1SHA384Identifier[] = {
+ DER_AID_V_mgf1SHA384Identifier
+};
+#define DER_AID_SZ_mgf1SHA384Identifier sizeof(der_aid_mgf1SHA384Identifier)
+
+#define DER_AID_V_mgf1SHA512Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha512Identifier, \
+ DER_OID_V_id_mgf1, \
+ DER_AID_V_sha512Identifier
+static const unsigned char der_aid_mgf1SHA512Identifier[] = {
+ DER_AID_V_mgf1SHA512Identifier
+};
+#define DER_AID_SZ_mgf1SHA512Identifier sizeof(der_aid_mgf1SHA512Identifier)
+
+#define DER_AID_V_mgf1SHA512_224Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha512_224Identifier, \
+ DER_OID_V_id_mgf1, \
+ DER_AID_V_sha512_224Identifier
+static const unsigned char der_aid_mgf1SHA512_224Identifier[] = {
+ DER_AID_V_mgf1SHA512_224Identifier
+};
+#define DER_AID_SZ_mgf1SHA512_224Identifier sizeof(der_aid_mgf1SHA512_224Identifier)
+
+#define DER_AID_V_mgf1SHA512_256Identifier \
+ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \
+ DER_OID_SZ_id_mgf1 + DER_AID_SZ_sha512_256Identifier, \
+ DER_OID_V_id_mgf1, \
+ DER_AID_V_sha512_256Identifier
+static const unsigned char der_aid_mgf1SHA512_256Identifier[] = {
+ DER_AID_V_mgf1SHA512_256Identifier
+};
+#define DER_AID_SZ_mgf1SHA512_256Identifier sizeof(der_aid_mgf1SHA512_256Identifier)
+
+
+#define MGF1_SHA_CASE(bits, var) \
+ case NID_sha##bits: \
+ var = der_aid_mgf1SHA##bits##Identifier; \
+ var##_sz = sizeof(der_aid_mgf1SHA##bits##Identifier); \
+ break;
+
+/*-
+ * The name is borrowed from https://tools.ietf.org/html/rfc8017#appendix-A.2.1
+ *
+ * MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} }
+ */
+static int DER_w_MaskGenAlgorithm(WPACKET *pkt, int tag,
+ const RSA_PSS_PARAMS_30 *pss)
+{
+ if (pss != NULL && ossl_rsa_pss_params_30_maskgenalg(pss) == NID_mgf1) {
+ int maskgenhashalg_nid = ossl_rsa_pss_params_30_maskgenhashalg(pss);
+ const unsigned char *maskgenalg = NULL;
+ size_t maskgenalg_sz = 0;
+
+ switch (maskgenhashalg_nid) {
+ case NID_sha1:
+ break;
+ MGF1_SHA_CASE(224, maskgenalg);
+ MGF1_SHA_CASE(256, maskgenalg);
+ MGF1_SHA_CASE(384, maskgenalg);
+ MGF1_SHA_CASE(512, maskgenalg);
+ MGF1_SHA_CASE(512_224, maskgenalg);
+ MGF1_SHA_CASE(512_256, maskgenalg);
+ default:
+ return 0;
+ }
+
+ /* If there is none (or it was the default), we write nothing */
+ if (maskgenalg == NULL)
+ return 1;
+
+ return ossl_DER_w_precompiled(pkt, tag, maskgenalg, maskgenalg_sz);
+ }
+ return 0;
+}
+
+#define OAEP_PSS_MD_CASE(name, var) \
+ case NID_##name: \
+ var = ossl_der_aid_##name##Identifier; \
+ var##_sz = sizeof(ossl_der_aid_##name##Identifier); \
+ break;
+
+int ossl_DER_w_RSASSA_PSS_params(WPACKET *pkt, int tag,
+ const RSA_PSS_PARAMS_30 *pss)
+{
+ int hashalg_nid, default_hashalg_nid;
+ int saltlen, default_saltlen;
+ int trailerfield, default_trailerfield;
+ const unsigned char *hashalg = NULL;
+ size_t hashalg_sz = 0;
+
+ /*
+ * For an unrestricted key, this function should not have been called;
+ * the caller must be in control, because unrestricted keys are permitted
+ * in some situations (when encoding the public key in a SubjectKeyInfo,
+ * for example) while not in others, and this function doesn't know the
+ * intent. Therefore, we assert that here, the PSS parameters must show
+ * that the key is restricted.
+ */
+ if (!ossl_assert(pss != NULL
+ && !ossl_rsa_pss_params_30_is_unrestricted(pss)))
+ return 0;
+
+ hashalg_nid = ossl_rsa_pss_params_30_hashalg(pss);
+ saltlen = ossl_rsa_pss_params_30_saltlen(pss);
+ trailerfield = ossl_rsa_pss_params_30_trailerfield(pss);
+
+ if (saltlen < 0) {
+ ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_SALT_LENGTH);
+ return 0;
+ }
+ if (trailerfield != 1) {
+ ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_TRAILER);
+ return 0;
+ }
+
+ /* Getting default values */
+ default_hashalg_nid = ossl_rsa_pss_params_30_hashalg(NULL);
+ default_saltlen = ossl_rsa_pss_params_30_saltlen(NULL);
+ default_trailerfield = ossl_rsa_pss_params_30_trailerfield(NULL);
+
+ /*
+ * From https://tools.ietf.org/html/rfc8017#appendix-A.2.1:
+ *
+ * OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * { OID id-sha1 PARAMETERS NULL }|
+ * { OID id-sha224 PARAMETERS NULL }|
+ * { OID id-sha256 PARAMETERS NULL }|
+ * { OID id-sha384 PARAMETERS NULL }|
+ * { OID id-sha512 PARAMETERS NULL }|
+ * { OID id-sha512-224 PARAMETERS NULL }|
+ * { OID id-sha512-256 PARAMETERS NULL },
+ * ... -- Allows for future expansion --
+ * }
+ */
+ switch (hashalg_nid) {
+ OAEP_PSS_MD_CASE(sha1, hashalg);
+ OAEP_PSS_MD_CASE(sha224, hashalg);
+ OAEP_PSS_MD_CASE(sha256, hashalg);
+ OAEP_PSS_MD_CASE(sha384, hashalg);
+ OAEP_PSS_MD_CASE(sha512, hashalg);
+ OAEP_PSS_MD_CASE(sha512_224, hashalg);
+ OAEP_PSS_MD_CASE(sha512_256, hashalg);
+ default:
+ return 0;
+ }
+
+ return ossl_DER_w_begin_sequence(pkt, tag)
+ && (trailerfield == default_trailerfield
+ || ossl_DER_w_uint32(pkt, 3, (uint32_t)trailerfield))
+ && (saltlen == default_saltlen || ossl_DER_w_uint32(pkt, 2, (uint32_t)saltlen))
+ && DER_w_MaskGenAlgorithm(pkt, 1, pss)
+ && (hashalg_nid == default_hashalg_nid
+ || ossl_DER_w_precompiled(pkt, 0, hashalg, hashalg_sz))
+ && ossl_DER_w_end_sequence(pkt, tag);
+}
+
+/* Aliases so we can have a uniform RSA_CASE */
+#define ossl_der_oid_rsassaPss ossl_der_oid_id_RSASSA_PSS
+
+#define RSA_CASE(name, var) \
+ var##_nid = NID_##name; \
+ var##_oid = ossl_der_oid_##name; \
+ var##_oid_sz = sizeof(ossl_der_oid_##name); \
+ break;
+
+int ossl_DER_w_algorithmIdentifier_RSA_PSS(WPACKET *pkt, int tag,
+ int rsa_type,
+ const RSA_PSS_PARAMS_30 *pss)
+{
+ int rsa_nid = NID_undef;
+ const unsigned char *rsa_oid = NULL;
+ size_t rsa_oid_sz = 0;
+
+ switch (rsa_type) {
+ case RSA_FLAG_TYPE_RSA:
+ RSA_CASE(rsaEncryption, rsa);
+ case RSA_FLAG_TYPE_RSASSAPSS:
+ RSA_CASE(rsassaPss, rsa);
+ }
+
+ if (rsa_oid == NULL)
+ return 0;
+
+ return ossl_DER_w_begin_sequence(pkt, tag)
+ && (rsa_nid != NID_rsassaPss
+ || ossl_rsa_pss_params_30_is_unrestricted(pss)
+ || ossl_DER_w_RSASSA_PSS_params(pkt, -1, pss))
+ && ossl_DER_w_precompiled(pkt, -1, rsa_oid, rsa_oid_sz)
+ && ossl_DER_w_end_sequence(pkt, tag);
+}
+
+int ossl_DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa)
+{
+ int rsa_type = RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK);
+ RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30(rsa);
+
+ return ossl_DER_w_algorithmIdentifier_RSA_PSS(pkt, tag, rsa_type,
+ pss_params);
+}
diff --git a/providers/common/der/der_rsa_sig.c b/providers/common/der/der_rsa_sig.c
new file mode 100644
index 000000000000..08d00641e9b3
--- /dev/null
+++ b/providers/common/der/der_rsa_sig.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/obj_mac.h>
+#include "internal/packet.h"
+#include "prov/der_rsa.h"
+#include "prov/der_digests.h"
+
+/* Aliases so we can have a uniform MD_with_RSA_CASE */
+#define ossl_der_oid_sha3_224WithRSAEncryption \
+ ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_224
+#define ossl_der_oid_sha3_256WithRSAEncryption \
+ ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_256
+#define ossl_der_oid_sha3_384WithRSAEncryption \
+ ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_384
+#define ossl_der_oid_sha3_512WithRSAEncryption \
+ ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_512
+#define ossl_der_oid_mdc2WithRSAEncryption \
+ ossl_der_oid_mdc2WithRSASignature
+
+#define MD_with_RSA_CASE(name, var) \
+ case NID_##name: \
+ var = ossl_der_oid_##name##WithRSAEncryption; \
+ var##_sz = sizeof(ossl_der_oid_##name##WithRSAEncryption); \
+ break;
+
+int ossl_DER_w_algorithmIdentifier_MDWithRSAEncryption(WPACKET *pkt, int tag,
+ int mdnid)
+{
+ const unsigned char *precompiled = NULL;
+ size_t precompiled_sz = 0;
+
+ switch (mdnid) {
+#ifndef FIPS_MODULE
+ MD_with_RSA_CASE(md2, precompiled);
+ MD_with_RSA_CASE(md5, precompiled);
+ MD_with_RSA_CASE(md4, precompiled);
+ MD_with_RSA_CASE(ripemd160, precompiled);
+ MD_with_RSA_CASE(mdc2, precompiled);
+#endif
+ MD_with_RSA_CASE(sha1, precompiled);
+ MD_with_RSA_CASE(sha224, precompiled);
+ MD_with_RSA_CASE(sha256, precompiled);
+ MD_with_RSA_CASE(sha384, precompiled);
+ MD_with_RSA_CASE(sha512, precompiled);
+ MD_with_RSA_CASE(sha512_224, precompiled);
+ MD_with_RSA_CASE(sha512_256, precompiled);
+ MD_with_RSA_CASE(sha3_224, precompiled);
+ MD_with_RSA_CASE(sha3_256, precompiled);
+ MD_with_RSA_CASE(sha3_384, precompiled);
+ MD_with_RSA_CASE(sha3_512, precompiled);
+ default:
+ /*
+ * Hash algorithms for which we do not have a valid OID
+ * such as md5sha1 will just fail to provide the der encoding.
+ * That does not prevent producing signatures if OID is not needed.
+ */
+ return -1;
+ }
+
+ return ossl_DER_w_begin_sequence(pkt, tag)
+ /* PARAMETERS, always NULL according to current standards */
+ && ossl_DER_w_null(pkt, -1)
+ /* OID */
+ && ossl_DER_w_precompiled(pkt, -1, precompiled, precompiled_sz)
+ && ossl_DER_w_end_sequence(pkt, tag);
+}
diff --git a/providers/common/der/der_sm2_gen.c.in b/providers/common/der/der_sm2_gen.c.in
new file mode 100644
index 000000000000..ac28307bfb7d
--- /dev/null
+++ b/providers/common/der/der_sm2_gen.c.in
@@ -0,0 +1,19 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "prov/der_sm2.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/SM2.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_C });
+-}
diff --git a/providers/common/der/der_sm2_key.c b/providers/common/der/der_sm2_key.c
new file mode 100644
index 000000000000..d0b7e3aa2854
--- /dev/null
+++ b/providers/common/der/der_sm2_key.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/obj_mac.h>
+#include "internal/packet.h"
+#include "prov/der_ec.h"
+#include "prov/der_sm2.h"
+
+int ossl_DER_w_algorithmIdentifier_SM2(WPACKET *pkt, int cont, EC_KEY *ec)
+{
+ return ossl_DER_w_begin_sequence(pkt, cont)
+ /* No parameters (yet?) */
+ /* It seems SM2 identifier is the same as id_ecPublidKey */
+ && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_ecPublicKey,
+ sizeof(ossl_der_oid_id_ecPublicKey))
+ && ossl_DER_w_end_sequence(pkt, cont);
+}
diff --git a/providers/common/der/der_sm2_sig.c b/providers/common/der/der_sm2_sig.c
new file mode 100644
index 000000000000..085e2c7cb534
--- /dev/null
+++ b/providers/common/der/der_sm2_sig.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/obj_mac.h>
+#include "internal/packet.h"
+#include "prov/der_sm2.h"
+
+/* Aliases so we can have a uniform MD_CASE */
+#define ossl_der_oid_id_sm2_with_sm3 ossl_der_oid_sm2_with_SM3
+
+#define MD_CASE(name) \
+ case NID_##name: \
+ precompiled = ossl_der_oid_id_sm2_with_##name; \
+ precompiled_sz = sizeof(ossl_der_oid_id_sm2_with_##name); \
+ break;
+
+int ossl_DER_w_algorithmIdentifier_SM2_with_MD(WPACKET *pkt, int cont,
+ EC_KEY *ec, int mdnid)
+{
+ const unsigned char *precompiled = NULL;
+ size_t precompiled_sz = 0;
+
+ switch (mdnid) {
+ MD_CASE(sm3);
+ default:
+ return 0;
+ }
+
+ return ossl_DER_w_begin_sequence(pkt, cont)
+ /* No parameters (yet?) */
+ && ossl_DER_w_precompiled(pkt, -1, precompiled, precompiled_sz)
+ && ossl_DER_w_end_sequence(pkt, cont);
+}
diff --git a/providers/common/der/der_wrap_gen.c.in b/providers/common/der/der_wrap_gen.c.in
new file mode 100644
index 000000000000..d3a6bb909257
--- /dev/null
+++ b/providers/common/der/der_wrap_gen.c.in
@@ -0,0 +1,19 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "prov/der_wrap.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/wrap.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_C });
+-}
diff --git a/providers/common/der/oids_to_c.pm b/providers/common/der/oids_to_c.pm
new file mode 100644
index 000000000000..6f57df09b93a
--- /dev/null
+++ b/providers/common/der/oids_to_c.pm
@@ -0,0 +1,113 @@
+#! /usr/bin/env perl
+# Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+use warnings;
+
+package oids_to_c;
+
+use Carp;
+use File::Spec;
+use OpenSSL::OID;
+
+my $OID_name_re = qr/([a-z](?:[-_A-Za-z0-9]*[A-Za-z0-9])?)/;
+my $OID_value_re = qr/(\{.*?\})/s;
+my $OID_def_re = qr/
+ ${OID_name_re} \s+ OBJECT \s+ IDENTIFIER \s*
+ ::=
+ \s* ${OID_value_re}
+ /x;
+
+sub filter_to_H {
+ my ($name, $comment) = @{ shift() };
+ my @oid_nums = @_;
+ my $oid_size = scalar @oid_nums;
+
+ (my $C_comment = $comment) =~ s|^| * |msg;
+ $C_comment = "\n/*\n${C_comment}\n */" if $C_comment ne '';
+ (my $C_name = $name) =~ s|-|_|g;
+ my $C_bytes_size = 2 + scalar @_;
+ my $C_bytes = join(', ', map { sprintf("0x%02X", $_) } @oid_nums );
+
+ return <<"_____";
+$C_comment
+#define DER_OID_V_${C_name} DER_P_OBJECT, $oid_size, ${C_bytes}
+#define DER_OID_SZ_${C_name} ${C_bytes_size}
+extern const unsigned char ossl_der_oid_${C_name}[DER_OID_SZ_${C_name}];
+_____
+}
+
+sub filter_to_C {
+ my ($name, $comment) = @{ shift() };
+ my @oid_nums = @_;
+ my $oid_size = scalar @oid_nums;
+
+ croak "Unsupported OID size (>127 bytes)" if $oid_size > 127;
+
+ (my $C_comment = $comment) =~ s|^| * |msg;
+ $C_comment = "\n/*\n${C_comment}\n */" if $C_comment ne '';
+ (my $C_name = $name) =~ s|-|_|g;
+ my $C_bytes_size = 2 + $oid_size;
+
+ return <<"_____";
+$C_comment
+const unsigned char ossl_der_oid_${C_name}[DER_OID_SZ_${C_name}] = {
+ DER_OID_V_${C_name}
+};
+_____
+}
+
+sub _process {
+ my %opts = %{ pop @_ } if ref $_[$#_] eq 'HASH';
+
+ # To maintain input order
+ my @OID_names = ();
+
+ foreach my $file (@_) {
+ my $input = File::Spec->catfile($opts{dir}, $file);
+ open my $fh, $input or die "Reading $input: $!\n";
+
+ my $text = join('',
+ map {
+ s|--.*(\R)$|$1|;
+ $_;
+ } <$fh>);
+ # print STDERR "-----BEGIN DEBUG-----\n";
+ # print STDERR $text;
+ # print STDERR "-----END DEBUG-----\n";
+ use re 'debugcolor';
+ while ($text =~ m/${OID_def_re}/sg) {
+ my $comment = $&;
+ my $name = $1;
+ my $value = $2;
+
+ # print STDERR "-----BEGIN DEBUG $name-----\n";
+ # print STDERR $value,"\n";
+ # print STDERR "-----END DEBUG $name-----\n";
+ register_oid($name, $value);
+ push @OID_names, [ $name, $comment ];
+ }
+ }
+
+ return @OID_names;
+}
+
+sub process_leaves {
+ my %opts = %{ $_[$#_] } if ref $_[$#_] eq 'HASH';
+ my @OID_names = _process @_;
+
+ my $text = '';
+ my %leaves = map { $_ => 1 } registered_oid_leaves;
+ foreach (grep { defined $leaves{$_->[0]} } @OID_names) {
+ my $lines = $opts{filter}->($_, encode_oid($_->[0]));
+ $text .= $lines;
+ }
+ return $text;
+}
+
+1;
diff --git a/providers/common/der/wrap.asn1 b/providers/common/der/wrap.asn1
new file mode 100644
index 000000000000..07e23b440ea0
--- /dev/null
+++ b/providers/common/der/wrap.asn1
@@ -0,0 +1,26 @@
+-- Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+--
+-- Licensed under the Apache License 2.0 (the "License"). You may not use
+-- this file except in compliance with the License. You can obtain a copy
+-- in the file LICENSE in the source distribution or at
+-- https://www.openssl.org/source/license.html
+
+-- -------------------------------------------------------------------
+-- Taken from RFC 3370, Section 4.3.1 Triple-DES Key Wrap
+-- (https://tools.ietf.org/html/rfc3370)
+
+id-alg-CMS3DESwrap OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 6
+}
+
+-- -------------------------------------------------------------------
+-- Taken from RFC 3394, Section 3. Object Identifiers
+-- (https://tools.ietf.org/html/rfc3565)
+
+aes OBJECT IDENTIFIER ::= {
+ joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1
+}
+
+id-aes128-wrap OBJECT IDENTIFIER ::= { aes 5 }
+id-aes192-wrap OBJECT IDENTIFIER ::= { aes 25 }
+id-aes256-wrap OBJECT IDENTIFIER ::= { aes 45 }
diff --git a/providers/common/digest_to_nid.c b/providers/common/digest_to_nid.c
new file mode 100644
index 000000000000..49af04ad2a21
--- /dev/null
+++ b/providers/common/digest_to_nid.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/deprecated.h"
+
+#include <openssl/objects.h>
+#include <openssl/core_names.h>
+#include <openssl/evp.h>
+#include <openssl/core.h>
+#include "prov/securitycheck.h"
+#include "internal/nelem.h"
+
+/*
+ * Internal library code deals with NIDs, so we need to translate from a name.
+ * We do so using EVP_MD_is_a(), and therefore need a name to NID map.
+ */
+int ossl_digest_md_to_nid(const EVP_MD *md, const OSSL_ITEM *it, size_t it_len)
+{
+ size_t i;
+
+ if (md == NULL)
+ return NID_undef;
+
+ for (i = 0; i < it_len; i++)
+ if (EVP_MD_is_a(md, it[i].ptr))
+ return (int)it[i].id;
+ return NID_undef;
+}
+
+/*
+ * Retrieve one of the FIPS approved hash algorithms by nid.
+ * See FIPS 180-4 "Secure Hash Standard" and FIPS 202 - SHA-3.
+ */
+int ossl_digest_get_approved_nid(const EVP_MD *md)
+{
+ static const OSSL_ITEM name_to_nid[] = {
+ { NID_sha1, OSSL_DIGEST_NAME_SHA1 },
+ { NID_sha224, OSSL_DIGEST_NAME_SHA2_224 },
+ { NID_sha256, OSSL_DIGEST_NAME_SHA2_256 },
+ { NID_sha384, OSSL_DIGEST_NAME_SHA2_384 },
+ { NID_sha512, OSSL_DIGEST_NAME_SHA2_512 },
+ { NID_sha512_224, OSSL_DIGEST_NAME_SHA2_512_224 },
+ { NID_sha512_256, OSSL_DIGEST_NAME_SHA2_512_256 },
+ { NID_sha3_224, OSSL_DIGEST_NAME_SHA3_224 },
+ { NID_sha3_256, OSSL_DIGEST_NAME_SHA3_256 },
+ { NID_sha3_384, OSSL_DIGEST_NAME_SHA3_384 },
+ { NID_sha3_512, OSSL_DIGEST_NAME_SHA3_512 },
+ };
+
+ return ossl_digest_md_to_nid(md, name_to_nid, OSSL_NELEM(name_to_nid));
+}
diff --git a/providers/common/include/prov/__DECC_INCLUDE_EPILOGUE.H b/providers/common/include/prov/__DECC_INCLUDE_EPILOGUE.H
new file mode 100644
index 000000000000..2ab493330675
--- /dev/null
+++ b/providers/common/include/prov/__DECC_INCLUDE_EPILOGUE.H
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * This file is only used by HP C/C++ on VMS, and is included automatically
+ * after each header file from this directory
+ */
+
+/*
+ * The C++ compiler doesn't understand these pragmas, even though it
+ * understands the corresponding command line qualifier.
+ */
+#ifndef __cplusplus
+/* restore state. Must correspond to the save in __decc_include_prologue.h */
+# pragma names restore
+#endif
diff --git a/providers/common/include/prov/__DECC_INCLUDE_PROLOGUE.H b/providers/common/include/prov/__DECC_INCLUDE_PROLOGUE.H
new file mode 100644
index 000000000000..8e95fa975488
--- /dev/null
+++ b/providers/common/include/prov/__DECC_INCLUDE_PROLOGUE.H
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * This file is only used by HP C/C++ on VMS, and is included automatically
+ * after each header file from this directory
+ */
+
+/*
+ * The C++ compiler doesn't understand these pragmas, even though it
+ * understands the corresponding command line qualifier.
+ */
+#ifndef __cplusplus
+/* save state */
+# pragma names save
+/* have the compiler shorten symbols larger than 31 chars to 23 chars
+ * followed by a 8 hex char CRC
+ */
+# pragma names as_is,shortened
+#endif
diff --git a/providers/common/include/prov/bio.h b/providers/common/include/prov/bio.h
new file mode 100644
index 000000000000..da7e7e87f593
--- /dev/null
+++ b/providers/common/include/prov/bio.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdarg.h>
+#include <openssl/bio.h>
+#include <openssl/core.h>
+#include "prov/provider_ctx.h"
+
+int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns);
+
+OSSL_CORE_BIO *ossl_prov_bio_new_file(const char *filename, const char *mode);
+OSSL_CORE_BIO *ossl_prov_bio_new_membuf(const char *filename, int len);
+int ossl_prov_bio_read_ex(OSSL_CORE_BIO *bio, void *data, size_t data_len,
+ size_t *bytes_read);
+int ossl_prov_bio_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len,
+ size_t *written);
+int ossl_prov_bio_gets(OSSL_CORE_BIO *bio, char *buf, int size);
+int ossl_prov_bio_puts(OSSL_CORE_BIO *bio, const char *str);
+int ossl_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr);
+int ossl_prov_bio_up_ref(OSSL_CORE_BIO *bio);
+int ossl_prov_bio_free(OSSL_CORE_BIO *bio);
+int ossl_prov_bio_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list ap);
+int ossl_prov_bio_printf(OSSL_CORE_BIO *bio, const char *format, ...);
+
+BIO_METHOD *ossl_bio_prov_init_bio_method(void);
+BIO *ossl_bio_new_from_core_bio(PROV_CTX *provctx, OSSL_CORE_BIO *corebio);
diff --git a/providers/common/include/prov/der_digests.h.in b/providers/common/include/prov/der_digests.h.in
new file mode 100644
index 000000000000..f8f89973398b
--- /dev/null
+++ b/providers/common/include/prov/der_digests.h.in
@@ -0,0 +1,20 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/der.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/NIST.asn1',
+ 'providers/common/der/DIGESTS.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_H });
+-}
diff --git a/providers/common/include/prov/der_dsa.h.in b/providers/common/include/prov/der_dsa.h.in
new file mode 100644
index 000000000000..75e44a16f176
--- /dev/null
+++ b/providers/common/include/prov/der_dsa.h.in
@@ -0,0 +1,25 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/der.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/DSA.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_H });
+-}
+
+/* Subject Public Key Info */
+int ossl_DER_w_algorithmIdentifier_DSA(WPACKET *pkt, int tag, DSA *dsa);
+/* Signature */
+int ossl_DER_w_algorithmIdentifier_DSA_with_MD(WPACKET *pkt, int tag,
+ DSA *dsa, int mdnid);
diff --git a/providers/common/include/prov/der_ec.h.in b/providers/common/include/prov/der_ec.h.in
new file mode 100644
index 000000000000..ebc9bb0310e8
--- /dev/null
+++ b/providers/common/include/prov/der_ec.h.in
@@ -0,0 +1,26 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "crypto/ec.h"
+#include "internal/der.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/EC.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_H });
+-}
+
+/* Subject Public Key Info */
+int ossl_DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec);
+/* Signature */
+int ossl_DER_w_algorithmIdentifier_ECDSA_with_MD(WPACKET *pkt, int cont,
+ EC_KEY *ec, int mdnid);
diff --git a/providers/common/include/prov/der_ecx.h.in b/providers/common/include/prov/der_ecx.h.in
new file mode 100644
index 000000000000..2ca86fb1dd7d
--- /dev/null
+++ b/providers/common/include/prov/der_ecx.h.in
@@ -0,0 +1,25 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/der.h"
+#include "crypto/ecx.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/ECX.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_H });
+-}
+
+int ossl_DER_w_algorithmIdentifier_ED25519(WPACKET *pkt, int cont, ECX_KEY *ec);
+int ossl_DER_w_algorithmIdentifier_ED448(WPACKET *pkt, int cont, ECX_KEY *ec);
+int ossl_DER_w_algorithmIdentifier_X25519(WPACKET *pkt, int cont, ECX_KEY *ec);
+int ossl_DER_w_algorithmIdentifier_X448(WPACKET *pkt, int cont, ECX_KEY *ec);
diff --git a/providers/common/include/prov/der_rsa.h.in b/providers/common/include/prov/der_rsa.h.in
new file mode 100644
index 000000000000..97e5377358cc
--- /dev/null
+++ b/providers/common/include/prov/der_rsa.h.in
@@ -0,0 +1,33 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "crypto/rsa.h"
+#include "internal/der.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/NIST.asn1',
+ 'providers/common/der/RSA.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_H });
+-}
+
+/* PSS parameters */
+int ossl_DER_w_RSASSA_PSS_params(WPACKET *pkt, int tag,
+ const RSA_PSS_PARAMS_30 *pss);
+/* Subject Public Key Info */
+int ossl_DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa);
+int ossl_DER_w_algorithmIdentifier_RSA_PSS(WPACKET *pkt, int tag,
+ int rsa_type,
+ const RSA_PSS_PARAMS_30 *pss);
+/* Signature */
+int ossl_DER_w_algorithmIdentifier_MDWithRSAEncryption(WPACKET *pkt, int tag,
+ int mdnid);
diff --git a/providers/common/include/prov/der_sm2.h.in b/providers/common/include/prov/der_sm2.h.in
new file mode 100644
index 000000000000..f4f2bd72ee90
--- /dev/null
+++ b/providers/common/include/prov/der_sm2.h.in
@@ -0,0 +1,26 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "crypto/ec.h"
+#include "internal/der.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/SM2.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_H });
+-}
+
+/* Subject Public Key Info */
+int ossl_DER_w_algorithmIdentifier_SM2(WPACKET *pkt, int cont, EC_KEY *ec);
+/* Signature */
+int ossl_DER_w_algorithmIdentifier_SM2_with_MD(WPACKET *pkt, int cont,
+ EC_KEY *ec, int mdnid);
diff --git a/providers/common/include/prov/der_wrap.h.in b/providers/common/include/prov/der_wrap.h.in
new file mode 100644
index 000000000000..a20f3d45ec87
--- /dev/null
+++ b/providers/common/include/prov/der_wrap.h.in
@@ -0,0 +1,19 @@
+/*
+ * {- join("\n * ", @autowarntext) -}
+ *
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/der.h"
+
+/* Well known OIDs precompiled */
+{-
+ $OUT = oids_to_c::process_leaves('providers/common/der/wrap.asn1',
+ { dir => $config{sourcedir},
+ filter => \&oids_to_c::filter_to_H });
+-}
diff --git a/providers/common/include/prov/proverr.h b/providers/common/include/prov/proverr.h
new file mode 100644
index 000000000000..5084af201e05
--- /dev/null
+++ b/providers/common/include/prov/proverr.h
@@ -0,0 +1,27 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OSSL_PROVERR_H
+# define OSSL_PROVERR_H
+# pragma once
+
+# include <openssl/opensslconf.h>
+# include <openssl/symhacks.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+int ossl_err_load_PROV_strings(void);
+
+# ifdef __cplusplus
+}
+# endif
+#endif
diff --git a/providers/common/include/prov/provider_ctx.h b/providers/common/include/prov/provider_ctx.h
new file mode 100644
index 000000000000..c8126e176161
--- /dev/null
+++ b/providers/common/include/prov/provider_ctx.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OSSL_PROV_PROVIDER_CTX_H
+# define OSSL_PROV_PROVIDER_CTX_H
+
+# include <openssl/types.h>
+# include <openssl/crypto.h>
+# include <openssl/bio.h>
+# include <openssl/core.h>
+
+typedef struct prov_ctx_st {
+ const OSSL_CORE_HANDLE *handle;
+ OSSL_LIB_CTX *libctx; /* For all provider modules */
+ BIO_METHOD *corebiometh;
+} PROV_CTX;
+
+/*
+ * To be used anywhere the library context needs to be passed, such as to
+ * fetching functions.
+ */
+# define PROV_LIBCTX_OF(provctx) \
+ ossl_prov_ctx_get0_libctx((provctx))
+
+PROV_CTX *ossl_prov_ctx_new(void);
+void ossl_prov_ctx_free(PROV_CTX *ctx);
+void ossl_prov_ctx_set0_libctx(PROV_CTX *ctx, OSSL_LIB_CTX *libctx);
+void ossl_prov_ctx_set0_handle(PROV_CTX *ctx, const OSSL_CORE_HANDLE *handle);
+void ossl_prov_ctx_set0_core_bio_method(PROV_CTX *ctx, BIO_METHOD *corebiometh);
+OSSL_LIB_CTX *ossl_prov_ctx_get0_libctx(PROV_CTX *ctx);
+const OSSL_CORE_HANDLE *ossl_prov_ctx_get0_handle(PROV_CTX *ctx);
+BIO_METHOD *ossl_prov_ctx_get0_core_bio_method(PROV_CTX *ctx);
+
+#endif
diff --git a/providers/common/include/prov/provider_util.h b/providers/common/include/prov/provider_util.h
new file mode 100644
index 000000000000..dfe91f29bcdb
--- /dev/null
+++ b/providers/common/include/prov/provider_util.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/provider.h>
+#include <openssl/types.h>
+
+typedef struct {
+ /*
+ * References to the underlying cipher implementation. |cipher| caches
+ * the cipher, always. |alloc_cipher| only holds a reference to an
+ * explicitly fetched cipher.
+ */
+ const EVP_CIPHER *cipher; /* cipher */
+ EVP_CIPHER *alloc_cipher; /* fetched cipher */
+
+ /* Conditions for legacy EVP_CIPHER uses */
+ ENGINE *engine; /* cipher engine */
+} PROV_CIPHER;
+
+typedef struct {
+ /*
+ * References to the underlying digest implementation. |md| caches
+ * the digest, always. |alloc_md| only holds a reference to an explicitly
+ * fetched digest.
+ */
+ const EVP_MD *md; /* digest */
+ EVP_MD *alloc_md; /* fetched digest */
+
+ /* Conditions for legacy EVP_MD uses */
+ ENGINE *engine; /* digest engine */
+} PROV_DIGEST;
+
+/* Cipher functions */
+/*
+ * Load a cipher from the specified parameters with the specified context.
+ * The params "properties", "engine" and "cipher" are used to determine the
+ * implementation used. If a provider cannot be found, it falls back to trying
+ * non-provider based implementations.
+ */
+int ossl_prov_cipher_load_from_params(PROV_CIPHER *pc,
+ const OSSL_PARAM params[],
+ OSSL_LIB_CTX *ctx);
+
+/* Reset the PROV_CIPHER fields and free any allocated cipher reference */
+void ossl_prov_cipher_reset(PROV_CIPHER *pc);
+
+/* Clone a PROV_CIPHER structure into a second */
+int ossl_prov_cipher_copy(PROV_CIPHER *dst, const PROV_CIPHER *src);
+
+/* Query the cipher and associated engine (if any) */
+const EVP_CIPHER *ossl_prov_cipher_cipher(const PROV_CIPHER *pc);
+ENGINE *ossl_prov_cipher_engine(const PROV_CIPHER *pc);
+
+/* Digest functions */
+
+/*
+ * Fetch a digest from the specified libctx using the provided mdname and
+ * propquery. Store the result in the PROV_DIGEST and return the fetched md.
+ */
+const EVP_MD *ossl_prov_digest_fetch(PROV_DIGEST *pd, OSSL_LIB_CTX *libctx,
+ const char *mdname, const char *propquery);
+
+/*
+ * Load a digest from the specified parameters with the specified context.
+ * The params "properties", "engine" and "digest" are used to determine the
+ * implementation used. If a provider cannot be found, it falls back to trying
+ * non-provider based implementations.
+ */
+int ossl_prov_digest_load_from_params(PROV_DIGEST *pd,
+ const OSSL_PARAM params[],
+ OSSL_LIB_CTX *ctx);
+
+/* Reset the PROV_DIGEST fields and free any allocated digest reference */
+void ossl_prov_digest_reset(PROV_DIGEST *pd);
+
+/* Clone a PROV_DIGEST structure into a second */
+int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src);
+
+/* Query the digest and associated engine (if any) */
+const EVP_MD *ossl_prov_digest_md(const PROV_DIGEST *pd);
+ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd);
+
+
+/*
+ * Set the various parameters on an EVP_MAC_CTX from the supplied arguments.
+ * If any of the supplied ciphername/mdname etc are NULL then the values
+ * from the supplied params (if non NULL) are used instead.
+ */
+int ossl_prov_set_macctx(EVP_MAC_CTX *macctx,
+ const OSSL_PARAM params[],
+ const char *ciphername,
+ const char *mdname,
+ const char *engine,
+ const char *properties,
+ const unsigned char *key,
+ size_t keylen);
+
+/* MAC functions */
+/*
+ * Load an EVP_MAC_CTX* from the specified parameters with the specified
+ * library context.
+ * The params "mac" and "properties" are used to determine the implementation
+ * used, and the parameters "digest", "cipher", "engine" and "properties" are
+ * passed to the MAC via the created MAC context if they are given.
+ * If there is already a created MAC context, it will be replaced if the "mac"
+ * parameter is found, otherwise it will simply be used as is, and passed the
+ * parameters to pilfer as it sees fit.
+ *
+ * As an option, a MAC name may be explicitly given, and if it is, the "mac"
+ * parameter will be ignored.
+ * Similarly, as an option, a cipher name or a digest name may be explicitly
+ * given, and if any of them is, the "digest" and "cipher" parameters are
+ * ignored.
+ */
+int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
+ const OSSL_PARAM params[],
+ const char *macname,
+ const char *ciphername,
+ const char *mdname,
+ OSSL_LIB_CTX *ctx);
+
+typedef struct ag_capable_st {
+ OSSL_ALGORITHM alg;
+ int (*capable)(void);
+} OSSL_ALGORITHM_CAPABLE;
+
+/*
+ * Dynamically select algorithms by calling a capable() method.
+ * If this method is NULL or the method returns 1 then the algorithm is added.
+ */
+void ossl_prov_cache_exported_algorithms(const OSSL_ALGORITHM_CAPABLE *in,
+ OSSL_ALGORITHM *out);
diff --git a/providers/common/include/prov/providercommon.h b/providers/common/include/prov/providercommon.h
new file mode 100644
index 000000000000..6366547e7cfb
--- /dev/null
+++ b/providers/common/include/prov/providercommon.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/provider.h>
+#include <openssl/core_dispatch.h>
+
+const OSSL_CORE_HANDLE *FIPS_get_core_handle(OSSL_LIB_CTX *ctx);
+
+int ossl_cipher_capable_aes_cbc_hmac_sha1(void);
+int ossl_cipher_capable_aes_cbc_hmac_sha256(void);
+
+OSSL_FUNC_provider_get_capabilities_fn ossl_prov_get_capabilities;
+
+/* Set the error state if this is a FIPS module */
+void ossl_set_error_state(const char *type);
+
+/* Return true if the module is in a usable condition */
+int ossl_prov_is_running(void);
diff --git a/providers/common/include/prov/securitycheck.h b/providers/common/include/prov/securitycheck.h
new file mode 100644
index 000000000000..4a7f85f71186
--- /dev/null
+++ b/providers/common/include/prov/securitycheck.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "crypto/types.h"
+
+/* Functions that are common */
+int ossl_rsa_check_key(OSSL_LIB_CTX *ctx, const RSA *rsa, int operation);
+int ossl_ec_check_key(OSSL_LIB_CTX *ctx, const EC_KEY *ec, int protect);
+int ossl_dsa_check_key(OSSL_LIB_CTX *ctx, const DSA *dsa, int sign);
+int ossl_dh_check_key(OSSL_LIB_CTX *ctx, const DH *dh);
+
+int ossl_digest_is_allowed(OSSL_LIB_CTX *ctx, const EVP_MD *md);
+/* With security check enabled it can return -1 to indicate disallowed md */
+int ossl_digest_get_approved_nid_with_sha1(OSSL_LIB_CTX *ctx, const EVP_MD *md,
+ int sha1_allowed);
+
+/* Functions that are common */
+int ossl_digest_md_to_nid(const EVP_MD *md, const OSSL_ITEM *it, size_t it_len);
+int ossl_digest_get_approved_nid(const EVP_MD *md);
+
+/* Functions that have different implementations for the FIPS_MODULE */
+int ossl_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md,
+ int sha1_allowed);
+int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx);
diff --git a/providers/common/provider_ctx.c b/providers/common/provider_ctx.c
new file mode 100644
index 000000000000..9690abfd5776
--- /dev/null
+++ b/providers/common/provider_ctx.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdlib.h>
+#include "prov/provider_ctx.h"
+#include "prov/bio.h"
+
+PROV_CTX *ossl_prov_ctx_new(void)
+{
+ return OPENSSL_zalloc(sizeof(PROV_CTX));
+}
+
+void ossl_prov_ctx_free(PROV_CTX *ctx)
+{
+ OPENSSL_free(ctx);
+}
+
+void ossl_prov_ctx_set0_libctx(PROV_CTX *ctx, OSSL_LIB_CTX *libctx)
+{
+ if (ctx != NULL)
+ ctx->libctx = libctx;
+}
+
+void ossl_prov_ctx_set0_handle(PROV_CTX *ctx, const OSSL_CORE_HANDLE *handle)
+{
+ if (ctx != NULL)
+ ctx->handle = handle;
+}
+
+void ossl_prov_ctx_set0_core_bio_method(PROV_CTX *ctx, BIO_METHOD *corebiometh)
+{
+ if (ctx != NULL)
+ ctx->corebiometh = corebiometh;
+}
+
+OSSL_LIB_CTX *ossl_prov_ctx_get0_libctx(PROV_CTX *ctx)
+{
+ if (ctx == NULL)
+ return NULL;
+ return ctx->libctx;
+}
+
+const OSSL_CORE_HANDLE *ossl_prov_ctx_get0_handle(PROV_CTX *ctx)
+{
+ if (ctx == NULL)
+ return NULL;
+ return ctx->handle;
+}
+
+BIO_METHOD *ossl_prov_ctx_get0_core_bio_method(PROV_CTX *ctx)
+{
+ if (ctx == NULL)
+ return NULL;
+ return ctx->corebiometh;
+}
diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c
new file mode 100644
index 000000000000..344c12211266
--- /dev/null
+++ b/providers/common/provider_err.c
@@ -0,0 +1,229 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/err.h>
+#include <openssl/proverr.h>
+#include "include/prov/proverr.h"
+
+#ifndef OPENSSL_NO_ERR
+
+static const ERR_STRING_DATA PROV_str_reasons[] = {
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ADDITIONAL_INPUT_TOO_LONG),
+ "additional input too long"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ALGORITHM_MISMATCH),
+ "algorithm mismatch"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ALREADY_INSTANTIATED),
+ "already instantiated"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_DECRYPT), "bad decrypt"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_ENCODING), "bad encoding"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_LENGTH), "bad length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_TLS_CLIENT_VERSION),
+ "bad tls client version"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BN_ERROR), "bn error"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_CIPHER_OPERATION_FAILED),
+ "cipher operation failed"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_DERIVATION_FUNCTION_INIT_FAILED),
+ "derivation function init failed"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_DIGEST_NOT_ALLOWED),
+ "digest not allowed"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK),
+ "entropy source strength too weak"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ERROR_INSTANTIATING_DRBG),
+ "error instantiating drbg"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ERROR_RETRIEVING_ENTROPY),
+ "error retrieving entropy"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ERROR_RETRIEVING_NONCE),
+ "error retrieving nonce"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_DURING_DERIVATION),
+ "failed during derivation"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_CREATE_LOCK),
+ "failed to create lock"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_DECRYPT), "failed to decrypt"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_GENERATE_KEY),
+ "failed to generate key"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_GET_PARAMETER),
+ "failed to get parameter"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SET_PARAMETER),
+ "failed to set parameter"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SIGN), "failed to sign"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR),
+ "fips module conditional error"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE),
+ "fips module entering error state"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_IN_ERROR_STATE),
+ "fips module in error state"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_GENERATE_ERROR), "generate error"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE),
+ "illegal or unsupported padding mode"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INDICATOR_INTEGRITY_FAILURE),
+ "indicator integrity failure"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INSUFFICIENT_DRBG_STRENGTH),
+ "insufficient drbg strength"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_AAD), "invalid aad"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CONFIG_DATA),
+ "invalid config data"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CONSTANT_LENGTH),
+ "invalid constant length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CURVE), "invalid curve"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CUSTOM_LENGTH),
+ "invalid custom length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DATA), "invalid data"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DIGEST), "invalid digest"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DIGEST_LENGTH),
+ "invalid digest length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DIGEST_SIZE),
+ "invalid digest size"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_INPUT_LENGTH),
+ "invalid input length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_ITERATION_COUNT),
+ "invalid iteration count"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_IV_LENGTH), "invalid iv length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY), "invalid key"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY_LENGTH),
+ "invalid key length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MAC), "invalid mac"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MGF1_MD), "invalid mgf1 md"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MODE), "invalid mode"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_OUTPUT_LENGTH),
+ "invalid output length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PADDING_MODE),
+ "invalid padding mode"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PUBINFO), "invalid pubinfo"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SALT_LENGTH),
+ "invalid salt length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SEED_LENGTH),
+ "invalid seed length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SIGNATURE_SIZE),
+ "invalid signature size"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_STATE), "invalid state"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAG), "invalid tag"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAG_LENGTH),
+ "invalid tag length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_UKM_LENGTH),
+ "invalid ukm length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_X931_DIGEST),
+ "invalid x931 digest"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_IN_ERROR_STATE), "in error state"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_KEY_SETUP_FAILED), "key setup failed"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_KEY_SIZE_TOO_SMALL),
+ "key size too small"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_LENGTH_TOO_LARGE), "length too large"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISMATCHING_DOMAIN_PARAMETERS),
+ "mismatching domain parameters"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CEK_ALG), "missing cek alg"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CIPHER), "missing cipher"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CONFIG_DATA),
+ "missing config data"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CONSTANT), "missing constant"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_KEY), "missing key"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MAC), "missing mac"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MESSAGE_DIGEST),
+ "missing message digest"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_OID), "missing OID"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_PASS), "missing pass"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_SALT), "missing salt"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_SECRET), "missing secret"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_SEED), "missing seed"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_SESSION_ID),
+ "missing session id"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_TYPE), "missing type"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_XCGHASH), "missing xcghash"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MODULE_INTEGRITY_FAILURE),
+ "module integrity failure"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PRIVATE_KEY), "not a private key"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PUBLIC_KEY), "not a public key"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_INSTANTIATED), "not instantiated"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_PARAMETERS), "not parameters"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_SUPPORTED), "not supported"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_XOF_OR_INVALID_LENGTH),
+ "not xof or invalid length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NO_KEY_SET), "no key set"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NO_PARAMETERS_SET), "no parameters set"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),
+ "operation not supported for this keytype"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_OUTPUT_BUFFER_TOO_SMALL),
+ "output buffer too small"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PARENT_CANNOT_GENERATE_RANDOM_NUMBERS),
+ "parent cannot generate random numbers"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PARENT_CANNOT_SUPPLY_ENTROPY_SEED),
+ "parent cannot supply entropy seed"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PARENT_LOCKING_NOT_ENABLED),
+ "parent locking not enabled"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PARENT_STRENGTH_TOO_WEAK),
+ "parent strength too weak"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PATH_MUST_BE_ABSOLUTE),
+ "path must be absolute"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PERSONALISATION_STRING_TOO_LONG),
+ "personalisation string too long"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PSS_SALTLEN_TOO_SMALL),
+ "pss saltlen too small"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_REQUEST_TOO_LARGE_FOR_DRBG),
+ "request too large for drbg"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_REQUIRE_CTR_MODE_CIPHER),
+ "require ctr mode cipher"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_RESEED_ERROR), "reseed error"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES),
+ "search only supported for directories"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SEED_SOURCES_MUST_NOT_HAVE_A_PARENT),
+ "seed sources must not have a parent"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SELF_TEST_KAT_FAILURE),
+ "self test kat failure"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SELF_TEST_POST_FAILURE),
+ "self test post failure"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOT_NEEDED), "tag not needed"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOT_SET), "tag not set"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TOO_MANY_RECORDS), "too many records"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_FIND_CIPHERS),
+ "unable to find ciphers"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH),
+ "unable to get parent strength"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_GET_PASSPHRASE),
+ "unable to get passphrase"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_INITIALISE_CIPHERS),
+ "unable to initialise ciphers"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_LOAD_SHA256),
+ "unable to load sha256"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_LOCK_PARENT),
+ "unable to lock parent"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_RESEED), "unable to reseed"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_CEK_ALG),
+ "unsupported cek alg"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_KEY_SIZE),
+ "unsupported key size"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_MAC_TYPE),
+ "unsupported mac type"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS),
+ "unsupported number of rounds"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_URI_AUTHORITY_UNSUPPORTED),
+ "uri authority unsupported"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_VALUE_ERROR), "value error"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_WRONG_FINAL_BLOCK_LENGTH),
+ "wrong final block length"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_WRONG_OUTPUT_BUFFER_SIZE),
+ "wrong output buffer size"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_XOF_DIGESTS_NOT_ALLOWED),
+ "xof digests not allowed"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE),
+ "xts data unit is too large"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_XTS_DUPLICATED_KEYS),
+ "xts duplicated keys"},
+ {0, NULL}
+};
+
+#endif
+
+int ossl_err_load_PROV_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+ if (ERR_reason_error_string(PROV_str_reasons[0].error) == NULL)
+ ERR_load_strings_const(PROV_str_reasons);
+#endif
+ return 1;
+}
diff --git a/providers/common/provider_seeding.c b/providers/common/provider_seeding.c
new file mode 100644
index 000000000000..0edbb8763066
--- /dev/null
+++ b/providers/common/provider_seeding.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/core_dispatch.h>
+#include "prov/seeding.h"
+
+static OSSL_FUNC_get_entropy_fn *c_get_entropy = NULL;
+static OSSL_FUNC_cleanup_entropy_fn *c_cleanup_entropy = NULL;
+static OSSL_FUNC_get_nonce_fn *c_get_nonce = NULL;
+static OSSL_FUNC_cleanup_nonce_fn *c_cleanup_nonce = NULL;
+
+int ossl_prov_seeding_from_dispatch(const OSSL_DISPATCH *fns)
+{
+ for (; fns->function_id != 0; fns++) {
+ /*
+ * We do not support the scenario of an application linked against
+ * multiple versions of libcrypto (e.g. one static and one dynamic), but
+ * sharing a single fips.so. We do a simple sanity check here.
+ */
+#define set_func(c, f) \
+ do { if (c == NULL) c = f; else if (c != f) return 0; } while (0)
+ switch (fns->function_id) {
+ case OSSL_FUNC_GET_ENTROPY:
+ set_func(c_get_entropy, OSSL_FUNC_get_entropy(fns));
+ break;
+ case OSSL_FUNC_CLEANUP_ENTROPY:
+ set_func(c_cleanup_entropy, OSSL_FUNC_cleanup_entropy(fns));
+ break;
+ case OSSL_FUNC_GET_NONCE:
+ set_func(c_get_nonce, OSSL_FUNC_get_nonce(fns));
+ break;
+ case OSSL_FUNC_CLEANUP_NONCE:
+ set_func(c_cleanup_nonce, OSSL_FUNC_cleanup_nonce(fns));
+ break;
+ }
+#undef set_func
+ }
+ return 1;
+}
+
+size_t ossl_prov_get_entropy(PROV_CTX *prov_ctx, unsigned char **pout,
+ int entropy, size_t min_len, size_t max_len)
+{
+ if (c_get_entropy == NULL)
+ return 0;
+ return c_get_entropy(ossl_prov_ctx_get0_handle(prov_ctx),
+ pout, entropy, min_len, max_len);
+}
+
+void ossl_prov_cleanup_entropy(PROV_CTX *prov_ctx, unsigned char *buf,
+ size_t len)
+{
+ if (c_cleanup_entropy != NULL)
+ c_cleanup_entropy(ossl_prov_ctx_get0_handle(prov_ctx), buf, len);
+}
+
+size_t ossl_prov_get_nonce(PROV_CTX *prov_ctx, unsigned char **pout,
+ size_t min_len, size_t max_len,
+ const void *salt,size_t salt_len)
+{
+ if (c_get_nonce == NULL)
+ return 0;
+ return c_get_nonce(ossl_prov_ctx_get0_handle(prov_ctx), pout,
+ min_len, max_len, salt, salt_len);
+}
+
+void ossl_prov_cleanup_nonce(PROV_CTX *prov_ctx, unsigned char *buf, size_t len)
+{
+ if (c_cleanup_nonce != NULL)
+ c_cleanup_nonce(ossl_prov_ctx_get0_handle(prov_ctx), buf, len);
+}
diff --git a/providers/common/provider_util.c b/providers/common/provider_util.c
new file mode 100644
index 000000000000..58d4db33793f
--- /dev/null
+++ b/providers/common/provider_util.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* We need to use some engine deprecated APIs */
+#define OPENSSL_SUPPRESS_DEPRECATED
+
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
+#include <openssl/err.h>
+#include <openssl/proverr.h>
+#ifndef FIPS_MODULE
+# include <openssl/engine.h>
+# include "crypto/evp.h"
+#endif
+#include "prov/provider_util.h"
+#include "internal/nelem.h"
+
+void ossl_prov_cipher_reset(PROV_CIPHER *pc)
+{
+ EVP_CIPHER_free(pc->alloc_cipher);
+ pc->alloc_cipher = NULL;
+ pc->cipher = NULL;
+#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE)
+ ENGINE_finish(pc->engine);
+#endif
+ pc->engine = NULL;
+}
+
+int ossl_prov_cipher_copy(PROV_CIPHER *dst, const PROV_CIPHER *src)
+{
+ if (src->alloc_cipher != NULL && !EVP_CIPHER_up_ref(src->alloc_cipher))
+ return 0;
+#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE)
+ if (src->engine != NULL && !ENGINE_init(src->engine)) {
+ EVP_CIPHER_free(src->alloc_cipher);
+ return 0;
+ }
+#endif
+ dst->engine = src->engine;
+ dst->cipher = src->cipher;
+ dst->alloc_cipher = src->alloc_cipher;
+ return 1;
+}
+
+static int load_common(const OSSL_PARAM params[], const char **propquery,
+ ENGINE **engine)
+{
+ const OSSL_PARAM *p;
+
+ *propquery = NULL;
+ p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_PROPERTIES);
+ if (p != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ *propquery = p->data;
+ }
+
+#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE)
+ ENGINE_finish(*engine);
+#endif
+ *engine = NULL;
+ /* Inside the FIPS module, we don't support legacy ciphers */
+#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE)
+ p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_ENGINE);
+ if (p != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ /* Get a structural reference */
+ *engine = ENGINE_by_id(p->data);
+ if (*engine == NULL)
+ return 0;
+ /* Get a functional reference */
+ if (!ENGINE_init(*engine)) {
+ ENGINE_free(*engine);
+ *engine = NULL;
+ return 0;
+ }
+ /* Free the structural reference */
+ ENGINE_free(*engine);
+ }
+#endif
+ return 1;
+}
+
+int ossl_prov_cipher_load_from_params(PROV_CIPHER *pc,
+ const OSSL_PARAM params[],
+ OSSL_LIB_CTX *ctx)
+{
+ const OSSL_PARAM *p;
+ const char *propquery;
+
+ if (params == NULL)
+ return 1;
+
+ if (!load_common(params, &propquery, &pc->engine))
+ return 0;
+
+ p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_CIPHER);
+ if (p == NULL)
+ return 1;
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+
+ EVP_CIPHER_free(pc->alloc_cipher);
+ ERR_set_mark();
+ pc->cipher = pc->alloc_cipher = EVP_CIPHER_fetch(ctx, p->data, propquery);
+#ifndef FIPS_MODULE /* Inside the FIPS module, we don't support legacy ciphers */
+ if (pc->cipher == NULL) {
+ const EVP_CIPHER *cipher;
+
+ cipher = EVP_get_cipherbyname(p->data);
+ /* Do not use global EVP_CIPHERs */
+ if (cipher != NULL && cipher->origin != EVP_ORIG_GLOBAL)
+ pc->cipher = cipher;
+ }
+#endif
+ if (pc->cipher != NULL)
+ ERR_pop_to_mark();
+ else
+ ERR_clear_last_mark();
+ return pc->cipher != NULL;
+}
+
+const EVP_CIPHER *ossl_prov_cipher_cipher(const PROV_CIPHER *pc)
+{
+ return pc->cipher;
+}
+
+ENGINE *ossl_prov_cipher_engine(const PROV_CIPHER *pc)
+{
+ return pc->engine;
+}
+
+void ossl_prov_digest_reset(PROV_DIGEST *pd)
+{
+ EVP_MD_free(pd->alloc_md);
+ pd->alloc_md = NULL;
+ pd->md = NULL;
+#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE)
+ ENGINE_finish(pd->engine);
+#endif
+ pd->engine = NULL;
+}
+
+int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src)
+{
+ if (src->alloc_md != NULL && !EVP_MD_up_ref(src->alloc_md))
+ return 0;
+#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE)
+ if (src->engine != NULL && !ENGINE_init(src->engine)) {
+ EVP_MD_free(src->alloc_md);
+ return 0;
+ }
+#endif
+ dst->engine = src->engine;
+ dst->md = src->md;
+ dst->alloc_md = src->alloc_md;
+ return 1;
+}
+
+const EVP_MD *ossl_prov_digest_fetch(PROV_DIGEST *pd, OSSL_LIB_CTX *libctx,
+ const char *mdname, const char *propquery)
+{
+ EVP_MD_free(pd->alloc_md);
+ pd->md = pd->alloc_md = EVP_MD_fetch(libctx, mdname, propquery);
+
+ return pd->md;
+}
+
+int ossl_prov_digest_load_from_params(PROV_DIGEST *pd,
+ const OSSL_PARAM params[],
+ OSSL_LIB_CTX *ctx)
+{
+ const OSSL_PARAM *p;
+ const char *propquery;
+
+ if (params == NULL)
+ return 1;
+
+ if (!load_common(params, &propquery, &pd->engine))
+ return 0;
+
+ p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST);
+ if (p == NULL)
+ return 1;
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+
+ ERR_set_mark();
+ ossl_prov_digest_fetch(pd, ctx, p->data, propquery);
+#ifndef FIPS_MODULE /* Inside the FIPS module, we don't support legacy digests */
+ if (pd->md == NULL) {
+ const EVP_MD *md;
+
+ md = EVP_get_digestbyname(p->data);
+ /* Do not use global EVP_MDs */
+ if (md != NULL && md->origin != EVP_ORIG_GLOBAL)
+ pd->md = md;
+ }
+#endif
+ if (pd->md != NULL)
+ ERR_pop_to_mark();
+ else
+ ERR_clear_last_mark();
+ return pd->md != NULL;
+}
+
+const EVP_MD *ossl_prov_digest_md(const PROV_DIGEST *pd)
+{
+ return pd->md;
+}
+
+ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd)
+{
+ return pd->engine;
+}
+
+int ossl_prov_set_macctx(EVP_MAC_CTX *macctx,
+ const OSSL_PARAM params[],
+ const char *ciphername,
+ const char *mdname,
+ const char *engine,
+ const char *properties,
+ const unsigned char *key,
+ size_t keylen)
+{
+ const OSSL_PARAM *p;
+ OSSL_PARAM mac_params[6], *mp = mac_params;
+
+ if (params != NULL) {
+ if (mdname == NULL) {
+ if ((p = OSSL_PARAM_locate_const(params,
+ OSSL_ALG_PARAM_DIGEST)) != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ mdname = p->data;
+ }
+ }
+ if (ciphername == NULL) {
+ if ((p = OSSL_PARAM_locate_const(params,
+ OSSL_ALG_PARAM_CIPHER)) != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ ciphername = p->data;
+ }
+ }
+ if (engine == NULL) {
+ if ((p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_ENGINE))
+ != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ engine = p->data;
+ }
+ }
+ }
+
+ if (mdname != NULL)
+ *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ (char *)mdname, 0);
+ if (ciphername != NULL)
+ *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
+ (char *)ciphername, 0);
+ if (properties != NULL)
+ *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES,
+ (char *)properties, 0);
+
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
+ if (engine != NULL)
+ *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_ENGINE,
+ (char *) engine, 0);
+#endif
+
+ if (key != NULL)
+ *mp++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+ (unsigned char *)key,
+ keylen);
+
+ *mp = OSSL_PARAM_construct_end();
+
+ return EVP_MAC_CTX_set_params(macctx, mac_params);
+
+}
+
+int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
+ const OSSL_PARAM params[],
+ const char *macname,
+ const char *ciphername,
+ const char *mdname,
+ OSSL_LIB_CTX *libctx)
+{
+ const OSSL_PARAM *p;
+ const char *properties = NULL;
+
+ if (macname == NULL
+ && (p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_MAC)) != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ macname = p->data;
+ }
+ if ((p = OSSL_PARAM_locate_const(params,
+ OSSL_ALG_PARAM_PROPERTIES)) != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ properties = p->data;
+ }
+
+ /* If we got a new mac name, we make a new EVP_MAC_CTX */
+ if (macname != NULL) {
+ EVP_MAC *mac = EVP_MAC_fetch(libctx, macname, properties);
+
+ EVP_MAC_CTX_free(*macctx);
+ *macctx = mac == NULL ? NULL : EVP_MAC_CTX_new(mac);
+ /* The context holds on to the MAC */
+ EVP_MAC_free(mac);
+ if (*macctx == NULL)
+ return 0;
+ }
+
+ /*
+ * If there is no MAC yet (and therefore, no MAC context), we ignore
+ * all other parameters.
+ */
+ if (*macctx == NULL)
+ return 1;
+
+ if (ossl_prov_set_macctx(*macctx, params, ciphername, mdname, NULL,
+ properties, NULL, 0))
+ return 1;
+
+ EVP_MAC_CTX_free(*macctx);
+ *macctx = NULL;
+ return 0;
+}
+
+void ossl_prov_cache_exported_algorithms(const OSSL_ALGORITHM_CAPABLE *in,
+ OSSL_ALGORITHM *out)
+{
+ int i, j;
+
+ if (out[0].algorithm_names == NULL) {
+ for (i = j = 0; in[i].alg.algorithm_names != NULL; ++i) {
+ if (in[i].capable == NULL || in[i].capable())
+ out[j++] = in[i].alg;
+ }
+ out[j++] = in[i].alg;
+ }
+}
diff --git a/providers/common/securitycheck.c b/providers/common/securitycheck.c
new file mode 100644
index 000000000000..0d3acdbe56e2
--- /dev/null
+++ b/providers/common/securitycheck.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/deprecated.h"
+
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+#include <openssl/ec.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/proverr.h>
+#include <openssl/core_names.h>
+#include <openssl/obj_mac.h>
+#include "prov/securitycheck.h"
+
+/*
+ * FIPS requires a minimum security strength of 112 bits (for encryption or
+ * signing), and for legacy purposes 80 bits (for decryption or verifying).
+ * Set protect = 1 for encryption or signing operations, or 0 otherwise. See
+ * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf.
+ */
+int ossl_rsa_check_key(OSSL_LIB_CTX *ctx, const RSA *rsa, int operation)
+{
+ int protect = 0;
+
+ switch (operation) {
+ case EVP_PKEY_OP_SIGN:
+ protect = 1;
+ /* fallthrough */
+ case EVP_PKEY_OP_VERIFY:
+ break;
+ case EVP_PKEY_OP_ENCAPSULATE:
+ case EVP_PKEY_OP_ENCRYPT:
+ protect = 1;
+ /* fallthrough */
+ case EVP_PKEY_OP_VERIFYRECOVER:
+ case EVP_PKEY_OP_DECAPSULATE:
+ case EVP_PKEY_OP_DECRYPT:
+ if (RSA_test_flags(rsa,
+ RSA_FLAG_TYPE_MASK) == RSA_FLAG_TYPE_RSASSAPSS) {
+ ERR_raise_data(ERR_LIB_PROV,
+ PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE,
+ "operation: %d", operation);
+ return 0;
+ }
+ break;
+ default:
+ ERR_raise_data(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR,
+ "invalid operation: %d", operation);
+ return 0;
+ }
+
+#if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
+ if (ossl_securitycheck_enabled(ctx)) {
+ int sz = RSA_bits(rsa);
+
+ if (protect ? (sz < 2048) : (sz < 1024)) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH,
+ "operation: %d", operation);
+ return 0;
+ }
+ }
+#else
+ /* make protect used */
+ (void)protect;
+#endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
+ return 1;
+}
+
+#ifndef OPENSSL_NO_EC
+/*
+ * In FIPS mode:
+ * protect should be 1 for any operations that need 112 bits of security
+ * strength (such as signing, and key exchange), or 0 for operations that allow
+ * a lower security strength (such as verify).
+ *
+ * For ECDH key agreement refer to SP800-56A
+ * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf
+ * "Appendix D"
+ *
+ * For ECDSA signatures refer to
+ * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf
+ * "Table 2"
+ */
+int ossl_ec_check_key(OSSL_LIB_CTX *ctx, const EC_KEY *ec, int protect)
+{
+# if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
+ if (ossl_securitycheck_enabled(ctx)) {
+ int nid, strength;
+ const char *curve_name;
+ const EC_GROUP *group = EC_KEY_get0_group(ec);
+
+ if (group == NULL) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, "No group");
+ return 0;
+ }
+ nid = EC_GROUP_get_curve_name(group);
+ if (nid == NID_undef) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE,
+ "Explicit curves are not allowed in fips mode");
+ return 0;
+ }
+
+ curve_name = EC_curve_nid2nist(nid);
+ if (curve_name == NULL) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE,
+ "Curve %s is not approved in FIPS mode", curve_name);
+ return 0;
+ }
+
+ /*
+ * For EC the security strength is the (order_bits / 2)
+ * e.g. P-224 is 112 bits.
+ */
+ strength = EC_GROUP_order_bits(group) / 2;
+ /* The min security strength allowed for legacy verification is 80 bits */
+ if (strength < 80) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
+ return 0;
+ }
+
+ /*
+ * For signing or key agreement only allow curves with at least 112 bits of
+ * security strength
+ */
+ if (protect && strength < 112) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE,
+ "Curve %s cannot be used for signing", curve_name);
+ return 0;
+ }
+ }
+# endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
+ return 1;
+}
+#endif /* OPENSSL_NO_EC */
+
+#ifndef OPENSSL_NO_DSA
+/*
+ * Check for valid key sizes if fips mode. Refer to
+ * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf
+ * "Table 2"
+ */
+int ossl_dsa_check_key(OSSL_LIB_CTX *ctx, const DSA *dsa, int sign)
+{
+# if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
+ if (ossl_securitycheck_enabled(ctx)) {
+ size_t L, N;
+ const BIGNUM *p, *q;
+
+ if (dsa == NULL)
+ return 0;
+
+ p = DSA_get0_p(dsa);
+ q = DSA_get0_q(dsa);
+ if (p == NULL || q == NULL)
+ return 0;
+
+ L = BN_num_bits(p);
+ N = BN_num_bits(q);
+
+ /*
+ * For Digital signature verification DSA keys with < 112 bits of
+ * security strength, are still allowed for legacy
+ * use. The bounds given in SP 800-131Ar2 - Table 2 are
+ * (512 <= L < 2048 or 160 <= N < 224).
+ *
+ * We are a little stricter and insist that both minimums are met.
+ * For example a L = 256, N = 160 key *would* be allowed by SP 800-131Ar2
+ * but we don't.
+ */
+ if (!sign) {
+ if (L < 512 || N < 160)
+ return 0;
+ if (L < 2048 || N < 224)
+ return 1;
+ }
+
+ /* Valid sizes for both sign and verify */
+ if (L == 2048 && (N == 224 || N == 256)) /* 112 bits */
+ return 1;
+ return (L == 3072 && N == 256); /* 128 bits */
+ }
+# endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
+ return 1;
+}
+#endif /* OPENSSL_NO_DSA */
+
+#ifndef OPENSSL_NO_DH
+/*
+ * For DH key agreement refer to SP800-56A
+ * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf
+ * "Section 5.5.1.1FFC Domain Parameter Selection/Generation" and
+ * "Appendix D" FFC Safe-prime Groups
+ */
+int ossl_dh_check_key(OSSL_LIB_CTX *ctx, const DH *dh)
+{
+# if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
+ if (ossl_securitycheck_enabled(ctx)) {
+ size_t L, N;
+ const BIGNUM *p, *q;
+
+ if (dh == NULL)
+ return 0;
+
+ p = DH_get0_p(dh);
+ q = DH_get0_q(dh);
+ if (p == NULL || q == NULL)
+ return 0;
+
+ L = BN_num_bits(p);
+ if (L < 2048)
+ return 0;
+
+ /* If it is a safe prime group then it is ok */
+ if (DH_get_nid(dh))
+ return 1;
+
+ /* If not then it must be FFC, which only allows certain sizes. */
+ N = BN_num_bits(q);
+
+ return (L == 2048 && (N == 224 || N == 256));
+ }
+# endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
+ return 1;
+}
+#endif /* OPENSSL_NO_DH */
+
+int ossl_digest_get_approved_nid_with_sha1(OSSL_LIB_CTX *ctx, const EVP_MD *md,
+ int sha1_allowed)
+{
+ int mdnid = ossl_digest_get_approved_nid(md);
+
+# if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
+ if (ossl_securitycheck_enabled(ctx)) {
+ if (mdnid == NID_undef || (mdnid == NID_sha1 && !sha1_allowed))
+ mdnid = -1; /* disallowed by security checks */
+ }
+# endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
+ return mdnid;
+}
+
+int ossl_digest_is_allowed(OSSL_LIB_CTX *ctx, const EVP_MD *md)
+{
+# if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
+ if (ossl_securitycheck_enabled(ctx))
+ return ossl_digest_get_approved_nid(md) != NID_undef;
+# endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
+ return 1;
+}
diff --git a/providers/common/securitycheck_default.c b/providers/common/securitycheck_default.c
new file mode 100644
index 000000000000..de7f0d3a0a57
--- /dev/null
+++ b/providers/common/securitycheck_default.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/deprecated.h"
+
+#include <openssl/rsa.h>
+#include <openssl/core.h>
+#include <openssl/core_names.h>
+#include <openssl/obj_mac.h>
+#include "prov/securitycheck.h"
+#include "internal/nelem.h"
+
+/* Disable the security checks in the default provider */
+int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx)
+{
+ return 0;
+}
+
+int ossl_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md,
+ ossl_unused int sha1_allowed)
+{
+ int mdnid;
+
+ static const OSSL_ITEM name_to_nid[] = {
+ { NID_md5, OSSL_DIGEST_NAME_MD5 },
+ { NID_md5_sha1, OSSL_DIGEST_NAME_MD5_SHA1 },
+ { NID_md2, OSSL_DIGEST_NAME_MD2 },
+ { NID_md4, OSSL_DIGEST_NAME_MD4 },
+ { NID_mdc2, OSSL_DIGEST_NAME_MDC2 },
+ { NID_ripemd160, OSSL_DIGEST_NAME_RIPEMD160 },
+ };
+
+ mdnid = ossl_digest_get_approved_nid_with_sha1(ctx, md, 1);
+ if (mdnid == NID_undef)
+ mdnid = ossl_digest_md_to_nid(md, name_to_nid, OSSL_NELEM(name_to_nid));
+ return mdnid;
+}
diff --git a/providers/common/securitycheck_fips.c b/providers/common/securitycheck_fips.c
new file mode 100644
index 000000000000..b7659bd395c3
--- /dev/null
+++ b/providers/common/securitycheck_fips.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/deprecated.h"
+
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+#include <openssl/ec.h>
+#include <openssl/err.h>
+#include <openssl/proverr.h>
+#include <openssl/core_names.h>
+#include <openssl/obj_mac.h>
+#include "prov/securitycheck.h"
+
+int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx);
+
+int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx)
+{
+#if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
+ return FIPS_security_check_enabled(libctx);
+#else
+ return 0;
+#endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
+}
+
+int ossl_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md,
+ int sha1_allowed)
+{
+#if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
+ if (ossl_securitycheck_enabled(ctx))
+ return ossl_digest_get_approved_nid_with_sha1(ctx, md, sha1_allowed);
+#endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
+ return ossl_digest_get_approved_nid(md);
+}