163057e
From 97ac06e5a8e3a8699279c06eeb64c8e958bad7bd Mon Sep 17 00:00:00 2001
163057e
From: Clemens Lang <cllang@redhat.com>
163057e
Date: Fri, 15 Jul 2022 17:45:40 +0200
163057e
Subject: [PATCH] FIPS: Use digest_sign & digest_verify in self test
163057e
163057e
In review for FIPS 140-3, the lack of a self-test for the digest_sign
163057e
and digest_verify provider functions was highlighted as a problem. NIST
163057e
no longer provides ACVP tests for the RSA SigVer primitive (see
163057e
https://github.com/usnistgov/ACVP/issues/1347). Because FIPS 140-3
163057e
recommends the use of functions that compute the digest and signature
163057e
within the module, we have been advised in our module review that the
163057e
self tests should also use the combined digest and signature APIs, i.e.
163057e
the digest_sign and digest_verify provider functions.
163057e
163057e
Modify the signature self-test to use these instead by switching to
163057e
EVP_DigestSign and EVP_DigestVerify. This requires adding more ifdefs to
163057e
crypto/evp/m_sigver.c to make these functions usable in the FIPS module.
163057e
163057e
Signed-off-by: Clemens Lang <cllang@redhat.com>
163057e
---
163057e
 crypto/evp/m_sigver.c           | 43 +++++++++++++++++++++++++++------
163057e
 providers/fips/self_test_kats.c | 37 +++++++++++++++-------------
163057e
 2 files changed, 56 insertions(+), 24 deletions(-)
163057e
163057e
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
163057e
index db1a1d7bc3..c94c3c53bd 100644
163057e
--- a/crypto/evp/m_sigver.c
163057e
+++ b/crypto/evp/m_sigver.c
163057e
@@ -88,6 +88,7 @@ static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen)
163057e
     ERR_raise(ERR_LIB_EVP, EVP_R_ONLY_ONESHOT_SUPPORTED);
163057e
     return 0;
163057e
 }
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
 
163057e
 /*
163057e
  * If we get the "NULL" md then the name comes back as "UNDEF". We want to use
163057e
@@ -130,8 +131,10 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
163057e
         reinit = 0;
163057e
         if (e == NULL)
163057e
             ctx->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, props);
163057e
+#ifndef FIPS_MODULE
163057e
         else
163057e
             ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
     }
163057e
     if (ctx->pctx == NULL)
163057e
         return 0;
163057e
@@ -139,8 +142,10 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
163057e
     locpctx = ctx->pctx;
163057e
     ERR_set_mark();
163057e
 
163057e
+#ifndef FIPS_MODULE
163057e
     if (evp_pkey_ctx_is_legacy(locpctx))
163057e
         goto legacy;
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
 
163057e
     /* do not reinitialize if pkey is set or operation is different */
163057e
     if (reinit
163057e
@@ -225,8 +230,10 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
163057e
             signature =
163057e
                 evp_signature_fetch_from_prov((OSSL_PROVIDER *)tmp_prov,
163057e
                                               supported_sig, locpctx->propquery);
163057e
+#ifndef FIPS_MODULE
163057e
             if (signature == NULL)
163057e
                 goto legacy;
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
             break;
163057e
         }
163057e
         if (signature == NULL)
163057e
@@ -310,6 +317,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
163057e
             ctx->fetched_digest = EVP_MD_fetch(locpctx->libctx, mdname, props);
163057e
             if (ctx->fetched_digest != NULL) {
163057e
                 ctx->digest = ctx->reqdigest = ctx->fetched_digest;
163057e
+#ifndef FIPS_MODULE
163057e
             } else {
163057e
                 /* legacy engine support : remove the mark when this is deleted */
163057e
                 ctx->reqdigest = ctx->digest = EVP_get_digestbyname(mdname);
163057e
@@ -318,11 +326,13 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
163057e
                     ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
163057e
                     goto err;
163057e
                 }
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
             }
163057e
             (void)ERR_pop_to_mark();
163057e
         }
163057e
     }
163057e
 
163057e
+#ifndef FIPS_MODULE
163057e
     if (ctx->reqdigest != NULL
163057e
             && !EVP_PKEY_is_a(locpctx->pkey, SN_hmac)
163057e
             && !EVP_PKEY_is_a(locpctx->pkey, SN_tls1_prf)
163057e
@@ -334,6 +344,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
163057e
             goto err;
163057e
         }
163057e
     }
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
 
