e35e9c
From 2ddeec574bc1ae90bb4242c4ce9ad9e7975a27bd Mon Sep 17 00:00:00 2001
e35e9c
From: Jakub Jelen <jjelen@redhat.com>
e35e9c
Date: Wed, 1 Mar 2023 15:42:29 +0100
e35e9c
Subject: [PATCH] ecc: Do not allow skipping tests in FIPS Mode.
e35e9c
e35e9c
* cipher/ecc.c (ecc_generate): Do not allow skipping tests PCT tests
e35e9c
in FIPS mode.
e35e9c
e35e9c
--
e35e9c
e35e9c
The new FIPS specification requires to run the PCT without any
e35e9c
exceptions.
e35e9c
e35e9c
GnuPG-bug-id: 6394
e35e9c
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
e35e9c
---
e35e9c
 cipher/ecc.c | 2 +-
e35e9c
 1 file changed, 1 insertion(+), 1 deletion(-)
e35e9c
e35e9c
diff --git a/cipher/ecc.c b/cipher/ecc.c
e35e9c
index 1e80200e..797f2368 100644
e35e9c
--- a/cipher/ecc.c
e35e9c
+++ b/cipher/ecc.c
e35e9c
@@ -677,7 +677,7 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
e35e9c
         log_debug ("ecgen result  using Ed25519+EdDSA\n");
e35e9c
     }
e35e9c
 
e35e9c
-  if (!(flags & PUBKEY_FLAG_NO_KEYTEST) && fips_mode ())
e35e9c
+  if (fips_mode ())
e35e9c
     test_keys_fips (*r_skey);
e35e9c
 
e35e9c
  leave:
e35e9c
-- 
e35e9c
2.39.2
e35e9c
e35e9c
From 23a2d1285e35b2eb91bb422609eb1c965c8a9bf6 Mon Sep 17 00:00:00 2001
e35e9c
From: Jakub Jelen <jjelen@redhat.com>
e35e9c
Date: Thu, 2 Mar 2023 09:43:44 +0100
e35e9c
Subject: [PATCH] ecc: Make the PCT recoverable in FIPS mode and consistent
e35e9c
 with RSA.
e35e9c
e35e9c
* cipher/ecc.c (test_keys_fips): Replace calls to log_fatal with
e35e9c
return code on error.
e35e9c
(ecc_generate): Signal error when PCT fails in FIPS mode.
e35e9c
e35e9c
--
e35e9c
e35e9c
GnuPG-bug-id: 6397
e35e9c
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
e35e9c
---
e35e9c
 cipher/ecc.c | 36 ++++++++++++++++++++++++++++--------
e35e9c
 1 file changed, 28 insertions(+), 8 deletions(-)
e35e9c
e35e9c
diff --git a/cipher/ecc.c b/cipher/ecc.c
e35e9c
index 797f2368..19520db3 100644
e35e9c
--- a/cipher/ecc.c
e35e9c
+++ b/cipher/ecc.c
e35e9c
@@ -101,7 +101,7 @@ static void *progress_cb_data;
e35e9c
 
e35e9c
 /* Local prototypes. */
e35e9c
 static void test_keys (mpi_ec_t ec, unsigned int nbits);
e35e9c
-static void test_keys_fips (gcry_sexp_t skey);
e35e9c
+static int test_keys_fips (gcry_sexp_t skey);
e35e9c
 static void test_ecdh_only_keys (mpi_ec_t ec, unsigned int nbits, int flags);
e35e9c
 static unsigned int ecc_get_nbits (gcry_sexp_t parms);
e35e9c
 
e35e9c
@@ -308,9 +308,10 @@ test_keys (mpi_ec_t ec, unsigned int nbits)
e35e9c
 /* We should get here only with the NIST curves as they are the only ones
e35e9c
  * having the fips bit set in ecc_domain_parms_t struct so this is slightly
e35e9c
  * simpler than the whole ecc_generate function */
e35e9c
-static void
e35e9c
+static int
e35e9c
 test_keys_fips (gcry_sexp_t skey)
