Add provider awareness of EVP_DigestSign() and EVP_DigestVerify()
authorMatt Caswell <matt@openssl.org>
Thu, 5 Mar 2020 15:40:48 +0000 (15:40 +0000)
committerMatt Caswell <matt@openssl.org>
Mon, 9 Mar 2020 07:59:05 +0000 (07:59 +0000)
These "one-shot" functions are the only ones supported by Ed25519 and
Ed448, so we need to ensure that libcrypto can handle provider
based implementations of these functions.

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/11261)

crypto/evp/m_sigver.c
crypto/evp/signature.c
include/openssl/core_numbers.h

index b6c66722ec4b03c8156321611e16aa1e7b40edd4..225017b5095fd54df14f0cf577c98d372b101733 100644 (file)
@@ -24,6 +24,18 @@ static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen)
     return 0;
 }
 
+/*
+ * If we get the "NULL" md then the name comes back as "UNDEF". We want to use
+ * NULL for this.
+ */
+static const char *canon_mdname(const char *mdname)
+{
+    if (mdname != NULL && strcmp(mdname, "UNDEF") == 0)
+        return NULL;
+
+    return mdname;
+}
+
 static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                           const EVP_MD *type, const char *mdname,
                           const char *props, ENGINE *e, EVP_PKEY *pkey,
@@ -134,12 +146,12 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
     if (type != NULL) {
         ctx->reqdigest = type;
         if (mdname == NULL)
-            mdname = EVP_MD_name(type);
+            mdname = canon_mdname(EVP_MD_name(type));
     } else {
         if (mdname == NULL
             && EVP_PKEY_get_default_digest_name(locpctx->pkey, locmdname,
                                                 sizeof(locmdname)))
-            mdname = locmdname;
+            mdname = canon_mdname(locmdname);
 
         if (mdname != NULL) {
             /*
@@ -280,6 +292,11 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
             || pctx->op.sig.signature == NULL)
         goto legacy;
 
+    if (pctx->op.sig.signature->digest_sign_update == NULL) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
     return pctx->op.sig.signature->digest_sign_update(pctx->op.sig.sigprovctx,
                                                       data, dsize);
 
@@ -297,6 +314,11 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
             || pctx->op.sig.signature == NULL)
         goto legacy;
 
+    if (pctx->op.sig.signature->digest_verify_update == NULL) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
     return pctx->op.sig.signature->digest_verify_update(pctx->op.sig.sigprovctx,
                                                         data, dsize);
 
@@ -391,8 +413,22 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
 int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
                    const unsigned char *tbs, size_t tbslen)
 {
-    if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL)
-        return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen);
+    EVP_PKEY_CTX *pctx = ctx->pctx;
+
+    if (pctx != NULL
+            && pctx->operation == EVP_PKEY_OP_SIGNCTX
+            && pctx->op.sig.sigprovctx != NULL
+            && pctx->op.sig.signature != NULL) {
+        if (pctx->op.sig.signature->digest_sign != NULL)
+            return pctx->op.sig.signature->digest_sign(pctx->op.sig.sigprovctx,
+                                                       sigret, siglen, SIZE_MAX,
+                                                       tbs, tbslen);
+    } else {
+        /* legacy */
+        if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL)
+            return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen);
+    }
+
     if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0)
         return 0;
     return EVP_DigestSignFinal(ctx, sigret, siglen);
@@ -454,8 +490,22 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
 int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
                      size_t siglen, const unsigned char *tbs, size_t tbslen)
 {
-    if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestverify != NULL)
-        return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen);
+    EVP_PKEY_CTX *pctx = ctx->pctx;
+
+    if (pctx != NULL
+            && pctx->operation == EVP_PKEY_OP_VERIFYCTX
+            && pctx->op.sig.sigprovctx != NULL
+            && pctx->op.sig.signature != NULL) {
+        if (pctx->op.sig.signature->digest_verify != NULL)
+            return pctx->op.sig.signature->digest_verify(pctx->op.sig.sigprovctx,
+                                                         sigret, siglen,
+                                                         tbs, tbslen);
+    } else {
+        /* legacy */
+        if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestverify != NULL)
+            return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen);
+    }
+
     if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0)
         return -1;
     return EVP_DigestVerifyFinal(ctx, sigret, siglen);
