public inbox for linux-modules@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 087/104] crypto: fips140: convert crypto/asymmetric_keys/x509_loader.c to using crypto API wrappers
From: Vegard Nossum @ 2025-09-04 15:51 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Use CRYPTO_API() etc. from include/crypto/api.h in preparation for
compilation as part of support for FIPS 140 standalone modules.

Generated using:

  ./fipsify.py --config CONFIG_X509_CERTIFICATE_PARSER --source crypto/asymmetric_keys/x509_loader.c --header include/keys/asymmetric-type.h

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 crypto/asymmetric_keys/x509_loader.c |  4 ++--
 crypto/fips140-api.c                 | 11 +++++++++++
 include/keys/asymmetric-type.h       |  5 +++--
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/crypto/asymmetric_keys/x509_loader.c b/crypto/asymmetric_keys/x509_loader.c
index a41741326998..a480763b1649 100644
--- a/crypto/asymmetric_keys/x509_loader.c
+++ b/crypto/asymmetric_keys/x509_loader.c
@@ -4,7 +4,7 @@
 #include <linux/key.h>
 #include <keys/asymmetric-type.h>
 
-int x509_load_certificate_list(const u8 cert_list[],
+int CRYPTO_API(x509_load_certificate_list)(const u8 cert_list[],
 			       const unsigned long list_size,
 			       const struct key *keyring)
 {
@@ -55,4 +55,4 @@ int x509_load_certificate_list(const u8 cert_list[],
 	pr_err("Problem parsing in-kernel X.509 certificate list\n");
 	return 0;
 }
-EXPORT_SYMBOL_GPL(x509_load_certificate_list);
+DEFINE_CRYPTO_API(x509_load_certificate_list);
diff --git a/crypto/fips140-api.c b/crypto/fips140-api.c
index db5b142e21df..91812ed74f8a 100644
--- a/crypto/fips140-api.c
+++ b/crypto/fips140-api.c
@@ -713,3 +713,14 @@ DEFINE_CRYPTO_API_STUB(x509_decode_time);
 
 #endif
 
+/*
+ * crypto/asymmetric_keys/x509_loader.c
+ */
+#if !IS_BUILTIN(CONFIG_X509_CERTIFICATE_PARSER)
+
+#include <keys/asymmetric-type.h>
+
+DEFINE_CRYPTO_API_STUB(x509_load_certificate_list);
+
+#endif
+
diff --git a/include/keys/asymmetric-type.h b/include/keys/asymmetric-type.h
index fb7f82527978..ee1bf9b28bfd 100644
--- a/include/keys/asymmetric-type.h
+++ b/include/keys/asymmetric-type.h
@@ -84,8 +84,9 @@ DECLARE_CRYPTO_API(find_asymmetric_key, struct key *,
 	(struct key *keyring, const struct asymmetric_key_id *id_0, const struct asymmetric_key_id *id_1, const struct asymmetric_key_id *id_2, bool partial),
 	(keyring, id_0, id_1, id_2, partial));
 
-int x509_load_certificate_list(const u8 cert_list[], const unsigned long list_size,
-			       const struct key *keyring);
+DECLARE_CRYPTO_API(x509_load_certificate_list, int,
+	(const u8 cert_list[], const unsigned long list_size, const struct key *keyring),
+	(cert_list, list_size, keyring));
 
 /*
  * The payload is at the discretion of the subtype.
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 088/104] crypto: fips140: convert crypto/asymmetric_keys/x509_public_key.c to using crypto API wrappers
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Use CRYPTO_API() etc. from include/crypto/api.h in preparation for
compilation as part of support for FIPS 140 standalone modules.

Generated using:

  ./fipsify.py --config CONFIG_X509_CERTIFICATE_PARSER --source crypto/asymmetric_keys/x509_public_key.c

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 crypto/asymmetric_keys/x509_public_key.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 8409d7d36cb4..2f76b7b855de 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -246,8 +246,8 @@ static void __exit x509_key_exit(void)
 	unregister_asymmetric_key_parser(&x509_key_parser);
 }
 
-module_init(x509_key_init);
-module_exit(x509_key_exit);
+crypto_module_init(x509_key_init);
+crypto_module_exit(x509_key_exit);
 
 MODULE_DESCRIPTION("X.509 certificate parser");
 MODULE_AUTHOR("Red Hat, Inc.");
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 090/104] crypto: fips140: manual fixups for include/crypto/sha2.h
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Define fips_/nonfips_ variants of sha*_zero_message_hash when the
kernel is configured to use a standalone FIPS module.

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 include/crypto/sha2.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/crypto/sha2.h b/include/crypto/sha2.h
index ce908568009a..5af928f61d9e 100644
--- a/include/crypto/sha2.h
+++ b/include/crypto/sha2.h
@@ -59,6 +59,20 @@
 #define SHA512_H6	0x1f83d9abfb41bd6bULL
 #define SHA512_H7	0x5be0cd19137e2179ULL
 
+#ifdef CONFIG_CRYPTO_FIPS140_EXTMOD
+#ifdef FIPS_MODULE
+#define sha224_zero_message_hash fips_sha224_zero_message_hash
+#define sha256_zero_message_hash fips_sha256_zero_message_hash
+#define sha384_zero_message_hash fips_sha384_zero_message_hash
+#define sha512_zero_message_hash fips_sha512_zero_message_hash
+#else
+#define sha224_zero_message_hash nonfips_sha224_zero_message_hash
+#define sha256_zero_message_hash nonfips_sha256_zero_message_hash
+#define sha384_zero_message_hash nonfips_sha384_zero_message_hash
+#define sha512_zero_message_hash nonfips_sha512_zero_message_hash
+#endif
+#endif
+
 extern const u8 sha224_zero_message_hash[SHA224_DIGEST_SIZE];
 
 extern const u8 sha256_zero_message_hash[SHA256_DIGEST_SIZE];
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 089/104] crypto: fips140: manual fixups for include/keys/asymmetric-type.h
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Define fips_/nonfips_ variants of key_type_asymmetric when the kernel is
configured to use a standalone FIPS module.

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 include/keys/asymmetric-type.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/include/keys/asymmetric-type.h b/include/keys/asymmetric-type.h
index ee1bf9b28bfd..12c6f113b612 100644
--- a/include/keys/asymmetric-type.h
+++ b/include/keys/asymmetric-type.h
@@ -14,6 +14,14 @@
 #include <linux/key-type.h>
 #include <linux/verification.h>
 
+#ifdef CONFIG_CRYPTO_FIPS140_EXTMOD
+#ifdef FIPS_MODULE
+#define key_type_asymmetric fips_key_type_asymmetric
+#else
+#define key_type_asymmetric nonfips_key_type_asymmetric
+#endif
+#endif
+
 extern struct key_type key_type_asymmetric;
 
 /*
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 091/104] crypto: fips140: manual fixups for include/crypto/public_key.h
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Define fips_/nonfips_ variants of public_key_subtype when the kernel is
configured to use a standalone FIPS module.

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 include/crypto/public_key.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index c8f30adbd655..b995644b0c92 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -58,6 +58,14 @@ DECLARE_CRYPTO_API(public_key_signature_free, void,
 	(struct public_key_signature *sig),
 	(sig));
 
+#ifdef CONFIG_CRYPTO_FIPS140_EXTMOD
+#ifdef FIPS_MODULE
+#define public_key_subtype fips_public_key_subtype
+#else
+#define public_key_subtype nonfips_public_key_subtype
+#endif
+#endif
+
 extern struct asymmetric_key_subtype public_key_subtype;
 
 struct key;
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 092/104] crypto: fips140: manual fixups for include/crypto/aes.h
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Define fips_/nonfips_ variants of crypto_*_tab when the kernel is
configured to use a standalone FIPS module.

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 include/crypto/aes.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/crypto/aes.h b/include/crypto/aes.h
index 6a732ea5ee1b..77f5515c49c9 100644
--- a/include/crypto/aes.h
+++ b/include/crypto/aes.h
@@ -29,6 +29,16 @@ struct crypto_aes_ctx {
 	u32 key_length;
 };
 
+#ifdef CONFIG_CRYPTO_FIPS140_EXTMOD
+#ifdef FIPS_MODULE
+#define crypto_ft_tab fips_crypto_ft_tab
+#define crypto_it_tab fips_crypto_it_tab
+#else
+#define crypto_ft_tab nonfips_crypto_ft_tab
+#define crypto_it_tab nonfips_crypto_it_tab
+#endif
+#endif
+
 extern const u32 crypto_ft_tab[4][256] ____cacheline_aligned;
 extern const u32 crypto_it_tab[4][256] ____cacheline_aligned;
 
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 094/104] crypto: fips140: manual fixups for include/crypto/internal/ecc.h
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Define fips_/nonfips_ variants of ecdsa_*_tmpl when the kernel is
configured to use a standalone FIPS module.

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 include/crypto/internal/ecc.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h
index 906d1443de96..b8ce202530de 100644
--- a/include/crypto/internal/ecc.h
+++ b/include/crypto/internal/ecc.h
@@ -30,6 +30,16 @@
 #include <crypto/ecc_curve.h>
 #include <linux/unaligned.h>
 
+#ifdef CONFIG_CRYPTO_FIPS140_EXTMOD
+#ifdef FIPS_MODULE
+#define ecdsa_x962_tmpl fips_ecdsa_x962_tmpl
+#define ecdsa_p1363_tmpl fips_ecdsa_p1363_tmpl
+#else
+#define ecdsa_x962_tmpl nonfips_ecdsa_x962_tmpl
+#define ecdsa_p1363_tmpl nonfips_ecdsa_p1363_tmpl
+#endif
+#endif
+
 /* One digit is u64 qword. */
 #define ECC_CURVE_NIST_P192_DIGITS  3
 #define ECC_CURVE_NIST_P256_DIGITS  4
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 093/104] crypto: fips140: manual fixups for crypto/internal.h
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Define fips_/nonfips_ variants of cryoto_{alg_list,alg_sem,chain} when
the kernel is configured to use a standalone FIPS module.

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 crypto/internal.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/crypto/internal.h b/crypto/internal.h
index f4b12863d922..08f2f04b010d 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -62,6 +62,18 @@ enum {
 /* Maximum number of (rtattr) parameters for each template. */
 #define CRYPTO_MAX_ATTRS 32
 
+#ifdef CONFIG_CRYPTO_FIPS140_EXTMOD
+#ifdef FIPS_MODULE
+#define crypto_alg_list fips_crypto_alg_list
+#define crypto_alg_sem fips_crypto_alg_sem
+#define crypto_chain fips_crypto_chain
+#else
+#define crypto_alg_list nonfips_crypto_alg_list
+#define crypto_alg_sem nonfips_crypto_alg_sem
+#define crypto_chain nonfips_crypto_chain
+#endif
+#endif
+
 extern struct list_head crypto_alg_list;
 extern struct rw_semaphore crypto_alg_sem;
 extern struct blocking_notifier_head crypto_chain;
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 095/104] crypto: fips140: manual fixups for include/crypto/internal/rsa.h
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Define fips_/nonfips_ variants of rsa_pkcs1pad_tmpl and
rsassa_pkcs1_tmpl when the kernel is configured to use a standalone
FIPS module.

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 include/crypto/internal/rsa.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h
index 1265aa81f6fe..9028a184d06e 100644
--- a/include/crypto/internal/rsa.h
+++ b/include/crypto/internal/rsa.h
@@ -12,6 +12,16 @@
 #include <linux/types.h>
 #include <crypto/akcipher.h>
 
+#ifdef CONFIG_CRYPTO_FIPS140_EXTMOD
+#ifdef FIPS_MODULE
+#define rsa_pkcs1pad_tmpl fips_rsa_pkcs1pad_tmpl
+#define rsassa_pkcs1_tmpl fips_rsassa_pkcs1_tmpl
+#else
+#define rsa_pkcs1pad_tmpl nonfips_rsa_pkcs1pad_tmpl
+#define rsassa_pkcs1_tmpl nonfips_rsassa_pkcs1_tmpl
+#endif
+#endif
+
 /**
  * rsa_key - RSA key structure
  * @n           : RSA modulus raw byte stream
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 096/104] crypto: fips140: manual fixups for include/crypto/aes.h
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Define fips_/nonfips_ variants of crypto_aes_*sbox when the kernel is
configured to use a standalone FIPS module.

Vegard Nossum <vegard.nossum@oracle.com>
---
 include/crypto/aes.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/crypto/aes.h b/include/crypto/aes.h
index 77f5515c49c9..fc84ffcd00a7 100644
--- a/include/crypto/aes.h
+++ b/include/crypto/aes.h
@@ -101,6 +101,16 @@ DECLARE_CRYPTO_API(aes_decrypt, void,
 	(const struct crypto_aes_ctx *ctx, u8 *out, const u8 *in),
 	(ctx, out, in));
 
+#ifdef CONFIG_CRYPTO_FIPS140_EXTMOD
+#ifdef FIPS_MODULE
+#define crypto_aes_sbox fips_crypto_aes_sbox
+#define crypto_aes_inv_sbox fips_crypto_aes_inv_sbox
+#else
+#define crypto_aes_sbox nonfips_crypto_aes_sbox
+#define crypto_aes_inv_sbox nonfips_crypto_aes_inv_sbox
+#endif
+#endif
+
 extern const u8 crypto_aes_sbox[];
 extern const u8 crypto_aes_inv_sbox[];
 
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 097/104] crypto: fips140: manual fixups for lib/crypto/sha256.c
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Don't build arch-specific SHA256 code yet when building the FIPS 140
standalone module.

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 lib/crypto/sha256.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/crypto/sha256.c b/lib/crypto/sha256.c
index 36a9f2bf77e2..bc20cdb9eb94 100644
--- a/lib/crypto/sha256.c
+++ b/lib/crypto/sha256.c
@@ -148,7 +148,7 @@ sha256_blocks_generic(struct sha256_block_state *state,
 	memzero_explicit(W, sizeof(W));
 }
 
-#if defined(CONFIG_CRYPTO_LIB_SHA256_ARCH) && !defined(__DISABLE_EXPORTS)
+#if defined(CONFIG_CRYPTO_LIB_SHA256_ARCH) && !defined(__DISABLE_EXPORTS) && !defined(FIPS_MODULE)
 #include "sha256.h" /* $(SRCARCH)/sha256.h */
 #else
 #define sha256_blocks sha256_blocks_generic
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 098/104] crypto: fips140: manual fixups for lib/crypto/sha512.c
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Don't build arch-specific SHA512 code yet when building the FIPS 140
standalone module.

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 lib/crypto/sha512.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/crypto/sha512.c b/lib/crypto/sha512.c
index 9a170bf1a48c..a6a3e102c6a8 100644
--- a/lib/crypto/sha512.c
+++ b/lib/crypto/sha512.c
@@ -132,7 +132,7 @@ sha512_blocks_generic(struct sha512_block_state *state,
 	} while (--nblocks);
 }
 
