From: Jay Wang <wanjay@amazon.com>
To: Herbert Xu <herbert@gondor.apana.org.au>,
"David S . Miller" <davem@davemloft.net>,
<linux-crypto@vger.kernel.org>
Cc: Jay Wang <jay.wang.upstream@gmail.com>,
Vegard Nossum <vegard.nossum@oracle.com>,
Nicolai Stange <nstange@suse.de>,
Ilia Okomin <ilya.okomin@oracle.com>,
Catalin Marinas <catalin.marinas@arm.com>,
"Will Deacon" <will@kernel.org>,
Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
Borislav Petkov <bp@alien8.de>,
Luis Chamberlain <mcgrof@kernel.org>,
Petr Pavlu <petr.pavlu@suse.com>,
Nathan Chancellor <nathan@kernel.org>,
Nicolas Schier <nsc@kernel.org>,
<linux-arm-kernel@lists.infradead.org>, <x86@kernel.org>,
<linux-kbuild@vger.kernel.org>, <linux-modules@vger.kernel.org>
Subject: [PATCH 11/17] Allow selective crypto module loading at boot based on FIPS mode
Date: Thu, 12 Feb 2026 02:42:15 +0000 [thread overview]
Message-ID: <20260212024228.6267-12-wanjay@amazon.com> (raw)
In-Reply-To: <20260212024228.6267-1-wanjay@amazon.com>
Introduce CONFIG_CRYPTO_FIPS140_DUAL_VERSION to enable dual crypto module
versions within a single kernel build, allowing boot-time selection based on
FIPS mode status.
This configuration allows FIPS mode to use pre-compiled certified crypto
modules from external source, while regular mode uses freshly built kernel
crypto implementation for optimal performance and latest security features.
The implementation embeds both certified and non-certified fips140.ko
modules in vmlinux and adds new linker sections (.nonfips140_embedded,
.nonfips140_btf) for non-FIPS crypto module storage. It modifies
fips140-loader.c to select appropriate module at boot time based on
fips_enabled flag, updates build system to generate and embed both module
versions, and includes BTF support for both module variants when
CONFIG_DEBUG_INFO_BTF_MODULES is enabled.
For modular crypto algorithms (e.g., aes.ko), they are not automatically
duplicated. They should either be built-in to fips140.ko for automatic
duplication, or require userspace utilities like modprobe to handle
proper isolation between FIPS and non-FIPS modular crypto implementations.
Signed-off-by: Jay Wang <wanjay@amazon.com>
---
Makefile | 13 +++++++++++++
arch/arm64/kernel/vmlinux.lds.S | 16 ++++++++++++++++
arch/x86/kernel/vmlinux.lds.S | 16 ++++++++++++++++
crypto/fips140/Kconfig | 24 ++++++++++++++++++++++++
crypto/fips140/Makefile | 5 ++++-
crypto/fips140/fips140-loader.c | 28 +++++++++++++++++++++++++++-
scripts/Makefile.vmlinux | 29 +++++++++++++++++++++++++++--
scripts/link-vmlinux.sh | 6 ++++++
8 files changed, 133 insertions(+), 4 deletions(-)
diff --git a/Makefile b/Makefile
index 7530009d8081..b3a9f7a17ddf 100644
--- a/Makefile
+++ b/Makefile
@@ -1293,6 +1293,9 @@ vmlinux: private _LDFLAGS_vmlinux := $(LDFLAGS_vmlinux)
vmlinux: export LDFLAGS_vmlinux = $(_LDFLAGS_vmlinux)
ifdef CONFIG_CRYPTO_FIPS140_EXTMOD
vmlinux: crypto/fips140/fips140-embedded.o crypto/fips140/fips140-digest.o
+ifdef CONFIG_CRYPTO_FIPS140_DUAL_VERSION
+vmlinux: crypto/fips140/nonfips140-embedded.o
+endif
fips140_build = .
ifeq ($(CONFIG_CRYPTO_FIPS140_EXTMOD_SOURCE),y)
fips140_build = fips140_build
@@ -1302,6 +1305,14 @@ crypto/fips140/fips140-embedded.o: fips140-ready
@$(LD) -r -b binary -o $@ $(fips140_build)/crypto/fips140/fips140.ko
@$(OBJCOPY) --rename-section .data=.fips140_module_data $@
+ifdef CONFIG_CRYPTO_FIPS140_DUAL_VERSION
+crypto/fips140/nonfips140-embedded.o: fips140-ready
+ @echo " LD $@"
+ @$(LD) -r -b binary -o $@ crypto/fips140/fips140.ko
+ @$(OBJCOPY) --rename-section .data=.nonfips140_module_data \
+ --prefix-symbols nonfips140_ $@
+endif
+
crypto/fips140/.fips140.hmac: crypto/fips140/fips140-embedded.o
@echo " HMAC $@"
@hmac_key=$$(awk -F'"' '/^CONFIG_CRYPTO_FIPS140_HMAC_KEY=/{print $$2}' .config); \
@@ -1319,9 +1330,11 @@ fips140-ready: crypto/fips140/fips140.o crypto/fips140/.fips140.order crypto/fip
ifneq ($(KBUILD_MODPOST_NOFINAL),1)
$(Q)$(MAKE) KBUILD_MODULES=y crypto-module-gen=1 -f $(srctree)/scripts/Makefile.modfinal
endif
+ifndef CONFIG_CRYPTO_FIPS140_DUAL_VERSION
ifeq ($(CONFIG_CRYPTO_FIPS140_EXTMOD_SOURCE),y)
cp "$(fips140_build)/crypto/fips140/fips140.ko" crypto/fips140/fips140.ko;
endif
+endif
# Generate fips140.o from crypto-module.a files
crypto/fips140/fips140.o: crypto-module.a FORCE
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 41223fa3f14e..0722e07c5551 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -222,6 +222,22 @@ SECTIONS
__stop_fips140_btf = .;
}
#endif
+#ifdef CONFIG_CRYPTO_FIPS140_DUAL_VERSION
+ .nonfips140_embedded : {
+ . = ALIGN(8);
+ _binary_nonfips140_ko_start = .;
+ KEEP(*(.nonfips140_module_data))
+ _binary_nonfips140_ko_end = .;
+ }
+#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
+ .nonfips140_btf : {
+ . = ALIGN(8);
+ __start_nonfips140_btf = .;
+ KEEP(*(.nonfips140_btf))
+ __stop_nonfips140_btf = .;
+ }
+#endif
+#endif
#endif
HYPERVISOR_RODATA_SECTIONS
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index e07c1b5c52cf..aa1b97d7aabd 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -193,6 +193,22 @@ SECTIONS
__stop_fips140_btf = .;
}
#endif
+#ifdef CONFIG_CRYPTO_FIPS140_DUAL_VERSION
+ .nonfips140_embedded : AT(ADDR(.nonfips140_embedded) - LOAD_OFFSET) {
+ . = ALIGN(8);
+ _binary_nonfips140_ko_start = .;
+ KEEP(*(.nonfips140_module_data))
+ _binary_nonfips140_ko_end = .;
+ }
+#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
+ .nonfips140_btf : AT(ADDR(.nonfips140_btf) - LOAD_OFFSET) {
+ . = ALIGN(8);
+ __start_nonfips140_btf = .;
+ KEEP(*(.nonfips140_btf))
+ __stop_nonfips140_btf = .;
+ }
+#endif
+#endif
#endif
/* Data */
diff --git a/crypto/fips140/Kconfig b/crypto/fips140/Kconfig
index 68b877f0dbab..7d8997aa1094 100644
--- a/crypto/fips140/Kconfig
+++ b/crypto/fips140/Kconfig
@@ -42,3 +42,27 @@ config CRYPTO_FIPS140_EXTMOD_SOURCE
- fips140_build/crypto/sha256.ko
If unsure, say N.
+config CRYPTO_FIPS140_DUAL_VERSION
+ bool "Enable dual crypto versions for FIPS and regular modes"
+ depends on CRYPTO_FIPS140_EXTMOD && CRYPTO_FIPS140_EXTMOD_SOURCE
+ default n
+ help
+ Enable keeping two crypto module versions in the same kernel build
+ for boot-time switching based on FIPS mode status. This allows:
+ - Non-FIPS users: Get latest crypto algorithms built from current
+ kernel sources for optimal performance and security features
+ - FIPS users: Get pre-compiled certified crypto modules that have
+ undergone formal validation and certification processes
+
+ When enabled:
+
+ For core fips140.ko:
+ - FIPS mode: Uses certified module from CRYPTO_FIPS140_EXTMOD_SOURCE
+ - Regular mode: Uses freshly built kernel crypto implementation
+
+ For modular algorithms (e.g., aes.ko), they are not duplicated
+ automatically. Either make them built-in to be included into
+ fips140.ko for automatic duplication, or require OS utilities such
+ as `modprobe` to correctly isolate modular cryptos in filesystems.
+
+ If unsure, say N.
\ No newline at end of file
diff --git a/crypto/fips140/Makefile b/crypto/fips140/Makefile
index ac8ae42eb0fa..c99bf2948432 100644
--- a/crypto/fips140/Makefile
+++ b/crypto/fips140/Makefile
@@ -15,4 +15,7 @@ $(obj)/fips140-api-fips.o: $(src)/fips140-api.c FORCE
CFLAGS_fips140-api-main.o += -I$(srctree)
CFLAGS_fips140-api-fips.o += -I$(srctree)
-clean-files:= .fips140.order .fips140.symvers .fips140.hmac .fips140.ko.btf
\ No newline at end of file
+clean-files:= .fips140.order .fips140.symvers .fips140.hmac .fips140.ko.btf
+ifdef CONFIG_CRYPTO_FIPS140_DUAL_VERSION
+clean-files += .nonfips140.ko.btf
+endif
\ No newline at end of file
diff --git a/crypto/fips140/fips140-loader.c b/crypto/fips140/fips140-loader.c
index 13c82ffdc65b..826075928723 100644
--- a/crypto/fips140/fips140-loader.c
+++ b/crypto/fips140/fips140-loader.c
@@ -11,12 +11,20 @@
#include <linux/elf.h>
#include <linux/kthread.h>
#include <linux/wait.h>
+#include <linux/fips.h>
extern const u8 _binary_fips140_ko_start[];
extern const u8 _binary_fips140_ko_end[];
extern const u8 _binary_fips140_hmac_start[];
extern const u8 _binary_fips140_hmac_end[];
+#ifdef CONFIG_CRYPTO_FIPS140_DUAL_VERSION
+/* For non-FIPS mode: no module signature/HMAC is required,
+ * so only include binary start/end address without module sig address */
+extern const u8 _binary_nonfips140_ko_start[];
+extern const u8 _binary_nonfips140_ko_end[];
+#endif
+
const u8 *_binary_crypto_ko_start;
EXPORT_SYMBOL_GPL(_binary_crypto_ko_start);
const u8 *_binary_crypto_ko_end;
@@ -29,6 +37,10 @@ EXPORT_SYMBOL_GPL(_binary_crypto_hmac_end);
#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
extern const u8 __start_fips140_btf[];
extern const u8 __stop_fips140_btf[];
+#ifdef CONFIG_CRYPTO_FIPS140_DUAL_VERSION
+extern const u8 __start_nonfips140_btf[];
+extern const u8 __stop_nonfips140_btf[];
+#endif
const u8 *__start_crypto_btf;
const u8 *__stop_crypto_btf;
#endif
@@ -49,11 +61,25 @@ static void load_prepare(void)
_binary_crypto_ko_end = _binary_fips140_ko_end;
_binary_crypto_hmac_start = _binary_fips140_hmac_start;
_binary_crypto_hmac_end = _binary_fips140_hmac_end;
-
+
#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
__start_crypto_btf = __start_fips140_btf;
__stop_crypto_btf = __stop_fips140_btf;
#endif
+
+#ifdef CONFIG_CRYPTO_FIPS140_DUAL_VERSION
+ if (!fips_enabled) {
+ _binary_crypto_ko_start = _binary_nonfips140_ko_start;
+ _binary_crypto_ko_end = _binary_nonfips140_ko_end;
+ _binary_crypto_hmac_start = NULL;
+ _binary_crypto_hmac_end = NULL;
+
+#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
+ __start_crypto_btf = __start_nonfips140_btf;
+ __stop_crypto_btf = __stop_nonfips140_btf;
+#endif
+ }
+#endif
}
static int __init fips_loader_init(void)
diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux
index b30d65f8b6b3..996d016e518c 100644
--- a/scripts/Makefile.vmlinux
+++ b/scripts/Makefile.vmlinux
@@ -81,7 +81,18 @@ ifdef CONFIG_DEBUG_INFO_BTF_MODULES
cp crypto/fips140/.fips140.ko.btf crypto/fips140/.fips140.ko.btf.first; \
rm -f crypto/fips140/fips140.ko.tmp; \
$(LD) -r -b binary -o crypto/fips140/fips140_btf.o crypto/fips140/.fips140.ko.btf; \
- $(OBJCOPY) --rename-section .data=.fips140_btf crypto/fips140/fips140_btf.o; \
+ $(OBJCOPY) --rename-section .data=.fips140_btf crypto/fips140/fips140_btf.o
+ifdef CONFIG_CRYPTO_FIPS140_DUAL_VERSION
+ cmd_link_vmlinux += ; \
+ cp crypto/fips140/fips140.ko crypto/fips140/nonfips140.ko.tmp; \
+ LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base $@ crypto/fips140/nonfips140.ko.tmp; \
+ $(RESOLVE_BTFIDS) -b $@ crypto/fips140/nonfips140.ko.tmp; \
+ $(OBJCOPY) --dump-section=.BTF=crypto/fips140/.nonfips140.ko.btf crypto/fips140/nonfips140.ko.tmp; \
+ rm -f crypto/fips140/nonfips140.ko.tmp; \
+ $(LD) -r -b binary -o crypto/fips140/nonfips140_btf.o crypto/fips140/.nonfips140.ko.btf; \
+ $(OBJCOPY) --rename-section .data=.nonfips140_btf --prefix-symbols nonfips140_ crypto/fips140/nonfips140_btf.o
+endif
+ cmd_link_vmlinux += ; \
rm -f $@; \
FIPS140_BTF_RELINK=1 $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)" "$@"; \
cp $(fips140_build)/crypto/fips140/fips140.ko crypto/fips140/fips140.ko.tmp2; \
@@ -90,13 +101,27 @@ ifdef CONFIG_DEBUG_INFO_BTF_MODULES
$(OBJCOPY) --dump-section=.BTF=crypto/fips140/.fips140.ko.btf.second crypto/fips140/fips140.ko.tmp2; \
rm -f crypto/fips140/fips140.ko.tmp2; \
diff crypto/fips140/.fips140.ko.btf.first crypto/fips140/.fips140.ko.btf.second >/dev/null || echo "Module BTF differs"; \
- rm -f crypto/fips140/.fips140.ko.btf.first crypto/fips140/.fips140.ko.btf.second; \
+ rm -f crypto/fips140/.fips140.ko.btf.first crypto/fips140/.fips140.ko.btf.second
+ifdef CONFIG_CRYPTO_FIPS140_DUAL_VERSION
+ cmd_link_vmlinux += ; \
+ cp crypto/fips140/fips140.ko crypto/fips140/nonfips140.ko.tmp2; \
+ LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base $@ crypto/fips140/nonfips140.ko.tmp2; \
+ $(RESOLVE_BTFIDS) -b $@ crypto/fips140/nonfips140.ko.tmp2; \
+ $(OBJCOPY) --dump-section=.BTF=crypto/fips140/.nonfips140.ko.btf.second crypto/fips140/nonfips140.ko.tmp2; \
+ rm -f crypto/fips140/nonfips140.ko.tmp2; \
+ diff crypto/fips140/.nonfips140.ko.btf crypto/fips140/.nonfips140.ko.btf.second >/dev/null || echo "Nonfips140 Module BTF differs"; \
+ rm -f crypto/fips140/.nonfips140.ko.btf.second
+endif
+ cmd_link_vmlinux += ; \
$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
endif
endif
ifdef CONFIG_CRYPTO_FIPS140_EXTMOD
fips140-deps := crypto/fips140/fips140-embedded.o crypto/fips140/fips140-digest.o
+ifdef CONFIG_CRYPTO_FIPS140_DUAL_VERSION
+fips140-deps += crypto/fips140/nonfips140-embedded.o
+endif
endif
targets += vmlinux.unstripped .vmlinux.export.o
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 37c9b8576ec7..43a272e8d3a4 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -78,8 +78,14 @@ vmlinux_link()
if is_enabled CONFIG_CRYPTO_FIPS140_EXTMOD; then
objs="${objs} crypto/fips140/fips140-embedded.o crypto/fips140/fips140-digest.o"
+ if is_enabled CONFIG_CRYPTO_FIPS140_DUAL_VERSION; then
+ objs="${objs} crypto/fips140/nonfips140-embedded.o"
+ fi
if is_enabled CONFIG_DEBUG_INFO_BTF_MODULES && [ -n "${FIPS140_BTF_RELINK}" ] && [ -f crypto/fips140/fips140_btf.o ]; then
objs="${objs} crypto/fips140/fips140_btf.o"
+ if is_enabled CONFIG_CRYPTO_FIPS140_DUAL_VERSION && [ -f crypto/fips140/nonfips140_btf.o ]; then
+ objs="${objs} crypto/fips140/nonfips140_btf.o"
+ fi
fi
fi
--
2.47.3
next prev parent reply other threads:[~2026-02-12 2:45 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-12 2:42 [PATCH v1 00/17] crypto: Standalone crypto module (Series 1/4): Core implementation Jay Wang
2026-02-12 2:42 ` [PATCH 01/17] crypto: add Kconfig options for standalone crypto module Jay Wang
2026-02-12 2:42 ` [PATCH 02/17] crypto: add module entry for standalone crypto kernel module Jay Wang
2026-02-12 2:42 ` [PATCH 03/17] build: special compilation rule for building the standalone crypto module Jay Wang
2026-02-12 2:42 ` [PATCH 04/17] build: Add ELF marker for crypto-objs-m modules Jay Wang
2026-02-12 2:42 ` [PATCH 05/17] module: allow kernel module loading directly from memory Jay Wang
2026-02-12 2:42 ` [PATCH 06/17] crypto: add pluggable interface for builtin crypto modules Jay Wang
2026-02-12 2:42 ` [PATCH 07/17] crypto: dedicated ELF sections for collected crypto initcalls Jay Wang
2026-02-12 2:42 ` [PATCH 08/17] crypto: fips140: add crypto module loader Jay Wang
2026-02-12 2:42 ` [PATCH 09/17] build: embed the standalone crypto module into vmlinux Jay Wang
2026-02-12 2:42 ` [PATCH 10/17] build: add CONFIG_DEBUG_INFO_BTF_MODULES support for the standalone crypto kernel module Jay Wang
2026-02-12 2:42 ` Jay Wang [this message]
2026-02-12 2:42 ` [PATCH 12/17] Execute crypto initcalls during module initialization Jay Wang
2026-02-12 2:42 ` [PATCH 13/17] crypto/algapi.c: skip crypto_check_module_sig() for the standalone crypto module Jay Wang
2026-02-12 2:42 ` [PATCH 14/17] crypto: fips140: add module integrity self-check Jay Wang
2026-02-12 2:42 ` [PATCH 15/17] x86: crypto: to convert exported crypto symbols into pluggable interface for x86 cryptos Jay Wang
2026-02-12 2:42 ` [PATCH 16/17] arm64: crypto: to convert exported crypto symbols into pluggable interface for arm64 cryptos Jay Wang
2026-02-12 2:42 ` [PATCH 17/17] Add standalone crypto kernel module technical documentation Jay Wang
2026-02-25 1:55 ` Eric Biggers
2026-02-25 14:08 ` Christoph Hellwig
2026-02-25 17:35 ` Jay Wang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260212024228.6267-12-wanjay@amazon.com \
--to=wanjay@amazon.com \
--cc=bp@alien8.de \
--cc=catalin.marinas@arm.com \
--cc=davem@davemloft.net \
--cc=herbert@gondor.apana.org.au \
--cc=ilya.okomin@oracle.com \
--cc=jay.wang.upstream@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-modules@vger.kernel.org \
--cc=mcgrof@kernel.org \
--cc=mingo@redhat.com \
--cc=nathan@kernel.org \
--cc=nsc@kernel.org \
--cc=nstange@suse.de \
--cc=petr.pavlu@suse.com \
--cc=tglx@kernel.org \
--cc=vegard.nossum@oracle.com \
--cc=will@kernel.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox