From 6f5837dc1621882a3a9f34a2910321751ab002c2 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Tue, 31 Mar 2020 17:15:17 +0200 Subject: [PATCH] PROV: Add DERlib support for RSA This replaces crypto/rsa/rsa_aid.c with new code and generated OIDs Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/11450) --- crypto/rsa/build.info | 2 +- crypto/rsa/rsa_aid.c | 98 ------------------- providers/common/der/RSA.asn1 | 88 +++++++++++++++++ providers/common/der/build.info | 11 +++ providers/common/der/der_rsa.c.in | 74 ++++++++++++++ providers/common/der/der_rsa.h.in | 21 ++++ .../implementations/signature/build.info | 2 + providers/implementations/signature/rsa.c | 41 ++++---- 8 files changed, 220 insertions(+), 117 deletions(-) delete mode 100644 crypto/rsa/rsa_aid.c create mode 100644 providers/common/der/RSA.asn1 create mode 100644 providers/common/der/build.info create mode 100644 providers/common/der/der_rsa.c.in create mode 100644 providers/common/der/der_rsa.h.in diff --git a/crypto/rsa/build.info b/crypto/rsa/build.info index 7921202739..0c9e46684c 100644 --- a/crypto/rsa/build.info +++ b/crypto/rsa/build.info @@ -1,6 +1,6 @@ LIBS=../../libcrypto -$COMMON=rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_aid.c rsa_pk1.c \ +$COMMON=rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_pk1.c \ rsa_none.c rsa_oaep.c rsa_chk.c rsa_pss.c rsa_x931.c rsa_crpt.c \ rsa_x931g.c rsa_sp800_56b_gen.c rsa_sp800_56b_check.c rsa_backend.c \ rsa_mp_names.c diff --git a/crypto/rsa/rsa_aid.c b/crypto/rsa/rsa_aid.c deleted file mode 100644 index 4b4d3a62f1..0000000000 --- a/crypto/rsa/rsa_aid.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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 - -#include -#include "crypto/rsa.h" - -#define ASN1_SEQUENCE 0x30 -#define ASN1_OID 0x06 - -/* - * -- RFC 2313 - * pkcs-1 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) US(840) rsadsi(113549) pkcs(1) 1 - * } - */ - -/* - * -- RFC 3279 - * md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 } - * md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 } - * sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 } - */ -#define ENCODE_ALGORITHMIDENTIFIER_PKCS1(name, n) \ - static const unsigned char algorithmidentifier_##name##_der[] = { \ - ASN1_SEQUENCE, 0x0b, \ - ASN1_OID, 0x09, 1 * 40 + 2, 134, 72, 134, 247, 13, 1, 1, n \ -} -#ifndef FIPS_MODE -ENCODE_ALGORITHMIDENTIFIER_PKCS1(md2, 2); -ENCODE_ALGORITHMIDENTIFIER_PKCS1(md5, 4); -#endif -ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha1, 5); - -/* - * -- RFC 4055 - * sha224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 14 } - * sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 } - * sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 } - * sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 } - */ -ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha224, 14); -ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha256, 11); -ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha384, 12); -ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha512, 13); - -/* - * -- https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration - * - * sigAlgs OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 4 3 } - * - * id-rsassa-pkcs1-v1_5-with-sha3-224 ::= { sigAlgs 13 } - * id-rsassa-pkcs1-v1_5-with-sha3-256 ::= { sigAlgs 14 } - * id-rsassa-pkcs1-v1_5-with-sha3-384 ::= { sigAlgs 15 } - * id-rsassa-pkcs1-v1_5-with-sha3-512 ::= { sigAlgs 16 } - */ -#define ENCODE_ALGORITHMIDENTIFIER_SIGALGS(name, n) \ - static const unsigned char algorithmidentifier_##name##_der[] = { \ - ASN1_SEQUENCE, 0x0c, \ - ASN1_OID, 0x0a, 1 * 40 + 2, 16, 134, 72, 1, 101, 3, 4, 3, n \ -} -ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_224, 13); -ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_256, 14); -ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_384, 15); -ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_512, 16); - -#define MD_CASE(name) \ - case NID_##name: \ - *len = sizeof(algorithmidentifier_##name##_der); \ - return algorithmidentifier_##name##_der - -const unsigned char *rsa_algorithmidentifier_encoding(int md_nid, size_t *len) -{ - switch (md_nid) { -#ifndef FIPS_MODE - MD_CASE(md2); - MD_CASE(md5); -#endif - 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 NULL; - } -} diff --git a/providers/common/der/RSA.asn1 b/providers/common/der/RSA.asn1 new file mode 100644 index 0000000000..7bce636029 --- /dev/null +++ b/providers/common/der/RSA.asn1 @@ -0,0 +1,88 @@ +-- ------------------------------------------------------------------- +-- 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 } + +-- +-- This OID really belongs in a module with the secsig OIDs. +-- +id-sha1 OBJECT IDENTIFIER ::= { + iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) + 26 +} + +-- +-- OIDs for MD2 and MD5, 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 +} + +-- +-- 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 + +sigAlgs OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 4 3 } + +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 } diff --git a/providers/common/der/build.info b/providers/common/der/build.info new file mode 100644 index 0000000000..dd3a86978a --- /dev/null +++ b/providers/common/der/build.info @@ -0,0 +1,11 @@ +$FIPSABLE=der_rsa.c + +SOURCE[../../libfips.a]=$FIPSABLE +SOURCE[../../libnonfips.a]=$FIPSABLE + +GENERATE[der_rsa.c]=der_rsa.c.in +DEPEND[der_rsa.c]=oids_to_c.pm + +DEPEND[der_rsa.o]=../include/prov/der_rsa.h +GENERATE[../include/prov/der_rsa.h]=der_rsa.h.in +DEPEND[../include/prov/der_rsa.h]=oids_to_c.pm diff --git a/providers/common/der/der_rsa.c.in b/providers/common/der/der_rsa.c.in new file mode 100644 index 0000000000..fb936d2966 --- /dev/null +++ b/providers/common/der/der_rsa.c.in @@ -0,0 +1,74 @@ +/* + * 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 +#include +#include "prov/der_rsa.h" + +/* Well known OIDs precompiled */ +{- + $OUT = oids_to_c::process_leaves('providers/common/der/RSA.asn1', + { dir => $config{sourcedir}, + filter => \&oids_to_c::filter_to_C }); +-} + +int DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa) +{ + return DER_w_begin_sequence(pkt, tag) + /* No parameters (yet?) */ + && DER_w_precompiled(pkt, -1, der_oid_rsaEncryption, + sizeof(der_oid_rsaEncryption)) + && DER_w_end_sequence(pkt, tag); +} + +/* Aliases so we can have a uniform MD_CASE */ +#define der_oid_sha3_224WithRSAEncryption \ + der_oid_id_rsassa_pkcs1_v1_5_with_sha3_224 +#define der_oid_sha3_256WithRSAEncryption \ + der_oid_id_rsassa_pkcs1_v1_5_with_sha3_256 +#define der_oid_sha3_384WithRSAEncryption \ + der_oid_id_rsassa_pkcs1_v1_5_with_sha3_384 +#define der_oid_sha3_512WithRSAEncryption \ + der_oid_id_rsassa_pkcs1_v1_5_with_sha3_512 + +#define MD_CASE(name) \ + case NID_##name: \ + precompiled = der_oid_##name##WithRSAEncryption; \ + precompiled_sz = sizeof(der_oid_##name##WithRSAEncryption); \ + break; + +int DER_w_algorithmIdentifier_RSA_with(WPACKET *pkt, int tag, + RSA *rsa, int mdnid) +{ + const unsigned char *precompiled = NULL; + size_t precompiled_sz = 0; + + switch (mdnid) { +#ifndef FIPS_MODE + MD_CASE(md2); + MD_CASE(md5); +#endif + 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 DER_w_begin_sequence(pkt, tag) + /* No parameters (yet?) */ + && DER_w_precompiled(pkt, -1, precompiled, precompiled_sz) + && DER_w_end_sequence(pkt, tag); +} diff --git a/providers/common/der/der_rsa.h.in b/providers/common/der/der_rsa.h.in new file mode 100644 index 0000000000..3f7cc0e029 --- /dev/null +++ b/providers/common/der/der_rsa.h.in @@ -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 "internal/der.h" + +/* Well known OIDs precompiled */ +{- + $OUT = oids_to_c::process_leaves('providers/common/der/RSA.asn1', + { dir => $config{sourcedir}, + filter => \&oids_to_c::filter_to_H }); +-} + +int DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa); +int DER_w_algorithmIdentifier_RSA_with(WPACKET *pkt, int tag, + RSA *rsa, int mdnid); diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info index 6f19ca83f6..352cd38cc7 100644 --- a/providers/implementations/signature/build.info +++ b/providers/implementations/signature/build.info @@ -16,3 +16,5 @@ ENDIF SOURCE[../../libfips.a]=rsa.c SOURCE[../../libnonfips.a]=rsa.c + +DEPEND[rsa.o]=../../common/include/prov/der_rsa.h diff --git a/providers/implementations/signature/rsa.c b/providers/implementations/signature/rsa.c index 848cbd7249..cfa76921b5 100644 --- a/providers/implementations/signature/rsa.c +++ b/providers/implementations/signature/rsa.c @@ -28,6 +28,7 @@ #include "prov/providercommonerr.h" #include "prov/implementations.h" #include "prov/provider_ctx.h" +#include "prov/der_rsa.h" static OSSL_OP_signature_newctx_fn rsa_newctx; static OSSL_OP_signature_sign_init_fn rsa_signature_init; @@ -83,7 +84,8 @@ typedef struct { unsigned int flag_allow_md : 1; /* The Algorithm Identifier of the combined signature agorithm */ - unsigned char aid[128]; + unsigned char aid_buf[128]; + unsigned char *aid; size_t aid_len; /* main digest */ @@ -216,35 +218,38 @@ static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, if (mdname != NULL) { EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); int md_nid = rsa_get_md_nid(md); - size_t algorithmidentifier_len = 0; - const unsigned char *algorithmidentifier = NULL; + WPACKET pkt; - if (md == NULL) - return 0; - - if (!rsa_check_padding(md_nid, ctx->pad_mode)) { + if (md == NULL + || md_nid == NID_undef + || !rsa_check_padding(md_nid, ctx->pad_mode)) { EVP_MD_free(md); return 0; } EVP_MD_CTX_free(ctx->mdctx); EVP_MD_free(ctx->md); - ctx->md = NULL; - ctx->mdctx = NULL; - ctx->mdname[0] = '\0'; - ctx->aid[0] = '\0'; - ctx->aid_len = 0; - algorithmidentifier = - rsa_algorithmidentifier_encoding(md_nid, &algorithmidentifier_len); + /* + * TODO(3.0) Should we care about DER writing errors? + * All it really means is that for some reason, there's no + * AlgorithmIdentifier to be had (consider RSA with MD5-SHA1), + * but the operation itself is still valid, just as long as it's + * not used to construct anything that needs an AlgorithmIdentifier. + */ + ctx->aid_len = 0; + if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) + && DER_w_algorithmIdentifier_RSA_with(&pkt, -1, ctx->rsa, md_nid) + && WPACKET_finish(&pkt)) { + WPACKET_get_total_written(&pkt, &ctx->aid_len); + ctx->aid = WPACKET_get_curr(&pkt); + } + WPACKET_cleanup(&pkt); + ctx->mdctx = NULL; ctx->md = md; ctx->mdnid = md_nid; OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname)); - if (algorithmidentifier != NULL) { - memcpy(ctx->aid, algorithmidentifier, algorithmidentifier_len); - ctx->aid_len = algorithmidentifier_len; - } } return 1; -- 2.39.2