diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig index da9565891738..4b4d2aeef539 100644 --- a/security/integrity/Kconfig +++ b/security/integrity/Kconfig @@ -51,6 +51,17 @@ config INTEGRITY_TRUSTED_KEYRING .evm keyrings be signed by a key on the system trusted keyring. +config INTEGRITY_PLATFORM_KEYRING + bool "Provide keyring for platform/firmware trusted keys" + depends on INTEGRITY_ASYMMETRIC_KEYS + depends on SYSTEM_BLACKLIST_KEYRING + depends on EFI + help + Provide a separate, distinct keyring for platform trusted keys, which + the kernel automatically populates during initialization from values + provided by the platform for verifying the kexec'ed kerned image + and, possibly, the initramfs signature. + config INTEGRITY_AUDIT bool "Enables integrity auditing support " depends on AUDIT diff --git a/security/integrity/Makefile b/security/integrity/Makefile index 04d6e462b079..046ffc1bb42d 100644 --- a/security/integrity/Makefile +++ b/security/integrity/Makefile @@ -9,6 +9,7 @@ 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 subdir-$(CONFIG_IMA) += ima obj-$(CONFIG_IMA) += ima/ diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 5eacba858e4b..4a22730e0cc6 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -35,6 +35,7 @@ static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = { ".ima", #endif "_module", + ".platform", }; #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY @@ -73,12 +74,39 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, return -EOPNOTSUPP; } -int __init integrity_init_keyring(const unsigned int id) +static int __integrity_init_keyring(const unsigned int id, key_perm_t perm, + struct key_restriction *restriction) { const struct cred *cred = current_cred(); - struct key_restriction *restriction; int err = 0; + keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), + KGIDT_INIT(0), cred, perm, + KEY_ALLOC_NOT_IN_QUOTA, + restriction, NULL); + if (IS_ERR(keyring[id])) { + err = PTR_ERR(keyring[id]); + pr_info("Can't allocate %s keyring (%d)\n", + keyring_name[id], err); + keyring[id] = NULL; + } + + return err; +} + +int __init integrity_init_keyring(const unsigned int id) +{ + struct key_restriction *restriction; + key_perm_t perm; + + perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW + | KEY_USR_READ | KEY_USR_SEARCH; + + if (id == INTEGRITY_KEYRING_PLATFORM) { + restriction = NULL; + goto out; + } + if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING)) return 0; @@ -87,21 +115,10 @@ int __init integrity_init_keyring(const unsigned int id) return -ENOMEM; restriction->check = restrict_link_to_ima; + perm |= KEY_USR_WRITE; - keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), - KGIDT_INIT(0), cred, - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | - KEY_USR_VIEW | KEY_USR_READ | - KEY_USR_WRITE | KEY_USR_SEARCH), - KEY_ALLOC_NOT_IN_QUOTA, - restriction, NULL); - if (IS_ERR(keyring[id])) { - err = PTR_ERR(keyring[id]); - pr_info("Can't allocate %s keyring (%d)\n", - keyring_name[id], err); - keyring[id] = NULL; - } - return err; +out: + return __integrity_init_keyring(id, perm, restriction); } int __init integrity_load_x509(const unsigned int id, const char *path) diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index e60473b13a8d..c2332a44799e 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -142,7 +142,8 @@ int integrity_kernel_read(struct file *file, loff_t offset, #define INTEGRITY_KEYRING_EVM 0 #define INTEGRITY_KEYRING_IMA 1 #define INTEGRITY_KEYRING_MODULE 2 -#define INTEGRITY_KEYRING_MAX 3 +#define INTEGRITY_KEYRING_PLATFORM 3 +#define INTEGRITY_KEYRING_MAX 4 extern struct dentry *integrity_dir; diff --git a/security/integrity/platform_certs/platform_keyring.c b/security/integrity/platform_certs/platform_keyring.c new file mode 100644 index 000000000000..79f80af5b470 --- /dev/null +++ b/security/integrity/platform_certs/platform_keyring.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Platform keyring for firmware/platform keys + * + * Copyright IBM Corporation, 2018 + * Author(s): Nayna Jain + */ + +#include +#include +#include +#include +#include +#include +#include "../integrity.h" + +/* + * Create the trusted keyrings. + */ +static __init int platform_keyring_init(void) +{ + int rc; + + rc = integrity_init_keyring(INTEGRITY_KEYRING_PLATFORM); + if (rc) + return rc; + + pr_notice("Platform Keyring initialized\n"); + return 0; +} + +/* + * Must be initialised before we try and load the keys into the keyring. + */ +device_initcall(platform_keyring_init);