Blame view
security/integrity/digsig_asymmetric.c
3.41 KB
e0751257a ima: digital sign... |
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 integrity: preven... |
16 |
#include <linux/ratelimit.h> |
e0751257a ima: digital sign... |
17 18 |
#include <linux/key-type.h> #include <crypto/public_key.h> |
4e8ae72a7 X.509: Make algo ... |
19 |
#include <crypto/hash_info.h> |
e0751257a ima: digital sign... |
20 |
#include <keys/asymmetric-type.h> |
41c89b64d IMA: create machi... |
21 |
#include <keys/system_keyring.h> |
e0751257a ima: digital sign... |
22 23 24 25 |
#include "integrity.h" /* |
e0751257a ima: digital sign... |
26 27 28 29 30 31 |
* Request an asymmetric key. */ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid) { struct key *key; char name[12]; |
594081ee7 integrity: do zer... |
32 |
sprintf(name, "id:%08x", keyid); |
e0751257a ima: digital sign... |
33 34 35 |
pr_debug("key search: \"%s\" ", name); |
41c89b64d IMA: create machi... |
36 37 38 39 40 41 42 43 44 45 46 47 |
key = get_ima_blacklist_keyring(); if (key) { key_ref_t kref; kref = keyring_search(make_key_ref(key, 1), &key_type_asymmetric, name); if (!IS_ERR(kref)) { pr_err("Key '%s' is in ima_blacklist_keyring ", name); return ERR_PTR(-EKEYREJECTED); } } |
e0751257a ima: digital sign... |
48 49 50 |
if (keyring) { /* search in specific keyring */ key_ref_t kref; |
41c89b64d IMA: create machi... |
51 |
|
e0751257a ima: digital sign... |
52 53 54 55 56 57 58 59 60 61 62 |
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 integrity: preven... |
63 64 65 |
pr_err_ratelimited("Request for unknown key '%s' err %ld ", name, PTR_ERR(key)); |
e0751257a ima: digital sign... |
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 |
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); |
bb543e395 integrity: Small ... |
95 |
if (siglen != be16_to_cpu(hdr->sig_size)) |
e0751257a ima: digital sign... |
96 |
return -EBADMSG; |
4e8ae72a7 X.509: Make algo ... |
97 |
if (hdr->hash_algo >= HASH_ALGO__LAST) |
e0751257a ima: digital sign... |
98 |
return -ENOPKG; |
bb543e395 integrity: Small ... |
99 |
key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid)); |
e0751257a ima: digital sign... |
100 101 102 103 |
if (IS_ERR(key)) return PTR_ERR(key); memset(&pks, 0, sizeof(pks)); |
4e8ae72a7 X.509: Make algo ... |
104 105 |
pks.pkey_algo = "rsa"; pks.hash_algo = hash_algo_name[hdr->hash_algo]; |
e0751257a ima: digital sign... |
106 107 |
pks.digest = (u8 *)data; pks.digest_size = datalen; |
eb5798f2e integrity: conver... |
108 109 110 |
pks.s = hdr->sig; pks.s_size = siglen; ret = verify_signature(key, &pks); |
e0751257a ima: digital sign... |
111 112 113 114 115 |
key_put(key); pr_debug("%s() = %d ", __func__, ret); return ret; } |
6eb864c1d integrity: preven... |
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
/** * integrity_kernel_module_request - prevent crypto-pkcs1pad(rsa,*) requests * @kmod_name: kernel module name * * We have situation, when public_key_verify_signature() in case of RSA * algorithm use alg_name to store internal information in order to * construct an algorithm on the fly, but crypto_larval_lookup() will try * to use alg_name in order to load kernel module with same name. * Since we don't have any real "crypto-pkcs1pad(rsa,*)" kernel modules, * we are safe to fail such module request from crypto_larval_lookup(). * * In this way we prevent modprobe execution during digsig verification * and avoid possible deadlock if modprobe and/or it's dependencies * also signed with digsig. */ int integrity_kernel_module_request(char *kmod_name) { if (strncmp(kmod_name, "crypto-pkcs1pad(rsa,", 20) == 0) return -EINVAL; return 0; } |