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 21 #include "integrity.h" 22 23 /* 24 * Request an asymmetric key. 25 */ 26 static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid) 27 { 28 struct key *key; 29 char name[12]; 30 31 sprintf(name, "id:%08x", keyid); 32 33 pr_debug("key search: \"%s\"\n", name); 34 35 if (keyring) { 36 /* search in specific keyring */ 37 key_ref_t kref; 38 kref = keyring_search(make_key_ref(keyring, 1), 39 &key_type_asymmetric, name); 40 if (IS_ERR(kref)) 41 key = ERR_CAST(kref); 42 else 43 key = key_ref_to_ptr(kref); 44 } else { 45 key = request_key(&key_type_asymmetric, name, NULL); 46 } 47 48 if (IS_ERR(key)) { 49 pr_err_ratelimited("Request for unknown key '%s' err %ld\n", 50 name, PTR_ERR(key)); 51 switch (PTR_ERR(key)) { 52 /* Hide some search errors */ 53 case -EACCES: 54 case -ENOTDIR: 55 case -EAGAIN: 56 return ERR_PTR(-ENOKEY); 57 default: 58 return key; 59 } 60 } 61 62 pr_debug("%s() = 0 [%x]\n", __func__, key_serial(key)); 63 64 return key; 65 } 66 67 int asymmetric_verify(struct key *keyring, const char *sig, 68 int siglen, const char *data, int datalen) 69 { 70 struct public_key_signature pks; 71 struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig; 72 struct key *key; 73 int ret = -ENOMEM; 74 75 if (siglen <= sizeof(*hdr)) 76 return -EBADMSG; 77 78 siglen -= sizeof(*hdr); 79 80 if (siglen != __be16_to_cpu(hdr->sig_size)) 81 return -EBADMSG; 82 83 if (hdr->hash_algo >= PKEY_HASH__LAST) 84 return -ENOPKG; 85 86 key = request_asymmetric_key(keyring, __be32_to_cpu(hdr->keyid)); 87 if (IS_ERR(key)) 88 return PTR_ERR(key); 89 90 memset(&pks, 0, sizeof(pks)); 91 92 pks.pkey_hash_algo = hdr->hash_algo; 93 pks.digest = (u8 *)data; 94 pks.digest_size = datalen; 95 pks.nr_mpi = 1; 96 pks.rsa.s = mpi_read_raw_data(hdr->sig, siglen); 97 98 if (pks.rsa.s) 99 ret = verify_signature(key, &pks); 100 101 mpi_free(pks.rsa.s); 102 key_put(key); 103 pr_debug("%s() = %d\n", __func__, ret); 104 return ret; 105 } 106