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