File openssl-FIPS-Use-digest_sign-digest_verify-in-self-test.patch of Package openssl-3

From 97ac06e5a8e3a8699279c06eeb64c8e958bad7bd Mon Sep 17 00:00:00 2001
From: Clemens Lang <cllang@redhat.com>
Date: Fri, 15 Jul 2022 17:45:40 +0200
Subject: [PATCH] FIPS: Use digest_sign & digest_verify in self test

In review for FIPS 140-3, the lack of a self-test for the digest_sign
and digest_verify provider functions was highlighted as a problem. NIST
no longer provides ACVP tests for the RSA SigVer primitive (see
https://github.com/usnistgov/ACVP/issues/1347). Because FIPS 140-3
recommends the use of functions that compute the digest and signature
within the module, we have been advised in our module review that the
self tests should also use the combined digest and signature APIs, i.e.
the digest_sign and digest_verify provider functions.

Modify the signature self-test to use these instead by switching to
EVP_DigestSign and EVP_DigestVerify. This requires adding more ifdefs to
crypto/evp/m_sigver.c to make these functions usable in the FIPS module.

Signed-off-by: Clemens Lang <cllang@redhat.com>
---
 crypto/evp/m_sigver.c           | 43 +++++++++++++++++++++++++++------
 providers/fips/self_test_kats.c | 37 +++++++++++++++-------------
 2 files changed, 56 insertions(+), 24 deletions(-)

Index: openssl-3.1.4/crypto/evp/m_sigver.c
===================================================================
--- openssl-3.1.4.orig/crypto/evp/m_sigver.c
+++ openssl-3.1.4/crypto/evp/m_sigver.c
@@ -90,6 +90,7 @@ static int update(EVP_MD_CTX *ctx, const
     ERR_raise(ERR_LIB_EVP, EVP_R_ONLY_ONESHOT_SUPPORTED);
     return 0;
 }
+#endif /* !defined(FIPS_MODULE) */
 
 /*
  * If we get the "NULL" md then the name comes back as "UNDEF". We want to use
@@ -125,8 +126,10 @@ static int do_sigver_init(EVP_MD_CTX *ct
         reinit = 0;
         if (e == NULL)
             ctx->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, props);
+#ifndef FIPS_MODULE
         else
             ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
+#endif /* !defined(FIPS_MODULE) */
     }
     if (ctx->pctx == NULL)
         return 0;
