[PATCH 4/4] integrity: CA enforcement in machine keyring

Eric Snowberg eric.snowberg at oracle.com
Tue Mar 1 17:36:51 UTC 2022


When INTEGRITY_MACHINE_KEYRING is set, all Machine Owner Keys (MOK)
are loaded into the machine keyring.  Add a new
INTEGRITY_MACHINE_KEYRING_CA_ENFORCED option where only MOK CA keys are
added.  

Set the restriction check to restrict_link_by_ca.  This will only allow 
CA keys into the machine keyring. Unlike when INTEGRITY_MACHINE_KEYRING
is enabled, IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY may
also be enabled, allowing IMA to use keys in the machine keyring as
another trust anchor.

Signed-off-by: Eric Snowberg <eric.snowberg at oracle.com>
---
 certs/system_keyring.c                        |  9 +++++---
 include/keys/system_keyring.h                 |  3 ++-
 security/integrity/Kconfig                    | 21 +++++++++++++++++++
 security/integrity/Makefile                   |  1 +
 security/integrity/digsig.c                   | 14 ++++++++++---
 security/integrity/integrity.h                |  3 ++-
 .../platform_certs/keyring_handler.c          |  4 +++-
 7 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 05b66ce9d1c9..0811b44cf3bf 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -22,7 +22,8 @@ static struct key *builtin_trusted_keys;
 #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
 static struct key *secondary_trusted_keys;
 #endif
-#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
+#if defined(CONFIG_INTEGRITY_MACHINE_KEYRING) || \
+    defined(CONFIG_INTEGRITY_MACHINE_KEYRING_CA_ENFORCED)
 static struct key *machine_trusted_keys;
 #endif
 #ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
@@ -89,7 +90,8 @@ static __init struct key_restriction *get_builtin_and_secondary_restriction(void
 	if (!restriction)
 		panic("Can't allocate secondary trusted keyring restriction\n");
 
-	if (IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING))
+	if (IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING) ||
+	    IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING_CA_ENFORCED))
 		restriction->check = restrict_link_by_builtin_secondary_and_machine;
 	else
 		restriction->check = restrict_link_by_builtin_and_secondary_trusted;
@@ -97,7 +99,8 @@ static __init struct key_restriction *get_builtin_and_secondary_restriction(void
 	return restriction;
 }
 #endif
