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

integrity: Load certs to the platform keyring

The patch refactors integrity_load_x509(), making it a wrapper for a new
function named integrity_add_key(). This patch also defines a new
function named integrity_load_cert() for loading the platform keys.

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
60740acc 9dc92c45

+86 -24
+43 -24
security/integrity/digsig.c
··· 82 82 83 83 keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 84 84 KGIDT_INIT(0), cred, perm, 85 - KEY_ALLOC_NOT_IN_QUOTA, 86 - restriction, NULL); 85 + KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL); 87 86 if (IS_ERR(keyring[id])) { 88 87 err = PTR_ERR(keyring[id]); 89 88 pr_info("Can't allocate %s keyring (%d)\n", ··· 120 121 return __integrity_init_keyring(id, perm, restriction); 121 122 } 122 123 123 - int __init integrity_load_x509(const unsigned int id, const char *path) 124 + int __init integrity_add_key(const unsigned int id, const void *data, 125 + off_t size, key_perm_t perm) 124 126 { 125 127 key_ref_t key; 126 - void *data; 127 - loff_t size; 128 - int rc; 128 + int rc = 0; 129 129 130 130 if (!keyring[id]) 131 131 return -EINVAL; 132 + 133 + key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric", 134 + NULL, data, size, perm, 135 + KEY_ALLOC_NOT_IN_QUOTA); 136 + if (IS_ERR(key)) { 137 + rc = PTR_ERR(key); 138 + pr_err("Problem loading X.509 certificate %d\n", rc); 139 + } else { 140 + pr_notice("Loaded X.509 cert '%s'\n", 141 + key_ref_to_ptr(key)->description); 142 + key_ref_put(key); 143 + } 144 + 145 + return rc; 146 + 147 + } 148 + 149 + int __init integrity_load_x509(const unsigned int id, const char *path) 150 + { 151 + void *data; 152 + loff_t size; 153 + int rc; 154 + key_perm_t perm; 132 155 133 156 rc = kernel_read_file_from_path(path, &data, &size, 0, 134 157 READING_X509_CERTIFICATE); ··· 159 138 return rc; 160 139 } 161 140 162 - key = key_create_or_update(make_key_ref(keyring[id], 1), 163 - "asymmetric", 164 - NULL, 165 - data, 166 - size, 167 - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 168 - KEY_USR_VIEW | KEY_USR_READ), 169 - KEY_ALLOC_NOT_IN_QUOTA); 170 - if (IS_ERR(key)) { 171 - rc = PTR_ERR(key); 172 - pr_err("Problem loading X.509 certificate (%d): %s\n", 173 - rc, path); 174 - } else { 175 - pr_notice("Loaded X.509 cert '%s': %s\n", 176 - key_ref_to_ptr(key)->description, path); 177 - key_ref_put(key); 178 - } 141 + perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ; 142 + 143 + pr_info("Loading X.509 certificate: %s\n", path); 144 + rc = integrity_add_key(id, (const void *)data, size, perm); 145 + 179 146 vfree(data); 180 - return 0; 147 + return rc; 148 + } 149 + 150 + int __init integrity_load_cert(const unsigned int id, const char *source, 151 + const void *data, size_t len, key_perm_t perm) 152 + { 153 + if (!data) 154 + return -EINVAL; 155 + 156 + pr_info("Loading X.509 certificate: %s\n", source); 157 + return integrity_add_key(id, data, len, perm); 181 158 }
+20
security/integrity/integrity.h
··· 154 154 155 155 int __init integrity_init_keyring(const unsigned int id); 156 156 int __init integrity_load_x509(const unsigned int id, const char *path); 157 + int __init integrity_load_cert(const unsigned int id, const char *source, 158 + const void *data, size_t len, key_perm_t perm); 157 159 #else 158 160 159 161 static inline int integrity_digsig_verify(const unsigned int id, ··· 166 164 } 167 165 168 166 static inline int integrity_init_keyring(const unsigned int id) 167 + { 168 + return 0; 169 + } 170 + 171 + static inline int __init integrity_load_cert(const unsigned int id, 172 + const char *source, 173 + const void *data, size_t len, 174 + key_perm_t perm) 169 175 { 170 176 return 0; 171 177 } ··· 232 222 return NULL; 233 223 } 234 224 225 + #endif 226 + 227 + #ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING 228 + void __init add_to_platform_keyring(const char *source, const void *data, 229 + size_t len); 230 + #else 231 + static inline void __init add_to_platform_keyring(const char *source, 232 + const void *data, size_t len) 233 + { 234 + } 235 235 #endif
+23
security/integrity/platform_certs/platform_keyring.c
··· 14 14 #include <linux/slab.h> 15 15 #include "../integrity.h" 16 16 17 + /** 18 + * add_to_platform_keyring - Add to platform keyring without validation. 19 + * @source: Source of key 20 + * @data: The blob holding the key 21 + * @len: The length of the data blob 22 + * 23 + * Add a key to the platform keyring without checking its trust chain. This 24 + * is available only during kernel initialisation. 25 + */ 26 + void __init add_to_platform_keyring(const char *source, const void *data, 27 + size_t len) 28 + { 29 + key_perm_t perm; 30 + int rc; 31 + 32 + perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW; 33 + 34 + rc = integrity_load_cert(INTEGRITY_KEYRING_PLATFORM, source, data, len, 35 + perm); 36 + if (rc) 37 + pr_info("Error adding keys to platform keyring %s\n", source); 38 + } 39 + 17 40 /* 18 41 * Create the trusted keyrings. 19 42 */