-#ifdef CONFIG_CRYPTO_LIB_SHA512_ARCH
+#if defined(CONFIG_CRYPTO_LIB_SHA512_ARCH) && !defined(FIPS_MODULE)
 #include "sha512.h" /* $(SRCARCH)/sha512.h */
 #else
 #define sha512_blocks sha512_blocks_generic
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 101/104] crypto: fips140: add FIPS 140 module loader
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum,
	Saeed Mirzamohammadi
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Add a mechanism for loading a FIPS module from a byte array compiled
into vmlinux.

fips140-module.o and fips140-digest.o are files generated during the build
of the FIPS cryptographic module; fips140-module.o provides the following
symbols:

 - _binary_fips140_ko_start
 - _binary_fips140_ko_end

while fips140-digest.o provides the following symbol:

 - _binary_fips140_hmac_start

fips140-loader.c then uses the _binary_fips140_ko_start/_end byte array
with load_module_mem() in arch_initcall_sync call to load the
precompiled FIPS 140 module.

This code is partly based on the existing crypto/fips.c code and partly on
the Android FIPS 140 module [1].

[1]: https://android.googlesource.com/kernel/common/+/1ca1130ec62d/crypto/fips140-module.c

Only arm64 and x86-64 are explicitly supported for now.

Co-developed-by: Saeed Mirzamohammadi <saeed.mirzamohammadi@oracle.com>
Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 arch/arm64/kernel/vmlinux.lds.S   |  1 +
 crypto/Makefile                   | 24 ++++++++
 crypto/fips140-loader.c           | 96 +++++++++++++++++++++++++++++++
 include/asm-generic/vmlinux.lds.h | 37 +++++++++++-
 include/linux/fips.h              | 17 ++++++
 5 files changed, 174 insertions(+), 1 deletion(-)
 create mode 100644 crypto/fips140-loader.c

diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index ad6133b89e7a..58a99b2de237 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -271,6 +271,7 @@ SECTIONS
 		INIT_RAM_FS
 		*(.init.altinstructions .init.bss)	/* from the EFI stub */
 	}
+	FIPS140
 	.exit.data : {
 		EXIT_DATA
 	}
diff --git a/crypto/Makefile b/crypto/Makefile
index 6c5d59369dac..e07e93b189fe 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -7,7 +7,9 @@ obj-$(CONFIG_CRYPTO) += crypto.o
 crypto-y := api.o cipher.o
 
 obj-$(CONFIG_CRYPTO_ENGINE) += crypto_engine.o
+ifneq ($(CONFIG_CRYPTO_FIPS140_EXTMOD),y)
 obj-$(CONFIG_CRYPTO_FIPS) += fips.o
+endif
 
 crypto_algapi-$(CONFIG_PROC_FS) += proc.o
 crypto_algapi-y := algapi.o scatterwalk.o $(crypto_algapi-y)
@@ -211,3 +213,25 @@ obj-$(CONFIG_CRYPTO_SIMD) += crypto_simd.o
 obj-$(CONFIG_CRYPTO_KDF800108_CTR) += kdf_sp800108.o
 
 obj-$(CONFIG_CRYPTO_KRB5) += krb5/
+
+#
+# Loader for standalone FIPS 140 module
+#
+
+obj-$(CONFIG_CRYPTO_FIPS140_EXTMOD) += fips140-loader.o
+
+#
+# Standalone FIPS 140 module
+#
+
+quiet_cmd_ld_bin = LD      $@
+      cmd_ld_bin = (cd "$(dir $<)" && \
+                    $(LD) -r -b binary -o $(abspath $@) $(notdir $<) && \
+                    $(OBJCOPY) --rename-section .data=$(2) $(abspath $@))
+
+$(obj)/fips140-module.o: $(src)/fips140.ko FORCE
+	$(call if_changed,ld_bin,__fips140_module)
+$(obj)/fips140-digest.o: $(src)/fips140.hmac FORCE
+	$(call if_changed,ld_bin,__fips140_digest)
+
+obj-$(CONFIG_CRYPTO_FIPS140_EXTMOD) += fips140-module.o fips140-digest.o fips140-api.o
diff --git a/crypto/fips140-loader.c b/crypto/fips140-loader.c
new file mode 100644
index 000000000000..865d45d46786
--- /dev/null
+++ b/crypto/fips140-loader.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * FIPS 140-3 module loader.
+ *
+ * Copyright (c) 2008 Neil Horman <nhorman@tuxdriver.com>
+ * Copyright 2021 Google LLC
+ * Copyright (c) 2025, Oracle and/or its affiliates.
+ */
+
+#include <linux/fips.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/panic.h>
+#include <linux/printk.h>
+#include <linux/string.h>
+
+#include <crypto/api.h>
+#include <crypto/hash.h>
+
+int fips_enabled;
+EXPORT_SYMBOL_GPL(fips_enabled);
+
+ATOMIC_NOTIFIER_HEAD(fips_fail_notif_chain);
+EXPORT_SYMBOL_GPL(fips_fail_notif_chain);
+
+void fips_fail_notify(void)
+{
+	if (fips_enabled)
+		atomic_notifier_call_chain(&fips_fail_notif_chain, 0, NULL);
+}
+EXPORT_SYMBOL_GPL(fips_fail_notify);
+
+/* defined in crypto/fips140-{module,digest}.o -OR- vmlinux.lds */
+EXPORT_SYMBOL_GPL(_binary_fips140_ko_start);
+EXPORT_SYMBOL_GPL(_binary_fips140_ko_end);
+EXPORT_SYMBOL_GPL(_binary_fips140_hmac_start);
+
+/* Process kernel command-line parameter at boot time. fips=0 or fips=1 */
+static int fips_enable(char *str)
+{
+	fips_enabled = !!simple_strtol(str, NULL, 0);
+	if (!fips_enabled)
+		pr_info("FIPS 140-3 module: disabled\n");
+
+	return 1;
+}
+
+__setup("fips=", fips_enable);
+
+static struct ctl_table crypto_sysctl_table[] = {
+	{
+		.procname	= "fips_enabled",
+		.data		= &fips_enabled,
+		.maxlen		= sizeof(int),
+		.mode		= 0444,
+		.proc_handler	= proc_dointvec,
+	},
+};
+
+static int __init fips_loader_init(void)
+{
+	void *ko_mem;
+	int err;
+	struct ctl_table_header *crypto_sysctls;
+
+	if (!fips_enabled) {
+		/* Add crypto sysctl for nonfips mode */
+		crypto_sysctls = register_sysctl("crypto", crypto_sysctl_table);
+		if (!crypto_sysctls)
+			pr_err("fips 140: failed to register sysctl for nonfips mode");
+
+		return 0;
+	}
+
+	/*
+	 * Duplicate the memory as the kernel module loader will
+	 * modify it and mess up the integrity check.
+	 */
+	ko_mem = kvmemdup(_binary_fips140_ko_start, _binary_fips140_ko_size, GFP_KERNEL);
+	if (!ko_mem) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	err = load_module_mem(ko_mem, _binary_fips140_ko_size);
+	if (err)
+		goto out;
+
+	kvfree(ko_mem);
+
+out:
+	if (err)
+		panic("FIPS 140-3 module: loading error\n");
+	return err;
+}
+arch_initcall_sync(fips_loader_init);
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 1881d9b6b3ae..b4aee570223c 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -454,6 +454,40 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
 #endif
 #endif
 
+#ifdef CONFIG_CRYPTO_FIPS140_EXTMOD
+/*
+ * We have an external module; include it and its digest in their own
+ * named sections so they are easy to extract from the vmlinux ELF file
+ * after the kernel has been built.
+ */
+#define FIPS140 \
+	. = ALIGN(PAGE_SIZE); \
+	__fips140_module : AT(ADDR(__fips140_module) - LOAD_OFFSET) {	\
+		*(__fips140_module)					\
+	}								\
+	. = ALIGN(PAGE_SIZE);						\
+	__fips140_digest : AT(ADDR(__fips140_digest) - LOAD_OFFSET) {	\
+		*(__fips140_digest)					\
+	}
+#else
+#ifdef CONFIG_CRYPTO_FIPS140_EXTMOD
+/*
+ * We don't have an external module (yet) but the kernel has been built
+ * with the loader, so this just defines an empty byte array where the
+ * module will go eventually.
+ */
+#define FIPS140 \
+	_binary_fips140_ko_start = .; \
+	_binary_fips140_ko_end = .; \
+	_binary_fips140_hmac_start = .; \
+	_binary_fips140_hmac_end = .;
+#else
+#define FIPS140
+#endif
+#endif
+
+
+
 /*
  * Read only Data
  */
@@ -1145,7 +1179,8 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
 		INIT_CALLS						\
 		CON_INITCALL						\
 		INIT_RAM_FS						\
-	}
+	}								\
+	FIPS140
 
 #define BSS_SECTION(sbss_align, bss_align, stop_align)			\
 	. = ALIGN(sbss_align);						\
diff --git a/include/linux/fips.h b/include/linux/fips.h
index c6961e932fef..81560dfc6cef 100644
--- a/include/linux/fips.h
+++ b/include/linux/fips.h
@@ -2,12 +2,29 @@
 #ifndef _FIPS_H
 #define _FIPS_H
 
+#include <linux/init.h>
+
+#include <crypto/sha2.h> /* SHA256_DIGEST_SIZE */
+
 #ifdef CONFIG_CRYPTO_FIPS
+/*
+ * fips_enabled = FIPS mode was requested on the command line
+ * fips_operational = FIPS module has run self-tests etc. and is operational
+ */
 extern int fips_enabled;
+extern int fips_operational;
+
 extern struct atomic_notifier_head fips_fail_notif_chain;
 
 void fips_fail_notify(void);
 
+/* FIPS-certified module blob and digest */
+extern const u8 __initconst _binary_fips140_ko_start[];
+extern const u8 __initconst _binary_fips140_ko_end[];
+extern const u8 __initconst _binary_fips140_hmac_start[SHA256_DIGEST_SIZE];
+
+#define _binary_fips140_ko_size (_binary_fips140_ko_end - _binary_fips140_ko_start)
+
 #else
 #define fips_enabled 0
 
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 099/104] crypto: fips140: add symlinks to kernel sources
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

In order to minimize source code duplication, we symlink all files under
fips140/ to their top-level source tree equivalents, e.g.:

  fips140/crypto/api.c -> crypto/api.c

