OSDN Git Service

certs: Factor out the blacklist hash creation
authorMickaël Salaün <mic@linux.microsoft.com>
Mon, 12 Jul 2021 17:03:12 +0000 (19:03 +0200)
committerJarkko Sakkinen <jarkko@kernel.org>
Mon, 23 May 2022 15:47:49 +0000 (18:47 +0300)
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>
certs/blacklist.c
crypto/asymmetric_keys/x509_public_key.c
include/keys/system_keyring.h
security/integrity/platform_certs/keyring_handler.c

index c9a435b..1cdf309 100644 (file)
@@ -83,11 +83,43 @@ static struct key_type key_type_blacklist = {
        .describe               = blacklist_describe,
 };
 
+static char *get_raw_hash(const u8 *hash, size_t hash_len,
+               enum blacklist_hash_type hash_type)
+{
+       size_t type_len;
+       const char *type_prefix;
+       char *buffer, *p;
+
+       switch (hash_type) {
+       case BLACKLIST_HASH_X509_TBS:
+               type_len = sizeof(tbs_prefix) - 1;
+               type_prefix = tbs_prefix;
+               break;
+       case BLACKLIST_HASH_BINARY:
+               type_len = sizeof(bin_prefix) - 1;
+               type_prefix = bin_prefix;
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               return ERR_PTR(-EINVAL);
+       }
+       buffer = kmalloc(type_len + 1 + hash_len * 2 + 1, GFP_KERNEL);
+       if (!buffer)
+               return ERR_PTR(-ENOMEM);
+       p = memcpy(buffer, type_prefix, type_len);
+       p += type_len;
+       *p++ = ':';
+       bin2hex(p, hash, hash_len);
+       p += hash_len * 2;
+       *p = '\0';
+       return buffer;
+}
+
 /**
- * mark_hash_blacklisted - Add a hash to the system blacklist
+ * mark_raw_hash_blacklisted - Add a hash to the system blacklist
  * @hash: The hash as a hex string with a type prefix (eg. "tbs:23aa429783")
  */
-int mark_hash_blacklisted(const char *hash)
+static int mark_raw_hash_blacklisted(const char *hash)
 {
        key_ref_t key;
 
@@ -107,29 +139,36 @@ int mark_hash_blacklisted(const char *hash)
        return 0;
 }
 
+int mark_hash_blacklisted(const u8 *hash, size_t hash_len,
+               enum blacklist_hash_type hash_type)
+{
+       const char *buffer;
+       int err;
+
+       buffer = get_raw_hash(hash, hash_len, hash_type);
+       if (IS_ERR(buffer))
+               return PTR_ERR(buffer);
+       err = mark_raw_hash_blacklisted(buffer);
+       kfree(buffer);
+       return err;
+}
+
 /**
  * is_hash_blacklisted - Determine if a hash is blacklisted
  * @hash: The hash to be checked as a binary blob
  * @hash_len: The length of the binary hash
- * @type: Type of hash
+ * @hash_type: Type of hash
  */
