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 */ 26static 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 */ 126static int pefile_strip_sig_wrapper(const void *pebuf, 127 struct pefile_context *ctx) 128{ 129 struct win_certificate wrapper; 130 const u8 *pkcs7; 131 unsigned len; 132 133 if (ctx->sig_len < sizeof(wrapper)) { 134 pr_debug("Signature wrapper too short\n"); 135 return -ELIBBAD; 136 } 137 138 memcpy(&wrapper, pebuf + ctx->sig_offset, sizeof(wrapper)); 139 pr_debug("sig wrapper = { %x, %x, %x }\n", 140 wrapper.length, wrapper.revision, wrapper.cert_type); 141 142 /* Both pesign and sbsign round up the length of certificate table 143 * (in optional header data directories) to 8 byte alignment. 144 */ 145 if (round_up(wrapper.length, 8) != ctx->sig_len) { 146 pr_debug("Signature wrapper len wrong\n"); 147 return -ELIBBAD; 148 } 149 if (wrapper.revision != WIN_CERT_REVISION_2_0) { 150 pr_debug("Signature is not revision 2.0\n"); 151 return -ENOTSUPP; 152 } 153 if (wrapper.cert_type != WIN_CERT_TYPE_PKCS_SIGNED_DATA) { 154 pr_debug("Signature certificate type is not PKCS\n"); 155 return -ENOTSUPP; 156 } 157 158 /* It looks like the pkcs signature length in wrapper->length and the 159 * size obtained from the data dir entries, which lists the total size 160 * of certificate table, are both aligned to an octaword boundary, so 161 * we may have to deal with some padding. 162 */ 163 ctx->sig_len = wrapper.length; 164 ctx->sig_offset += sizeof(wrapper); 165 ctx->sig_len -= sizeof(wrapper); 166 if (ctx->sig_len < 4) { 167 pr_debug("Signature data missing\n"); 168 return -EKEYREJECTED; 169 } 170 171 /* What's left should be a PKCS#7 cert */ 172 pkcs7 = pebuf + ctx->sig_offset; 173 if (pkcs7[0] != (ASN1_CONS_BIT | ASN1_SEQ)) 174 goto not_pkcs7; 175 176 switch (pkcs7[1]) { 177 case 0 ... 0x7f: 178 len = pkcs7[1] + 2; 179 goto check_len; 180 case ASN1_INDEFINITE_LENGTH: 181 return 0; 182 case 0x81: 183 len = pkcs7[2] + 3; 184 goto check_len; 185 case 0x82: 186 len = ((pkcs7[2] << 8) | pkcs7[3]) + 4; 187 goto check_len; 188 case 0x83 ... 0xff: 189 return -EMSGSIZE; 190 default: 191 goto not_pkcs7; 192 } 193 194check_len: 195 if (len <= ctx->sig_len) { 196 /* There may be padding */ 197 ctx->sig_len = len; 198 return 0; 199 } 200not_pkcs7: 201 pr_debug("Signature data not PKCS#7\n"); 202 return -ELIBBAD; 203} 204 205/* 206 * Compare two sections for canonicalisation. 207 */ 208static int pefile_compare_shdrs(const void *a, const void *b) 209{ 210 const struct section_header *shdra = a; 211 const struct section_header *shdrb = b; 212 int rc; 213 214 if (shdra->data_addr > shdrb->data_addr) 215 return 1; 216 if (shdrb->data_addr > shdra->data_addr) 217 return -1; 218 219 if (shdra->virtual_address > shdrb->virtual_address) 220 return 1; 221 if (shdrb->virtual_address > shdra->virtual_address) 222 return -1; 223 224 rc = strcmp(shdra->name, shdrb->name); 225 if (rc != 0) 226 return rc; 227 228 if (shdra->virtual_size > shdrb->virtual_size) 229 return 1; 230 if (shdrb->virtual_size > shdra->virtual_size) 231 return -1; 232 233 if (shdra->raw_data_size > shdrb->raw_data_size) 234 return 1; 235 if (shdrb->raw_data_size > shdra->raw_data_size) 236 return -1; 237 238 return 0; 239} 240 241/* 242 * Load the contents of the PE binary into the digest, leaving out the image 243 * checksum and the certificate data block. 244 */ 245static int pefile_digest_pe_contents(const void *pebuf, unsigned int pelen, 246 struct pefile_context *ctx, 247 struct shash_desc *desc) 248{ 249 unsigned *canon, tmp, loop, i, hashed_bytes; 250 int ret; 251 252 /* Digest the header and data directory, but leave out the image 253 * checksum and the data dirent for the signature. 254 */ 255 ret = crypto_shash_update(desc, pebuf, ctx->image_checksum_offset); 256 if (ret < 0) 257 return ret; 258 259 tmp = ctx->image_checksum_offset + sizeof(uint32_t); 260 ret = crypto_shash_update(desc, pebuf + tmp, 261 ctx->cert_dirent_offset - tmp); 262 if (ret < 0) 263 return ret; 264 265 tmp = ctx->cert_dirent_offset + sizeof(struct data_dirent); 266 ret = crypto_shash_update(desc, pebuf + tmp, ctx->header_size - tmp); 267 if (ret < 0) 268 return ret; 269 270 canon = kcalloc(ctx->n_sections, sizeof(unsigned), GFP_KERNEL); 271 if (!canon) 272 return -ENOMEM; 273 274 /* We have to canonicalise the section table, so we perform an 275 * insertion sort. 276 */ 277 canon[0] = 0; 278 for (loop = 1; loop < ctx->n_sections; loop++) { 279 for (i = 0; i < loop; i++) { 280 if (pefile_compare_shdrs(&ctx->secs[canon[i]], 281 &ctx->secs[loop]) > 0) { 282 memmove(&canon[i + 1], &canon[i], 283 (loop - i) * sizeof(canon[0])); 284 break; 285 } 286 } 287 canon[i] = loop; 288 } 289 290 hashed_bytes = ctx->header_size; 291 for (loop = 0; loop < ctx->n_sections; loop++) { 292 i = canon[loop]; 293 if (ctx->secs[i].raw_data_size == 0) 294 continue; 295 ret = crypto_shash_update(desc, 296 pebuf + ctx->secs[i].data_addr, 297 ctx->secs[i].raw_data_size); 298 if (ret < 0) { 299 kfree(canon); 300 return ret; 301 } 302 hashed_bytes += ctx->secs[i].raw_data_size; 303 } 304 kfree(canon); 305 306 if (pelen > hashed_bytes) { 307 tmp = hashed_bytes + ctx->certs_size; 308 ret = crypto_shash_update(desc, 309 pebuf + hashed_bytes, 310 pelen - tmp); 311 if (ret < 0) 312 return ret; 313 } 314 315 return 0; 316} 317 318/* 319 * Digest the contents of the PE binary, leaving out the image checksum and the 320 * certificate data block. 321 */ 322static int pefile_digest_pe(const void *pebuf, unsigned int pelen, 323 struct pefile_context *ctx) 324{ 325 struct crypto_shash *tfm; 326 struct shash_desc *desc; 327 size_t digest_size, desc_size; 328 void *digest; 329 int ret; 330 331 kenter(",%u", ctx->digest_algo); 332 333 /* Allocate the hashing algorithm we're going to need and find out how 334 * big the hash operational data will be. 335 */ 336 tfm = crypto_alloc_shash(hash_algo_name[ctx->digest_algo], 0, 0); 337 if (IS_ERR(tfm)) 338 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); 339 340 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 341 digest_size = crypto_shash_digestsize(tfm); 342 343 if (digest_size != ctx->digest_len) { 344 pr_debug("Digest size mismatch (%zx != %x)\n", 345 digest_size, ctx->digest_len); 346 ret = -EBADMSG; 347 goto error_no_desc; 348 } 349 pr_debug("Digest: desc=%zu size=%zu\n", desc_size, digest_size); 350 351 ret = -ENOMEM; 352 desc = kzalloc(desc_size + digest_size, GFP_KERNEL); 353 if (!desc) 354 goto error_no_desc; 355 356 desc->tfm = tfm; 357 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 358 ret = crypto_shash_init(desc); 359 if (ret < 0) 360 goto error; 361 362 ret = pefile_digest_pe_contents(pebuf, pelen, ctx, desc); 363 if (ret < 0) 364 goto error; 365 366 digest = (void *)desc + desc_size; 367 ret = crypto_shash_final(desc, digest); 368 if (ret < 0) 369 goto error; 370 371 pr_debug("Digest calc = [%*ph]\n", ctx->digest_len, digest); 372 373 /* Check that the PE file digest matches that in the MSCODE part of the 374 * PKCS#7 certificate. 375 */ 376 if (memcmp(digest, ctx->digest, ctx->digest_len) != 0) { 377 pr_debug("Digest mismatch\n"); 378 ret = -EKEYREJECTED; 379 } else { 380 pr_debug("The digests match!\n"); 381 } 382 383error: 384 kfree(desc); 385error_no_desc: 386 crypto_free_shash(tfm); 387 kleave(" = %d", ret); 388 return ret; 389} 390 391/** 392 * verify_pefile_signature - Verify the signature on a PE binary image 393 * @pebuf: Buffer containing the PE binary image 394 * @pelen: Length of the binary image 395 * @trust_keyring: Signing certificates to use as starting points 396 * @_trusted: Set to true if trustworth, false otherwise 397 * 398 * Validate that the certificate chain inside the PKCS#7 message inside the PE 399 * binary image intersects keys we already know and trust. 400 * 401 * Returns, in order of descending priority: 402 * 403 * (*) -ELIBBAD if the image cannot be parsed, or: 404 * 405 * (*) -EKEYREJECTED if a signature failed to match for which we have a valid 406 * key, or: 407 * 408 * (*) 0 if at least one signature chain intersects with the keys in the trust 409 * keyring, or: 410 * 411 * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a 412 * chain. 413 * 414 * (*) -ENOKEY if we couldn't find a match for any of the signature chains in 415 * the message. 416 * 417 * May also return -ENOMEM. 418 */ 419int verify_pefile_signature(const void *pebuf, unsigned pelen, 420 struct key *trusted_keyring, bool *_trusted) 421{ 422 struct pkcs7_message *pkcs7; 423 struct pefile_context ctx; 424 const void *data; 425 size_t datalen; 426 int ret; 427 428 kenter(""); 429 430 memset(&ctx, 0, sizeof(ctx)); 431 ret = pefile_parse_binary(pebuf, pelen, &ctx); 432 if (ret < 0) 433 return ret; 434 435 ret = pefile_strip_sig_wrapper(pebuf, &ctx); 436 if (ret < 0) 437 return ret; 438 439 pkcs7 = pkcs7_parse_message(pebuf + ctx.sig_offset, ctx.sig_len); 440 if (IS_ERR(pkcs7)) 441 return PTR_ERR(pkcs7); 442 ctx.pkcs7 = pkcs7; 443 444 ret = pkcs7_get_content_data(ctx.pkcs7, &data, &datalen, false); 445 if (ret < 0 || datalen == 0) { 446 pr_devel("PKCS#7 message does not contain data\n"); 447 ret = -EBADMSG; 448 goto error; 449 } 450 451 ret = mscode_parse(&ctx); 452 if (ret < 0) 453 goto error; 454 455 pr_debug("Digest: %u [%*ph]\n", 456 ctx.digest_len, ctx.digest_len, ctx.digest); 457 458 /* Generate the digest and check against the PKCS7 certificate 459 * contents. 460 */ 461 ret = pefile_digest_pe(pebuf, pelen, &ctx); 462 if (ret < 0) 463 goto error; 464 465 ret = pkcs7_verify(pkcs7); 466 if (ret < 0) 467 goto error; 468 469 ret = pkcs7_validate_trust(pkcs7, trusted_keyring, _trusted); 470 471error: 472 pkcs7_free_message(ctx.pkcs7); 473 return ret; 474} 475