We're going to build these files as an out-of-tree module (with
-DFIPS_MODULE=1).

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 fips140/crypto/aead.c                             | 1 +
 fips140/crypto/aes_generic.c                      | 1 +
 fips140/crypto/ahash.c                            | 1 +
 fips140/crypto/akcipher.c                         | 1 +
 fips140/crypto/algapi.c                           | 1 +
 fips140/crypto/algboss.c                          | 1 +
 fips140/crypto/api.c                              | 1 +
 fips140/crypto/asymmetric_keys/asymmetric_keys.h  | 1 +
 fips140/crypto/asymmetric_keys/asymmetric_type.c  | 1 +
 fips140/crypto/asymmetric_keys/mscode_parser.c    | 1 +
 fips140/crypto/asymmetric_keys/pkcs7.asn1         | 1 +
 fips140/crypto/asymmetric_keys/pkcs7_key_type.c   | 1 +
 fips140/crypto/asymmetric_keys/pkcs7_parser.c     | 1 +
 fips140/crypto/asymmetric_keys/pkcs7_parser.h     | 1 +
 fips140/crypto/asymmetric_keys/pkcs7_trust.c      | 1 +
 fips140/crypto/asymmetric_keys/pkcs7_verify.c     | 1 +
 fips140/crypto/asymmetric_keys/pkcs8.asn1         | 1 +
 fips140/crypto/asymmetric_keys/pkcs8_parser.c     | 1 +
 fips140/crypto/asymmetric_keys/public_key.c       | 1 +
 fips140/crypto/asymmetric_keys/restrict.c         | 1 +
 fips140/crypto/asymmetric_keys/selftest.c         | 1 +
 fips140/crypto/asymmetric_keys/selftest.h         | 1 +
 fips140/crypto/asymmetric_keys/selftest_ecdsa.c   | 1 +
 fips140/crypto/asymmetric_keys/selftest_rsa.c     | 1 +
 fips140/crypto/asymmetric_keys/signature.c        | 1 +
 fips140/crypto/asymmetric_keys/verify_pefile.c    | 1 +
 fips140/crypto/asymmetric_keys/verify_pefile.h    | 1 +
 fips140/crypto/asymmetric_keys/x509.asn1          | 1 +
 fips140/crypto/asymmetric_keys/x509_akid.asn1     | 1 +
 fips140/crypto/asymmetric_keys/x509_cert_parser.c | 1 +
 fips140/crypto/asymmetric_keys/x509_loader.c      | 1 +
 fips140/crypto/asymmetric_keys/x509_parser.h      | 1 +
 fips140/crypto/asymmetric_keys/x509_public_key.c  | 1 +
 fips140/crypto/authenc.c                          | 1 +
 fips140/crypto/authencesn.c                       | 1 +
 fips140/crypto/cbc.c                              | 1 +
 fips140/crypto/ccm.c                              | 1 +
 fips140/crypto/cipher.c                           | 1 +
 fips140/crypto/cmac.c                             | 1 +
 fips140/crypto/cryptd.c                           | 1 +
 fips140/crypto/ctr.c                              | 1 +
 fips140/crypto/dh.c                               | 1 +
 fips140/crypto/dh_helper.c                        | 1 +
 fips140/crypto/drbg.c                             | 1 +
 fips140/crypto/ecb.c                              | 1 +
 fips140/crypto/ecc.c                              | 1 +
 fips140/crypto/ecc_curve_defs.h                   | 1 +
 fips140/crypto/ecdh.c                             | 1 +
 fips140/crypto/ecdh_helper.c                      | 1 +
 fips140/crypto/ecdsa-p1363.c                      | 1 +
 fips140/crypto/ecdsa-x962.c                       | 1 +
 fips140/crypto/ecdsa.c                            | 1 +
 fips140/crypto/ecdsasignature.asn1                | 1 +
 fips140/crypto/echainiv.c                         | 1 +
 fips140/crypto/essiv.c                            | 1 +
 fips140/crypto/gcm.c                              | 1 +
 fips140/crypto/geniv.c                            | 1 +
 fips140/crypto/ghash-generic.c                    | 1 +
 fips140/crypto/hash.h                             | 1 +
 fips140/crypto/hmac.c                             | 1 +
 fips140/crypto/internal.h                         | 1 +
 fips140/crypto/jitterentropy-kcapi.c              | 1 +
 fips140/crypto/jitterentropy.c                    | 1 +
 fips140/crypto/jitterentropy.h                    | 1 +
 fips140/crypto/kpp.c                              | 1 +
 fips140/crypto/lskcipher.c                        | 1 +
 fips140/crypto/pcrypt.c                           | 1 +
 fips140/crypto/proc.c                             | 1 +
 fips140/crypto/rng.c                              | 1 +
 fips140/crypto/rsa-pkcs1pad.c                     | 1 +
 fips140/crypto/rsa.c                              | 1 +
 fips140/crypto/rsa_helper.c                       | 1 +
 fips140/crypto/rsaprivkey.asn1                    | 1 +
 fips140/crypto/rsapubkey.asn1                     | 1 +
 fips140/crypto/rsassa-pkcs1.c                     | 1 +
 fips140/crypto/seqiv.c                            | 1 +
 fips140/crypto/sha256.c                           | 1 +
 fips140/crypto/sha3_generic.c                     | 1 +
 fips140/crypto/sha512.c                           | 1 +
 fips140/crypto/shash.c                            | 1 +
 fips140/crypto/sig.c                              | 1 +
 fips140/crypto/simd.c                             | 1 +
 fips140/crypto/skcipher.c                         | 1 +
 fips140/crypto/skcipher.h                         | 1 +
 fips140/crypto/tcrypt.c                           | 1 +
 fips140/crypto/tcrypt.h                           | 1 +
 fips140/crypto/testmgr.c                          | 1 +
 fips140/crypto/testmgr.h                          | 1 +
 fips140/crypto/xts.c                              | 1 +
 fips140/lib/crypto/aes.c                          | 1 +
 fips140/lib/crypto/aesgcm.c                       | 1 +
 fips140/lib/crypto/gf128mul.c                     | 1 +
 fips140/lib/crypto/memneq.c                       | 1 +
 fips140/lib/crypto/sha256.c                       | 1 +
 fips140/lib/crypto/sha512.c                       | 1 +
 fips140/lib/crypto/utils.c                        | 1 +
 96 files changed, 96 insertions(+)
 create mode 120000 fips140/crypto/aead.c
 create mode 120000 fips140/crypto/aes_generic.c
 create mode 120000 fips140/crypto/ahash.c
 create mode 120000 fips140/crypto/akcipher.c
 create mode 120000 fips140/crypto/algapi.c
 create mode 120000 fips140/crypto/algboss.c
 create mode 120000 fips140/crypto/api.c
 create mode 120000 fips140/crypto/asymmetric_keys/asymmetric_keys.h
 create mode 120000 fips140/crypto/asymmetric_keys/asymmetric_type.c
 create mode 120000 fips140/crypto/asymmetric_keys/mscode_parser.c
 create mode 120000 fips140/crypto/asymmetric_keys/pkcs7.asn1
 create mode 120000 fips140/crypto/asymmetric_keys/pkcs7_key_type.c
 create mode 120000 fips140/crypto/asymmetric_keys/pkcs7_parser.c
 create mode 120000 fips140/crypto/asymmetric_keys/pkcs7_parser.h
 create mode 120000 fips140/crypto/asymmetric_keys/pkcs7_trust.c
 create mode 120000 fips140/crypto/asymmetric_keys/pkcs7_verify.c
 create mode 120000 fips140/crypto/asymmetric_keys/pkcs8.asn1
 create mode 120000 fips140/crypto/asymmetric_keys/pkcs8_parser.c
 create mode 120000 fips140/crypto/asymmetric_keys/public_key.c
 create mode 120000 fips140/crypto/asymmetric_keys/restrict.c
 create mode 120000 fips140/crypto/asymmetric_keys/selftest.c
 create mode 120000 fips140/crypto/asymmetric_keys/selftest.h
 create mode 120000 fips140/crypto/asymmetric_keys/selftest_ecdsa.c
 create mode 120000 fips140/crypto/asymmetric_keys/selftest_rsa.c
 create mode 120000 fips140/crypto/asymmetric_keys/signature.c
 create mode 120000 fips140/crypto/asymmetric_keys/verify_pefile.c
 create mode 120000 fips140/crypto/asymmetric_keys/verify_pefile.h
 create mode 120000 fips140/crypto/asymmetric_keys/x509.asn1
 create mode 120000 fips140/crypto/asymmetric_keys/x509_akid.asn1
 create mode 120000 fips140/crypto/asymmetric_keys/x509_cert_parser.c
 create mode 120000 fips140/crypto/asymmetric_keys/x509_loader.c
 create mode 120000 fips140/crypto/asymmetric_keys/x509_parser.h
 create mode 120000 fips140/crypto/asymmetric_keys/x509_public_key.c
 create mode 120000 fips140/crypto/authenc.c
 create mode 120000 fips140/crypto/authencesn.c
 create mode 120000 fips140/crypto/cbc.c
 create mode 120000 fips140/crypto/ccm.c
 create mode 120000 fips140/crypto/cipher.c
 create mode 120000 fips140/crypto/cmac.c
 create mode 120000 fips140/crypto/cryptd.c
 create mode 120000 fips140/crypto/ctr.c
 create mode 120000 fips140/crypto/dh.c
 create mode 120000 fips140/crypto/dh_helper.c
 create mode 120000 fips140/crypto/drbg.c
 create mode 120000 fips140/crypto/ecb.c
 create mode 120000 fips140/crypto/ecc.c
 create mode 120000 fips140/crypto/ecc_curve_defs.h
 create mode 120000 fips140/crypto/ecdh.c
 create mode 120000 fips140/crypto/ecdh_helper.c
 create mode 120000 fips140/crypto/ecdsa-p1363.c
 create mode 120000 fips140/crypto/ecdsa-x962.c
 create mode 120000 fips140/crypto/ecdsa.c
 create mode 120000 fips140/crypto/ecdsasignature.asn1
 create mode 120000 fips140/crypto/echainiv.c
 create mode 120000 fips140/crypto/essiv.c
 create mode 120000 fips140/crypto/gcm.c
 create mode 120000 fips140/crypto/geniv.c
 create mode 120000 fips140/crypto/ghash-generic.c
 create mode 120000 fips140/crypto/hash.h
 create mode 120000 fips140/crypto/hmac.c
 create mode 120000 fips140/crypto/internal.h
 create mode 120000 fips140/crypto/jitterentropy-kcapi.c
 create mode 120000 fips140/crypto/jitterentropy.c
 create mode 120000 fips140/crypto/jitterentropy.h
 create mode 120000 fips140/crypto/kpp.c
 create mode 120000 fips140/crypto/lskcipher.c
 create mode 120000 fips140/crypto/pcrypt.c
 create mode 120000 fips140/crypto/proc.c
 create mode 120000 fips140/crypto/rng.c
 create mode 120000 fips140/crypto/rsa-pkcs1pad.c
 create mode 120000 fips140/crypto/rsa.c
 create mode 120000 fips140/crypto/rsa_helper.c
 create mode 120000 fips140/crypto/rsaprivkey.asn1
 create mode 120000 fips140/crypto/rsapubkey.asn1
 create mode 120000 fips140/crypto/rsassa-pkcs1.c
 create mode 120000 fips140/crypto/seqiv.c
 create mode 120000 fips140/crypto/sha256.c
 create mode 120000 fips140/crypto/sha3_generic.c
 create mode 120000 fips140/crypto/sha512.c
 create mode 120000 fips140/crypto/shash.c
 create mode 120000 fips140/crypto/sig.c
 create mode 120000 fips140/crypto/simd.c
 create mode 120000 fips140/crypto/skcipher.c
 create mode 120000 fips140/crypto/skcipher.h
 create mode 120000 fips140/crypto/tcrypt.c
 create mode 120000 fips140/crypto/tcrypt.h
 create mode 120000 fips140/crypto/testmgr.c
 create mode 120000 fips140/crypto/testmgr.h
 create mode 120000 fips140/crypto/xts.c
 create mode 120000 fips140/lib/crypto/aes.c
 create mode 120000 fips140/lib/crypto/aesgcm.c
 create mode 120000 fips140/lib/crypto/gf128mul.c
 create mode 120000 fips140/lib/crypto/memneq.c
 create mode 120000 fips140/lib/crypto/sha256.c
 create mode 120000 fips140/lib/crypto/sha512.c
 create mode 120000 fips140/lib/crypto/utils.c

