1 /* Parse a signed PE binary 2 * 3 * Copyright (C) 2014 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 #define pr_fmt(fmt) "PEFILE: "fmt 13 #include <linux/module.h> 14 #include <linux/kernel.h> 15 #include <linux/slab.h> 16 #include <linux/err.h> 17 #include <linux/pe.h> 18 #include <linux/asn1.h> 19 #include <crypto/pkcs7.h> 20 #include <crypto/hash.h> 21 #include "verify_pefile.h" 22 23 /* 24 * Parse a PE binary. 25 */ 26 static int pefile_parse_binary(const void *pebuf, unsigned int pelen, 27 struct pefile_context *ctx) 28 { 29 const struct mz_hdr *mz = pebuf; 30 const struct pe_hdr *pe; 31 const struct pe32_opt_hdr *pe32; 32 const struct pe32plus_opt_hdr *pe64; 33 const struct data_directory *ddir; 34 const struct data_dirent *dde; 35 const struct section_header *secs, *sec; 36 size_t cursor, datalen = pelen; 37 38 kenter(""); 39 40 #define chkaddr(base, x, s) \ 41 do { \ 42 if ((x) < base || (s) >= datalen || (x) > datalen - (s)) \ 43 return -ELIBBAD; \ 44 } while (0) 45 46 chkaddr(0, 0, sizeof(*mz)); 47 if (mz->magic != MZ_MAGIC) 48 return -ELIBBAD; 49 cursor = sizeof(*mz); 50 51 chkaddr(cursor, mz->peaddr, sizeof(*pe)); 52 pe = pebuf + mz->peaddr; 53 if (pe->magic != PE_MAGIC) 54 return -ELIBBAD; 55 cursor = mz->peaddr + sizeof(*pe); 56 57 chkaddr(0, cursor, sizeof(pe32->magic)); 58 pe32 = pebuf + cursor; 59 pe64 = pebuf + cursor; 60 61 switch (pe32->magic) { 62 case PE_OPT_MAGIC_PE32: 63 chkaddr(0, cursor, sizeof(*pe32)); 64 ctx->image_checksum_offset = 65 (unsigned long)&pe32->csum - (unsigned long)pebuf; 66 ctx->header_size = pe32->header_size; 67 cursor += sizeof(*pe32); 68 ctx->n_data_dirents = pe32->data_dirs; 69 break; 70 71 case PE_OPT_MAGIC_PE32PLUS: 72 chkaddr(0, cursor, sizeof(*pe64)); 73 ctx->image_checksum_offset = 74 (unsigned long)&pe64->csum - (unsigned long)pebuf; 75 ctx->header_size = pe64->header_size; 76 cursor += sizeof(*pe64); 77 ctx->n_data_dirents = pe64->data_dirs; 78 break; 79 80 default: 81 pr_debug("Unknown PEOPT magic = %04hx\n", pe32->magic); 82 return -ELIBBAD; 83 } 84 85 pr_debug("checksum @ %x\n", ctx->image_checksum_offset); 86 pr_debug("header size = %x\n", ctx->header_size); 87 88 if (cursor >= ctx->header_size || ctx->header_size >= datalen) 89 return -ELIBBAD; 90 91 if (ctx->n_data_dirents > (ctx->header_size - cursor) / sizeof(*dde)) 92 return -ELIBBAD; 93 94 ddir = pebuf + cursor; 95 cursor += sizeof(*dde) * ctx->n_data_dirents; 96 97 ctx->cert_dirent_offset = 98 (unsigned long)&ddir->certs - (unsigned long)pebuf; 99 ctx->certs_size = ddir->certs.size; 100 101 if (!ddir->certs.virtual_address || !ddir->certs.size) { 102 pr_debug("Unsigned PE binary\n"); 103 return -EKEYREJECTED; 104 } 105 106 chkaddr(ctx->header_size, ddir->certs.virtual_address, 107 ddir->certs.size); 108 ctx->sig_offset = ddir->certs.virtual_address; 109 ctx->sig_len = ddir->certs.size; 110 pr_debug("cert = %x @%x [%*ph]\n", 111 ctx->sig_len, ctx->sig_offset, 112 ctx->sig_len, pebuf + ctx->sig_offset); 113 114 ctx->n_sections = pe->sections; 115 if (ctx->n_sections > (ctx->header_size - cursor) / sizeof(*sec)) 116 return -ELIBBAD; 117 ctx->secs = secs = pebuf + cursor; 118 119 return 0; 120 } 121 122 /* 123 * Check and strip the PE wrapper from around the signature and check that the 124 * remnant looks something like PKCS#7. 125 */ 126 static int pefile_strip_sig_wrapper(const void *pebuf, 127 struct pefile_context *ctx) 128 { 129 struct win_certificate wrapper; 130 const u8 *pkcs7; 131 132 if (ctx->sig_len < sizeof(wrapper)) { 133 pr_debug("Signature wrapper too short\n"); 134 return -ELIBBAD; 135 } 136 137 memcpy(&wrapper, pebuf + ctx->sig_offset, sizeof(wrapper)); 138 pr_debug("sig wrapper = { %x, %x, %x }\n", 139 wrapper.length, wrapper.revision, wrapper.cert_type); 140 141 /* Both pesign and sbsign round up the length of certificate table 142 * (in optional header data directories) to 8 byte alignment. 143 */ 144 if (round_up(wrapper.length, 8) != ctx->sig_len) { 145 pr_debug("Signature wrapper len wrong\n"); 146 return -ELIBBAD; 147 } 148 if (wrapper.revision != WIN_CERT_REVISION_2_0) { 149 pr_debug("Signature is not revision 2.0\n"); 150 return -ENOTSUPP; 151 } 152 if (wrapper.cert_type != WIN_CERT_TYPE_PKCS_SIGNED_DATA) { 153 pr_debug("Signature certificate type is not PKCS\n"); 154 return -ENOTSUPP; 155 } 156 157 /* Looks like actual pkcs signature length is in wrapper->length. 158 * size obtained from data dir entries lists the total size of 159 * certificate table which is also aligned to octawrod boundary. 160 * 161 * So set signature length field appropriately. 162 */ 163 ctx->sig_len = wrapper.length; 164 ctx->sig_offset += sizeof(wrapper); 165 ctx->sig_len -= sizeof(wrapper); 166 if (ctx->sig_len == 0) { 167 pr_debug("Signature data missing\n"); 168 return -EKEYREJECTED; 169 } 170 171 /* What's left should a PKCS#7 cert */ 172 pkcs7 = pebuf + ctx->sig_offset; 173 if (pkcs7[0] == (ASN1_CONS_BIT | ASN1_SEQ)) { 174 if (pkcs7[1] == 0x82 && 175 pkcs7[2] == (((ctx->sig_len - 4) >> 8) & 0xff) && 176 pkcs7[3] == ((ctx->sig_len - 4) & 0xff)) 177 return 0; 178 if (pkcs7[1] == 0x80) 179 return 0; 180 if (pkcs7[1] > 0x82) 181 return -EMSGSIZE; 182 } 183 184 pr_debug("Signature data not PKCS#7\n"); 185 return -ELIBBAD; 186 } 187 188 /* 189 * Compare two sections for canonicalisation. 190 */ 191 static int pefile_compare_shdrs(const void *a, const void *b) 192 { 193 const struct section_header *shdra = a; 194 const struct section_header *shdrb = b; 195 int rc; 196 197 if (shdra->data_addr > shdrb->data_addr) 198 return 1; 199 if (shdrb->data_addr > shdra->data_addr) 200 return -1; 201 202 if (shdra->virtual_address > shdrb->virtual_address) 203 return 1; 204 if (shdrb->virtual_address > shdra->virtual_address) 205 return -1; 206 207 rc = strcmp(shdra->name, shdrb->name); 208 if (rc != 0) 209 return rc; 210 211 if (shdra->virtual_size > shdrb->virtual_size) 212 return 1; 213 if (shdrb->virtual_size > shdra->virtual_size) 214 return -1; 215 216 if (shdra->raw_data_size > shdrb->raw_data_size) 217 return 1; 218 if (shdrb->raw_data_size > shdra->raw_data_size) 219 return -1; 220 221 return 0; 222 } 223 224 /* 225 * Load the contents of the PE binary into the digest, leaving out the image 226 * checksum and the certificate data block. 227 */ 228 static int pefile_digest_pe_contents(const void *pebuf, unsigned int pelen, 229 struct pefile_context *ctx, 230 struct shash_desc *desc) 231 { 232 unsigned *canon, tmp, loop, i, hashed_bytes; 233 int ret; 234 235 /* Digest the header and data directory, but leave out the image 236 * checksum and the data dirent for the signature. 237 */ 238 ret = crypto_shash_update(desc, pebuf, ctx->image_checksum_offset); 239 if (ret < 0) 240 return ret; 241 242 tmp = ctx->image_checksum_offset + sizeof(uint32_t); 243 ret = crypto_shash_update(desc, pebuf + tmp, 244 ctx->cert_dirent_offset - tmp); 245 if (ret < 0) 246 return ret; 247 248 tmp = ctx->cert_dirent_offset + sizeof(struct data_dirent); 249 ret = crypto_shash_update(desc, pebuf + tmp, ctx->header_size - tmp); 250 if (ret < 0) 251 return ret; 252 253 canon = kcalloc(ctx->n_sections, sizeof(unsigned), GFP_KERNEL); 254 if (!canon) 255 return -ENOMEM; 256 257 /* We have to canonicalise the section table, so we perform an 258 * insertion sort. 259 */ 260 canon[0] = 0; 261 for (loop = 1; loop < ctx->n_sections; loop++) { 262 for (i = 0; i < loop; i++) { 263 if (pefile_compare_shdrs(&ctx->secs[canon[i]], 264 &ctx->secs[loop]) > 0) { 265 memmove(&canon[i + 1], &canon[i], 266 (loop - i) * sizeof(canon[0])); 267 break; 268 } 269 } 270 canon[i] = loop; 271 } 272 273 hashed_bytes = ctx->header_size; 274 for (loop = 0; loop < ctx->n_sections; loop++) { 275 i = canon[loop]; 276 if (ctx->secs[i].raw_data_size == 0) 277 continue; 278 ret = crypto_shash_update(desc, 279 pebuf + ctx->secs[i].data_addr, 280 ctx->secs[i].raw_data_size); 281 if (ret < 0) { 282 kfree(canon); 283 return ret; 284 } 285 hashed_bytes += ctx->secs[i].raw_data_size; 286 } 287 kfree(canon); 288 289 if (pelen > hashed_bytes) { 290 tmp = hashed_bytes + ctx->certs_size; 291 ret = crypto_shash_update(desc, 292 pebuf + hashed_bytes, 293 pelen - tmp); 294 if (ret < 0) 295 return ret; 296 } 297 298 return 0; 299 } 300 301 /* 302 * Digest the contents of the PE binary, leaving out the image checksum and the 303 * certificate data block. 304 */ 305 static int pefile_digest_pe(const void *pebuf, unsigned int pelen, 306 struct pefile_context *ctx) 307 { 308 struct crypto_shash *tfm; 309 struct shash_desc *desc; 310 size_t digest_size, desc_size; 311 void *digest; 312 int ret; 313 314 kenter(",%u", ctx->digest_algo); 315 316 /* Allocate the hashing algorithm we're going to need and find out how 317 * big the hash operational data will be. 318 */ 319 tfm = crypto_alloc_shash(hash_algo_name[ctx->digest_algo], 0, 0); 320 if (IS_ERR(tfm)) 321 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); 322 323 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 324 digest_size = crypto_shash_digestsize(tfm); 325 326 if (digest_size != ctx->digest_len) { 327 pr_debug("Digest size mismatch (%zx != %x)\n", 328 digest_size, ctx->digest_len); 329 ret = -EBADMSG; 330 goto error_no_desc; 331 } 332 pr_debug("Digest: desc=%zu size=%zu\n", desc_size, digest_size); 333 334 ret = -ENOMEM; 335 desc = kzalloc(desc_size + digest_size, GFP_KERNEL); 336 if (!desc) 337 goto error_no_desc; 338 339 desc->tfm = tfm; 340 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 341 ret = crypto_shash_init(desc); 342 if (ret < 0) 343 goto error; 344 345 ret = pefile_digest_pe_contents(pebuf, pelen, ctx, desc); 346 if (ret < 0) 347 goto error; 348 349 digest = (void *)desc + desc_size; 350 ret = crypto_shash_final(desc, digest); 351 if (ret < 0) 352 goto error; 353 354 pr_debug("Digest calc = [%*ph]\n", ctx->digest_len, digest); 355 356 /* Check that the PE file digest matches that in the MSCODE part of the 357 * PKCS#7 certificate. 358 */ 359 if (memcmp(digest, ctx->digest, ctx->digest_len) != 0) { 360 pr_debug("Digest mismatch\n"); 361 ret = -EKEYREJECTED; 362 } else { 363 pr_debug("The digests match!\n"); 364 } 365 366 error: 367 kfree(desc); 368 error_no_desc: 369 crypto_free_shash(tfm); 370 kleave(" = %d", ret); 371 return ret; 372 } 373 374 /** 375 * verify_pefile_signature - Verify the signature on a PE binary image 376 * @pebuf: Buffer containing the PE binary image 377 * @pelen: Length of the binary image 378 * @trust_keyring: Signing certificates to use as starting points 379 * @_trusted: Set to true if trustworth, false otherwise 380 * 381 * Validate that the certificate chain inside the PKCS#7 message inside the PE 382 * binary image intersects keys we already know and trust. 383 * 384 * Returns, in order of descending priority: 385 * 386 * (*) -ELIBBAD if the image cannot be parsed, or: 387 * 388 * (*) -EKEYREJECTED if a signature failed to match for which we have a valid 389 * key, or: 390 * 391 * (*) 0 if at least one signature chain intersects with the keys in the trust 392 * keyring, or: 393 * 394 * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a 395 * chain. 396 * 397 * (*) -ENOKEY if we couldn't find a match for any of the signature chains in 398 * the message. 399 * 400 * May also return -ENOMEM. 401 */ 402 int verify_pefile_signature(const void *pebuf, unsigned pelen, 403 struct key *trusted_keyring, bool *_trusted) 404 { 405 struct pkcs7_message *pkcs7; 406 struct pefile_context ctx; 407 const void *data; 408 size_t datalen; 409 int ret; 410 411 kenter(""); 412 413 memset(&ctx, 0, sizeof(ctx)); 414 ret = pefile_parse_binary(pebuf, pelen, &ctx); 415 if (ret < 0) 416 return ret; 417 418 ret = pefile_strip_sig_wrapper(pebuf, &ctx); 419 if (ret < 0) 420 return ret; 421 422 pkcs7 = pkcs7_parse_message(pebuf + ctx.sig_offset, ctx.sig_len); 423 if (IS_ERR(pkcs7)) 424 return PTR_ERR(pkcs7); 425 ctx.pkcs7 = pkcs7; 426 427 ret = pkcs7_get_content_data(ctx.pkcs7, &data, &datalen, false); 428 if (ret < 0 || datalen == 0) { 429 pr_devel("PKCS#7 message does not contain data\n"); 430 ret = -EBADMSG; 431 goto error; 432 } 433 434 ret = mscode_parse(&ctx); 435 if (ret < 0) 436 goto error; 437 438 pr_debug("Digest: %u [%*ph]\n", 439 ctx.digest_len, ctx.digest_len, ctx.digest); 440 441 /* Generate the digest and check against the PKCS7 certificate 442 * contents. 443 */ 444 ret = pefile_digest_pe(pebuf, pelen, &ctx); 445 if (ret < 0) 446 goto error; 447 448 ret = pkcs7_verify(pkcs7); 449 if (ret < 0) 450 goto error; 451 452 ret = pkcs7_validate_trust(pkcs7, trusted_keyring, _trusted); 453 454 error: 455 pkcs7_free_message(ctx.pkcs7); 456 return ret; 457 } 458