lkml.org 
[lkml]   [2022]   [Jan]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v7 3/3] integrity: support including firmware ".platform" keys at build time
Date
Allow firmware keys to be embedded in the Linux kernel and loaded onto
the ".platform" keyring on boot.

The firmware keys can be specified in a file as a list of PEM encoded
certificates using new config INTEGRITY_PLATFORM_KEYS. The certificates
are embedded in the image by converting the PEM-formatted certificates
into DER(binary) and generating
security/integrity/platform_certs/platform_certificate_list file at
build time. On boot, the embedded certs from the image are loaded onto
the ".platform" keyring at late_initcall(), ensuring the platform keyring
exists before loading the keys.

Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
---
security/integrity/Kconfig | 10 +++++++
security/integrity/Makefile | 17 +++++++++++-
.../integrity/platform_certs/platform_cert.S | 23 ++++++++++++++++
.../platform_certs/platform_keyring.c | 26 +++++++++++++++++++
4 files changed, 75 insertions(+), 1 deletion(-)
create mode 100644 security/integrity/platform_certs/platform_cert.S

diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 71f0177e8716..9fccf1368b8a 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -62,6 +62,16 @@ config INTEGRITY_PLATFORM_KEYRING
provided by the platform for verifying the kexec'ed kerned image
and, possibly, the initramfs signature.

+config INTEGRITY_PLATFORM_KEYS
+ string "Builtin X.509 keys for .platform keyring"
+ depends on KEYS
+ depends on ASYMMETRIC_KEY_TYPE
+ depends on INTEGRITY_PLATFORM_KEYRING
+ help
+ If set, this option should be the filename of a PEM-formatted file
+ containing X.509 certificates to be loaded onto the ".platform"
+ keyring.
+
config LOAD_UEFI_KEYS
depends on INTEGRITY_PLATFORM_KEYRING
depends on EFI
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
index 7ee39d66cf16..46629f5ef4f6 100644
--- a/security/integrity/Makefile
+++ b/security/integrity/Makefile
@@ -3,13 +3,18 @@
# Makefile for caching inode integrity data (iint)
#

+quiet_cmd_extract_certs = EXTRACT_CERTS $(patsubst "%",%,$(2))
+ cmd_extract_certs = scripts/extract-cert $(2) $@
+$(eval $(call config_filename,INTEGRITY_PLATFORM_KEYS))
+
obj-$(CONFIG_INTEGRITY) += integrity.o

integrity-y := iint.o
integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
-integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o
+integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o \
+ platform_certs/platform_cert.o
integrity-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/efi_parser.o \
platform_certs/load_uefi.o \
platform_certs/keyring_handler.o
@@ -19,3 +24,13 @@ integrity-$(CONFIG_LOAD_PPC_KEYS) += platform_certs/efi_parser.o \
platform_certs/keyring_handler.o
obj-$(CONFIG_IMA) += ima/
obj-$(CONFIG_EVM) += evm/
+
+
+$(obj)/platform_certs/platform_cert.o: $(obj)/platform_certs/platform_certificate_list
+
+targets += platform_certificate_list
+
+$(obj)/platform_certs/platform_certificate_list: scripts/extract-cert $(INTEGRITY_PLATFORM_KEYS_FILENAME) FORCE
+ $(call if_changed,extract_certs,$(CONFIG_INTEGRITY_PLATFORM_KEYS))
+
+clean-files := platform_certs/platform_certificate_list
diff --git a/security/integrity/platform_certs/platform_cert.S b/security/integrity/platform_certs/platform_cert.S
new file mode 100644
index 000000000000..20bccce5dc5a
--- /dev/null
+++ b/security/integrity/platform_certs/platform_cert.S
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/export.h>
+#include <linux/init.h>
+
+ __INITRODATA
+
+ .align 8
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
+ .globl platform_certificate_list
+platform_certificate_list:
+__cert_list_start:
+ .incbin "security/integrity/platform_certs/platform_certificate_list"
+__cert_list_end:
+#endif
+
+ .align 8
+ .globl platform_certificate_list_size
+platform_certificate_list_size:
+#ifdef CONFIG_64BIT
+ .quad __cert_list_end - __cert_list_start
+#else
+ .long __cert_list_end - __cert_list_start
+#endif
diff --git a/security/integrity/platform_certs/platform_keyring.c b/security/integrity/platform_certs/platform_keyring.c
index bcafd7387729..b45de142c5f5 100644
--- a/security/integrity/platform_certs/platform_keyring.c
+++ b/security/integrity/platform_certs/platform_keyring.c
@@ -12,8 +12,12 @@
#include <linux/cred.h>
#include <linux/err.h>
#include <linux/slab.h>
+#include <keys/system_keyring.h>
#include "../integrity.h"

+extern __initconst const u8 platform_certificate_list[];
+extern __initconst const unsigned long platform_certificate_list_size;
+
/**
* add_to_platform_keyring - Add to platform keyring without validation.
* @source: Source of key
@@ -37,6 +41,28 @@ void __init add_to_platform_keyring(const char *source, const void *data,
pr_info("Error adding keys to platform keyring %s\n", source);
}

+static __init int load_platform_certificate_list(void)
+{
+ const u8 *p;
+ unsigned long size;
+ int rc;
+ struct key *keyring;
+
+ p = platform_certificate_list;
+ size = platform_certificate_list_size;
+
+ keyring = integrity_keyring_from_id(INTEGRITY_KEYRING_PLATFORM);
+ if (IS_ERR(keyring))
+ return PTR_ERR(keyring);
+
+ rc = load_certificate_list(p, size, keyring);
+ if (rc)
+ pr_info("Error adding keys to platform keyring %d\n", rc);
+
+ return rc;
+}
+late_initcall(load_platform_certificate_list);
+
/*
* Create the trusted keyrings.
*/
--
2.27.0
\
 
 \ /
  Last update: 2022-01-05 18:55    [W:0.149 / U:0.432 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site