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

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