@@ -134,8 +137,10 @@ static int do_sigver_init(EVP_MD_CTX *ct
     locpctx = ctx->pctx;
     ERR_set_mark();
 
+#ifndef FIPS_MODULE
     if (evp_pkey_ctx_is_legacy(locpctx))
         goto legacy;
+#endif /* !defined(FIPS_MODULE) */
 
     /* do not reinitialize if pkey is set or operation is different */
     if (reinit
@@ -220,8 +225,10 @@ static int do_sigver_init(EVP_MD_CTX *ct
             signature =
                 evp_signature_fetch_from_prov((OSSL_PROVIDER *)tmp_prov,
                                               supported_sig, locpctx->propquery);
+#ifndef FIPS_MODULE
             if (signature == NULL)
                 goto legacy;
+#endif /* !defined(FIPS_MODULE) */
             break;
         }
         if (signature == NULL)
@@ -305,6 +312,7 @@ static int do_sigver_init(EVP_MD_CTX *ct
             ctx->fetched_digest = EVP_MD_fetch(locpctx->libctx, mdname, props);
             if (ctx->fetched_digest != NULL) {
                 ctx->digest = ctx->reqdigest = ctx->fetched_digest;
+#ifndef FIPS_MODULE
             } else {
                 /* legacy engine support : remove the mark when this is deleted */
                 ctx->reqdigest = ctx->digest = EVP_get_digestbyname(mdname);
@@ -313,11 +321,13 @@ static int do_sigver_init(EVP_MD_CTX *ct
                     ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
                     goto err;
                 }
+#endif /* !defined(FIPS_MODULE) */
             }
             (void)ERR_pop_to_mark();
         }
     }
 
+#ifndef FIPS_MODULE
     if (ctx->reqdigest != NULL
             && !EVP_PKEY_is_a(locpctx->pkey, SN_hmac)
             && !EVP_PKEY_is_a(locpctx->pkey, SN_tls1_prf)
@@ -329,6 +339,7 @@ static int do_sigver_init(EVP_MD_CTX *ct
             goto err;
         }
     }
+#endif /* !defined(FIPS_MODULE) */
 
     if (ver) {
         if (signature->digest_verify_init == NULL) {
@@ -361,6 +372,7 @@ static int do_sigver_init(EVP_MD_CTX *ct
     EVP_KEYMGMT_free(tmp_keymgmt);
     return 0;
 
+#ifndef FIPS_MODULE
  legacy:
     /*
      * If we don't have the full support we need with provided methods,
@@ -432,6 +444,7 @@ static int do_sigver_init(EVP_MD_CTX *ct
         ctx->pctx->flag_call_digest_custom = 1;
 
     ret = 1;
+#endif /* !defined(FIPS_MODULE) */
 
  end:
 #ifndef FIPS_MODULE
@@ -474,7 +487,6 @@ int EVP_DigestVerifyInit(EVP_MD_CTX *ctx
     return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 1,
                           NULL);
 }
-#endif /* FIPS_MDOE */
 
 int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
 {
@@ -536,23 +548,29 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *c
     return EVP_DigestUpdate(ctx, data, dsize);
 }
 
-#ifndef FIPS_MODULE
 int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
                         size_t *siglen)
 {
-    int sctx = 0, r = 0;
-    EVP_PKEY_CTX *dctx, *pctx = ctx->pctx;
+    int r = 0;
+#ifndef FIPS_MODULE
+    int sctx = 0;
+    EVP_PKEY_CTX *dctx;
+#endif /* !defined(FIPS_MODULE) */
+    EVP_PKEY_CTX *pctx = ctx->pctx;
 
+#ifndef FIPS_MODULE
     if (pctx == NULL
             || pctx->operation != EVP_PKEY_OP_SIGNCTX
             || pctx->op.sig.algctx == NULL
             || pctx->op.sig.signature == NULL)
         goto legacy;
+#endif /* !defined(FIPS_MODULE) */
 
     if (sigret == NULL || (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0)
         return pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx,
                                                          sigret, siglen,
                                                          sigret == NULL ? 0 : *siglen);
+#ifndef FIPS_MODULE
     dctx = EVP_PKEY_CTX_dup(pctx);
     if (dctx == NULL)
         return 0;
@@ -561,8 +579,10 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx,
                                                   sigret, siglen,
                                                   *siglen);
     EVP_PKEY_CTX_free(dctx);
+#endif /* defined(FIPS_MODULE) */
     return r;
 
+#ifndef FIPS_MODULE
  legacy:
     if (pctx == NULL || pctx->pmeth == NULL) {
         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
@@ -634,6 +654,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx,
         }
     }
     return 1;
+#endif /* !defined(FIPS_MODULE) */
 }
 
 int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
@@ -664,21 +685,27 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsi
 int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
                           size_t siglen)
 {
-    unsigned char md[EVP_MAX_MD_SIZE];
     int r = 0;
+#ifndef FIPS_MODULE
+    unsigned char md[EVP_MAX_MD_SIZE];
     unsigned int mdlen = 0;
     int vctx = 0;
-    EVP_PKEY_CTX *dctx, *pctx = ctx->pctx;
+    EVP_PKEY_CTX *dctx;
+#endif /* !defined(FIPS_MODULE) */
+    EVP_PKEY_CTX *pctx = ctx->pctx;
 
+#ifndef FIPS_MODULE
     if (pctx == NULL
             || pctx->operation != EVP_PKEY_OP_VERIFYCTX
             || pctx->op.sig.algctx == NULL
             || pctx->op.sig.signature == NULL)
         goto legacy;
+#endif /* !defined(FIPS_MODULE) */
 
     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0)
         return pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx,
                                                            sig, siglen);
+#ifndef FIPS_MODULE
     dctx = EVP_PKEY_CTX_dup(pctx);
     if (dctx == NULL)
         return 0;
@@ -686,8 +713,10 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ct
     r = dctx->op.sig.signature->digest_verify_final(dctx->op.sig.algctx,
                                                     sig, siglen);
     EVP_PKEY_CTX_free(dctx);
+#endif /* !defined(FIPS_MODULE) */
     return r;
 