e35e9c
 {
e35e9c
+  int result = -1; /* Default to failure */
e35e9c
   gcry_md_hd_t hd = NULL;
e35e9c
   const char *data_tmpl = "(data (flags rfc6979) (hash %s %b))";
e35e9c
   gcry_sexp_t sig = NULL;
e35e9c
@@ -323,18 +324,27 @@ test_keys_fips (gcry_sexp_t skey)
e35e9c
   /* Open MD context and feed the random data in */
e35e9c
   rc = _gcry_md_open (&hd, GCRY_MD_SHA256, 0);
e35e9c
   if (rc)
e35e9c
-    log_fatal ("ECDSA operation: failed to initialize MD context: %s\n", gpg_strerror (rc));
e35e9c
+    {
e35e9c
+      log_error ("ECDSA operation: failed to initialize MD context: %s\n", gpg_strerror (rc));
e35e9c
+      goto leave;
e35e9c
+    }
e35e9c
   _gcry_md_write (hd, plaintext, sizeof(plaintext));
e35e9c
 
e35e9c
   /* Sign the data */
e35e9c
   rc = _gcry_pk_sign_md (&sig, data_tmpl, hd, skey, NULL);
e35e9c
   if (rc)
e35e9c
-    log_fatal ("ECDSA operation: signing failed: %s\n", gpg_strerror (rc));
e35e9c
+    {
e35e9c
+      log_error ("ECDSA operation: signing failed: %s\n", gpg_strerror (rc));
e35e9c
+      goto leave;
e35e9c
+    }
e35e9c
 
e35e9c
   /* Verify this signature.  */
e35e9c
   rc = _gcry_pk_verify_md (sig, data_tmpl, hd, skey, NULL);
e35e9c
   if (rc)
e35e9c
-    log_fatal ("ECDSA operation: verification failed: %s\n", gpg_strerror (rc));
e35e9c
+    {
e35e9c
+      log_error ("ECDSA operation: verification failed: %s\n", gpg_strerror (rc));
e35e9c
+      goto leave;
e35e9c
+    }
e35e9c
 
e35e9c
   /* Modify the data and check that the signing fails.  */
e35e9c
   _gcry_md_reset(hd);
e35e9c
@@ -342,10 +352,16 @@ test_keys_fips (gcry_sexp_t skey)
e35e9c
   _gcry_md_write (hd, plaintext, sizeof(plaintext));
e35e9c
   rc = _gcry_pk_verify_md (sig, data_tmpl, hd, skey, NULL);
e35e9c
   if (rc != GPG_ERR_BAD_SIGNATURE)
e35e9c
-    log_fatal ("ECDSA operation: signature verification worked on modified data\n");
e35e9c
+    {
e35e9c
+      log_error ("ECDSA operation: signature verification worked on modified data\n");
e35e9c
+      goto leave;
e35e9c
+    }
e35e9c
 
e35e9c
+  result = 0;
e35e9c
+leave:
e35e9c
   _gcry_md_close (hd);
e35e9c
   sexp_release (sig);
e35e9c
+  return result;
e35e9c
 }
e35e9c
 
e35e9c
 
e35e9c
@@ -677,8 +693,12 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
e35e9c
         log_debug ("ecgen result  using Ed25519+EdDSA\n");
e35e9c
     }
e35e9c
 
e35e9c
-  if (fips_mode ())
e35e9c
-    test_keys_fips (*r_skey);
e35e9c
+  if (fips_mode () && test_keys_fips (*r_skey))
e35e9c
+    {
e35e9c
+      sexp_release (*r_skey); r_skey = NULL;
e35e9c
+      fips_signal_error ("self-test after key generation failed");
e35e9c
+      rc = GPG_ERR_SELFTEST_FAILED;
e35e9c
+    }
e35e9c
 
e35e9c
  leave:
e35e9c
   mpi_free (public);
e35e9c
-- 
e35e9c
2.39.2
e35e9c