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@xxxxxxxxxx> --- 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