PROV: Add DERlib support for RSA
authorRichard Levitte <levitte@openssl.org>
Tue, 31 Mar 2020 15:15:17 +0000 (17:15 +0200)
committerRichard Levitte <levitte@openssl.org>
Tue, 7 Apr 2020 09:16:56 +0000 (11:16 +0200)
This replaces crypto/rsa/rsa_aid.c with new code and generated OIDs

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11450)

crypto/rsa/build.info
crypto/rsa/rsa_aid.c [deleted file]
providers/common/der/RSA.asn1 [new file with mode: 0644]
providers/common/der/build.info [new file with mode: 0644]
providers/common/der/der_rsa.c.in [new file with mode: 0644]
providers/common/der/der_rsa.h.in [new file with mode: 0644]
providers/implementations/signature/build.info
providers/implementations/signature/rsa.c

index 7921202..0c9e466 100644 (file)
@@ -1,6 +1,6 @@
 LIBS=../../libcrypto
 
 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
         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 (file)
index 4b4d3a6..0000000
+++ /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 <stdlib.h>
-
-#include <openssl/objects.h>
-#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 (file)
index 0000000..7bce636
--- /dev/null
@@ -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 (file)
index 0000000..dd3a869
--- /dev/null
@@ -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 (file)
index 0000000..fb936d2
--- /dev/null
@@ -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 <openssl/bn.h>
+#include <openssl/obj_mac.h>
+#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 (file)
index 0000000..3f7cc0e
--- /dev/null
@@ -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);
index 6f19ca8..352cd38 100644 (file)
@@ -16,3 +16,5 @@ ENDIF
 
 SOURCE[../../libfips.a]=rsa.c
 SOURCE[../../libnonfips.a]=rsa.c
 
 SOURCE[../../libfips.a]=rsa.c
 SOURCE[../../libnonfips.a]=rsa.c
+
+DEPEND[rsa.o]=../../common/include/prov/der_rsa.h
index 848cbd7..cfa7692 100644 (file)
@@ -28,6 +28,7 @@
 #include "prov/providercommonerr.h"
 #include "prov/implementations.h"
 #include "prov/provider_ctx.h"
 #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;
 
 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 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 */
     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);
     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);
             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));
         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;
     }
 
     return 1;