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

certs: Factor out the blacklist hash creation

Factor out the blacklist hash creation with the get_raw_hash() helper.
This also centralize the "tbs" and "bin" prefixes and make them private,
which help to manage them consistently.

Cc: David Howells <dhowells@redhat.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Eric Snowberg <eric.snowberg@oracle.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com>
Link: https://lore.kernel.org/r/20210712170313.884724-5-mic@digikod.net
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>

authored by

Mickaël Salaün and committed by
Jarkko Sakkinen
141e5239 58d41635

+73 -46
+58 -18
certs/blacklist.c
··· 83 83 .describe = blacklist_describe, 84 84 }; 85 85 86 + static char *get_raw_hash(const u8 *hash, size_t hash_len, 87 + enum blacklist_hash_type hash_type) 88 + { 89 + size_t type_len; 90 + const char *type_prefix; 91 + char *buffer, *p; 92 + 93 + switch (hash_type) { 94 + case BLACKLIST_HASH_X509_TBS: 95 + type_len = sizeof(tbs_prefix) - 1; 96 + type_prefix = tbs_prefix; 97 + break; 98 + case BLACKLIST_HASH_BINARY: 99 + type_len = sizeof(bin_prefix) - 1; 100 + type_prefix = bin_prefix; 101 + break; 102 + default: 103 + WARN_ON_ONCE(1); 104 + return ERR_PTR(-EINVAL); 105 + } 106 + buffer = kmalloc(type_len + 1 + hash_len * 2 + 1, GFP_KERNEL); 107 + if (!buffer) 108 + return ERR_PTR(-ENOMEM); 109 + p = memcpy(buffer, type_prefix, type_len); 110 + p += type_len; 111 + *p++ = ':'; 112 + bin2hex(p, hash, hash_len); 113 + p += hash_len * 2; 114 + *p = '\0'; 115 + return buffer; 116 + } 117 + 86 118 /** 87 - * mark_hash_blacklisted - Add a hash to the system blacklist 119 + * mark_raw_hash_blacklisted - Add a hash to the system blacklist 88 120 * @hash: The hash as a hex string with a type prefix (eg. "tbs:23aa429783") 89 121 */ 90 - int mark_hash_blacklisted(const char *hash) 122 + static int mark_raw_hash_blacklisted(const char *hash) 91 123 { 92 124 key_ref_t key; 93 125 ··· 139 107 return 0; 140 108 } 141 109 110 + int mark_hash_blacklisted(const u8 *hash, size_t hash_len, 111 + enum blacklist_hash_type hash_type) 112 + { 113 + const char *buffer; 114 + int err; 115 + 116 + buffer = get_raw_hash(hash, hash_len, hash_type); 117 + if (IS_ERR(buffer)) 118 + return PTR_ERR(buffer); 119 + err = mark_raw_hash_blacklisted(buffer); 120 + kfree(buffer); 121 + return err; 122 + } 123 + 142 124 /** 143 125 * is_hash_blacklisted - Determine if a hash is blacklisted 144 126 * @hash: The hash to be checked as a binary blob 145 127 * @hash_len: The length of the binary hash 146 - * @type: Type of hash 128 + * @hash_type: Type of hash 147 129 */ 148 - int is_hash_blacklisted(const u8 *hash, size_t hash_len, const char *type) 130 + int is_hash_blacklisted(const u8 *hash, size_t hash_len, 131 + enum blacklist_hash_type hash_type) 149 132 { 150 133 key_ref_t kref; 151 - size_t type_len = strlen(type); 152 - char *buffer, *p; 134 + const char *buffer; 153 135 int ret = 0; 154 136 155 - buffer = kmalloc(type_len + 1 + hash_len * 2 + 1, GFP_KERNEL); 156 - if (!buffer) 157 - return -ENOMEM; 158 - p = memcpy(buffer, type, type_len); 159 - p += type_len; 160 - *p++ = ':'; 161 - bin2hex(p, hash, hash_len); 162 - p += hash_len * 2; 163 - *p = 0; 164 - 137 + buffer = get_raw_hash(hash, hash_len, hash_type); 138 + if (IS_ERR(buffer)) 139 + return PTR_ERR(buffer); 165 140 kref = keyring_search(make_key_ref(blacklist_keyring, true), 166 141 &key_type_blacklist, buffer, false); 167 142 if (!IS_ERR(kref)) { ··· 183 144 184 145 int is_binary_blacklisted(const u8 *hash, size_t hash_len) 185 146 { 186 - if (is_hash_blacklisted(hash, hash_len, "bin") == -EKEYREJECTED) 147 + if (is_hash_blacklisted(hash, hash_len, BLACKLIST_HASH_BINARY) == 148 + -EKEYREJECTED) 187 149 return -EPERM; 188 150 189 151 return 0; ··· 257 217 panic("Can't allocate system blacklist keyring\n"); 258 218 259 219 for (bl = blacklist_hashes; *bl; bl++) 260 - if (mark_hash_blacklisted(*bl) < 0) 220 + if (mark_raw_hash_blacklisted(*bl) < 0) 261 221 pr_err("- blacklisting failed\n"); 262 222 return 0; 263 223 }
+2 -1
crypto/asymmetric_keys/x509_public_key.c
··· 69 69 if (ret < 0) 70 70 goto error_2; 71 71 72 - ret = is_hash_blacklisted(sig->digest, sig->digest_size, "tbs"); 72 + ret = is_hash_blacklisted(sig->digest, sig->digest_size, 73 + BLACKLIST_HASH_X509_TBS); 73 74 if (ret == -EKEYREJECTED) { 74 75 pr_err("Cert %*phN is blacklisted\n", 75 76 sig->digest_size, sig->digest);
+11 -3
include/keys/system_keyring.h
··· 10 10 11 11 #include <linux/key.h> 12 12 13 + enum blacklist_hash_type { 14 + /* TBSCertificate hash */ 15 + BLACKLIST_HASH_X509_TBS = 1, 16 + /* Raw data hash */ 17 + BLACKLIST_HASH_BINARY = 2, 18 + }; 19 + 13 20 #ifdef CONFIG_SYSTEM_TRUSTED_KEYRING 14 21 15 22 extern int restrict_link_by_builtin_trusted(struct key *keyring, ··· 61 54 62 55 extern struct pkcs7_message *pkcs7; 63 56 #ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING 64 - extern int mark_hash_blacklisted(const char *hash); 57 + extern int mark_hash_blacklisted(const u8 *hash, size_t hash_len, 58 + enum blacklist_hash_type hash_type); 65 59 extern int is_hash_blacklisted(const u8 *hash, size_t hash_len, 66 - const char *type); 60 + enum blacklist_hash_type hash_type); 67 61 extern int is_binary_blacklisted(const u8 *hash, size_t hash_len); 68 62 #else 69 63 static inline int is_hash_blacklisted(const u8 *hash, size_t hash_len, 70 - const char *type) 64 + enum blacklist_hash_type hash_type) 71 65 { 72 66 return 0; 73 67 }
+2 -24
security/integrity/platform_certs/keyring_handler.c
··· 17 17 static efi_guid_t efi_cert_sha256_guid __initdata = EFI_CERT_SHA256_GUID; 18 18 19 19 /* 20 - * Blacklist a hash. 21 - */ 22 - static __init void uefi_blacklist_hash(const char *source, const void *data, 23 - size_t len, const char *type, 24 - size_t type_len) 25 - { 26 - char *hash, *p; 27 - 28 - hash = kmalloc(type_len + len * 2 + 1, GFP_KERNEL); 29 - if (!hash) 30 - return; 31 - p = memcpy(hash, type, type_len); 32 - p += type_len; 33 - bin2hex(p, data, len); 34 - p += len * 2; 35 - *p = 0; 36 - 37 - mark_hash_blacklisted(hash); 38 - kfree(hash); 39 - } 40 - 41 - /* 42 20 * Blacklist an X509 TBS hash. 43 21 */ 44 22 static __init void uefi_blacklist_x509_tbs(const char *source, 45 23 const void *data, size_t len) 46 24 { 47 - uefi_blacklist_hash(source, data, len, "tbs:", 4); 25 + mark_hash_blacklisted(data, len, BLACKLIST_HASH_X509_TBS); 48 26 } 49 27 50 28 /* ··· 31 53 static __init void uefi_blacklist_binary(const char *source, 32 54 const void *data, size_t len) 33 55 { 34 - uefi_blacklist_hash(source, data, len, "bin:", 4); 56 + mark_hash_blacklisted(data, len, BLACKLIST_HASH_BINARY); 35 57 } 36 58 37 59 /*