diff --git a/fips140/crypto/aead.c b/fips140/crypto/aead.c
new file mode 120000
index 000000000000..212e18356521
--- /dev/null
+++ b/fips140/crypto/aead.c
@@ -0,0 +1 @@
+../../crypto/aead.c
\ No newline at end of file
diff --git a/fips140/crypto/aes_generic.c b/fips140/crypto/aes_generic.c
new file mode 120000
index 000000000000..98deccd59067
--- /dev/null
+++ b/fips140/crypto/aes_generic.c
@@ -0,0 +1 @@
+../../crypto/aes_generic.c
\ No newline at end of file
diff --git a/fips140/crypto/ahash.c b/fips140/crypto/ahash.c
new file mode 120000
index 000000000000..81e1d69b51b3
--- /dev/null
+++ b/fips140/crypto/ahash.c
@@ -0,0 +1 @@
+../../crypto/ahash.c
\ No newline at end of file
diff --git a/fips140/crypto/akcipher.c b/fips140/crypto/akcipher.c
new file mode 120000
index 000000000000..66a618824b92
--- /dev/null
+++ b/fips140/crypto/akcipher.c
@@ -0,0 +1 @@
+../../crypto/akcipher.c
\ No newline at end of file
diff --git a/fips140/crypto/algapi.c b/fips140/crypto/algapi.c
new file mode 120000
index 000000000000..31fc6b4fb765
--- /dev/null
+++ b/fips140/crypto/algapi.c
@@ -0,0 +1 @@
+../../crypto/algapi.c
\ No newline at end of file
diff --git a/fips140/crypto/algboss.c b/fips140/crypto/algboss.c
new file mode 120000
index 000000000000..e27142d777f7
--- /dev/null
+++ b/fips140/crypto/algboss.c
@@ -0,0 +1 @@
+../../crypto/algboss.c
\ No newline at end of file
diff --git a/fips140/crypto/api.c b/fips140/crypto/api.c
new file mode 120000
index 000000000000..7c60a1d33673
--- /dev/null
+++ b/fips140/crypto/api.c
@@ -0,0 +1 @@
+../../crypto/api.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/asymmetric_keys.h b/fips140/crypto/asymmetric_keys/asymmetric_keys.h
new file mode 120000
index 000000000000..16867d35838f
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/asymmetric_keys.h
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/asymmetric_keys.h
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/asymmetric_type.c b/fips140/crypto/asymmetric_keys/asymmetric_type.c
new file mode 120000
index 000000000000..9f9119a13078
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/asymmetric_type.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/asymmetric_type.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/mscode_parser.c b/fips140/crypto/asymmetric_keys/mscode_parser.c
new file mode 120000
index 000000000000..fc2e5ba2b6ba
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/mscode_parser.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/mscode_parser.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/pkcs7.asn1 b/fips140/crypto/asymmetric_keys/pkcs7.asn1
new file mode 120000
index 000000000000..c05196a6916d
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/pkcs7.asn1
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/pkcs7.asn1
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/pkcs7_key_type.c b/fips140/crypto/asymmetric_keys/pkcs7_key_type.c
new file mode 120000
index 000000000000..1483042a2f94
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/pkcs7_key_type.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/pkcs7_key_type.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/pkcs7_parser.c b/fips140/crypto/asymmetric_keys/pkcs7_parser.c
new file mode 120000
index 000000000000..fadba19812d9
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/pkcs7_parser.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/pkcs7_parser.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/pkcs7_parser.h b/fips140/crypto/asymmetric_keys/pkcs7_parser.h
new file mode 120000
index 000000000000..a002feec14a9
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/pkcs7_parser.h
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/pkcs7_parser.h
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/pkcs7_trust.c b/fips140/crypto/asymmetric_keys/pkcs7_trust.c
new file mode 120000
index 000000000000..bc319e2fa53f
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/pkcs7_trust.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/pkcs7_trust.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/pkcs7_verify.c b/fips140/crypto/asymmetric_keys/pkcs7_verify.c
new file mode 120000
index 000000000000..e973804a9fd5
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/pkcs7_verify.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/pkcs7_verify.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/pkcs8.asn1 b/fips140/crypto/asymmetric_keys/pkcs8.asn1
new file mode 120000
index 000000000000..c8696cd8abc9
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/pkcs8.asn1
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/pkcs8.asn1
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/pkcs8_parser.c b/fips140/crypto/asymmetric_keys/pkcs8_parser.c
new file mode 120000
index 000000000000..4549c6abdca6
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/pkcs8_parser.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/pkcs8_parser.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/public_key.c b/fips140/crypto/asymmetric_keys/public_key.c
new file mode 120000
index 000000000000..8095065156ab
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/public_key.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/public_key.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/restrict.c b/fips140/crypto/asymmetric_keys/restrict.c
new file mode 120000
index 000000000000..78d8775f18c6
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/restrict.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/restrict.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/selftest.c b/fips140/crypto/asymmetric_keys/selftest.c
new file mode 120000
index 000000000000..634ea04a70ac
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/selftest.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/selftest.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/selftest.h b/fips140/crypto/asymmetric_keys/selftest.h
new file mode 120000
index 000000000000..3a769362b7ca
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/selftest.h
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/selftest.h
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/selftest_ecdsa.c b/fips140/crypto/asymmetric_keys/selftest_ecdsa.c
new file mode 120000
index 000000000000..efaeb42740a9
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/selftest_ecdsa.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/selftest_ecdsa.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/selftest_rsa.c b/fips140/crypto/asymmetric_keys/selftest_rsa.c
new file mode 120000
index 000000000000..d6418f82a81b
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/selftest_rsa.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/selftest_rsa.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/signature.c b/fips140/crypto/asymmetric_keys/signature.c
new file mode 120000
index 000000000000..415c34d1e33b
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/signature.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/signature.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/verify_pefile.c b/fips140/crypto/asymmetric_keys/verify_pefile.c
new file mode 120000
index 000000000000..9b7153555f36
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/verify_pefile.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/verify_pefile.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/verify_pefile.h b/fips140/crypto/asymmetric_keys/verify_pefile.h
new file mode 120000
index 000000000000..62483171759e
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/verify_pefile.h
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/verify_pefile.h
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/x509.asn1 b/fips140/crypto/asymmetric_keys/x509.asn1
new file mode 120000
index 000000000000..1aa8edbc2ec4
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/x509.asn1
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/x509.asn1
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/x509_akid.asn1 b/fips140/crypto/asymmetric_keys/x509_akid.asn1
new file mode 120000
index 000000000000..f952c11063f3
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/x509_akid.asn1
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/x509_akid.asn1
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/x509_cert_parser.c b/fips140/crypto/asymmetric_keys/x509_cert_parser.c
new file mode 120000
index 000000000000..a86d71968d3f
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/x509_cert_parser.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/x509_cert_parser.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/x509_loader.c b/fips140/crypto/asymmetric_keys/x509_loader.c
new file mode 120000
index 000000000000..efa9c866d065
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/x509_loader.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/x509_loader.c
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/x509_parser.h b/fips140/crypto/asymmetric_keys/x509_parser.h
new file mode 120000
index 000000000000..cbf61d79a344
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/x509_parser.h
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/x509_parser.h
\ No newline at end of file
diff --git a/fips140/crypto/asymmetric_keys/x509_public_key.c b/fips140/crypto/asymmetric_keys/x509_public_key.c
new file mode 120000
index 000000000000..000f40135e91
--- /dev/null
+++ b/fips140/crypto/asymmetric_keys/x509_public_key.c
@@ -0,0 +1 @@
+../../../crypto/asymmetric_keys/x509_public_key.c
\ No newline at end of file
diff --git a/fips140/crypto/authenc.c b/fips140/crypto/authenc.c
new file mode 120000
index 000000000000..21e091ad0815
--- /dev/null
+++ b/fips140/crypto/authenc.c
@@ -0,0 +1 @@
+../../crypto/authenc.c
\ No newline at end of file
diff --git a/fips140/crypto/authencesn.c b/fips140/crypto/authencesn.c
new file mode 120000
index 000000000000..00bb54b7be3f
--- /dev/null
+++ b/fips140/crypto/authencesn.c
@@ -0,0 +1 @@
+../../crypto/authencesn.c
\ No newline at end of file
diff --git a/fips140/crypto/cbc.c b/fips140/crypto/cbc.c
new file mode 120000
index 000000000000..aa1f6fb840c0
--- /dev/null
+++ b/fips140/crypto/cbc.c
@@ -0,0 +1 @@
+../../crypto/cbc.c
\ No newline at end of file
diff --git a/fips140/crypto/ccm.c b/fips140/crypto/ccm.c
new file mode 120000
index 000000000000..879bd39b8843
--- /dev/null
+++ b/fips140/crypto/ccm.c
@@ -0,0 +1 @@
+../../crypto/ccm.c
\ No newline at end of file
diff --git a/fips140/crypto/cipher.c b/fips140/crypto/cipher.c
new file mode 120000
index 000000000000..53fd49f62385
--- /dev/null
+++ b/fips140/crypto/cipher.c
@@ -0,0 +1 @@
+../../crypto/cipher.c
\ No newline at end of file
diff --git a/fips140/crypto/cmac.c b/fips140/crypto/cmac.c
new file mode 120000
index 000000000000..da6195375be2
--- /dev/null
+++ b/fips140/crypto/cmac.c
@@ -0,0 +1 @@
+../../crypto/cmac.c
\ No newline at end of file
diff --git a/fips140/crypto/cryptd.c b/fips140/crypto/cryptd.c
new file mode 120000
index 000000000000..b18b260ec57d
--- /dev/null
+++ b/fips140/crypto/cryptd.c
@@ -0,0 +1 @@
+../../crypto/cryptd.c
\ No newline at end of file
diff --git a/fips140/crypto/ctr.c b/fips140/crypto/ctr.c
new file mode 120000
index 000000000000..3fe3cc809347
--- /dev/null
+++ b/fips140/crypto/ctr.c
@@ -0,0 +1 @@
+../../crypto/ctr.c
\ No newline at end of file
diff --git a/fips140/crypto/dh.c b/fips140/crypto/dh.c
new file mode 120000
index 000000000000..2052a9ead300
--- /dev/null
+++ b/fips140/crypto/dh.c
@@ -0,0 +1 @@
+../../crypto/dh.c
\ No newline at end of file
diff --git a/fips140/crypto/dh_helper.c b/fips140/crypto/dh_helper.c
new file mode 120000
index 000000000000..c14488c38829
--- /dev/null
+++ b/fips140/crypto/dh_helper.c
@@ -0,0 +1 @@
+../../crypto/dh_helper.c
\ No newline at end of file
diff --git a/fips140/crypto/drbg.c b/fips140/crypto/drbg.c
new file mode 120000
index 000000000000..7f59714d2569
--- /dev/null
+++ b/fips140/crypto/drbg.c
@@ -0,0 +1 @@
+../../crypto/drbg.c
\ No newline at end of file
diff --git a/fips140/crypto/ecb.c b/fips140/crypto/ecb.c
new file mode 120000
index 000000000000..3fc2a39f7569
--- /dev/null
+++ b/fips140/crypto/ecb.c
@@ -0,0 +1 @@
+../../crypto/ecb.c
\ No newline at end of file
diff --git a/fips140/crypto/ecc.c b/fips140/crypto/ecc.c
new file mode 120000
index 000000000000..45a59d048f04
--- /dev/null
+++ b/fips140/crypto/ecc.c
@@ -0,0 +1 @@
+../../crypto/ecc.c
\ No newline at end of file
diff --git a/fips140/crypto/ecc_curve_defs.h b/fips140/crypto/ecc_curve_defs.h
new file mode 120000
index 000000000000..7a065529702f
--- /dev/null
+++ b/fips140/crypto/ecc_curve_defs.h
@@ -0,0 +1 @@
+../../crypto/ecc_curve_defs.h
\ No newline at end of file
diff --git a/fips140/crypto/ecdh.c b/fips140/crypto/ecdh.c
new file mode 120000
index 000000000000..c82cae9a6272
--- /dev/null
+++ b/fips140/crypto/ecdh.c
@@ -0,0 +1 @@
+../../crypto/ecdh.c
\ No newline at end of file
diff --git a/fips140/crypto/ecdh_helper.c b/fips140/crypto/ecdh_helper.c
new file mode 120000
index 000000000000..a37954e0aa04
--- /dev/null
+++ b/fips140/crypto/ecdh_helper.c
@@ -0,0 +1 @@
+../../crypto/ecdh_helper.c
\ No newline at end of file
diff --git a/fips140/crypto/ecdsa-p1363.c b/fips140/crypto/ecdsa-p1363.c
new file mode 120000
index 000000000000..5795bc88ebaf
--- /dev/null
+++ b/fips140/crypto/ecdsa-p1363.c
@@ -0,0 +1 @@
+../../crypto/ecdsa-p1363.c
\ No newline at end of file
diff --git a/fips140/crypto/ecdsa-x962.c b/fips140/crypto/ecdsa-x962.c
new file mode 120000
index 000000000000..e0cf7c741683
--- /dev/null
+++ b/fips140/crypto/ecdsa-x962.c
@@ -0,0 +1 @@
+../../crypto/ecdsa-x962.c
\ No newline at end of file
diff --git a/fips140/crypto/ecdsa.c b/fips140/crypto/ecdsa.c
new file mode 120000
index 000000000000..b9bf37d37397
--- /dev/null
+++ b/fips140/crypto/ecdsa.c
@@ -0,0 +1 @@
+../../crypto/ecdsa.c
\ No newline at end of file
diff --git a/fips140/crypto/ecdsasignature.asn1 b/fips140/crypto/ecdsasignature.asn1
new file mode 120000
index 000000000000..7fa5850233fc
--- /dev/null
+++ b/fips140/crypto/ecdsasignature.asn1
@@ -0,0 +1 @@
+../../crypto/ecdsasignature.asn1
\ No newline at end of file
diff --git a/fips140/crypto/echainiv.c b/fips140/crypto/echainiv.c
new file mode 120000
index 000000000000..fee662c9a8d0
--- /dev/null
+++ b/fips140/crypto/echainiv.c
@@ -0,0 +1 @@
+../../crypto/echainiv.c
\ No newline at end of file
diff --git a/fips140/crypto/essiv.c b/fips140/crypto/essiv.c
new file mode 120000
index 000000000000..6554857abd79
--- /dev/null
+++ b/fips140/crypto/essiv.c
@@ -0,0 +1 @@
+../../crypto/essiv.c
\ No newline at end of file
diff --git a/fips140/crypto/gcm.c b/fips140/crypto/gcm.c
new file mode 120000
index 000000000000..b8ef945a7444
--- /dev/null
+++ b/fips140/crypto/gcm.c
@@ -0,0 +1 @@
+../../crypto/gcm.c
\ No newline at end of file
diff --git a/fips140/crypto/geniv.c b/fips140/crypto/geniv.c
new file mode 120000
index 000000000000..059afe3c124c
--- /dev/null
+++ b/fips140/crypto/geniv.c
@@ -0,0 +1 @@
+../../crypto/geniv.c
\ No newline at end of file
diff --git a/fips140/crypto/ghash-generic.c b/fips140/crypto/ghash-generic.c
new file mode 120000
index 000000000000..ebb7c8aee335
--- /dev/null
+++ b/fips140/crypto/ghash-generic.c
@@ -0,0 +1 @@
+../../crypto/ghash-generic.c
\ No newline at end of file
diff --git a/fips140/crypto/hash.h b/fips140/crypto/hash.h
new file mode 120000
index 000000000000..41ba73037bc9
--- /dev/null
+++ b/fips140/crypto/hash.h
@@ -0,0 +1 @@
+../../crypto/hash.h
\ No newline at end of file
diff --git a/fips140/crypto/hmac.c b/fips140/crypto/hmac.c
new file mode 120000
index 000000000000..162f4c205f1b
--- /dev/null
+++ b/fips140/crypto/hmac.c
@@ -0,0 +1 @@
+../../crypto/hmac.c
\ No newline at end of file
diff --git a/fips140/crypto/internal.h b/fips140/crypto/internal.h
new file mode 120000
index 000000000000..670e77b6a0d6
--- /dev/null
+++ b/fips140/crypto/internal.h
@@ -0,0 +1 @@
+../../crypto/internal.h
\ No newline at end of file
diff --git a/fips140/crypto/jitterentropy-kcapi.c b/fips140/crypto/jitterentropy-kcapi.c
new file mode 120000
index 000000000000..30e13bbd6099
--- /dev/null
+++ b/fips140/crypto/jitterentropy-kcapi.c
@@ -0,0 +1 @@
+../../crypto/jitterentropy-kcapi.c
\ No newline at end of file
diff --git a/fips140/crypto/jitterentropy.c b/fips140/crypto/jitterentropy.c
new file mode 120000
index 000000000000..cb9a117048af
--- /dev/null
+++ b/fips140/crypto/jitterentropy.c
@@ -0,0 +1 @@
+../../crypto/jitterentropy.c
\ No newline at end of file
diff --git a/fips140/crypto/jitterentropy.h b/fips140/crypto/jitterentropy.h
new file mode 120000
index 000000000000..991e4585e6e0
--- /dev/null
+++ b/fips140/crypto/jitterentropy.h
@@ -0,0 +1 @@
+../../crypto/jitterentropy.h
\ No newline at end of file
diff --git a/fips140/crypto/kpp.c b/fips140/crypto/kpp.c
new file mode 120000
index 000000000000..8fbd20de20df
--- /dev/null
+++ b/fips140/crypto/kpp.c
@@ -0,0 +1 @@
+../../crypto/kpp.c
\ No newline at end of file
diff --git a/fips140/crypto/lskcipher.c b/fips140/crypto/lskcipher.c
new file mode 120000
index 000000000000..997c2c0eafb4
--- /dev/null
+++ b/fips140/crypto/lskcipher.c
@@ -0,0 +1 @@
+../../crypto/lskcipher.c
\ No newline at end of file
diff --git a/fips140/crypto/pcrypt.c b/fips140/crypto/pcrypt.c
new file mode 120000
index 000000000000..9ef1ba4b9f66
--- /dev/null
+++ b/fips140/crypto/pcrypt.c
@@ -0,0 +1 @@
+../../crypto/pcrypt.c
\ No newline at end of file
diff --git a/fips140/crypto/proc.c b/fips140/crypto/proc.c
new file mode 120000
index 000000000000..5dfad57a688c
--- /dev/null
+++ b/fips140/crypto/proc.c
@@ -0,0 +1 @@
+../../crypto/proc.c
\ No newline at end of file
diff --git a/fips140/crypto/rng.c b/fips140/crypto/rng.c
new file mode 120000
index 000000000000..2ac107582b56
--- /dev/null
+++ b/fips140/crypto/rng.c
@@ -0,0 +1 @@
+../../crypto/rng.c
\ No newline at end of file
diff --git a/fips140/crypto/rsa-pkcs1pad.c b/fips140/crypto/rsa-pkcs1pad.c
new file mode 120000
index 000000000000..e81ca29bc1c0
--- /dev/null
+++ b/fips140/crypto/rsa-pkcs1pad.c
@@ -0,0 +1 @@
+../../crypto/rsa-pkcs1pad.c
\ No newline at end of file
diff --git a/fips140/crypto/rsa.c b/fips140/crypto/rsa.c
new file mode 120000
index 000000000000..05903a691c9f
--- /dev/null
+++ b/fips140/crypto/rsa.c
@@ -0,0 +1 @@
+../../crypto/rsa.c
\ No newline at end of file
diff --git a/fips140/crypto/rsa_helper.c b/fips140/crypto/rsa_helper.c
new file mode 120000
index 000000000000..ae17e923013c
--- /dev/null
+++ b/fips140/crypto/rsa_helper.c
@@ -0,0 +1 @@
+../../crypto/rsa_helper.c
\ No newline at end of file
diff --git a/fips140/crypto/rsaprivkey.asn1 b/fips140/crypto/rsaprivkey.asn1
new file mode 120000
index 000000000000..c798dadccde5
--- /dev/null
+++ b/fips140/crypto/rsaprivkey.asn1
@@ -0,0 +1 @@
+../../crypto/rsaprivkey.asn1
\ No newline at end of file
diff --git a/fips140/crypto/rsapubkey.asn1 b/fips140/crypto/rsapubkey.asn1
new file mode 120000
index 000000000000..e3bbdd50e4a1
--- /dev/null
+++ b/fips140/crypto/rsapubkey.asn1
@@ -0,0 +1 @@
+../../crypto/rsapubkey.asn1
\ No newline at end of file
diff --git a/fips140/crypto/rsassa-pkcs1.c b/fips140/crypto/rsassa-pkcs1.c
new file mode 120000
index 000000000000..8cb36646c148
--- /dev/null
+++ b/fips140/crypto/rsassa-pkcs1.c
@@ -0,0 +1 @@
+../../crypto/rsassa-pkcs1.c
\ No newline at end of file
diff --git a/fips140/crypto/seqiv.c b/fips140/crypto/seqiv.c
new file mode 120000
index 000000000000..dc7e9c533d2c
--- /dev/null
+++ b/fips140/crypto/seqiv.c
@@ -0,0 +1 @@
+../../crypto/seqiv.c
\ No newline at end of file
diff --git a/fips140/crypto/sha256.c b/fips140/crypto/sha256.c
new file mode 120000
index 000000000000..487d843d4d82
--- /dev/null
+++ b/fips140/crypto/sha256.c
@@ -0,0 +1 @@
+../../crypto/sha256.c
\ No newline at end of file
diff --git a/fips140/crypto/sha3_generic.c b/fips140/crypto/sha3_generic.c
new file mode 120000
index 000000000000..3719d7f58f4a
--- /dev/null
+++ b/fips140/crypto/sha3_generic.c
@@ -0,0 +1 @@
+../../crypto/sha3_generic.c
\ No newline at end of file
diff --git a/fips140/crypto/sha512.c b/fips140/crypto/sha512.c
new file mode 120000
index 000000000000..8639124175e2
--- /dev/null
+++ b/fips140/crypto/sha512.c
@@ -0,0 +1 @@
+../../crypto/sha512.c
\ No newline at end of file
diff --git a/fips140/crypto/shash.c b/fips140/crypto/shash.c
new file mode 120000
index 000000000000..ffb09e16c542
--- /dev/null
+++ b/fips140/crypto/shash.c
@@ -0,0 +1 @@
+../../crypto/shash.c
\ No newline at end of file
diff --git a/fips140/crypto/sig.c b/fips140/crypto/sig.c
new file mode 120000
index 000000000000..742f337b3cd5
--- /dev/null
+++ b/fips140/crypto/sig.c
@@ -0,0 +1 @@
+../../crypto/sig.c
\ No newline at end of file
diff --git a/fips140/crypto/simd.c b/fips140/crypto/simd.c
new file mode 120000
index 000000000000..72398481d19d
--- /dev/null
+++ b/fips140/crypto/simd.c
@@ -0,0 +1 @@
+../../crypto/simd.c
\ No newline at end of file
diff --git a/fips140/crypto/skcipher.c b/fips140/crypto/skcipher.c
new file mode 120000
index 000000000000..225d8cb56748
--- /dev/null
+++ b/fips140/crypto/skcipher.c
@@ -0,0 +1 @@
+../../crypto/skcipher.c
\ No newline at end of file
diff --git a/fips140/crypto/skcipher.h b/fips140/crypto/skcipher.h
new file mode 120000
index 000000000000..d93f94a9127e
--- /dev/null
+++ b/fips140/crypto/skcipher.h
@@ -0,0 +1 @@
+../../crypto/skcipher.h
\ No newline at end of file
diff --git a/fips140/crypto/tcrypt.c b/fips140/crypto/tcrypt.c
new file mode 120000
index 000000000000..5c59dd1d6109
--- /dev/null
+++ b/fips140/crypto/tcrypt.c
@@ -0,0 +1 @@
+../../crypto/tcrypt.c
\ No newline at end of file
diff --git a/fips140/crypto/tcrypt.h b/fips140/crypto/tcrypt.h
new file mode 120000
index 000000000000..d643316fd181
--- /dev/null
+++ b/fips140/crypto/tcrypt.h
@@ -0,0 +1 @@
+../../crypto/tcrypt.h
\ No newline at end of file
diff --git a/fips140/crypto/testmgr.c b/fips140/crypto/testmgr.c
new file mode 120000
index 000000000000..0b105587d3d8
--- /dev/null
+++ b/fips140/crypto/testmgr.c
@@ -0,0 +1 @@
+../../crypto/testmgr.c
\ No newline at end of file
diff --git a/fips140/crypto/testmgr.h b/fips140/crypto/testmgr.h
new file mode 120000
index 000000000000..486e31b584a5
--- /dev/null
+++ b/fips140/crypto/testmgr.h
@@ -0,0 +1 @@
+../../crypto/testmgr.h
\ No newline at end of file
diff --git a/fips140/crypto/xts.c b/fips140/crypto/xts.c
new file mode 120000
index 000000000000..2ee6ce8b2c43
--- /dev/null
+++ b/fips140/crypto/xts.c
@@ -0,0 +1 @@
+../../crypto/xts.c
\ No newline at end of file
diff --git a/fips140/lib/crypto/aes.c b/fips140/lib/crypto/aes.c
new file mode 120000
index 000000000000..752e48faca8f
--- /dev/null
+++ b/fips140/lib/crypto/aes.c
@@ -0,0 +1 @@
+../../../lib/crypto/aes.c
\ No newline at end of file
diff --git a/fips140/lib/crypto/aesgcm.c b/fips140/lib/crypto/aesgcm.c
new file mode 120000
index 000000000000..d36e6b666511
--- /dev/null
+++ b/fips140/lib/crypto/aesgcm.c
@@ -0,0 +1 @@
+../../../lib/crypto/aesgcm.c
\ No newline at end of file
diff --git a/fips140/lib/crypto/gf128mul.c b/fips140/lib/crypto/gf128mul.c
new file mode 120000
index 000000000000..ad4f4a232bb0
--- /dev/null
+++ b/fips140/lib/crypto/gf128mul.c
@@ -0,0 +1 @@
+../../../lib/crypto/gf128mul.c
\ No newline at end of file
diff --git a/fips140/lib/crypto/memneq.c b/fips140/lib/crypto/memneq.c
new file mode 120000
index 000000000000..3c73a12c9f71
--- /dev/null
+++ b/fips140/lib/crypto/memneq.c
@@ -0,0 +1 @@
+../../../lib/crypto/memneq.c
\ No newline at end of file
diff --git a/fips140/lib/crypto/sha256.c b/fips140/lib/crypto/sha256.c
new file mode 120000
index 000000000000..d36c2b0f3b4f
--- /dev/null
+++ b/fips140/lib/crypto/sha256.c
@@ -0,0 +1 @@
+../../../lib/crypto/sha256.c
\ No newline at end of file
diff --git a/fips140/lib/crypto/sha512.c b/fips140/lib/crypto/sha512.c
new file mode 120000
index 000000000000..94712c686209
--- /dev/null
+++ b/fips140/lib/crypto/sha512.c
@@ -0,0 +1 @@
+../../../lib/crypto/sha512.c
\ No newline at end of file
diff --git a/fips140/lib/crypto/utils.c b/fips140/lib/crypto/utils.c
new file mode 120000
index 000000000000..543c49b255de
--- /dev/null
+++ b/fips140/lib/crypto/utils.c
@@ -0,0 +1 @@
+../../../lib/crypto/utils.c
\ No newline at end of file
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 102/104] scripts/extract-fips140: new script
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Add a new script to extract a precompiled FIPS 140 module (.ko), its
authenticated digest (.hmac), and optionally also the .a of modules, from
a vmlinuz file.

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 scripts/extract-fips140 | 53 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100755 scripts/extract-fips140