-#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
+#if defined(CONFIG_INTEGRITY_MACHINE_KEYRING) || \
+    defined(CONFIG_INTEGRITY_MACHINE_KEYRING_CA_ENFORCED)
 void __init set_machine_trusted_keys(struct key *keyring)
 {
 	machine_trusted_keys = keyring;
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
index 91e080efb918..e4a6574bbcb6 100644
--- a/include/keys/system_keyring.h
+++ b/include/keys/system_keyring.h
@@ -45,7 +45,8 @@ extern int restrict_link_by_builtin_and_secondary_trusted(
 #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted
 #endif
 
-#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
+#if defined(CONFIG_INTEGRITY_MACHINE_KEYRING) || \
+    defined(CONFIG_INTEGRITY_MACHINE_KEYRING_CA_ENFORCED)
 extern int restrict_link_by_builtin_secondary_and_machine(
 	struct key *dest_keyring,
 	const struct key_type *type,
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 599429f99f99..14c927eea5ee 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -62,6 +62,14 @@ config INTEGRITY_PLATFORM_KEYRING
          provided by the platform for verifying the kexec'ed kerned image
          and, possibly, the initramfs signature.
 
+
+choice
+	prompt "Machine keyring"
+	default INTEGRITY_MACHINE_NONE
+
+config INTEGRITY_MACHINE_NONE
+	bool "Do not enable the Machine Owner Keyring"
+
 config INTEGRITY_MACHINE_KEYRING
 	bool "Provide a keyring to which Machine Owner Keys may be added"
 	depends on SECONDARY_TRUSTED_KEYRING
@@ -75,6 +83,19 @@ config INTEGRITY_MACHINE_KEYRING
 	 in the platform keyring, keys contained in the .machine keyring will
 	 be trusted within the kernel.
 
+config INTEGRITY_MACHINE_KEYRING_CA_ENFORCED
+	bool "Provide a keyring to which Machine Owner CA Keys may be added"
+	depends on SECONDARY_TRUSTED_KEYRING
+	depends on INTEGRITY_ASYMMETRIC_KEYS
+	depends on SYSTEM_BLACKLIST_KEYRING
+	depends on LOAD_UEFI_KEYS
+	help
+	 If set, provide a keyring to which CA Machine Owner Keys (MOK) may
+	 be added. This keyring shall contain just CA MOK keys.  Unlike keys
+	 in the platform keyring, keys contained in the .machine keyring will
+	 be trusted within the kernel.
+endchoice
+
 config LOAD_UEFI_KEYS
        depends on INTEGRITY_PLATFORM_KEYRING
        depends on EFI
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
index d0ffe37dc1d6..370ee63774c3 100644
--- a/security/integrity/Makefile
+++ b/security/integrity/Makefile
@@ -11,6 +11,7 @@ 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_MACHINE_KEYRING) += platform_certs/machine_keyring.o
+integrity-$(CONFIG_INTEGRITY_MACHINE_KEYRING_CA_ENFORCED) += platform_certs/machine_keyring.o
 integrity-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/efi_parser.o \
 				      platform_certs/load_uefi.o \
 				      platform_certs/keyring_handler.o
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index c8c8a4a4e7a0..041edd9744db 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -34,7 +34,11 @@ static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = {
 };
 
 #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
+#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING_CA_ENFORCED
+#define restrict_link_to_ima restrict_link_by_builtin_secondary_and_machine
+#else
 #define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted
+#endif
 #else
 #define restrict_link_to_ima restrict_link_by_builtin_trusted
 #endif
@@ -130,19 +134,23 @@ int __init integrity_init_keyring(const unsigned int id)
 		| KEY_USR_READ | KEY_USR_SEARCH;
 
 	if (id == INTEGRITY_KEYRING_PLATFORM ||
-	    id == INTEGRITY_KEYRING_MACHINE) {
+	   (IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING))) {
 		restriction = NULL;
 		goto out;
 	}
 
-	if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING))
+	if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING) &&
+	    id != INTEGRITY_KEYRING_MACHINE)
 		return 0;
 
 	restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL);
 	if (!restriction)
 		return -ENOMEM;
 
-	restriction->check = restrict_link_to_ima;
+	if (id == INTEGRITY_KEYRING_MACHINE)
+		restriction->check = restrict_link_by_ca;
+	else
+		restriction->check = restrict_link_to_ima;
 
 	/*
 	 * MOK keys can only be added through a read-only runtime services
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 2e214c761158..ca4d72fbd045 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -285,7 +285,8 @@ static inline void __init add_to_platform_keyring(const char *source,
 }
 #endif
 
-#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
+#if defined(CONFIG_INTEGRITY_MACHINE_KEYRING) || \
+    defined(CONFIG_INTEGRITY_MACHINE_KEYRING_CA_ENFORCED)
 void __init add_to_machine_keyring(const char *source, const void *data, size_t len);
 bool __init trust_moklist(void);
 #else
diff --git a/security/integrity/platform_certs/keyring_handler.c b/security/integrity/platform_certs/keyring_handler.c
index a2464f3e66cc..9c456ad0ab67 100644
--- a/security/integrity/platform_certs/keyring_handler.c
+++ b/security/integrity/platform_certs/keyring_handler.c
@@ -61,7 +61,9 @@ __init efi_element_handler_t get_handler_for_db(const efi_guid_t *sig_type)
 __init efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type)
 {
 	if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) {
-		if (IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING) && trust_moklist())
+		if ((IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING) ||
+		     IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING_CA_ENFORCED)) &&
+		     trust_moklist())
 			return add_to_machine_keyring;
 		else
 			return add_to_platform_keyring;
-- 
2.27.0



More information about the Linux-security-module-archive mailing list