Blame SOURCES/0074-FIPS-Use-digest_sign-digest_verify-in-self-test.patch

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