1 /* 2 * Copyright (C) 2013 Intel Corporation 3 * 4 * Author: 5 * Dmitry Kasatkin <dmitry.kasatkin@intel.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, version 2 of the License. 10 * 11 */ 12 13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 14 15 #include <linux/err.h> 16 #include <linux/ratelimit.h> 17 #include <linux/key-type.h> 18 #include <crypto/public_key.h> 19 #include <keys/asymmetric-type.h> 20 #include <keys/system_keyring.h> 21 22 #include "integrity.h" 23 24 /* 25 * Request an asymmetric key. 26 */ 27 static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid) 28 { 29 struct key *key; 30 char name[12]; 31 32 sprintf(name, "id:%08x", keyid); 33 34 pr_debug("key search: \"%s\"\n", name); 35 36 key = get_ima_blacklist_keyring(); 37 if (key) { 38 key_ref_t kref; 39 40 kref = keyring_search(make_key_ref(key, 1), 41 &key_type_asymmetric, name); 42 if (!IS_ERR(kref)) { 43 pr_err("Key '%s' is in ima_blacklist_keyring\n", name); 44 return ERR_PTR(-EKEYREJECTED); 45 } 46 } 47 48 if (keyring) { 49 /* search in specific keyring */ 50 key_ref_t kref; 51 52 kref = keyring_search(make_key_ref(keyring, 1), 53 &key_type_asymmetric, name); 54 if (IS_ERR(kref)) 55 key = ERR_CAST(kref); 56 else 57 key = key_ref_to_ptr(kref); 58 } else { 59 key = request_key(&key_type_asymmetric, name, NULL); 60 } 61 62 if (IS_ERR(key)) { 63 pr_err_ratelimited("Request for unknown key '%s' err %ld\n", 64 name, PTR_ERR(key)); 65 switch (PTR_ERR(key)) { 66 /* Hide some search errors */ 67 case -EACCES: 68 case -ENOTDIR: 69 case -EAGAIN: 70 return ERR_PTR(-ENOKEY); 71 default: 72 return key; 73 } 74 } 75 76 pr_debug("%s() = 0 [%x]\n", __func__, key_serial(key)); 77 78 return key; 79 } 80 81 int asymmetric_verify(struct key *keyring, const char *sig, 82 int siglen, const char *data, int datalen) 83 { 84 struct public_key_signature pks; 85 struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig; 86 struct key *key; 87 int ret = -ENOMEM; 88 89 if (siglen <= sizeof(*hdr)) 90 return -EBADMSG; 91 92 siglen -= sizeof(*hdr); 93 94 if (siglen != __be16_to_cpu(hdr->sig_size)) 95 return -EBADMSG; 96 97 if (hdr->hash_algo >= PKEY_HASH__LAST) 98 return -ENOPKG; 99 100 key = request_asymmetric_key(keyring, __be32_to_cpu(hdr->keyid)); 101 if (IS_ERR(key)) 102 return PTR_ERR(key); 103 104 memset(&pks, 0, sizeof(pks)); 105 106 pks.pkey_algo = PKEY_ALGO_RSA; 107 pks.pkey_hash_algo = hdr->hash_algo; 108 pks.digest = (u8 *)data; 109 pks.digest_size = datalen; 110 pks.s = hdr->sig; 111 pks.s_size = siglen; 112 ret = verify_signature(key, &pks); 113 key_put(key); 114 pr_debug("%s() = %d\n", __func__, ret); 115 return ret; 116 } 117