-int is_hash_blacklisted(const u8 *hash, size_t hash_len, const char *type)
+int is_hash_blacklisted(const u8 *hash, size_t hash_len,
+               enum blacklist_hash_type hash_type)
 {
        key_ref_t kref;
-       size_t type_len = strlen(type);
-       char *buffer, *p;
+       const char *buffer;
        int ret = 0;
 
-       buffer = kmalloc(type_len + 1 + hash_len * 2 + 1, GFP_KERNEL);
-       if (!buffer)
-               return -ENOMEM;
-       p = memcpy(buffer, type, type_len);
-       p += type_len;
-       *p++ = ':';
-       bin2hex(p, hash, hash_len);
-       p += hash_len * 2;
-       *p = 0;
-
+       buffer = get_raw_hash(hash, hash_len, hash_type);
+       if (IS_ERR(buffer))
+               return PTR_ERR(buffer);
        kref = keyring_search(make_key_ref(blacklist_keyring, true),
                              &key_type_blacklist, buffer, false);
        if (!IS_ERR(kref)) {
@@ -144,7 +183,8 @@ EXPORT_SYMBOL_GPL(is_hash_blacklisted);
 
 int is_binary_blacklisted(const u8 *hash, size_t hash_len)
 {
-       if (is_hash_blacklisted(hash, hash_len, "bin") == -EKEYREJECTED)
+       if (is_hash_blacklisted(hash, hash_len, BLACKLIST_HASH_BINARY) ==
+                       -EKEYREJECTED)
                return -EPERM;
 
        return 0;
@@ -217,7 +257,7 @@ static int __init blacklist_init(void)
                panic("Can't allocate system blacklist keyring\n");
 
        for (bl = blacklist_hashes; *bl; bl++)
-               if (mark_hash_blacklisted(*bl) < 0)
+               if (mark_raw_hash_blacklisted(*bl) < 0)
                        pr_err("- blacklisting failed\n");
        return 0;
 }
index 91a4ad5..77ed4e9 100644 (file)
@@ -69,7 +69,8 @@ int x509_get_sig_params(struct x509_certificate *cert)
        if (ret < 0)
                goto error_2;
 
-       ret = is_hash_blacklisted(sig->digest, sig->digest_size, "tbs");
+       ret = is_hash_blacklisted(sig->digest, sig->digest_size,
+                                 BLACKLIST_HASH_X509_TBS);
        if (ret == -EKEYREJECTED) {
                pr_err("Cert %*phN is blacklisted\n",
                       sig->digest_size, sig->digest);
index 2419a73..91e080e 100644 (file)
 
 #include <linux/key.h>
 
+enum blacklist_hash_type {
+       /* TBSCertificate hash */
+       BLACKLIST_HASH_X509_TBS = 1,
+       /* Raw data hash */
+       BLACKLIST_HASH_BINARY = 2,
+};
+
 #ifdef CONFIG_SYSTEM_TRUSTED_KEYRING
 
 extern int restrict_link_by_builtin_trusted(struct key *keyring,
@@ -54,13 +61,14 @@ static inline void __init set_machine_trusted_keys(struct key *keyring)
 
 extern struct pkcs7_message *pkcs7;
 #ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
-extern int mark_hash_blacklisted(const char *hash);
+extern int mark_hash_blacklisted(const u8 *hash, size_t hash_len,
+                              enum blacklist_hash_type hash_type);
 extern int is_hash_blacklisted(const u8 *hash, size_t hash_len,
-                              const char *type);
+                              enum blacklist_hash_type hash_type);
 extern int is_binary_blacklisted(const u8 *hash, size_t hash_len);
 #else
 static inline int is_hash_blacklisted(const u8 *hash, size_t hash_len,
-                                     const char *type)
+                                     enum blacklist_hash_type hash_type)
 {
        return 0;
 }
index 1db4d3b..a2464f3 100644 (file)
@@ -17,34 +17,12 @@ static efi_guid_t efi_cert_x509_sha256_guid __initdata =
 static efi_guid_t efi_cert_sha256_guid __initdata = EFI_CERT_SHA256_GUID;
 
 /*
- * Blacklist a hash.
- */
-static __init void uefi_blacklist_hash(const char *source, const void *data,
-                                      size_t len, const char *type,
-                                      size_t type_len)
-{
-       char *hash, *p;
-
-       hash = kmalloc(type_len + len * 2 + 1, GFP_KERNEL);
-       if (!hash)
-               return;
-       p = memcpy(hash, type, type_len);
-       p += type_len;
-       bin2hex(p, data, len);
-       p += len * 2;
-       *p = 0;
-
-       mark_hash_blacklisted(hash);
-       kfree(hash);
-}
-
-/*
  * Blacklist an X509 TBS hash.
  */
 static __init void uefi_blacklist_x509_tbs(const char *source,
                                           const void *data, size_t len)
 {
-       uefi_blacklist_hash(source, data, len, "tbs:", 4);
+       mark_hash_blacklisted(data, len, BLACKLIST_HASH_X509_TBS);
 }
 
 /*
@@ -53,7 +31,7 @@ static __init void uefi_blacklist_x509_tbs(const char *source,
 static __init void uefi_blacklist_binary(const char *source,
                                         const void *data, size_t len)
 {
-       uefi_blacklist_hash(source, data, len, "bin:", 4);
+       mark_hash_blacklisted(data, len, BLACKLIST_HASH_BINARY);
 }
 
 /*