File libgcrypt-FIPS-SLI-Implement-new-FIPS-service-indicator-for-gcry_md_hash_*.patch of Package libgcrypt.38414

From 3478caac62c712547f7c0e07f4cf9602bc317997 Mon Sep 17 00:00:00 2001
From: NIIBE Yutaka <gniibe@fsij.org>
Date: Fri, 6 Dec 2024 14:33:58 +0900
Subject: [PATCH 04/24] fips,md: Implement new FIPS service indicator for
 gcry_md_hash_*.

* cipher/md.c (md_enable): Add an NO_REJECT argument.
(md_open): Check flags against GCRY_MD_FLAG_FIPS_NO_REJECTION to
call md_enable.
(_gcry_md_enable): Follow the change.
(_gcry_md_hash_buffer): Don't reject but keep the computation.
Call fips_service_indicator_mark_success.
(_gcry_md_hash_buffers_extract): Likewise.
* src/gcrypt.h.in (GCRY_MD_FLAG_FIPS_NO_REJECTION): New.
* src/visibility.c (gcry_md_hash_buffer, gcry_md_hash_buffers): Call
fips_service_indicator_init.
(gcry_md_hash_buffers_ext): Likewise.

--

GnuPG-bug-id: 7338
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Signed-off-by: Lucas Mulling <lucas.mulling@suse.com>
---
 cipher/md.c      | 32 +++++++++++++++++++++++---------
 src/gcrypt.h.in  |  1 +
 src/visibility.c |  3 +++
 3 files changed, 27 insertions(+), 9 deletions(-)

Index: libgcrypt-1.10.3/cipher/md.c
===================================================================
--- libgcrypt-1.10.3.orig/cipher/md.c
+++ libgcrypt-1.10.3/cipher/md.c
@@ -276,7 +276,7 @@ struct gcry_md_context
 #define CTX_MAGIC_NORMAL 0x11071961
 #define CTX_MAGIC_SECURE 0x16917011
 
-static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo);
+static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo, int no_reject);
 static void md_close (gcry_md_hd_t a);
 static void md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen);
 static byte *md_read( gcry_md_hd_t a, int algo );
