1/* Module signature checker 2 * 3 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public Licence 8 * as published by the Free Software Foundation; either version 9 * 2 of the Licence, or (at your option) any later version. 10 */ 11 12#include <linux/kernel.h> 13#include <linux/err.h> 14#include <crypto/public_key.h> 15#include <crypto/hash.h> 16#include <keys/asymmetric-type.h> 17#include <keys/system_keyring.h> 18#include "module-internal.h" 19 20/* 21 * Module signature information block. 22 * 23 * The constituents of the signature section are, in order: 24 * 25 * - Signer's name 26 * - Key identifier 27 * - Signature data 28 * - Information block 29 */ 30struct module_signature { 31 u8 algo; /* Public-key crypto algorithm [enum pkey_algo] */ 32 u8 hash; /* Digest algorithm [enum hash_algo] */ 33 u8 id_type; /* Key identifier type [enum pkey_id_type] */ 34 u8 signer_len; /* Length of signer's name */ 35 u8 key_id_len; /* Length of key identifier */ 36 u8 __pad[3]; 37 __be32 sig_len; /* Length of signature data */ 38}; 39 40/* 41 * Digest the module contents. 42 */ 43static struct public_key_signature *mod_make_digest(enum hash_algo hash, 44 const void *mod, 45 unsigned long modlen) 46{ 47 struct public_key_signature *pks; 48 struct crypto_shash *tfm; 49 struct shash_desc *desc; 50 size_t digest_size, desc_size; 51 int ret; 52 53 pr_devel("==>%s()\n", __func__); 54 55 /* Allocate the hashing algorithm we're going to need and find out how 56 * big the hash operational data will be. 57 */ 58 tfm = crypto_alloc_shash(hash_algo_name[hash], 0, 0); 59 if (IS_ERR(tfm)) 60 return (PTR_ERR(tfm) == -ENOENT) ? ERR_PTR(-ENOPKG) : ERR_CAST(tfm); 61 62 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 63 digest_size = crypto_shash_digestsize(tfm); 64 65 /* We allocate the hash operational data storage on the end of our 66 * context data and the digest output buffer on the end of that. 67 */ 68 ret = -ENOMEM; 69 pks = kzalloc(digest_size + sizeof(*pks) + desc_size, GFP_KERNEL); 70 if (!pks) 71 goto error_no_pks; 72 73 pks->pkey_hash_algo = hash; 74 pks->digest = (u8 *)pks + sizeof(*pks) + desc_size; 75 pks->digest_size = digest_size; 76 77 desc = (void *)pks + sizeof(*pks); 78 desc->tfm = tfm; 79 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 80 81 ret = crypto_shash_init(desc); 82 if (ret < 0) 83 goto error; 84 85 ret = crypto_shash_finup(desc, mod, modlen, pks->digest); 86 if (ret < 0) 87 goto error; 88 89 crypto_free_shash(tfm); 90 pr_devel("<==%s() = ok\n", __func__); 91 return pks; 92 93error: 94 kfree(pks); 95error_no_pks: 96 crypto_free_shash(tfm); 97 pr_devel("<==%s() = %d\n", __func__, ret); 98 return ERR_PTR(ret); 99} 100 101/* 102 * Extract an MPI array from the signature data. This represents the actual 103 * signature. Each raw MPI is prefaced by a BE 2-byte value indicating the 104 * size of the MPI in bytes. 105 * 106 * RSA signatures only have one MPI, so currently we only read one. 107 */ 108static int mod_extract_mpi_array(struct public_key_signature *pks, 109 const void *data, size_t len) 110{ 111 size_t nbytes; 112 MPI mpi; 113 114 if (len < 3) 115 return -EBADMSG; 116 nbytes = ((const u8 *)data)[0] << 8 | ((const u8 *)data)[1]; 117 data += 2; 118 len -= 2; 119 if (len != nbytes) 120 return -EBADMSG; 121 122 mpi = mpi_read_raw_data(data, nbytes); 123 if (!mpi) 124 return -ENOMEM; 125 pks->mpi[0] = mpi; 126 pks->nr_mpi = 1; 127 return 0; 128} 129 130/* 131 * Request an asymmetric key. 132 */ 133static struct key *request_asymmetric_key(const char *signer, size_t signer_len, 134 const u8 *key_id, size_t key_id_len) 135{ 136 key_ref_t key; 137 size_t i; 138 char *id, *q; 139 140 pr_devel("==>%s(,%zu,,%zu)\n", __func__, signer_len, key_id_len); 141 142 /* Construct an identifier. */ 143 id = kmalloc(signer_len + 2 + key_id_len * 2 + 1, GFP_KERNEL); 144 if (!id) 145 return ERR_PTR(-ENOKEY); 146 147 memcpy(id, signer, signer_len); 148 149 q = id + signer_len; 150 *q++ = ':'; 151 *q++ = ' '; 152 for (i = 0; i < key_id_len; i++) { 153 *q++ = hex_asc[*key_id >> 4]; 154 *q++ = hex_asc[*key_id++ & 0x0f]; 155 } 156 157 *q = 0; 158 159 pr_debug("Look up: \"%s\"\n", id); 160 161 key = keyring_search(make_key_ref(system_trusted_keyring, 1), 162 &key_type_asymmetric, id); 163 if (IS_ERR(key)) 164 pr_warn("Request for unknown module key '%s' err %ld\n", 165 id, PTR_ERR(key)); 166 kfree(id); 167 168 if (IS_ERR(key)) { 169 switch (PTR_ERR(key)) { 170 /* Hide some search errors */ 171 case -EACCES: 172 case -ENOTDIR: 173 case -EAGAIN: 174 return ERR_PTR(-ENOKEY); 175 default: 176 return ERR_CAST(key); 177 } 178 } 179 180 pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key_ref_to_ptr(key))); 181 return key_ref_to_ptr(key); 182} 183 184/* 185 * Verify the signature on a module. 186 */ 187int mod_verify_sig(const void *mod, unsigned long *_modlen) 188{ 189 struct public_key_signature *pks; 190 struct module_signature ms; 191 struct key *key; 192 const void *sig; 193 size_t modlen = *_modlen, sig_len; 194 int ret; 195 196 pr_devel("==>%s(,%zu)\n", __func__, modlen); 197 198 if (modlen <= sizeof(ms)) 199 return -EBADMSG; 200 201 memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms)); 202 modlen -= sizeof(ms); 203 204 sig_len = be32_to_cpu(ms.sig_len); 205 if (sig_len >= modlen) 206 return -EBADMSG; 207 modlen -= sig_len; 208 if ((size_t)ms.signer_len + ms.key_id_len >= modlen) 209 return -EBADMSG; 210 modlen -= (size_t)ms.signer_len + ms.key_id_len; 211 212 *_modlen = modlen; 213 sig = mod + modlen; 214 215 /* For the moment, only support RSA and X.509 identifiers */ 216 if (ms.algo != PKEY_ALGO_RSA || 217 ms.id_type != PKEY_ID_X509) 218 return -ENOPKG; 219 220 if (ms.hash >= PKEY_HASH__LAST || 221 !hash_algo_name[ms.hash]) 222 return -ENOPKG; 223 224 key = request_asymmetric_key(sig, ms.signer_len, 225 sig + ms.signer_len, ms.key_id_len); 226 if (IS_ERR(key)) 227 return PTR_ERR(key); 228 229 pks = mod_make_digest(ms.hash, mod, modlen); 230 if (IS_ERR(pks)) { 231 ret = PTR_ERR(pks); 232 goto error_put_key; 233 } 234 235 ret = mod_extract_mpi_array(pks, sig + ms.signer_len + ms.key_id_len, 236 sig_len); 237 if (ret < 0) 238 goto error_free_pks; 239 240 ret = verify_signature(key, pks); 241 pr_devel("verify_signature() = %d\n", ret); 242 243error_free_pks: 244 mpi_free(pks->rsa.s); 245 kfree(pks); 246error_put_key: 247 key_put(key); 248 pr_devel("<==%s() = %d\n", __func__, ret); 249 return ret; 250} 251