Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

integrity: Define a trusted platform keyring

On secure boot enabled systems, a verified kernel may need to kexec
additional kernels. For example, it may be used as a bootloader needing
to kexec a target kernel or it may need to kexec a crashdump kernel. In
such cases, it may want to verify the signature of the next kernel
image.

It is further possible that the kernel image is signed with third party
keys which are stored as platform or firmware keys in the 'db' variable.
The kernel, however, can not directly verify these platform keys, and an
administrator may therefore not want to trust them for arbitrary usage.
In order to differentiate platform keys from other keys and provide the
necessary separation of trust, the kernel needs an additional keyring to
store platform keys.

This patch creates the new keyring called ".platform" to isolate keys
provided by platform from keys by kernel. These keys are used to
facilitate signature verification during kexec. Since the scope of this
keyring is only the platform/firmware keys, it cannot be updated from
userspace.

This keyring can be enabled by setting CONFIG_INTEGRITY_PLATFORM_KEYRING.

Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Acked-by: Serge Hallyn <serge@hallyn.com>
Reviewed-by: James Morris <james.morris@microsoft.com>
Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>

authored by

Nayna Jain and committed by
Mimi Zohar
9dc92c45 a802ed0d

+82 -17
+11
security/integrity/Kconfig
··· 51 51 .evm keyrings be signed by a key on the system trusted 52 52 keyring. 53 53 54 + config INTEGRITY_PLATFORM_KEYRING 55 + bool "Provide keyring for platform/firmware trusted keys" 56 + depends on INTEGRITY_ASYMMETRIC_KEYS 57 + depends on SYSTEM_BLACKLIST_KEYRING 58 + depends on EFI 59 + help 60 + Provide a separate, distinct keyring for platform trusted keys, which 61 + the kernel automatically populates during initialization from values 62 + provided by the platform for verifying the kexec'ed kerned image 63 + and, possibly, the initramfs signature. 64 + 54 65 config INTEGRITY_AUDIT 55 66 bool "Enables integrity auditing support " 56 67 depends on AUDIT
+1
security/integrity/Makefile
··· 9 9 integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o 10 10 integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o 11 11 integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o 12 + integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o 12 13 13 14 subdir-$(CONFIG_IMA) += ima 14 15 obj-$(CONFIG_IMA) += ima/
+33 -16
security/integrity/digsig.c
··· 35 35 ".ima", 36 36 #endif 37 37 "_module", 38 + ".platform", 38 39 }; 39 40 40 41 #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY ··· 74 73 return -EOPNOTSUPP; 75 74 } 76 75 77 - int __init integrity_init_keyring(const unsigned int id) 76 + static int __integrity_init_keyring(const unsigned int id, key_perm_t perm, 77 + struct key_restriction *restriction) 78 78 { 79 79 const struct cred *cred = current_cred(); 80 - struct key_restriction *restriction; 81 80 int err = 0; 81 + 82 + keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 83 + KGIDT_INIT(0), cred, perm, 84 + KEY_ALLOC_NOT_IN_QUOTA, 85 + restriction, NULL); 86 + if (IS_ERR(keyring[id])) { 87 + err = PTR_ERR(keyring[id]); 88 + pr_info("Can't allocate %s keyring (%d)\n", 89 + keyring_name[id], err); 90 + keyring[id] = NULL; 91 + } 92 + 93 + return err; 94 + } 95 + 96 + int __init integrity_init_keyring(const unsigned int id) 97 + { 98 + struct key_restriction *restriction; 99 + key_perm_t perm; 100 + 101 + perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW 102 + | KEY_USR_READ | KEY_USR_SEARCH; 103 + 104 + if (id == INTEGRITY_KEYRING_PLATFORM) { 105 + restriction = NULL; 106 + goto out; 107 + } 82 108 83 109 if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING)) 84 110 return 0; ··· 115 87 return -ENOMEM; 116 88 117 89 restriction->check = restrict_link_to_ima; 90 + perm |= KEY_USR_WRITE; 118 91 119 - keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 120 - KGIDT_INIT(0), cred, 121 - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 122 - KEY_USR_VIEW | KEY_USR_READ | 123 - KEY_USR_WRITE | KEY_USR_SEARCH), 124 - KEY_ALLOC_NOT_IN_QUOTA, 125 - restriction, NULL); 126 - if (IS_ERR(keyring[id])) { 127 - err = PTR_ERR(keyring[id]); 128 - pr_info("Can't allocate %s keyring (%d)\n", 129 - keyring_name[id], err); 130 - keyring[id] = NULL; 131 - } 132 - return err; 92 + out: 93 + return __integrity_init_keyring(id, perm, restriction); 133 94 } 134 95 135 96 int __init integrity_load_x509(const unsigned int id, const char *path)
+2 -1
security/integrity/integrity.h
··· 142 142 #define INTEGRITY_KEYRING_EVM 0 143 143 #define INTEGRITY_KEYRING_IMA 1 144 144 #define INTEGRITY_KEYRING_MODULE 2 145 - #define INTEGRITY_KEYRING_MAX 3 145 + #define INTEGRITY_KEYRING_PLATFORM 3 146 + #define INTEGRITY_KEYRING_MAX 4 146 147 147 148 extern struct dentry *integrity_dir; 148 149
+35
security/integrity/platform_certs/platform_keyring.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Platform keyring for firmware/platform keys 4 + * 5 + * Copyright IBM Corporation, 2018 6 + * Author(s): Nayna Jain <nayna@linux.ibm.com> 7 + */ 8 + 9 + #include <linux/export.h> 10 + #include <linux/kernel.h> 11 + #include <linux/sched.h> 12 + #include <linux/cred.h> 13 + #include <linux/err.h> 14 + #include <linux/slab.h> 15 + #include "../integrity.h" 16 + 17 + /* 18 + * Create the trusted keyrings. 19 + */ 20 + static __init int platform_keyring_init(void) 21 + { 22 + int rc; 23 + 24 + rc = integrity_init_keyring(INTEGRITY_KEYRING_PLATFORM); 25 + if (rc) 26 + return rc; 27 + 28 + pr_notice("Platform Keyring initialized\n"); 29 + return 0; 30 + } 31 + 32 + /* 33 + * Must be initialised before we try and load the keys into the keyring. 34 + */ 35 + device_initcall(platform_keyring_init);