[PATCH 14/17] crypto: fips140: add module integrity self-check
Jay Wang
wanjay at amazon.com
Wed Feb 11 18:42:18 PST 2026
Add verify_integrity() function to perform HMAC-SHA256 self verification
of this standalone crypto module against pre-computed hash. This integrity
self-check is required by FIPS 140-3.
This patch is picked from Vegard Nossum <vegard.nossum at oracle.com> with
minor modifications.
Co-developed-by: Vegard Nossum <vegard.nossum at oracle.com>
Signed-off-by: Jay Wang <wanjay at amazon.com>
---
crypto/fips140/fips140-module.c | 52 +++++++++++++++++++++++++++++++++
crypto/fips140/fips140-module.h | 4 +++
2 files changed, 56 insertions(+)
diff --git a/crypto/fips140/fips140-module.c b/crypto/fips140/fips140-module.c
index e0e669ba1b5e..3bc8865567cb 100644
--- a/crypto/fips140/fips140-module.c
+++ b/crypto/fips140/fips140-module.c
@@ -16,6 +16,54 @@
#define CRYPTO_INTERNAL "CRYPTO_INTERNAL"
+static const u8 fips140_integ_hmac_key[] = CONFIG_CRYPTO_FIPS140_HMAC_KEY;
+
+static int verify_integrity(void)
+{
+ extern const u8 *_binary_crypto_ko_start;
+ extern const u8 *_binary_crypto_ko_end;
+ extern const u8 *_binary_crypto_hmac_start;
+
+ struct crypto_shash *tfm;
+ SHASH_DESC_ON_STACK(desc, tfm);
+ u8 digest[SHA256_DIGEST_SIZE];
+ int err;
+
+ tfm = crypto_alloc_shash("hmac(sha256)", 0, 0);
+ if (IS_ERR(tfm))
+ panic("FIPS 140: failed to allocate hmac tfm (%ld)\n", PTR_ERR(tfm));
+
+ desc->tfm = tfm;
+
+ err = crypto_shash_setkey(tfm, fips140_integ_hmac_key, sizeof(fips140_integ_hmac_key) - 1);
+ if (err)
+ panic("FIPS 140: crypto_shash_setkey() failed: %d\n", err);
+
+ err = crypto_shash_init(desc);
+ if (err)
+ panic("FIPS 140: crypto_shash_init() failed: %d\n", err);
+
+ err = crypto_shash_update(desc, _binary_crypto_ko_start, _binary_crypto_ko_end - _binary_crypto_ko_start);
+ if (err)
+ panic("FIPS 140: crypto_shash_update() failed: %d\n", err);
+
+ err = crypto_shash_final(desc, digest);
+ if (err)
+ panic("FIPS 140: crypto_shash_final() failed: %d\n", err);
+
+ shash_desc_zero(desc);
+
+ if (memcmp(digest, _binary_crypto_hmac_start, sizeof(digest)))
+ panic("FIPS 140: failed integrity check\n");
+
+ pr_info("FIPS 140: integrity verification passed\n");
+
+ crypto_free_shash(tfm);
+ memzero_explicit(digest, sizeof(digest));
+
+ return 0;
+}
+
static int __init run_initcalls(void)
{
typedef int (*initcall_t)(void);
@@ -68,6 +116,10 @@ static int __init fips140_init(void)
pr_info("loading " FIPS140_MODULE_NAME "\n");
run_initcalls();
+
+ if (fips_enabled){
+ verify_integrity(); /* Panics if integrity check fails */
+ }
fips140_mark_module_level_complete(2);
return 0;
}
diff --git a/crypto/fips140/fips140-module.h b/crypto/fips140/fips140-module.h
index e95dac8eeda9..b8968d54800e 100644
--- a/crypto/fips140/fips140-module.h
+++ b/crypto/fips140/fips140-module.h
@@ -9,9 +9,13 @@
#include <linux/module.h>
#include <linux/crypto.h>
#include <crypto/algapi.h>
+#include <crypto/hash.h>
+#include <crypto/sha2.h>
#include <linux/init.h>
+#include <linux/string.h>
#include <linux/atomic.h>
#include <linux/wait.h>
+#include <linux/fips.h>
/* FIPS140 synchronization between kernel and module */
extern atomic_t fips140_kernel_level_complete;
--
2.47.3
More information about the linux-arm-kernel
mailing list