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

integrity: PowerVM support for loading third party code signing keys

On secure boot enabled PowerVM LPAR, third party code signing keys are
needed during early boot to verify signed third party modules. These
third party keys are stored in moduledb object in the Platform
KeyStore (PKS).

Load third party code signing keys onto .secondary_trusted_keys keyring.

Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
Reviewed-and-tested-by: Mimi Zohar <zohar@linux.ibm.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: Nageswara R Sastry <rnsastry@linux.ibm.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>

authored by

Nayna Jain and committed by
Jarkko Sakkinen
44e69ea5 d7d91c47

+64
+30
certs/system_keyring.c
··· 152 152 153 153 return restriction; 154 154 } 155 + 156 + /** 157 + * add_to_secondary_keyring - Add to secondary keyring. 158 + * @source: Source of key 159 + * @data: The blob holding the key 160 + * @len: The length of the data blob 161 + * 162 + * Add a key to the secondary keyring. The key must be vouched for by a key in the builtin, 163 + * machine or secondary keyring itself. 164 + */ 165 + void __init add_to_secondary_keyring(const char *source, const void *data, size_t len) 166 + { 167 + key_ref_t key; 168 + key_perm_t perm; 169 + 170 + perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW; 171 + 172 + key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1), 173 + "asymmetric", 174 + NULL, data, len, perm, 175 + KEY_ALLOC_NOT_IN_QUOTA); 176 + if (IS_ERR(key)) { 177 + pr_err("Problem loading X.509 certificate from %s to secondary keyring %ld\n", 178 + source, PTR_ERR(key)); 179 + return; 180 + } 181 + 182 + pr_notice("Loaded X.509 cert '%s'\n", key_ref_to_ptr(key)->description); 183 + key_ref_put(key); 184 + } 155 185 #endif 156 186 #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING 157 187 void __init set_machine_trusted_keys(struct key *keyring)
+4
include/keys/system_keyring.h
··· 50 50 const struct key_type *type, 51 51 const union key_payload *payload, 52 52 struct key *restriction_key); 53 + void __init add_to_secondary_keyring(const char *source, const void *data, size_t len); 53 54 #else 54 55 #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted 55 56 #define restrict_link_by_digsig_builtin_and_secondary restrict_link_by_digsig_builtin 57 + static inline void __init add_to_secondary_keyring(const char *source, const void *data, size_t len) 58 + { 59 + } 56 60 #endif 57 61 58 62 #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
+8
security/integrity/platform_certs/keyring_handler.c
··· 78 78 return NULL; 79 79 } 80 80 81 + __init efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type) 82 + { 83 + if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) 84 + return add_to_secondary_keyring; 85 + 86 + return NULL; 87 + } 88 + 81 89 /* 82 90 * Return the appropriate handler for particular signature list types found in 83 91 * the UEFI dbx and MokListXRT tables.
+5
security/integrity/platform_certs/keyring_handler.h
··· 35 35 efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type); 36 36 37 37 /* 38 + * Return the handler for particular signature list types for code signing keys. 39 + */ 40 + efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type); 41 + 42 + /* 38 43 * Return the handler for particular signature list types found in the dbx. 39 44 */ 40 45 efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_type);
+17
security/integrity/platform_certs/load_powerpc.c
··· 60 60 { 61 61 void *db = NULL, *dbx = NULL, *data = NULL; 62 62 void *trustedca; 63 + void *moduledb; 63 64 u64 dsize = 0; 64 65 u64 offset = 0; 65 66 int rc = 0; ··· 135 134 get_handler_for_ca_keys); 136 135 if (rc) 137 136 pr_err("Couldn't parse trustedcadb signatures: %d\n", rc); 137 + kfree(data); 138 + } 139 + 140 + data = get_cert_list("moduledb", 9, &dsize); 141 + if (!data) { 142 + pr_info("Couldn't get moduledb list from firmware\n"); 143 + } else if (IS_ERR(data)) { 144 + rc = PTR_ERR(data); 145 + pr_err("Error reading moduledb from firmware: %d\n", rc); 146 + } else { 147 + extract_esl(moduledb, data, dsize, offset); 148 + 149 + rc = parse_efi_signature_list("powerpc:moduledb", moduledb, dsize, 150 + get_handler_for_code_signing_keys); 151 + if (rc) 152 + pr_err("Couldn't parse moduledb signatures: %d\n", rc); 138 153 kfree(data); 139 154 } 140 155