diff --git a/scripts/extract-fips140 b/scripts/extract-fips140
new file mode 100755
index 000000000000..00ec7631fa3c
--- /dev/null
+++ b/scripts/extract-fips140
@@ -0,0 +1,53 @@
+#! /usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Extract FIPS 140 cryptographic module (and hmac) from vmlinuz.
+#
+# Copyright © 2025, Oracle and/or its affiliates.
+#
+
+import argparse
+import os
+import shutil
+import subprocess
+import sys
+import tempfile
+
+extract_vmlinux = os.path.join(os.path.dirname(__file__), 'extract-vmlinux')
+
+parser = argparse.ArgumentParser()
+parser.add_argument('vmlinux')
+
+args = parser.parse_args()
+
+warnings = False
+
+with tempfile.TemporaryDirectory() as tmp_dir:
+    vmlinux_path = os.path.join(tmp_dir, 'vmlinux')
+    with open(vmlinux_path, 'w') as f:
+        subprocess.check_call([extract_vmlinux, args.vmlinux], stdout=f)
+
+    def extract_section(input_path, output_path, section):
+        tmp_output_path = os.path.join(tmp_dir, output_path)
+
+        subprocess.check_call([
+            'objcopy',
+            '--only-section', section,
+            '--output-target', 'binary',
+            input_path,
+            tmp_output_path,
+        ])
+
+        if os.path.getsize(tmp_output_path) == 0:
+            print(f"warning: failed to extract {output_path}; empty section {section}?", file=sys.stderr)
+            global warnings
+            warnings = True
+        else:
+            shutil.move(tmp_output_path, output_path)
+            print(f"extracted {output_path}")
+
+    extract_section(vmlinux_path, 'fips140.ko', '__fips140_module')
+    extract_section(vmlinux_path, 'fips140.hmac', '__fips140_digest')
+
+if warnings:
+    sys.exit(1)
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 100/104] crypto: fips140: add standalone FIPS 140 module
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

This code is partly based on the existing crypto/fips.c code and partly on
the Android FIPS 140 module [1]; __fips_initcalls/run_initcalls() based
loosely on code by Jay Wang <wanjay@amazon.com>.

[1]: https://android.googlesource.com/kernel/common/+/1ca1130ec62d/crypto/fips140-module.c

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 crypto/Kconfig         |  16 +--
 fips140/Kconfig        | 174 +++++++++++++++++++++++++++++++++
 fips140/Makefile       | 183 ++++++++++++++++++++++++++++++++++
 fips140/fips140-glue.c | 216 +++++++++++++++++++++++++++++++++++++++++
 fips140/fips140.lds    |   9 ++
 5 files changed, 583 insertions(+), 15 deletions(-)
 create mode 100644 fips140/Kconfig
 create mode 100644 fips140/Makefile
 create mode 100644 fips140/fips140-glue.c
 create mode 100644 fips140/fips140.lds

diff --git a/crypto/Kconfig b/crypto/Kconfig
index a2696ea30bde..f9b2f87ad04b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -54,21 +54,7 @@ config CRYPTO_FIPS_VERSION
 	  This option provides the ability to override the FIPS Module Version.
 	  By default the KERNELRELEASE value is used.
 
-config CRYPTO_FIPS140_EXTMOD
-	bool "FIPS 140-3 external module"
-	depends on CRYPTO_FIPS
-	help
-	  Support loading a prebuilt FIPS 140-3 cryptographic module.
-
-config CRYPTO_FIPS140_HMAC_KEY
-	string "FIPS 140-3 external module HMAC key"
-	depends on CRYPTO_FIPS140_EXTMOD
-	default "Sphinx of black quartz, judge my vow"
-	help
-	  This is the HMAC key used to build and verify the integrity of
-	  the FIPS module.
-
-	  Must be at least 14 characters.
+source "fips140/Kconfig"
 
 config CRYPTO_ALGAPI
 	tristate
