From: Richard Levitte Date: Tue, 31 Mar 2020 15:16:59 +0000 (+0200) Subject: PROV: Add DERlib support for DSA X-Git-Tag: openssl-3.0.0-alpha1~153 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=8c555803476a2af366938161d1186a0d746910ea;ds=sidebyside PROV: Add DERlib support for DSA This replaces crypto/dsa/dsa_aid.c with new code and generated OIDs Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/11450) --- diff --git a/crypto/dsa/build.info b/crypto/dsa/build.info index d8f035000d..fb5a4fee2a 100644 --- a/crypto/dsa/build.info +++ b/crypto/dsa/build.info @@ -1,6 +1,6 @@ LIBS=../../libcrypto -$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c dsa_aid.c dsa_check.c \ +$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c dsa_check.c \ dsa_key.c dsa_backend.c SOURCE[../../libcrypto]=$COMMON\ diff --git a/crypto/dsa/dsa_aid.c b/crypto/dsa/dsa_aid.c deleted file mode 100644 index 505e2e2f40..0000000000 --- a/crypto/dsa/dsa_aid.c +++ /dev/null @@ -1,70 +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/dsa.h" - -#define ASN1_SEQUENCE 0x30 -#define ASN1_OID 0x06 - -/* - * id-dsa-with-sha1 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3 - * } - */ -#define ENCODE_ALGORITHMIDENTIFIER_RFC3279(name, n) \ - static const unsigned char algorithmidentifier_##name##_der[] = { \ - ASN1_SEQUENCE, 0x09, \ - ASN1_OID, 0x07, 1 * 40 + 2, 134, 72, 206, 56, 4, n \ -} - -ENCODE_ALGORITHMIDENTIFIER_RFC3279(sha1, 3); - -/* - * dsaWithSHAx OIDs are of the form: (sigAlgs |n|) - * where sigAlgs OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 4 3 } - */ -#define ENCODE_ALGORITHMIDENTIFIER_SIGALGS(name, n) \ - static const unsigned char algorithmidentifier_##name##_der[] = { \ - ASN1_SEQUENCE, 0x0b, \ - ASN1_OID, 0x09, 2 * 40 + 16, 0x86, 0x48, 1, 101, 3, 4, 3, n \ -} - -ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha224, 1); -ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha256, 2); -ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha384, 3); -ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha512, 4); -ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_224, 5); -ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_256, 6); -ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_384, 7); -ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_512, 8); - -#define MD_CASE(name) \ - case NID_##name: \ - *len = sizeof(algorithmidentifier_##name##_der); \ - return algorithmidentifier_##name##_der - -const unsigned char *dsa_algorithmidentifier_encoding(int md_nid, size_t *len) -{ - switch (md_nid) { - 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/DSA.asn1 b/providers/common/der/DSA.asn1 new file mode 100644 index 0000000000..84b677a40f --- /dev/null +++ b/providers/common/der/DSA.asn1 @@ -0,0 +1,29 @@ +-- ------------------------------------------------------------------- +-- 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/build.info b/providers/common/der/build.info index dd3a86978a..c560a7084d 100644 --- a/providers/common/der/build.info +++ b/providers/common/der/build.info @@ -1,4 +1,4 @@ -$FIPSABLE=der_rsa.c +$FIPSABLE=der_rsa.c der_dsa.c SOURCE[../../libfips.a]=$FIPSABLE SOURCE[../../libnonfips.a]=$FIPSABLE @@ -9,3 +9,10 @@ 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 + +GENERATE[der_dsa.c]=der_dsa.c.in +DEPEND[der_dsa.c]=oids_to_c.pm + +DEPEND[der_dsa.o]=../include/prov/der_dsa.h +GENERATE[../include/prov/der_dsa.h]=der_dsa.h.in +DEPEND[../include/prov/der_dsa.h]=oids_to_c.pm diff --git a/providers/common/der/der_dsa.c.in b/providers/common/der/der_dsa.c.in new file mode 100644 index 0000000000..28c0ba8c6c --- /dev/null +++ b/providers/common/der/der_dsa.c.in @@ -0,0 +1,59 @@ +/* + * 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_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 }); +-} + +int DER_w_algorithmIdentifier_DSA(WPACKET *pkt, int tag, DSA *dsa) +{ + return DER_w_begin_sequence(pkt, tag) + /* No parameters (yet?) */ + && DER_w_precompiled(pkt, -1, der_oid_id_dsa, sizeof(der_oid_id_dsa)) + && DER_w_end_sequence(pkt, tag); +} + +#define MD_CASE(name) \ + case NID_##name: \ + precompiled = der_oid_id_dsa_with_##name; \ + precompiled_sz = sizeof(der_oid_id_dsa_with_##name); \ + break; + +int DER_w_algorithmIdentifier_DSA_with(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 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_dsa.h.in b/providers/common/der/der_dsa.h.in new file mode 100644 index 0000000000..d9e7bf205a --- /dev/null +++ b/providers/common/der/der_dsa.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/DSA.asn1', + { dir => $config{sourcedir}, + filter => \&oids_to_c::filter_to_H }); +-} + +int DER_w_algorithmIdentifier_DSA(WPACKET *pkt, int tag, DSA *dsa); +int DER_w_algorithmIdentifier_DSA_with(WPACKET *pkt, int tag, + DSA *dsa, int mdnid); diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info index 352cd38cc7..c53673409f 100644 --- a/providers/implementations/signature/build.info +++ b/providers/implementations/signature/build.info @@ -18,3 +18,4 @@ SOURCE[../../libfips.a]=rsa.c SOURCE[../../libnonfips.a]=rsa.c DEPEND[rsa.o]=../../common/include/prov/der_rsa.h +DEPEND[dsa.o]=../../common/include/prov/der_dsa.h diff --git a/providers/implementations/signature/dsa.c b/providers/implementations/signature/dsa.c index 92c3b571c2..30147aa163 100644 --- a/providers/implementations/signature/dsa.c +++ b/providers/implementations/signature/dsa.c @@ -25,11 +25,13 @@ #include #include "internal/nelem.h" #include "internal/sizes.h" +#include "internal/cryptlib.h" #include "prov/providercommonerr.h" #include "prov/implementations.h" #include "prov/providercommonerr.h" #include "prov/provider_ctx.h" #include "crypto/dsa.h" +#include "prov/der_dsa.h" static OSSL_OP_signature_newctx_fn dsa_newctx; static OSSL_OP_signature_sign_init_fn dsa_signature_init; @@ -74,7 +76,8 @@ typedef struct { char mdname[OSSL_MAX_NAME_SIZE]; /* The Algorithm Identifier of the combined signature algorithm */ - unsigned char aid[OSSL_MAX_ALGORITHM_ID_SIZE]; + unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE]; + unsigned char *aid; size_t aid_len; /* main digest */ @@ -146,25 +149,35 @@ static int dsa_setup_md(PROV_DSA_CTX *ctx, if (mdname != NULL) { EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); int md_nid = dsa_get_md_nid(md); - size_t algorithmidentifier_len = 0; - const unsigned char *algorithmidentifier; + WPACKET pkt; - EVP_MD_free(ctx->md); - ctx->md = NULL; - ctx->mdname[0] = '\0'; - - algorithmidentifier = - dsa_algorithmidentifier_encoding(md_nid, &algorithmidentifier_len); - - if (algorithmidentifier == NULL) { + if (md == NULL || md_nid == NID_undef) { EVP_MD_free(md); return 0; } + EVP_MD_CTX_free(ctx->mdctx); + EVP_MD_free(ctx->md); + + /* + * 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, 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_DSA_with(&pkt, -1, ctx->dsa, 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; OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname)); - memcpy(ctx->aid, algorithmidentifier, algorithmidentifier_len); - ctx->aid_len = algorithmidentifier_len; } return 1; }