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