Add a crypto module loader mechanism that loads a precompiled crypto
kernel module that is embedded in vmlinux image directly from memory
(whose address stored in _binary_fips140_ko_start/end) during early boot.

This is built based on Vegard Nossum <[email protected]> and
Saeed Mirzamohammadi <[email protected]>, the
fips_loader_init is picked up. But different from them, such loader is
not executed as arch_initcall_sync(), but rather as a thread along main
kernel init to ensure proper initialization sequencing (Details are in
later patch).

Signed-off-by: Jay Wang <[email protected]>
---
 crypto/fips140/fips140-loader.c | 55 +++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 crypto/fips140/fips140-loader.c

diff --git a/crypto/fips140/fips140-loader.c b/crypto/fips140/fips140-loader.c
new file mode 100644
index 000000000000..cbf5ff59eb2e
--- /dev/null
+++ b/crypto/fips140/fips140-loader.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * FIPS 140 Early Loader
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/printk.h>
+#include <linux/vmalloc.h>
+#include <linux/string.h>
+#include <linux/elf.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+
+extern const u8 _binary_fips140_ko_start[];
+extern const u8 _binary_fips140_ko_end[];
+const u8 *_binary_crypto_ko_start;
+EXPORT_SYMBOL_GPL(_binary_crypto_ko_start);
+const u8 *_binary_crypto_ko_end;
+EXPORT_SYMBOL_GPL(_binary_crypto_ko_end);
+
+/* Function to load crypto module from memory */
+extern int load_crypto_module_mem(const char *mem, size_t size);
+
+static void load_prepare(void)
+{
+       _binary_crypto_ko_start = _binary_fips140_ko_start;
+       _binary_crypto_ko_end = _binary_fips140_ko_end;
+}
+
+static int __init fips_loader_init(void)
+{
+       load_prepare();
+       
+       const void *ko_mem = _binary_crypto_ko_start;
+       size_t ko_size = _binary_crypto_ko_end - _binary_crypto_ko_start;
+       void *vmalloc_mem;
+       int ret;
+       
+       // Copy to vmalloc'd memory since load_module expects to free it
+       vmalloc_mem = vmalloc(ko_size);
+       if (!vmalloc_mem) {
+               pr_err("FIPS140 loader: failed to allocate memory\n");
+               return -ENOMEM;
+       }
+       
+       memcpy(vmalloc_mem, ko_mem, ko_size);
+       
+       ret = load_crypto_module_mem(vmalloc_mem, ko_size); // Skip signature 
check
+       if (ret)
+               panic("FIPS140 loader: module loading error\n");
+
+       vfree(vmalloc_mem); // Free after successful module loading
+       return ret;
+}
-- 
2.47.3


Reply via email to