+#ifndef FIPS_MODULE
  legacy:
     if (pctx == NULL || pctx->pmeth == NULL) {
         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
@@ -727,6 +756,7 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ct
     if (vctx || !r)
         return r;
     return EVP_PKEY_verify(pctx, sig, siglen, md, mdlen);
+#endif /* !defined(FIPS_MODULE) */
 }
 
 int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
@@ -752,4 +782,3 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, co
         return -1;
     return EVP_DigestVerifyFinal(ctx, sigret, siglen);
 }
-#endif /* FIPS_MODULE */
Index: openssl-3.1.4/providers/fips/self_test_kats.c
===================================================================
--- openssl-3.1.4.orig/providers/fips/self_test_kats.c
+++ openssl-3.1.4/providers/fips/self_test_kats.c
@@ -450,10 +450,13 @@ static int self_test_sign(const ST_KAT_S
     int ret = 0;
     OSSL_PARAM *params = NULL, *params_sig = NULL;
     OSSL_PARAM_BLD *bld = NULL;
+    EVP_MD *md = NULL;
+    EVP_MD_CTX *ctx = NULL;
     EVP_PKEY_CTX *sctx = NULL, *kctx = NULL;
     EVP_PKEY *pkey = NULL;
-    unsigned char sig[256];
     BN_CTX *bnctx = NULL;
+    const char *msg = "Hello World!";
+    unsigned char sig[256];
     size_t siglen = sizeof(sig);
     static const unsigned char dgst[] = {
         0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81,
@@ -487,23 +490,26 @@ static int self_test_sign(const ST_KAT_S
         || EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
         goto err;
 
-    /* Create a EVP_PKEY_CTX to use for the signing operation */
-    sctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL);
-    if (sctx == NULL
-        || EVP_PKEY_sign_init(sctx) <= 0)
-        goto err;
-
-    /* set signature parameters */
-    if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_SIGNATURE_PARAM_DIGEST,
-                                         t->mdalgorithm,
-                                         strlen(t->mdalgorithm) + 1))
-        goto err;
+    /* Create a EVP_MD_CTX to use for the signature operation, assign signature
+     * parameters and sign */
     params_sig = OSSL_PARAM_BLD_to_param(bld);
-    if (EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0)
+    md = EVP_MD_fetch(libctx, "SHA256", NULL);
+    ctx = EVP_MD_CTX_new();
+    if (md == NULL || ctx == NULL)
+        goto err;
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE | EVP_MD_CTX_FLAG_ONESHOT);
+    if (EVP_DigestSignInit(ctx, &sctx, md, NULL, pkey) <= 0
+        || EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0
+        || EVP_DigestSign(ctx, sig, &siglen, (const unsigned char *)msg, strlen(msg)) <= 0
+        || EVP_MD_CTX_reset(ctx) <= 0)
         goto err;
 
-    if (EVP_PKEY_sign(sctx, sig, &siglen, dgst, sizeof(dgst)) <= 0
-        || EVP_PKEY_verify_init(sctx) <= 0
+    /* sctx is not freed automatically inside the FIPS module */
+    EVP_PKEY_CTX_free(sctx);
+    sctx = NULL;
+
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE | EVP_MD_CTX_FLAG_ONESHOT);
+    if (EVP_DigestVerifyInit(ctx, &sctx, md, NULL, pkey) <= 0
         || EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0)
         goto err;
 
@@ -513,14 +519,17 @@ static int self_test_sign(const ST_KAT_S
         goto err;
 
     OSSL_SELF_TEST_oncorrupt_byte(st, sig);
-    if (EVP_PKEY_verify(sctx, sig, siglen, dgst, sizeof(dgst)) <= 0)
+    if (EVP_DigestVerify(ctx, sig, siglen, (const unsigned char *)msg, strlen(msg)) <= 0)
         goto err;
     ret = 1;
 err:
     BN_CTX_free(bnctx);
     EVP_PKEY_free(pkey);
-    EVP_PKEY_CTX_free(kctx);
+    EVP_MD_free(md);
+    EVP_MD_CTX_free(ctx);
+    /* sctx is not freed automatically inside the FIPS module */
     EVP_PKEY_CTX_free(sctx);
+    EVP_PKEY_CTX_free(kctx);
     OSSL_PARAM_free(params);
     OSSL_PARAM_free(params_sig);
     OSSL_PARAM_BLD_free(bld);
openSUSE Build Service is sponsored by