index 3dfd4041e74e5e12038e3993d9101ceb32c0c73b..c01f0766098b835c551be28dbc7eb04b5626f6ab 100644 (file)
@@ -105,7 +105,6 @@ static void *evp_signature_from_dispatch(int name_id,
                 break;
             signature->digest_sign_init
                 = OSSL_get_OP_signature_digest_sign_init(fns);
-            digsignfncnt++;
             break;
         case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE:
             if (signature->digest_sign_update != NULL)
@@ -121,12 +120,17 @@ static void *evp_signature_from_dispatch(int name_id,
                 = OSSL_get_OP_signature_digest_sign_final(fns);
             digsignfncnt++;
             break;
+        case OSSL_FUNC_SIGNATURE_DIGEST_SIGN:
+            if (signature->digest_sign != NULL)
+                break;
+            signature->digest_sign
+                = OSSL_get_OP_signature_digest_sign(fns);
+            break;
         case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT:
             if (signature->digest_verify_init != NULL)
                 break;
             signature->digest_verify_init
                 = OSSL_get_OP_signature_digest_verify_init(fns);
-            digverifyfncnt++;
             break;
         case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE:
             if (signature->digest_verify_update != NULL)
@@ -142,6 +146,12 @@ static void *evp_signature_from_dispatch(int name_id,
                 = OSSL_get_OP_signature_digest_verify_final(fns);
             digverifyfncnt++;
             break;
+        case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY:
+            if (signature->digest_verify != NULL)
+                break;
+            signature->digest_verify
+                = OSSL_get_OP_signature_digest_verify(fns);
+            break;
         case OSSL_FUNC_SIGNATURE_FREECTX:
             if (signature->freectx != NULL)
                 break;
@@ -216,12 +226,20 @@ static void *evp_signature_from_dispatch(int name_id,
             && verifyfncnt == 0
             && verifyrecfncnt == 0
             && digsignfncnt == 0
-            && digverifyfncnt == 0)
+            && digverifyfncnt == 0
+            && signature->digest_sign == NULL
+            && signature->digest_verify == NULL)
         || (signfncnt != 0 && signfncnt != 2)
         || (verifyfncnt != 0 && verifyfncnt != 2)
         || (verifyrecfncnt != 0 && verifyrecfncnt != 2)
-        || (digsignfncnt != 0 && digsignfncnt != 3)
-        || (digverifyfncnt != 0 && digverifyfncnt != 3)
+        || (digsignfncnt != 0 && digsignfncnt != 2)
+        || (digsignfncnt == 2 && signature->digest_sign_init == NULL)
+        || (digverifyfncnt != 0 && digverifyfncnt != 2)
+        || (digverifyfncnt == 2 && signature->digest_verify_init == NULL)
+        || (signature->digest_sign != NULL
+            && signature->digest_sign_init == NULL)
+        || (signature->digest_verify != NULL
+            && signature->digest_verify_init == NULL)
         || (gparamfncnt != 0 && gparamfncnt != 2)
         || (sparamfncnt != 0 && sparamfncnt != 2)
         || (gmdparamfncnt != 0 && gmdparamfncnt != 2)
@@ -234,7 +252,9 @@ static void *evp_signature_from_dispatch(int name_id,
          *  (verify_init verify) or
          *  (verify_recover_init, verify_recover) or
          *  (digest_sign_init, digest_sign_update, digest_sign_final) or
-         *  (digest_verify_init, digest_verify_update, digest_verify_final).
+         *  (digest_verify_init, digest_verify_update, digest_verify_final) or
+         *  (digest_sign_init, digest_sign) or
+         *  (digest_verify_init, digest_verify).
          *
          * set_ctx_params and settable_ctx_params are optional, but if one of
          * them is present then the other one must also be present. The same
index 3314a0f665e23b8e83df7c9d8d2be32ccc5d09f9..c65041894a13f3a524a3b764c53c15d307a81e84 100644 (file)
@@ -480,19 +480,21 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keyexch_gettable_ctx_params,
 # define OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT        8
 # define OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE      9
 # define OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL      10
-# define OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT     11
-# define OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE   12
-# define OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL    13
-# define OSSL_FUNC_SIGNATURE_FREECTX                14
-# define OSSL_FUNC_SIGNATURE_DUPCTX                 15
-# define OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS         16
-# define OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS    17
-# define OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS         18
-# define OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS    19
-# define OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS      20
-# define OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS 21
-# define OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS      22
-# define OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS 23
+# define OSSL_FUNC_SIGNATURE_DIGEST_SIGN            11
+# define OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT     12
+# define OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE   13
+# define OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL    14
+# define OSSL_FUNC_SIGNATURE_DIGEST_VERIFY          15
+# define OSSL_FUNC_SIGNATURE_FREECTX                16
+# define OSSL_FUNC_SIGNATURE_DUPCTX                 17
+# define OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS         18
+# define OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS    19
+# define OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS         20
+# define OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS    21
+# define OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS      22
+# define OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS 23
+# define OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS      24
+# define OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS 25
 
 OSSL_CORE_MAKE_FUNC(void *, OP_signature_newctx, (void *provctx))
 OSSL_CORE_MAKE_FUNC(int, OP_signature_sign_init, (void *ctx, void *provkey))
@@ -522,6 +524,9 @@ OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_sign_update,
 OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_sign_final,
                     (void *ctx, unsigned char *sig, size_t *siglen,
                      size_t sigsize))
+OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_sign,
+                    (void *ctx, unsigned char *sigret, size_t *siglen,
+                     size_t sigsize, const unsigned char *tbs, size_t tbslen))
 OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_verify_init,
                     (void *ctx, const char *mdname, const char *props,
                      void *provkey))
@@ -529,6 +534,9 @@ OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_verify_update,
                     (void *ctx, const unsigned char *data, size_t datalen))
 OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_verify_final,
                     (void *ctx, const unsigned char *sig, size_t siglen))
+OSSL_CORE_MAKE_FUNC(int, OP_signature_digest_verify,
+                    (void *ctx, const unsigned char *sig, size_t siglen,
+                     const unsigned char *tbs, size_t tbslen))
 OSSL_CORE_MAKE_FUNC(void, OP_signature_freectx, (void *ctx))
 OSSL_CORE_MAKE_FUNC(void *, OP_signature_dupctx, (void *ctx))
 OSSL_CORE_MAKE_FUNC(int, OP_signature_get_ctx_params,