@@ -508,7 +508,8 @@ md_open (gcry_md_hd_t *h, int algo, unsi
 
       if (algo)
 	{
-	  err = md_enable (hd, algo);
+	  err = md_enable (hd, algo,
+                           !!(flags & GCRY_MD_FLAG_FIPS_NO_REJECTION));
 	  if (err)
 	    md_close (hd);
 	}
@@ -545,7 +546,7 @@ _gcry_md_open (gcry_md_hd_t *h, int algo
 
 
 static gcry_err_code_t
-md_enable (gcry_md_hd_t hd, int algorithm)
+md_enable (gcry_md_hd_t hd, int algorithm, int no_reject)
 {
   struct gcry_md_context *h = hd->ctx;
   const gcry_md_spec_t *spec;
@@ -567,7 +568,7 @@ md_enable (gcry_md_hd_t hd, int algorith
     err = GPG_ERR_DIGEST_ALGO;
 
   /* Any non-FIPS algorithm should go this way */
-  if (!err && !spec->flags.fips && fips_mode ())
+  if (!err && !no_reject && !spec->flags.fips && fips_mode ())
     err = GPG_ERR_DIGEST_ALGO;
 
   if (!err && h->flags.hmac && spec->read == NULL)
@@ -610,7 +611,7 @@ md_enable (gcry_md_hd_t hd, int algorith
 gcry_err_code_t
 _gcry_md_enable (gcry_md_hd_t hd, int algorithm)
 {
-  return md_enable (hd, algorithm);
+  return md_enable (hd, algorithm, 0);
 }
 
 
@@ -1200,7 +1201,7 @@ _gcry_md_hash_buffer (int algo, void *di
       iov.off = 0;
       iov.len = length;
 
-      if (spec->flags.disabled || (!spec->flags.fips && fips_mode ()))
+      if (spec->flags.disabled)
         log_bug ("gcry_md_hash_buffer failed for algo %d: %s",
                 algo, gpg_strerror (gcry_error (GPG_ERR_DIGEST_ALGO)));
 
@@ -1213,7 +1214,7 @@ _gcry_md_hash_buffer (int algo, void *di
       gcry_md_hd_t h;
       gpg_err_code_t err;
 
-      err = md_open (&h, algo, 0);
+      err = md_open (&h, algo, GCRY_MD_FLAG_FIPS_NO_REJECTION);
       if (err)
         log_bug ("gcry_md_open failed for algo %d: %s",
                 algo, gpg_strerror (gcry_error(err)));
@@ -1222,6 +1223,12 @@ _gcry_md_hash_buffer (int algo, void *di
       memcpy (digest, md_read (h, algo), md_digest_length (algo));
       md_close (h);
     }
+
+  if (fips_mode ())
+    {
+      int is_compliant = spec->flags.fips;
+      fips_service_indicator_mark_success (is_compliant);
+    }
 }
 
 
@@ -1273,7 +1280,7 @@ _gcry_md_hash_buffers_extract (int algo,
 
   if (!hmac && spec->hash_buffers)
     {
-      if (spec->flags.disabled || (!spec->flags.fips && fips_mode ()))
+      if (spec->flags.disabled)
         return GPG_ERR_DIGEST_ALGO;
 
       spec->hash_buffers (digest, digestlen, iov, iovcnt);
@@ -1285,7 +1292,8 @@ _gcry_md_hash_buffers_extract (int algo,
       gcry_md_hd_t h;
       gpg_err_code_t rc;
 
-      rc = md_open (&h, algo, (hmac? GCRY_MD_FLAG_HMAC:0));
+      rc = md_open (&h, algo, ((hmac? GCRY_MD_FLAG_HMAC:0)
+                               | GCRY_MD_FLAG_FIPS_NO_REJECTION));
       if (rc)
         return rc;
 
@@ -1311,6 +1319,12 @@ _gcry_md_hash_buffers_extract (int algo,
       md_close (h);
     }
 
+  if (fips_mode ())
+    {
+      int is_compliant = spec->flags.fips;
+      fips_service_indicator_mark_success (is_compliant);
+    }
+
   return 0;
 }
 
Index: libgcrypt-1.10.3/src/gcrypt.h.in
===================================================================
--- libgcrypt-1.10.3.orig/src/gcrypt.h.in
+++ libgcrypt-1.10.3/src/gcrypt.h.in
@@ -1296,6 +1296,7 @@ enum gcry_md_flags
   {
     GCRY_MD_FLAG_SECURE = 1,  /* Allocate all buffers in "secure" memory.  */
     GCRY_MD_FLAG_HMAC   = 2,  /* Make an HMAC out of this algorithm.  */
+    GCRY_MD_FLAG_FIPS_NO_REJECTION = 4,  /* Don't reject for FIPS.  */
     GCRY_MD_FLAG_BUGEMU1 = 0x0100
   };
 
Index: libgcrypt-1.10.3/src/visibility.c
===================================================================
--- libgcrypt-1.10.3.orig/src/visibility.c
+++ libgcrypt-1.10.3/src/visibility.c
@@ -1263,6 +1263,7 @@ gcry_md_hash_buffer (int algo, void *dig
       (void)fips_not_operational ();
       fips_signal_error ("called in non-operational state");
     }
+  fips_service_indicator_init ();
   _gcry_md_hash_buffer (algo, digest, buffer, length);
 }
 
@@ -1275,6 +1276,7 @@ gcry_md_hash_buffers (int algo, unsigned
       (void)fips_not_operational ();
       fips_signal_error ("called in non-operational state");
     }
+  fips_service_indicator_init ();
   return gpg_error (_gcry_md_hash_buffers (algo, flags, digest, iov, iovcnt));
 }
 
openSUSE Build Service is sponsored by