163057e
     if (ver) {
163057e
         if (signature->digest_verify_init == NULL) {
163057e
@@ -366,6 +377,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
163057e
     EVP_KEYMGMT_free(tmp_keymgmt);
163057e
     return 0;
163057e
 
163057e
+#ifndef FIPS_MODULE
163057e
  legacy:
163057e
     /*
163057e
      * If we don't have the full support we need with provided methods,
163057e
@@ -437,6 +449,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
163057e
         ctx->pctx->flag_call_digest_custom = 1;
163057e
 
163057e
     ret = 1;
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
 
163057e
  end:
163057e
 #ifndef FIPS_MODULE
163057e
@@ -479,7 +492,6 @@ int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
163057e
     return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 1,
163057e
                           NULL);
163057e
 }
163057e
-#endif /* FIPS_MDOE */
163057e
 
163057e
 int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
163057e
 {
163057e
@@ -541,23 +553,29 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
163057e
     return EVP_DigestUpdate(ctx, data, dsize);
163057e
 }
163057e
 
163057e
-#ifndef FIPS_MODULE
163057e
 int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
163057e
                         size_t *siglen)
163057e
 {
163057e
-    int sctx = 0, r = 0;
163057e
-    EVP_PKEY_CTX *dctx, *pctx = ctx->pctx;
163057e
+    int r = 0;
163057e
+#ifndef FIPS_MODULE
163057e
+    int sctx = 0;
163057e
+    EVP_PKEY_CTX *dctx;
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
+    EVP_PKEY_CTX *pctx = ctx->pctx;
163057e
 
163057e
+#ifndef FIPS_MODULE
163057e
     if (pctx == NULL
163057e
             || pctx->operation != EVP_PKEY_OP_SIGNCTX
163057e
             || pctx->op.sig.algctx == NULL
163057e
             || pctx->op.sig.signature == NULL)
163057e
         goto legacy;
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
 
163057e
     if (sigret == NULL || (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0)
163057e
         return pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx,
163057e
                                                          sigret, siglen,
163057e
                                                          sigret == NULL ? 0 : *siglen);
163057e
+#ifndef FIPS_MODULE
163057e
     dctx = EVP_PKEY_CTX_dup(pctx);
163057e
     if (dctx == NULL)
163057e
         return 0;
163057e
@@ -566,8 +584,10 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
163057e
                                                   sigret, siglen,
163057e
                                                   *siglen);
163057e
     EVP_PKEY_CTX_free(dctx);
163057e
+#endif /* defined(FIPS_MODULE) */
163057e
     return r;
163057e
 
163057e
+#ifndef FIPS_MODULE
163057e
  legacy:
163057e
     if (pctx == NULL || pctx->pmeth == NULL) {
163057e
         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
163057e
@@ -639,6 +659,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
163057e
         }
163057e
     }
163057e
     return 1;
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
 }
163057e
 
163057e
 int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
163057e
@@ -669,21 +690,27 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
163057e
 int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
163057e
                           size_t siglen)
163057e
 {
163057e
-    unsigned char md[EVP_MAX_MD_SIZE];
163057e
     int r = 0;
163057e
+#ifndef FIPS_MODULE
163057e
+    unsigned char md[EVP_MAX_MD_SIZE];
163057e
     unsigned int mdlen = 0;
163057e
     int vctx = 0;
163057e
-    EVP_PKEY_CTX *dctx, *pctx = ctx->pctx;
163057e
+    EVP_PKEY_CTX *dctx;
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
+    EVP_PKEY_CTX *pctx = ctx->pctx;
163057e
 
163057e
+#ifndef FIPS_MODULE
163057e
     if (pctx == NULL
163057e
             || pctx->operation != EVP_PKEY_OP_VERIFYCTX
163057e
             || pctx->op.sig.algctx == NULL
163057e
             || pctx->op.sig.signature == NULL)
163057e
         goto legacy;
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
 
163057e
     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0)
163057e
         return pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx,
163057e
                                                            sig, siglen);
163057e
+#ifndef FIPS_MODULE
163057e
     dctx = EVP_PKEY_CTX_dup(pctx);
163057e
     if (dctx == NULL)
163057e
         return 0;
163057e
@@ -691,8 +718,10 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
163057e
     r = dctx->op.sig.signature->digest_verify_final(dctx->op.sig.algctx,
163057e
                                                     sig, siglen);
163057e
     EVP_PKEY_CTX_free(dctx);
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
     return r;
163057e
 
163057e
+#ifndef FIPS_MODULE
163057e
  legacy:
163057e
     if (pctx == NULL || pctx->pmeth == NULL) {
163057e
         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
163057e
@@ -732,6 +761,7 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
163057e
     if (vctx || !r)
163057e
         return r;
163057e
     return EVP_PKEY_verify(pctx, sig, siglen, md, mdlen);
163057e
+#endif /* !defined(FIPS_MODULE) */
163057e
 }
163057e
 
163057e
 int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
163057e
@@ -757,4 +787,3 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
163057e
         return -1;
163057e
     return EVP_DigestVerifyFinal(ctx, sigret, siglen);
163057e
 }