diff --git a/fips140/Kconfig b/fips140/Kconfig
new file mode 100644
index 000000000000..188c5f360eab
--- /dev/null
+++ b/fips140/Kconfig
@@ -0,0 +1,174 @@
+# NOTE: the structure of this file mirrors that of crypto/Kconfig
+# and crypto/asymmetric/keys/Kconfig
+
+config CRYPTO_FIPS140_EXTMOD
+	bool "FIPS 140-3 external module"
+	depends on MODULES
+	depends on CRYPTO_FIPS
+	help
+	  Support loading a prebuilt FIPS 140-3 cryptographic module.
+
+if CRYPTO_FIPS140_EXTMOD
+
+config CRYPTO_FIPS140_HMAC_KEY
+	string "FIPS 140-3 external module HMAC key"
+	default "Sphinx of black quartz, judge my vow"
+	help
+	  This is the HMAC key used to build and verify the integrity of
+	  the FIPS module.
+
+	  Must be at least 14 characters.
+
+config CRYPTO_FIPS140_PCRYPT
+	bool
+	default CRYPTO_PCRYPT
+
+menu "FIPS 140 external module algorithms"
+	depends on CRYPTO_FIPS140_EXTMOD
+
+#
+# Public-key cryptography
+#
+
+config CRYPTO_FIPS140_RSA
+	bool "RSA (Rivest-Shamir-Adleman)"
+	default CRYPTO_RSA
+
+config CRYPTO_FIPS140_DH
+	bool "DH (Diffie-Hellman)"
+	default CRYPTO_DH
+
+config CRYPTO_FIPS140_ECC
+	bool
+	default CRYPTO_ECC
+
+config CRYPTO_FIPS140_ECDH
+	bool "ECDH (Elliptic Curve Diffie-Hellman)"
+	select CRYPTO_FIPS140_ECC
+	default CRYPTO_ECDH
+
+config CRYPTO_FIPS140_ECDSA
+	bool "ECDSA (Elliptic Curve Digital Signature Algorithm)"
+	default CRYPTO_ECDSA
+
+#
+# Block ciphers
+#
+
+config CRYPTO_FIPS140_AES
+	bool "AES (Advanced Encryption Standard)"
+	default CRYPTO_AES
+
+#
+# Length-preserving ciphers and modes
+#
+
+config CRYPTO_FIPS140_CBC
+	bool "CBC (Cipher Block Chaining)"
+	default CRYPTO_CBC
+
+config CRYPTO_FIPS140_CTR
+	bool "CTR (Counter)"
+	default CRYPTO_CTR
+
+config CRYPTO_FIPS140_ECB
+	bool "ECB (Electronic Codebook)"
+	default CRYPTO_ECB
+
+config CRYPTO_FIPS140_XTS
+	bool "XTS (XOR Encrypt XOR with ciphertext stealing)"
+	default CRYPTO_XTS
+
+#
+# AEAD (authenticated encryption with associated data) ciphers
+#
+
+config CRYPTO_FIPS140_CCM
+	bool "CCM (Counter with Cipher Block Chaining-MAC)"
+	default CRYPTO_CCM
+
+config CRYPTO_FIPS140_GCM
+	bool "GCM (Galois/Counter Mode) and GMAC (GCM MAC)"
+	default CRYPTO_GCM
+
+config CRYPTO_FIPS140_GENIV
+	bool
+	default CRYPTO_GENIV
+
+config CRYPTO_FIPS140_SEQIV
+	bool "Sequence Number IV Generator"
+	select CRYPTO_FIPS140_GENIV
+	default CRYPTO_SEQIV
+
+config CRYPTO_FIPS140_ECHAINIV
+	bool "Encrypted Chain IV Generator"
+	select CRYPTO_FIPS140_GENIV
+	default CRYPTO_ECHAINIV
+
+config CRYPTO_FIPS140_ESSIV
+	bool "Encrypted Salt-Sector IV Generator"
+	default CRYPTO_ESSIV
+
+#
+# Hashes, digests, and MACs
+#
+
+config CRYPTO_FIPS140_CMAC
+	bool "CMAC (Cipher-based MAC)"
+	default CRYPTO_CMAC
+
+config CRYPTO_FIPS140_HMAC
+	bool "HMAC (Keyed-Hash MAC)"
+	default CRYPTO_HMAC
+
+config CRYPTO_FIPS140_SHA256
+	bool "SHA-244 and SHA-256"
+	default CRYPTO_SHA256
+
+config CRYPTO_FIPS140_SHA512
+	bool "SHA-384 and SHA-512"
+	default CRYPTO_SHA512
+
+config CRYPTO_FIPS140_SHA3
+	bool "SHA-3"
+	default CRYPTO_SHA3
+
+#
+# Random number generation
+#
+
+config CRYPTO_FIPS140_JITTERENTROPY
+	bool "CPU Jitter Non-Deterministic RNG (Random Number Generator)"
+	select CRYPTO_FIPS140_SHA3
+
+#
+# Asymmetric keys
+#
+
+config FIPS140_ASYMMETRIC_KEY_TYPE
+	bool "Asymmetric (public-key cryptographic) key type"
+	default ASYMMETRIC_KEY_TYPE
+
+if FIPS140_ASYMMETRIC_KEY_TYPE
+
+config FIPS140_ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+	bool "Asymmetric public-key crypto algorithm subtype"
+	default ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+
+config FIPS140_X509_CERTIFICATE_PARSER
+	bool "X.509 certificate parser"
+	default X509_CERTIFICATE_PARSER
+
+config FIPS140_PKCS8_PRIVATE_KEY_PARSER
+	bool "PKCS#8 private key parser"
+	default PKCS8_PRIVATE_KEY_PARSER
+
+config FIPS140_PKCS7_MESSAGE_PARSER
+	bool "PKCS#7 message parser"
+	default PKCS7_MESSAGE_PARSER
+
+endif
+
+endmenu
+
+endif # if CRYPTO_FIPS140_EXTMOD
diff --git a/fips140/Makefile b/fips140/Makefile
new file mode 100644
index 000000000000..47365f1b3e27
--- /dev/null
+++ b/fips140/Makefile
@@ -0,0 +1,183 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
+# Copyright © 2025, Oracle and/or its affiliates.
+#
+
+#
+# Global options
+#
+
+# make sure both .c and .S files see this
+subdir-ccflags-y += -DFIPS_MODULE=1
+subdir-asflags-y += -DFIPS_MODULE=1
+
+#
+# Glue
+#
+
+fips140-y := fips140-glue.o
+
+#
+# crypto/Makefile
+#
+
+fips140-y += crypto/algapi.o
+fips140-y += crypto/api.o
+fips140-y += crypto/ahash.o
+fips140-y += crypto/cryptd.o
+fips140-y += crypto/shash.o
+fips140-y += crypto/proc.o
+
+# cryptomgr.ko
+fips140-y += crypto/algboss.o crypto/testmgr.o
+
+fips140-$(CONFIG_CRYPTO_FIPS140_SHA3) += crypto/sha3_generic.o
+
+# jitterentropy_rng.ko
+CFLAGS_crypto/jitterentropy.o = -O0
+KASAN_SANITIZE_crypto/jitterentropy.o = n
+UBSAN_SANITIZE_crypto/jitterentropy.o = n
+fips140-$(CONFIG_CRYPTO_FIPS140_JITTERENTROPY) += crypto/jitterentropy.o crypto/jitterentropy-kcapi.o
+
+fips140-$(CONFIG_CRYPTO_FIPS140_SHA512) += crypto/sha512.o
+
+fips140-$(CONFIG_CRYPTO_FIPS140_PCRYPT) += crypto/pcrypt.o
+fips140-y += crypto/ghash-generic.o
+
+# crypto_simd.ko
+fips140-y += crypto/simd.o
+
+fips140-$(CONFIG_CRYPTO_FIPS140_HMAC) += crypto/hmac.o
+fips140-y += crypto/authenc.o
+fips140-y += crypto/authencesn.o
+
+# rsa_generic.ko
+fips140-$(CONFIG_CRYPTO_FIPS140_RSA) += $(addprefix crypto/, \
+	rsapubkey.asn1.o \
+	rsaprivkey.asn1.o \
+	rsa.o \
+	rsa_helper.o \
+	rsa-pkcs1pad.o \
+	rsassa-pkcs1.o \
+)
+
+fips140-$(CONFIG_CRYPTO_FIPS140_SHA256) += crypto/sha256.o
+
+fips140-$(CONFIG_CRYPTO_FIPS140_CMAC) += crypto/cmac.o
+fips140-$(CONFIG_CRYPTO_FIPS140_AES) += crypto/aes_generic.o
+fips140-$(CONFIG_CRYPTO_FIPS140_CBC) += crypto/cbc.o
+fips140-$(CONFIG_CRYPTO_FIPS140_CCM) += crypto/ccm.o
+fips140-$(CONFIG_CRYPTO_FIPS140_ECB) += crypto/ecb.o
+fips140-$(CONFIG_CRYPTO_FIPS140_CTR) += crypto/ctr.o
+fips140-$(CONFIG_CRYPTO_FIPS140_ECC) += crypto/ecc.o
+fips140-y += crypto/drbg.o
+
+fips140-$(CONFIG_CRYPTO_FIPS140_ECDH) += $(addprefix crypto/, \
+	ecdh.o \
+	ecdh_helper.o \
+)
+
+# ecdsa_generic.ko
+$(obj)/crypto/ecdsasignature.asn1.o: $(obj)/crypto/ecdsasignature.asn1.c $(obj)/crypto/ecdsasignature.asn1.h
+$(obj)/crypto/ecdsa.o: $(obj)/crypto/ecdsasignature.asn1.h
+fips140-$(CONFIG_CRYPTO_FIPS140_ECDSA) += $(addprefix crypto/, \
+	ecdsa.o \
+	ecdsa-x962.o \
+	ecdsa-p1363.o \
+	ecdsasignature.asn1.o \
+)
+
+# dh_generic.ko
+fips140-$(CONFIG_CRYPTO_FIPS140_DH) += $(addprefix crypto/, \
+	dh.o \
+	dh_helper.o \
+)
+
+fips140-$(CONFIG_CRYPTO_FIPS140_GCM) += crypto/gcm.o
+fips140-$(CRYPTO_FIPS140_XTS) += crypto/xts.o
+fips140-y += crypto/tcrypt.o
+
+fips140-y += crypto/aead.o
+fips140-y += crypto/kpp.o
+fips140-y += crypto/cipher.o
+fips140-y += crypto/akcipher.o
+fips140-y += crypto/skcipher.o
+fips140-y += crypto/lskcipher.o
+fips140-y += crypto/rng.o
+fips140-y += crypto/sig.o
+fips140-$(CONFIG_CRYPTO_FIPS140_GENIV) += crypto/geniv.o
+fips140-$(CONFIG_CRYPTO_FIPS140_SEQIV) += crypto/seqiv.o
+fips140-$(CONFIG_CRYPTO_FIPS140_ECHAINIV) += crypto/echainiv.o
+fips140-$(CONFIG_CRYPTO_FIPS140_ESSIV) += crypto/essiv.o
+
+#
+# crypto/asymmetric_keys/Makefile
+#
+
+fips140-$(CONFIG_FIPS140_ASYMMETRIC_KEY_TYPE) += \
+	$(addprefix crypto/asymmetric_keys/, \
+		asymmetric_type.o restrict.o signature.o)
+
+fips140-$(CONFIG_FIPS140_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += crypto/asymmetric_keys/public_key.o
+
+$(obj)/crypto/asymmetric_keys/x509_cert_parser.o: \
+	$(addprefix $(obj)/crypto/asymmetric_keys/, \
+		x509.asn1.h x509_akid.asn1.h)
+$(obj)/crypto/asymmetric_keys/x509.asn1.o: \
+	$(addprefix $(obj)/crypto/asymmetric_keys/, \
+		x509.asn1.c x509.asn1.h)
+$(obj)/crypto/asymmetric_keys/x509_akid.asn1.o: \
+	$(addprefix $(obj)/crypto/asymmetric_keys/, \
+		x509_akid.asn1.c x509_akid.asn1.h)
+
+fips140-$(CONFIG_FIPS140_X509_CERTIFICATE_PARSER) += \
+	$(addprefix crypto/asymmetric_keys/, \
+		x509_cert_parser.o \
+		x509_loader.o \
+		x509_akid.asn1.o \
+		x509.asn1.o \
+		x509_public_key.o \
+	)
+
+$(obj)/crypto/asymmetric_keys/pkcs8_parser.o: $(obj)/crypto/asymmetric_keys/pkcs8.asn1.h
+$(obj)/crypto/asymmetric_keys/pkcs8-asn1.o: \
+	$(addprefix $(obj)/crypto/asymmetric_keys/, \
+		pkcs8.asn1.c pkcs8.asn1.h)
+
+fips140-$(CONFIG_FIPS140_PKCS8_PRIVATE_KEY_PARSER) += \
+	$(addprefix crypto/asymmetric_keys/, \
+		pkcs8_parser.o \
+		pkcs8.asn1.o \
+	)
+
+fips140-$(CONFIG_FIPS140_PKCS7_MESSAGE_PARSER) += \
+	$(addprefix crypto/asymmetric_keys/, \
+		pkcs7_parser.o \
+		pkcs7_trust.o \
+		pkcs7_verify.o \
+		pkcs7_key_type.o \
+		pkcs7.asn1.o \
+	)
+
+$(obj)/crypto/asymmetric_keys/pkcs7_parser.o: $(obj)/crypto/asymmetric_keys/pkcs7.asn1.h
+$(obj)/crypto/asymmetric_keys/pkcs7.asn1.o: \
+	$(addprefix $(obj)/crypto/asymmetric_keys/, \
+		pkcs7.asn1.c pkcs7.asn1.h)
+
+#
+# lib/crypto/Makefile
+#
+
+fips140-y += lib/crypto/aes.o
+fips140-y += lib/crypto/aesgcm.o
+fips140-y += lib/crypto/sha256.o
+fips140-y += lib/crypto/sha512.o
+fips140-y += lib/crypto/gf128mul.o
+fips140-y += lib/crypto/memneq.o
+fips140-y += lib/crypto/utils.o
+
+# Use custom linker script to collect initcalls
+LDFLAGS_fips140.o += -T $(src)/fips140.lds
+
+obj-m += fips140.o
diff --git a/fips140/fips140-glue.c b/fips140/fips140-glue.c
new file mode 100644
index 000000000000..69db638c68d1
--- /dev/null
+++ b/fips140/fips140-glue.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * FIPS 140-3 and FIPS 200 support.
+ *
+ * Copyright (c) 2008 Neil Horman <nhorman@tuxdriver.com>
+ * Copyright 2021 Google LLC
+ * Copyright (c) 2025, Oracle and/or its affiliates.
+ */
+
+#include <generated/utsrelease.h>
+
+#include <linux/export.h>
+#include <linux/fips.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/sysctl.h>
+
+#include <crypto/api.h>
+#include <crypto/hash.h>
+
+#include "crypto/internal.h"
+
+#define FIPS_MODULE_NAME CONFIG_CRYPTO_FIPS_NAME
+#ifdef CONFIG_CRYPTO_FIPS_CUSTOM_VERSION
+#define FIPS_MODULE_VERSION CONFIG_CRYPTO_FIPS_VERSION
+#else
+#define FIPS_MODULE_VERSION UTS_RELEASE
+#endif
+
+static char fips_name[] = FIPS_MODULE_NAME;
+static char fips_version[] = FIPS_MODULE_VERSION;
+
+/*
+ * FIPS 140-2 prefers the use of HMAC with a public key over a plain hash.
+ */
+static const u8 fips140_integ_hmac_key[] = CONFIG_CRYPTO_FIPS140_HMAC_KEY;
+
+int fips_operational = 0;
+
+static int verify_integrity(void)
+{
+	int err;
+
+	struct crypto_shash *tfm = NULL;
+	SHASH_DESC_ON_STACK(desc, dontcare);
+	u8 digest[SHA256_DIGEST_SIZE];
+
+	/*
+	 * Verify integrity
+	 */
+
+	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;
+	pr_info("FIPS 140: using '%s' for integrity check\n",
+		crypto_shash_driver_name(tfm));
+
+	err = crypto_shash_setkey(tfm, fips140_integ_hmac_key, strlen(fips140_integ_hmac_key));
+	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);
+
+	/* Compute HMAC over the module's source memory */
+	//err = crypto_shash_update(desc, THIS_MODULE->source_ptr, THIS_MODULE->source_len);
+	err = crypto_shash_update(desc, _binary_fips140_ko_start, _binary_fips140_ko_end - _binary_fips140_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);
+
+	/* Zeroizing this is important; see the comment below. */
+	shash_desc_zero(desc);
+
+	if (err)
+		panic("FIPS 140: failed to calculate hmac shash (%d)\n", err);
+
+	pr_info("FIPS 140: expected digest: %*phN\n", (int)sizeof(digest), _binary_fips140_hmac_start);
+	pr_info("FIPS 140: computed digest: %*phN\n", (int)sizeof(digest), digest);
+
+	if (memcmp(digest, _binary_fips140_hmac_start, sizeof(digest)))
+		panic("FIPS 140: failed integrity check\n");
+
+	/*
+	 * FIPS 140-3 requires that all "temporary value(s) generated during the
+	 * integrity test" be zeroized (ref: FIPS 140-3 IG 9.7.B).  There is no
+	 * technical reason to do this given that these values are public
+	 * information, but this is the requirement so we follow it.
+	 */
+	crypto_free_shash(tfm);
+	memzero_explicit(digest, sizeof(digest));
+
+	return 0;
+}
+
+/* This technically is never supposed to change. */
+static int fips_standalone = 1;
+
+static struct ctl_table crypto_sysctl_table[] = {
+	{
+		.procname	= "fips_enabled",
+		/*
+		 * Note: we use fips_operational instead of fips_enabled,
+		 * since fips_enabled is more like "FIPS was requested",
+		 * and is nonzero before self testing and integrity testing
+		 * has finished. However, the difference is theoretical
+		 * since this file will not even be created until the
+		 * testing has completed.
+		 */
+		.data		= &fips_operational,
+		.maxlen		= sizeof(int),
+		.mode		= 0444,
+		.proc_handler	= proc_dointvec,
+	},
+	{
+		.procname	= "fips_name",
+		.data		= &fips_name,
+		.maxlen		= sizeof(fips_name),
+		.mode		= 0444,
+		.proc_handler	= proc_dostring,
+	},
+	{
+		.procname	= "fips_version",
+		.data		= &fips_version,
+		.maxlen		= sizeof(fips_version),
+		.mode		= 0444,
+		.proc_handler	= proc_dostring,
+	},
+	/*
+	 * Helper file for dracut that always returns "1" to indicate
+	 * that no userspace help is needed to get the FIPS module
+	 * operational.
+	 */
+	{
+		.procname	= "fips_standalone",
+		.data		= &fips_standalone,
+		.maxlen		= sizeof(fips_standalone),
+		.mode		= 0444,
+		.proc_handler	= proc_dointvec,
+	},
+};
+
+static struct ctl_table_header *crypto_sysctls;
+
+static int __init check_nonfips_alg_list(void)
+{
+	extern struct list_head nonfips_crypto_alg_list;
+
+	struct crypto_alg *q;
+	int err = 0;
+
+	list_for_each_entry(q, &nonfips_crypto_alg_list, cra_list) {
+		pr_err("FIPS 140: found registered non-FIPS algorithm %s (%s)\n", q->cra_name, q->cra_driver_name);
+		err = 1;
+	}
+
+	return err;
+}
+
+static int __init run_initcalls(void)
+{
+	extern unsigned long __fips_initcalls_start[];
+	extern unsigned long __fips_initcalls_end[];
+
+	for (unsigned long *initcall = __fips_initcalls_start;
+		initcall != __fips_initcalls_end; ++initcall)
+	{
+		int ret;
+		initcall_t fn;
+
+		fn = (initcall_t) *initcall;
+		pr_info("FIPS 140: calling %pS\n", fn);
+
+		ret = fn();
+		if (!ret || ret == -ENODEV)
+			continue;
+
+		panic("FIPS 140: initcall %pS failed: %d\n", fn, ret);
+	}
+
+	return 0;
+}
+
+static int __init fips140_init(void)
+{
+	pr_info("FIPS 140: %s version %s\n", fips_name, fips_version);
+
+	if (check_nonfips_alg_list())
+		panic("FIPS 140: found registered non-FIPS algorithms\n");
+
+	run_initcalls();
+
+	if (verify_integrity())
+		panic("FIPS 140: integrity check failed\n");
+
+	crypto_sysctls = register_sysctl("crypto", crypto_sysctl_table);
+	if (!crypto_sysctls)
+		panic("FIPS 140: failed to register sysctls");
+
+	fips_operational = 1;
+
+	pr_info("FIPS 140: operational\n");
+	return 0;
+}
+module_init(fips140_init);
+
+MODULE_DESCRIPTION("FIPS 140 Cryptographic Module");
+MODULE_LICENSE("GPL");
diff --git a/fips140/fips140.lds b/fips140/fips140.lds
new file mode 100644
index 000000000000..78ac3fa7a7db
--- /dev/null
+++ b/fips140/fips140.lds
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+SECTIONS {
+	.init.data : {
+		__fips_initcalls_start = .;
+		*(.fips_initcall)
+		__fips_initcalls_end = .;
+       }
+}
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 103/104] Documentation/crypto: add fips140.rst
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum,
	Jonathan Corbet, linux-doc
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

