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