diff options
Diffstat (limited to 'providers/common')
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); +} |