163057e
-#endif /* FIPS_MODULE */
163057e
diff --git a/providers/fips/self_test_kats.c b/providers/fips/self_test_kats.c
163057e
index b6d5e8e134..77eec075e6 100644
163057e
--- a/providers/fips/self_test_kats.c
163057e
+++ b/providers/fips/self_test_kats.c
163057e
@@ -444,10 +444,13 @@ static int self_test_sign(const ST_KAT_SIGN *t,
163057e
     int ret = 0;
163057e
     OSSL_PARAM *params = NULL, *params_sig = NULL;
163057e
     OSSL_PARAM_BLD *bld = NULL;
163057e
+    EVP_MD *md = NULL;
163057e
+    EVP_MD_CTX *ctx = NULL;
163057e
     EVP_PKEY_CTX *sctx = NULL, *kctx = NULL;
163057e
     EVP_PKEY *pkey = NULL;
163057e
-    unsigned char sig[256];
163057e
     BN_CTX *bnctx = NULL;
163057e
+    const char *msg = "Hello World!";
163057e
+    unsigned char sig[256];
163057e
     size_t siglen = sizeof(sig);
163057e
     static const unsigned char dgst[] = {
163057e
         0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81,
163057e
@@ -488,23 +491,26 @@ static int self_test_sign(const ST_KAT_SIGN *t,
163057e
         || EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
163057e
         goto err;
163057e
 
163057e
-    /* Create a EVP_PKEY_CTX to use for the signing operation */
163057e
-    sctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL);
163057e
-    if (sctx == NULL
163057e
-        || EVP_PKEY_sign_init(sctx) <= 0)
163057e
-        goto err;
163057e
-
163057e
-    /* set signature parameters */
163057e
-    if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_SIGNATURE_PARAM_DIGEST,
163057e
-                                         t->mdalgorithm,
163057e
-                                         strlen(t->mdalgorithm) + 1))
163057e
-        goto err;
163057e
+    /* Create a EVP_MD_CTX to use for the signature operation, assign signature
163057e
+     * parameters and sign */
163057e
     params_sig = OSSL_PARAM_BLD_to_param(bld);
163057e
-    if (EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0)
163057e
+    md = EVP_MD_fetch(libctx, "SHA256", NULL);
163057e
+    ctx = EVP_MD_CTX_new();
163057e
+    if (md == NULL || ctx == NULL)
163057e
+        goto err;
163057e
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE | EVP_MD_CTX_FLAG_ONESHOT);
163057e
+    if (EVP_DigestSignInit(ctx, &sctx, md, NULL, pkey) <= 0
163057e
+        || EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0
163057e
+        || EVP_DigestSign(ctx, sig, &siglen, (const unsigned char *)msg, strlen(msg)) <= 0
163057e
+        || EVP_MD_CTX_reset(ctx) <= 0)
163057e
         goto err;
163057e
 
163057e
-    if (EVP_PKEY_sign(sctx, sig, &siglen, dgst, sizeof(dgst)) <= 0
163057e
-        || EVP_PKEY_verify_init(sctx) <= 0
163057e
+    /* sctx is not freed automatically inside the FIPS module */
163057e
+    EVP_PKEY_CTX_free(sctx);
163057e
+    sctx = NULL;
163057e
+
163057e
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE | EVP_MD_CTX_FLAG_ONESHOT);
163057e
+    if (EVP_DigestVerifyInit(ctx, &sctx, md, NULL, pkey) <= 0
163057e
         || EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0)
163057e
         goto err;
163057e
 
163057e
@@ -509,14 +510,17 @@ static int self_test_sign(const ST_KAT_SIGN *t,
163057e
         goto err;
163057e
 
163057e
     OSSL_SELF_TEST_oncorrupt_byte(st, sig);
163057e
-    if (EVP_PKEY_verify(sctx, sig, siglen, dgst, sizeof(dgst)) <= 0)
163057e
+    if (EVP_DigestVerify(ctx, sig, siglen, (const unsigned char *)msg, strlen(msg)) <= 0)
163057e
         goto err;
163057e
     ret = 1;
163057e
 err:
163057e
     BN_CTX_free(bnctx);
163057e
     EVP_PKEY_free(pkey);
163057e
-    EVP_PKEY_CTX_free(kctx);
163057e
+    EVP_MD_free(md);
163057e
+    EVP_MD_CTX_free(ctx);
163057e
+    /* sctx is not freed automatically inside the FIPS module */
163057e
     EVP_PKEY_CTX_free(sctx);
163057e
+    EVP_PKEY_CTX_free(kctx);
163057e
     OSSL_PARAM_free(params);
163057e
     OSSL_PARAM_free(params_sig);
163057e
     OSSL_PARAM_BLD_free(bld);
163057e
-- 
163057e
2.37.1
163057e