Add documentation for the FIPS140 standalone module.

Cc: Jonathan Corbet <corbet@lwn.net>
Cc: linux-doc@vger.kernel.org
Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 Documentation/crypto/fips140.rst | 231 +++++++++++++++++++++++++++++++
 Documentation/crypto/index.rst   |   1 +
 2 files changed, 232 insertions(+)
 create mode 100644 Documentation/crypto/fips140.rst

diff --git a/Documentation/crypto/fips140.rst b/Documentation/crypto/fips140.rst
new file mode 100644
index 000000000000..14a7fb7a69ed
--- /dev/null
+++ b/Documentation/crypto/fips140.rst
@@ -0,0 +1,231 @@
+=========================
+FIPS140 standalone module
+=========================
+
+:Author: Vegard Nossum <vegard.nossum@oracle.com>
+
+
+Target audience
+===============
+
+This document is primarily meant for Linux distribution developers and
+maintainers. It may also be interesting for kernel developers
+contributing to the kernel's crypto code as it explains some of the
+concepts and rationale behind the architecture of the crypto code and
+how FIPS support is implemented.
+
+
+Introduction
+============
+
+FIPS 140-3 is a Federal Information Protection Standard, "Security
+Requirements for Cryptographic Modules", maintained by the US National
+Institute of Standards and Technology (NIST). [#fips140]_
+
+Binary implementation of specific approved cryptographic algorithms
+can be certified as part of the Cryptographic Module Validation
+Program (CMVP). In practice, the certification process includes both
+source and binary code, though the end result is a certification
+attached to the binary code.
+
+Having FIPS 140-3 certification is a requirement for running in many
+secure contexts -- many Linux distros certify their kernels in order
+to satisfy these requirements.
+
+Many distros have certified the entire kernel as a "FIPS module" (not
+to be confused with kernel modules). Unfortunately, this means that
+one cannot change any part of the kernel without invalidating the
+certification. Moreover, certification is a costly process that can
+last up to or even more than 12 months.
+
+The FIPS 140 standalone module (AKA ``fips140.ko``) fixes this situation
+by allowing one to build the kernel's crypto code once and reuse it in
+subsequent builds, thus enabling the rest of the kernel to receive bug
+fixes and updates without invalidating the certification of the FIPS
+module.
+
+
+Design
+======
+
+Requirements:
+
+- the FIPS module must not impose a stable internal kernel API on
+  mainline or stable kernels
+- the FIPS module must be a single, contiguous binary file and its HMAC
+  (for easy verification)
+- all crypto algorithms and code must reside within the FIPS module
+- no crypto code in the FIPS module can be used before the FIPS module
+  has executed its self-tests
+- the FIPS module only comes into play when the kernel is booted with
+  ``fips=1``
+- source code should be shared between the kernel and the FIPS module
+  where possible
+
+In order to satisfy these requirements, we have settled on a design
+where the FIPS module duplicates the crypto API and all the algorithm
+implementations that are part of the FIPS module. To avoid source code
+duplication, we use symlinks from ``fips140/`` to the rest of the kernel
+tree and build this directory as an external module -- in other words,
+all the code and algorithms is built twice; once as part of vmlinux
+and/or regular (non-FIPS) kernel modules, and once as part of
+``fips140.ko``.
+
+To allow hot-swapping the crypto code (API + algorithms) at runtime
+(i.e. when ``fips=1`` is detected during boot), we wrap any exported
+symbols in C macros. These macros use static calls (see [#static_call]_)
+to patch any and all users of the crypto code to call the FIPS module's
+version of these functions instead of the functions in vmlinux.
+
+``fips140.ko`` is not really an ordinary kernel module -- it is not
+meant to be loaded with ``modprobe`` or ``insmod``; instead, it is
+embedded into the ``vmlinux`` image at build time. This avoid any
+chicken-and-egg issues around how to verify cryptographic signatures
+without using unverified crypto code. ``fips140.ko`` is loaded during
+early boot -- before any crypto code is used by the kernel.
+
+The code for the FIPS 140 standalone module is therefore split into
+two parts: the module itself (``fips140.ko``) and the loader
+(``crypto/fips140-loader.c``). The loader is **NOT** part of the module
+itself and is not covered by the certification; however, it is
+essentially just a wrapper around the kernel module loader that runs
+during early boot.
+
+We provide no explicit mechanisms to ensure compatibility between a
+precompiled FIPS module and the rest of the kernel; this is the
+responsibility of distros that choose to use the standalone FIPS module.
+
+
+Building
+========
+
+First off, ensure that ``CONFIG_CRYPTO_FIPS140_EXTMOD`` is enabled.
+
+Prepare for building out-of-tree module::
+
+  make modules_prepare
+
+Build fips140.ko as an out-of-tree module::
+
+  make M=fips140/ KBUILD_MODPOST_WARN=1
+  cp fips140/fips140.ko crypto/
+
+Generate fips140.hmac::
+
+  hmac_key=$(awk -F'"' '/^CONFIG_CRYPTO_FIPS140_HMAC_KEY=/{print $2}' .config)
+  openssl dgst -sha256 -hmac $hmac_key -binary -out crypto/fips140.hmac crypto/fips140.ko
+
+Build the rest of the kernel::
+
+  make
+
+
+Adopting a standaline FIPS module for your distro
+=================================================
+
+1. Carefully select which algorithms you want your FIPS module to
+   provide (``CONFIG_FIPS140_*`` and ``CONFIG_CRYPTO_FIPS140_*``
+   options)
+
+2. Integrate building ``fips140/`` as an out-of-tree module with the
+   build system used by your distro's package manager.
+
+   - You may want to strip and separate out debuginfo before copying
+     ``fips140.ko`` into ``crypto/``.
+   - You need a mechanism to save and reintroduce the precompiled
+     ``fips140.ko`` between builds.
+   - All of this "build support" infrastructure is out of scope for
+     mainline.
+
+3. Verify that the FIPS module satisfies your specific operational
+   requirements.
+
+4. Submit the FIPS module to the certifying lab.
+
+.. warning::
+   Mainline developers cannot and will not assist in getting a specific
+   FIPS module certified. The code provided in the mainline source tree
+   is intended to make certification of standalone FIPS modules easier,
+   but we do not guarantee that a build will be certifiable as-is out of
+   the box. Moreover, different distributions have different use cases,
+   different requirements, etc. and all of this influences the specifics
+   of any given FIPS module. Mainline developers will not be responsible
+   for the certification or certifiability of your FIPS module.
+
+
+Useful commands
+===============
+
+
+Extracting ``fips140.ko`` from ``vmlinux``
+------------------------------------------
+
+To extract ``fips140.ko`` and ``fips140.hmac`` from an existing
+``vmlinux`` build, use::
+
+  $ scripts/extract-fips140 /path/to/vmlinux
+  extracted fips140.ko
+  extracted fips140.hmac
+
+
+Verifying the ``fips140.ko`` HMAC digest
+----------------------------------------
+
+To verify the HMAC digest of ``fips140.ko``, use::
+
+  $ key="Sphinx of black quartz, judge my vow"
+  $ openssl dgst -sha256 -hmac "$key" -binary fips140.ko > fips140.hmac-computed
+  $ cmp -s fips140.hmac fips140.hmac-computed && echo ok
+  ok
+
+
+List the symbols used by ``fips140.ko``
+---------------------------------------
+
+To list the kernel symbols used by ``fips140.ko`` (useful for checking
+whether all the necessary crypto functions have been included in the
+module), use::
+
+  $ nm --undefined-only fips140.ko
+
+
+Quick crypto verification using AF_ALG
+--------------------------------------
+
+Testing whether the code works properly is fairly easy using Python
+and the ``AF_ALG`` interface, e.g.::
+
+  import socket
+
+  ALG_SET_KEY = 1
+
+  s = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)
+  s.bind(('hash', 'hmac(sha256)'))
+  s.setsockopt(socket.SOL_ALG, ALG_SET_KEY, b'x' * 16)
+
+  op, _ = s.accept()
+  op.sendall(b'x' * 32)
+  print(op.recv(32))
+
+
+Tracing the crypto code
+-----------------------
+
+Testing whether the FIPS module is used correctly can also be done
+using a combination of Python (as above) and ``trace-cmd`` like this::
+
+  $ sudo trace-cmd record -p function_graph -g __sys_bind python hmac.py
+  $ trace-cmd report
+
+
+Contributing
+============
+
+Patches welcome.
+
+
+References
+==========
+
+.. [#fips140] <https://csrc.nist.gov/pubs/fips/140-3/final>
+.. [#static_call] <https://lwn.net/Articles/815908/>
diff --git a/Documentation/crypto/index.rst b/Documentation/crypto/index.rst
index 100b47d049c0..e755ffd08d4f 100644
--- a/Documentation/crypto/index.rst
+++ b/Documentation/crypto/index.rst
@@ -27,3 +27,4 @@ for cryptographic use cases, as well as programming examples.
    descore-readme
    device_drivers/index
    krb5
+   fips140
-- 
2.39.3


^ permalink raw reply related

* [PATCH RFC 104/104] MAINTAINERS: add myself as FIPS140 standalone module maintainer
From: Vegard Nossum @ 2025-09-04 15:52 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Vegard Nossum
In-Reply-To: <20250904155216.460962-1-vegard.nossum@oracle.com>

As a gesture of accepting responsibility for the FIPS140 code, add
myself to MAINTAINERS. This is not meant to override or supersede
crypto maintainers and in fact I'd expect any FIPS140-related patches
to still go through the crypto tree(s). I encourage others with an
interest in the long term maintenance of the FIPS140 code to add
themselves to this entry as well.

Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Biggers <ebiggers@kernel.org>
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
---
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index daf520a13bdf..655c32f47343 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9467,6 +9467,16 @@ L:	linux-can@vger.kernel.org
 S:	Maintained
 F:	drivers/net/can/usb/f81604.c
 
+FIPS 140 STANDALONE MODULE SUPPORT
+M:	Vegard Nossum <vegard.nossum@oracle.com>
+L:	linux-crypto@vger.kernel.org
+S:	Maintained
+F:	crypto/fips140*
+F:	fips140/
+F:	include/crypto/api.h
+F:	scripts/extract-fips140
+F:	Documentation/crypto/fips140.rst
+
 FIREWIRE AUDIO DRIVERS and IEC 61883-1/6 PACKET STREAMING ENGINE
 M:	Clemens Ladisch <clemens@ladisch.de>
 M:	Takashi Sakamoto <o-takashi@sakamocchi.jp>
-- 
2.39.3


^ permalink raw reply related

* Re: [PATCH RFC 006/104] KEYS: trusted: eat -ENOENT from the crypto API
From: Linus Torvalds @ 2025-09-04 20:22 UTC (permalink / raw)
  To: Vegard Nossum
  Cc: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez, Ard Biesheuvel, Eric Biggers,
	Jason A . Donenfeld, Greg Kroah-Hartman, Wang, Jay,
	Nicolai Stange, Vladis Dronov, Stephan Mueller, Sami Tolvanen,
	linux-modules, Vijaykumar Hegde, Sriharsha Yadagudde, Sumit Garg,
	Jarkko Sakkinen
In-Reply-To: <20250904155216.460962-7-vegard.nossum@oracle.com>

On Thu, 4 Sept 2025 at 13:05, Vegard Nossum <vegard.nossum@oracle.com> wrote:
>
> However, since commit 9d50a25eeb05c ("crypto: testmgr - desupport SHA-1
> for FIPS 140") when booting with fips=1, the SHA-1 algorithm (or anything
> that uses it, like HMAC-SHA-1) will be unavailable.
>
> security/keys/trusted-keys/trusted_tpm1.c is hard-coded to use SHA-1 and
> will fail with -ENOENT when attempting to initialize the hash instance
> using the crypto API _if_ the hardware is available. This in turn causes
> the entire trusted.ko to fail to load.

Oh Christ.

Can we please just make that trusted_tpm1.c code use the sha1 library
code directly instead of going through the crypto layer to get it?
That would presumably neatly avoid the whole issue.

Eric - I haven't looked at how painful it is to just do conversions
like that - I assume it's a boilerplate thing and trivial to do if
you've one one. Please?

             Linus

^ permalink raw reply

* Re: [PATCH RFC 006/104] KEYS: trusted: eat -ENOENT from the crypto API
From: Eric Biggers @ 2025-09-04 20:37 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Vegard Nossum, Herbert Xu, David S. Miller, linux-crypto,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez, Ard Biesheuvel,
	Jason A . Donenfeld, Greg Kroah-Hartman, Wang, Jay,
	Nicolai Stange, Vladis Dronov, Stephan Mueller, Sami Tolvanen,
	linux-modules, Vijaykumar Hegde, Sriharsha Yadagudde, Sumit Garg,
	Jarkko Sakkinen
In-Reply-To: <CAHk-=wizcBV_yos1SZW9Zty7960TCeEE1t2qE_Wmm8CMoim60Q@mail.gmail.com>

On Thu, Sep 04, 2025 at 01:22:32PM -0700, Linus Torvalds wrote:
> On Thu, 4 Sept 2025 at 13:05, Vegard Nossum <vegard.nossum@oracle.com> wrote:
> >
> > However, since commit 9d50a25eeb05c ("crypto: testmgr - desupport SHA-1
> > for FIPS 140") when booting with fips=1, the SHA-1 algorithm (or anything
> > that uses it, like HMAC-SHA-1) will be unavailable.
> >
> > security/keys/trusted-keys/trusted_tpm1.c is hard-coded to use SHA-1 and
> > will fail with -ENOENT when attempting to initialize the hash instance
> > using the crypto API _if_ the hardware is available. This in turn causes
> > the entire trusted.ko to fail to load.
> 
> Oh Christ.
> 
> Can we please just make that trusted_tpm1.c code use the sha1 library
> code directly instead of going through the crypto layer to get it?
> That would presumably neatly avoid the whole issue.
> 
> Eric - I haven't looked at how painful it is to just do conversions
> like that - I assume it's a boilerplate thing and trivial to do if
> you've one one. Please?

I already got to this one:
https://lore.kernel.org/r/20250809171941.5497-3-ebiggers@kernel.org/

And yes, as usual it's much simpler:

     2 files changed, 36 insertions(+), 190 deletions(-)

(And faster too, since the library APIs have much less overhead.)

Jarkko is taking it for 6.18, I believe.

- Eric

^ permalink raw reply

* Re: [PATCH RFC 026/104] crypto: fips140: convert lib/crypto/sha256.c to using crypto API wrappers
From: Eric Biggers @ 2025-09-04 21:29 UTC (permalink / raw)
  To: Vegard Nossum
  Cc: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez, Ard Biesheuvel, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules
In-Reply-To: <20250904155216.460962-27-vegard.nossum@oracle.com>

On Thu, Sep 04, 2025 at 05:50:58PM +0200, Vegard Nossum wrote:
>  /**
>   * sha256() - Compute SHA-256 message digest in one shot
> @@ -373,7 +392,9 @@ void sha256_final(struct sha256_ctx *ctx, u8 out[SHA256_DIGEST_SIZE]);
>   *
>   * Context: Any context.
>   */
> -void sha256(const u8 *data, size_t len, u8 out[SHA256_DIGEST_SIZE]);
> +DECLARE_CRYPTO_API(sha256, void,
> +	(const u8 *data, size_t len, u8 out[SHA256_DIGEST_SIZE]),
> +	(data, len, out));

This makes all these function declarations awfully hard to read...  If
fips140.ko is really going to be supported at all, perhaps it would make
more sense for the override to happen in the function implementations?
E.g. the first line of the sha256() function implementation would be
FIPS_CALL(sha256, data, len, out) or similar, and that would either do
nothing, or call the sha256() from fips140.ko and return.

I think that would be *slightly* less invasive.  Though of course it
doesn't get around the problem that the fips140.ko override support
still has to be handled individually for every function...

- Eric

^ permalink raw reply

* Re: [PATCH RFC 097/104] crypto: fips140: manual fixups for lib/crypto/sha256.c
From: Eric Biggers @ 2025-09-04 21:35 UTC (permalink / raw)
  To: Vegard Nossum
  Cc: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez, Ard Biesheuvel, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules
In-Reply-To: <20250904155216.460962-98-vegard.nossum@oracle.com>

On Thu, Sep 04, 2025 at 05:52:09PM +0200, Vegard Nossum wrote:
> Don't build arch-specific SHA256 code yet when building the FIPS 140
> standalone module.

I'm afraid you can't just not support the architecture-optimized crypto
code.  It's usually much faster than the generic C code (often more than
an order of magnitude faster), and it's really important to include.
This applies to all algorithms.

- Eric

^ permalink raw reply

* Re: [PATCH RFC 103/104] Documentation/crypto: add fips140.rst
From: Randy Dunlap @ 2025-09-04 22:14 UTC (permalink / raw)
  To: Vegard Nossum, Herbert Xu, David S. Miller, linux-crypto,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Jonathan Corbet,
	linux-doc
In-Reply-To: <20250904155216.460962-104-vegard.nossum@oracle.com>



On 9/4/25 8:52 AM, Vegard Nossum wrote:
> Add documentation for the FIPS140 standalone module.
> 
> Cc: Jonathan Corbet <corbet@lwn.net>
> Cc: linux-doc@vger.kernel.org
> Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
> ---
>  Documentation/crypto/fips140.rst | 231 +++++++++++++++++++++++++++++++
>  Documentation/crypto/index.rst   |   1 +
>  2 files changed, 232 insertions(+)
>  create mode 100644 Documentation/crypto/fips140.rst
> 
> diff --git a/Documentation/crypto/fips140.rst b/Documentation/crypto/fips140.rst
> new file mode 100644
> index 000000000000..14a7fb7a69ed
> --- /dev/null
> +++ b/Documentation/crypto/fips140.rst
> @@ -0,0 +1,231 @@
> +=========================
> +FIPS140 standalone module
> +=========================
> +
> +:Author: Vegard Nossum <vegard.nossum@oracle.com>
> +
> +
> +Target audience
> +===============
> +
> +This document is primarily meant for Linux distribution developers and
> +maintainers. It may also be interesting for kernel developers
> +contributing to the kernel's crypto code as it explains some of the
> +concepts and rationale behind the architecture of the crypto code and
> +how FIPS support is implemented.
> +
> +
> +Introduction
> +============
> +
> +FIPS 140-3 is a Federal Information Protection Standard, "Security
> +Requirements for Cryptographic Modules", maintained by the US National
> +Institute of Standards and Technology (NIST). [#fips140]_
> +
> +Binary implementation of specific approved cryptographic algorithms
> +can be certified as part of the Cryptographic Module Validation
> +Program (CMVP). In practice, the certification process includes both
> +source and binary code, though the end result is a certification
> +attached to the binary code.
> +
> +Having FIPS 140-3 certification is a requirement for running in many
> +secure contexts -- many Linux distros certify their kernels in order
> +to satisfy these requirements.
> +
> +Many distros have certified the entire kernel as a "FIPS module" (not
> +to be confused with kernel modules). Unfortunately, this means that
> +one cannot change any part of the kernel without invalidating the
> +certification. Moreover, certification is a costly process that can
> +last up to or even more than 12 months.
> +
> +The FIPS 140 standalone module (AKA ``fips140.ko``) fixes this situation
> +by allowing one to build the kernel's crypto code once and reuse it in
> +subsequent builds, thus enabling the rest of the kernel to receive bug
> +fixes and updates without invalidating the certification of the FIPS
> +module.
> +
> +
> +Design
> +======
> +
> +Requirements:
> +
> +- the FIPS module must not impose a stable internal kernel API on
> +  mainline or stable kernels
> +- the FIPS module must be a single, contiguous binary file and its HMAC
> +  (for easy verification)
> +- all crypto algorithms and code must reside within the FIPS module
> +- no crypto code in the FIPS module can be used before the FIPS module
> +  has executed its self-tests
> +- the FIPS module only comes into play when the kernel is booted with
> +  ``fips=1``
> +- source code should be shared between the kernel and the FIPS module
> +  where possible
> +
> +In order to satisfy these requirements, we have settled on a design
> +where the FIPS module duplicates the crypto API and all the algorithm
> +implementations that are part of the FIPS module. To avoid source code
> +duplication, we use symlinks from ``fips140/`` to the rest of the kernel
> +tree and build this directory as an external module -- in other words,
> +all the code and algorithms is built twice; once as part of vmlinux
> +and/or regular (non-FIPS) kernel modules, and once as part of
> +``fips140.ko``.
> +
> +To allow hot-swapping the crypto code (API + algorithms) at runtime
> +(i.e. when ``fips=1`` is detected during boot), we wrap any exported
> +symbols in C macros. These macros use static calls (see [#static_call]_)
> +to patch any and all users of the crypto code to call the FIPS module's
> +version of these functions instead of the functions in vmlinux.
> +
> +``fips140.ko`` is not really an ordinary kernel module -- it is not
> +meant to be loaded with ``modprobe`` or ``insmod``; instead, it is
> +embedded into the ``vmlinux`` image at build time. This avoid any
> +chicken-and-egg issues around how to verify cryptographic signatures
> +without using unverified crypto code. ``fips140.ko`` is loaded during
> +early boot -- before any crypto code is used by the kernel.

Hm, I was going to look at how that is done, but I cannot find any
downloadable fips140 source code. Is it available for free download
somewhere?

Is it GPL-v2 licensed?


> +
> +The code for the FIPS 140 standalone module is therefore split into
> +two parts: the module itself (``fips140.ko``) and the loader
> +(``crypto/fips140-loader.c``). The loader is **NOT** part of the module
> +itself and is not covered by the certification; however, it is
> +essentially just a wrapper around the kernel module loader that runs
> +during early boot.
> +
> +We provide no explicit mechanisms to ensure compatibility between a
> +precompiled FIPS module and the rest of the kernel; this is the
> +responsibility of distros that choose to use the standalone FIPS module.
> +
> +
> +Building
> +========
> +
> +First off, ensure that ``CONFIG_CRYPTO_FIPS140_EXTMOD`` is enabled.
> +
> +Prepare for building out-of-tree module::
> +
> +  make modules_prepare
> +
> +Build fips140.ko as an out-of-tree module::
> +
> +  make M=fips140/ KBUILD_MODPOST_WARN=1
> +  cp fips140/fips140.ko crypto/
> +
> +Generate fips140.hmac::
> +
> +  hmac_key=$(awk -F'"' '/^CONFIG_CRYPTO_FIPS140_HMAC_KEY=/{print $2}' .config)
> +  openssl dgst -sha256 -hmac $hmac_key -binary -out crypto/fips140.hmac crypto/fips140.ko
> +
> +Build the rest of the kernel::
> +
> +  make
> +
> +
> +Adopting a standaline FIPS module for your distro
> +=================================================
> +
> +1. Carefully select which algorithms you want your FIPS module to
> +   provide (``CONFIG_FIPS140_*`` and ``CONFIG_CRYPTO_FIPS140_*``
> +   options)
> +
> +2. Integrate building ``fips140/`` as an out-of-tree module with the
> +   build system used by your distro's package manager.
> +
> +   - You may want to strip and separate out debuginfo before copying
> +     ``fips140.ko`` into ``crypto/``.
> +   - You need a mechanism to save and reintroduce the precompiled
> +     ``fips140.ko`` between builds.
> +   - All of this "build support" infrastructure is out of scope for
> +     mainline.
> +
> +3. Verify that the FIPS module satisfies your specific operational
> +   requirements.
> +
> +4. Submit the FIPS module to the certifying lab.
> +
> +.. warning::
> +   Mainline developers cannot and will not assist in getting a specific
> +   FIPS module certified. The code provided in the mainline source tree
> +   is intended to make certification of standalone FIPS modules easier,
> +   but we do not guarantee that a build will be certifiable as-is out of
> +   the box. Moreover, different distributions have different use cases,
> +   different requirements, etc. and all of this influences the specifics
> +   of any given FIPS module. Mainline developers will not be responsible
> +   for the certification or certifiability of your FIPS module.
> +
> +
> +Useful commands
> +===============
> +
> +
> +Extracting ``fips140.ko`` from ``vmlinux``
> +------------------------------------------
> +
> +To extract ``fips140.ko`` and ``fips140.hmac`` from an existing
> +``vmlinux`` build, use::
> +
> +  $ scripts/extract-fips140 /path/to/vmlinux
> +  extracted fips140.ko
> +  extracted fips140.hmac
> +
> +
> +Verifying the ``fips140.ko`` HMAC digest
> +----------------------------------------
> +
> +To verify the HMAC digest of ``fips140.ko``, use::
> +
> +  $ key="Sphinx of black quartz, judge my vow"
> +  $ openssl dgst -sha256 -hmac "$key" -binary fips140.ko > fips140.hmac-computed
> +  $ cmp -s fips140.hmac fips140.hmac-computed && echo ok
> +  ok
> +
> +
> +List the symbols used by ``fips140.ko``
> +---------------------------------------
> +
> +To list the kernel symbols used by ``fips140.ko`` (useful for checking
> +whether all the necessary crypto functions have been included in the
> +module), use::
> +
> +  $ nm --undefined-only fips140.ko
> +
> +
> +Quick crypto verification using AF_ALG
> +--------------------------------------
> +
> +Testing whether the code works properly is fairly easy using Python
> +and the ``AF_ALG`` interface, e.g.::
> +
> +  import socket
> +
> +  ALG_SET_KEY = 1
> +
> +  s = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)
> +  s.bind(('hash', 'hmac(sha256)'))
> +  s.setsockopt(socket.SOL_ALG, ALG_SET_KEY, b'x' * 16)
> +
> +  op, _ = s.accept()
> +  op.sendall(b'x' * 32)
> +  print(op.recv(32))
> +
> +
> +Tracing the crypto code
> +-----------------------
> +
> +Testing whether the FIPS module is used correctly can also be done
> +using a combination of Python (as above) and ``trace-cmd`` like this::
> +
> +  $ sudo trace-cmd record -p function_graph -g __sys_bind python hmac.py
> +  $ trace-cmd report
> +
> +
> +Contributing
> +============
> +
> +Patches welcome.

to what/where?

> +
> +
> +References
> +==========
> +
> +.. [#fips140] <https://csrc.nist.gov/pubs/fips/140-3/final>
> +.. [#static_call] <https://lwn.net/Articles/815908/>

Where are the other 103 patches?

thanks.
-- 
~Randy


^ permalink raw reply

* Re: [PATCH RFC 097/104] crypto: fips140: manual fixups for lib/crypto/sha256.c
From: Vegard Nossum @ 2025-09-04 22:20 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Herbert Xu, David S. Miller, linux-crypto, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez, Ard Biesheuvel, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules
In-Reply-To: <20250904213521.GE854551@google.com>


On 04/09/2025 23:35, Eric Biggers wrote:
> On Thu, Sep 04, 2025 at 05:52:09PM +0200, Vegard Nossum wrote:
>> Don't build arch-specific SHA256 code yet when building the FIPS 140
>> standalone module.

Emphasis on "yet" :-)

> I'm afraid you can't just not support the architecture-optimized crypto
> code.  It's usually much faster than the generic C code (often more than
> an order of magnitude faster), and it's really important to include.
> This applies to all algorithms.

We can easily support it with the exact same method as the generic code
and in fact we do this for the 6.12-based Oracle kernel. I noticed that
the architecture-specific crypto has been reworked since 6.12 so I
decided to drop it to keep the patch set a bit smaller; after all, this
still results in something that can be certified.

I think we can start with the x86 and arm64 code (and only the subset
which is NIST approved)? If anybody has a need for anything else, I can
add it to the patch set on an as-needed basis, let me know what you
would like to see there.

(It might be a bit annoying to deal with the CONFIG_ options for the
arch-specific stuff, but I think we can handle it.)


Vegard

^ permalink raw reply

* Re: [PATCH RFC 103/104] Documentation/crypto: add fips140.rst
From: Vegard Nossum @ 2025-09-04 22:28 UTC (permalink / raw)
  To: Randy Dunlap, Herbert Xu, David S. Miller, linux-crypto,
	Luis Chamberlain, Petr Pavlu, Daniel Gomez
  Cc: Ard Biesheuvel, Eric Biggers, Jason A . Donenfeld,
	Greg Kroah-Hartman, Wang, Jay, Nicolai Stange, Vladis Dronov,
	Stephan Mueller, Sami Tolvanen, linux-modules, Jonathan Corbet,
	linux-doc
In-Reply-To: <de23961f-ae2f-414b-8473-ce9eb17646fb@infradead.org>


On 05/09/2025 00:14, Randy Dunlap wrote:
> On 9/4/25 8:52 AM, Vegard Nossum wrote:
>> +``fips140.ko`` is not really an ordinary kernel module -- it is not
>> +meant to be loaded with ``modprobe`` or ``insmod``; instead, it is
>> +embedded into the ``vmlinux`` image at build time. This avoid any
>> +chicken-and-egg issues around how to verify cryptographic signatures
>> +without using unverified crypto code. ``fips140.ko`` is loaded during
>> +early boot -- before any crypto code is used by the kernel.
> 
> Hm, I was going to look at how that is done, but I cannot find any
> downloadable fips140 source code. Is it available for free download
> somewhere?
> 
> Is it GPL-v2 licensed?

Yes, it's the existing kernel crypto code but built as an external/out-
of-tree module.

>> +References
>> +==========
>> +
>> +.. [#fips140] <https://csrc.nist.gov/pubs/fips/140-3/final>
>> +.. [#static_call] <https://lwn.net/Articles/815908/>
> 
> Where are the other 103 patches?

Sorry, I guess git-send-email doesn't add everybody from individual
patches to the entire series. Here's the top of the thread with more of
an intro:

https://lore.kernel.org/all/20250904155216.460962-1-vegard.nossum@oracle.com/


Vegard

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox