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));
}