1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2018 Patrick Wildt <patrick@blueri.se> 4 * Copyright (c) 2019 Linaro Limited, Author: AKASHI Takahiro 5 */ 6 7#include <charset.h> 8#include <efi_loader.h> 9#include <efi_variable.h> 10#include <image.h> 11#include <hexdump.h> 12#include <malloc.h> 13#include <crypto/pkcs7.h> 14#include <crypto/pkcs7_parser.h> 15#include <crypto/public_key.h> 16#include <linux/compat.h> 17#include <linux/oid_registry.h> 18#include <u-boot/hash-checksum.h> 19#include <u-boot/rsa.h> 20#include <u-boot/sha256.h> 21 22const efi_guid_t efi_guid_sha256 = EFI_CERT_SHA256_GUID; 23const efi_guid_t efi_guid_cert_rsa2048 = EFI_CERT_RSA2048_GUID; 24const efi_guid_t efi_guid_cert_x509 = EFI_CERT_X509_GUID; 25const efi_guid_t efi_guid_cert_x509_sha256 = EFI_CERT_X509_SHA256_GUID; 26const efi_guid_t efi_guid_cert_x509_sha384 = EFI_CERT_X509_SHA384_GUID; 27const efi_guid_t efi_guid_cert_x509_sha512 = EFI_CERT_X509_SHA512_GUID; 28const efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; 29 30static u8 pkcs7_hdr[] = { 31 /* SEQUENCE */ 32 0x30, 0x82, 0x05, 0xc7, 33 /* OID: pkcs7-signedData */ 34 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 35 /* Context Structured? */ 36 0xa0, 0x82, 0x05, 0xb8, 37}; 38 39/** 40 * efi_parse_pkcs7_header - parse a signature in payload 41 * @buf: Pointer to payload's value 42 * @buflen: Length of @buf 43 * @tmpbuf: Pointer to temporary buffer 44 * 45 * Parse a signature embedded in payload's value and instantiate 46 * a pkcs7_message structure. Since pkcs7_parse_message() accepts only 47 * pkcs7's signedData, some header needed be prepended for correctly 48 * parsing authentication data 49 * A temporary buffer will be allocated if needed, and it should be 50 * kept valid during the authentication because some data in the buffer 51 * will be referenced by efi_signature_verify(). 52 * 53 * Return: Pointer to pkcs7_message structure on success, NULL on error 54 */ 55struct pkcs7_message *efi_parse_pkcs7_header(const void *buf, 56 size_t buflen, 57 u8 **tmpbuf) 58{ 59 u8 *ebuf; 60 size_t ebuflen, len; 61 struct pkcs7_message *msg; 62 63 /* 64 * This is the best assumption to check if the binary is 65 * already in a form of pkcs7's signedData. 66 */ 67 if (buflen > sizeof(pkcs7_hdr) && 68 !memcmp(&((u8 *)buf)[4], &pkcs7_hdr[4], 11)) { 69 msg = pkcs7_parse_message(buf, buflen); 70 if (IS_ERR(msg)) 71 return NULL; 72 return msg; 73 } 74 75 /* 76 * Otherwise, we should add a dummy prefix sequence for pkcs7 77 * message parser to be able to process. 78 * NOTE: EDK2 also uses similar hack in WrapPkcs7Data() 79 * in CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c 80 * TODO: 81 * The header should be composed in a more refined manner. 82 */ 83 EFI_PRINT("Makeshift prefix added to authentication data\n"); 84 ebuflen = sizeof(pkcs7_hdr) + buflen; 85 if (ebuflen <= 0x7f) { 86 EFI_PRINT("Data is too short\n"); 87 return NULL; 88 } 89 90 ebuf = malloc(ebuflen); 91 if (!ebuf) { 92 EFI_PRINT("Out of memory\n"); 93 return NULL; 94 } 95 96 memcpy(ebuf, pkcs7_hdr, sizeof(pkcs7_hdr)); 97 memcpy(ebuf + sizeof(pkcs7_hdr), buf, buflen); 98 len = ebuflen - 4; 99 ebuf[2] = (len >> 8) & 0xff; 100 ebuf[3] = len & 0xff; 101 len = ebuflen - 0x13; 102 ebuf[0x11] = (len >> 8) & 0xff; 103 ebuf[0x12] = len & 0xff; 104 105 msg = pkcs7_parse_message(ebuf, ebuflen); 106 107 if (IS_ERR(msg)) { 108 free(ebuf); 109 return NULL; 110 } 111 112 *tmpbuf = ebuf; 113 return msg; 114} 115 116/** 117 * efi_hash_regions - calculate a hash value 118 * @regs: Array of regions 119 * @count: Number of regions 120 * @hash: Pointer to a pointer to buffer holding a hash value 121 * @size: Size of buffer to be returned 122 * 123 * Calculate a sha256 value of @regs and return a value in @hash. 124 * 125 * Return: true on success, false on error 126 */ 127bool efi_hash_regions(struct image_region *regs, int count, 128 void **hash, const char *hash_algo, int *len) 129{ 130 int ret, hash_len; 131 132 if (!hash_algo) 133 return false; 134 135 hash_len = algo_to_len(hash_algo); 136 if (!hash_len) 137 return false; 138 139 if (!*hash) { 140 *hash = calloc(1, hash_len); 141 if (!*hash) { 142 EFI_PRINT("Out of memory\n"); 143 return false; 144 } 145 } 146 147 ret = hash_calculate(hash_algo, regs, count, *hash); 148 if (ret) 149 return false; 150 151 if (len) 152 *len = hash_len; 153#ifdef DEBUG 154 EFI_PRINT("hash calculated:\n"); 155 print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1, 156 *hash, hash_len, false); 157#endif 158 159 return true; 160} 161 162/** 163 * hash_algo_supported - check if the requested hash algorithm is supported 164 * @guid: guid of the algorithm 165 * 166 * Return: true if supported false otherwise 167 */ 168static bool hash_algo_supported(const efi_guid_t guid) 169{ 170 int i; 171 const efi_guid_t unsupported_hashes[] = { 172 EFI_CERT_SHA1_GUID, 173 EFI_CERT_SHA224_GUID, 174 EFI_CERT_SHA384_GUID, 175 EFI_CERT_SHA512_GUID, 176 }; 177 178 for (i = 0; i < ARRAY_SIZE(unsupported_hashes); i++) { 179 if (!guidcmp(&unsupported_hashes[i], &guid)) 180 return false; 181 } 182 183 return true; 184} 185 186/** 187 * efi_signature_lookup_digest - search for an image's digest in sigdb 188 * @regs: List of regions to be authenticated 189 * @db: Signature database for trusted certificates 190 * @dbx Caller needs to set this to true if he is searching dbx 191 * 192 * A message digest of image pointed to by @regs is calculated and 193 * its hash value is compared to entries in signature database pointed 194 * to by @db. 195 * 196 * Return: true if found, false if not 197 */ 198bool efi_signature_lookup_digest(struct efi_image_regions *regs, 199 struct efi_signature_store *db, 200 bool dbx) 201 202{ 203 struct efi_signature_store *siglist; 204 struct efi_sig_data *sig_data; 205 void *hash = NULL; 206 bool found = false; 207 bool hash_done = false; 208 209 EFI_PRINT("%s: Enter, %p, %p\n", __func__, regs, db); 210 211 if (!regs || !db || !db->sig_data_list) 212 goto out; 213 214 for (siglist = db; siglist; siglist = siglist->next) { 215 int len = 0; 216 const char *hash_algo = NULL; 217 /* 218 * if the hash algorithm is unsupported and we get an entry in 219 * dbx reject the image 220 */ 221 if (dbx && !hash_algo_supported(siglist->sig_type)) { 222 found = true; 223 continue; 224 }; 225 /* 226 * Only support sha256 for now, that's what 227 * hash-to-efi-sig-list produces 228 */ 229 if (guidcmp(&siglist->sig_type, &efi_guid_sha256)) 230 continue; 231 232 hash_algo = guid_to_sha_str(&efi_guid_sha256); 233 /* 234 * We could check size and hash_algo but efi_hash_regions() 235 * will do that for us 236 */ 237 if (!hash_done && 238 !efi_hash_regions(regs->reg, regs->num, &hash, hash_algo, 239 &len)) { 240 EFI_PRINT("Digesting an image failed\n"); 241 break; 242 } 243 hash_done = true; 244 245 for (sig_data = siglist->sig_data_list; sig_data; 246 sig_data = sig_data->next) { 247#ifdef DEBUG 248 EFI_PRINT("Msg digest in database:\n"); 249 print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1, 250 sig_data->data, sig_data->size, false); 251#endif 252 if (sig_data->size == len && 253 !memcmp(sig_data->data, hash, len)) { 254 found = true; 255 free(hash); 256 goto out; 257 } 258 } 259 260 free(hash); 261 hash = NULL; 262 } 263 264out: 265 EFI_PRINT("%s: Exit, found: %d\n", __func__, found); 266 return found; 267} 268 269/** 270 * efi_lookup_certificate - find a certificate within db 271 * @msg: Signature 272 * @db: Signature database 273 * 274 * Search signature database pointed to by @db and find a certificate 275 * pointed to by @cert. 276 * 277 * Return: true if found, false otherwise. 278 */ 279static bool efi_lookup_certificate(struct x509_certificate *cert, 280 struct efi_signature_store *db) 281{ 282 struct efi_signature_store *siglist; 283 struct efi_sig_data *sig_data; 284 struct image_region reg[1]; 285 void *hash = NULL, *hash_tmp = NULL; 286 int len = 0; 287 bool found = false; 288 const char *hash_algo = NULL; 289 290 EFI_PRINT("%s: Enter, %p, %p\n", __func__, cert, db); 291 292 if (!cert || !db || !db->sig_data_list) 293 goto out; 294 295 /* 296 * TODO: identify a certificate using sha256 digest 297 * Is there any better way? 298 */ 299 /* calculate hash of TBSCertificate */ 300 reg[0].data = cert->tbs; 301 reg[0].size = cert->tbs_size; 302 303 /* We just need any sha256 algo to start the matching */ 304 hash_algo = guid_to_sha_str(&efi_guid_sha256); 305 if (!efi_hash_regions(reg, 1, &hash, hash_algo, &len)) 306 goto out; 307 308 EFI_PRINT("%s: searching for %s\n", __func__, cert->subject); 309 for (siglist = db; siglist; siglist = siglist->next) { 310 /* only with x509 certificate */ 311 if (guidcmp(&siglist->sig_type, &efi_guid_cert_x509)) 312 continue; 313 314 for (sig_data = siglist->sig_data_list; sig_data; 315 sig_data = sig_data->next) { 316 struct x509_certificate *cert_tmp; 317 318 cert_tmp = x509_cert_parse(sig_data->data, 319 sig_data->size); 320 if (IS_ERR_OR_NULL(cert_tmp)) 321 continue; 322 323 EFI_PRINT("%s: against %s\n", __func__, 324 cert_tmp->subject); 325 reg[0].data = cert_tmp->tbs; 326 reg[0].size = cert_tmp->tbs_size; 327 if (!efi_hash_regions(reg, 1, &hash_tmp, hash_algo, 328 NULL)) 329 goto out; 330 331 x509_free_certificate(cert_tmp); 332 333 if (!memcmp(hash, hash_tmp, len)) { 334 found = true; 335 goto out; 336 } 337 } 338 } 339out: 340 free(hash); 341 free(hash_tmp); 342 343 EFI_PRINT("%s: Exit, found: %d\n", __func__, found); 344 return found; 345} 346 347/** 348 * efi_verify_certificate - verify certificate's signature with database 349 * @signer: Certificate 350 * @db: Signature database 351 * @root: Certificate to verify @signer 352 * 353 * Determine if certificate pointed to by @signer may be verified 354 * by one of certificates in signature database pointed to by @db. 355 * 356 * Return: true if certificate is verified, false otherwise. 357 */ 358static bool efi_verify_certificate(struct x509_certificate *signer, 359 struct efi_signature_store *db, 360 struct x509_certificate **root) 361{ 362 struct efi_signature_store *siglist; 363 struct efi_sig_data *sig_data; 364 struct x509_certificate *cert; 365 bool verified = false; 366 int ret; 367 368 EFI_PRINT("%s: Enter, %p, %p\n", __func__, signer, db); 369 370 if (!signer || !db || !db->sig_data_list) 371 goto out; 372 373 for (siglist = db; siglist; siglist = siglist->next) { 374 /* only with x509 certificate */ 375 if (guidcmp(&siglist->sig_type, &efi_guid_cert_x509)) 376 continue; 377 378 for (sig_data = siglist->sig_data_list; sig_data; 379 sig_data = sig_data->next) { 380 cert = x509_cert_parse(sig_data->data, sig_data->size); 381 if (IS_ERR_OR_NULL(cert)) { 382 EFI_PRINT("Cannot parse x509 certificate\n"); 383 continue; 384 } 385 386 ret = public_key_verify_signature(cert->pub, 387 signer->sig); 388 if (!ret) { 389 verified = true; 390 if (root) 391 *root = cert; 392 else 393 x509_free_certificate(cert); 394 goto out; 395 } 396 x509_free_certificate(cert); 397 } 398 } 399 400out: 401 EFI_PRINT("%s: Exit, verified: %d\n", __func__, verified); 402 return verified; 403} 404 405/** 406 * efi_signature_check_revocation - check revocation with dbx 407 * @sinfo: Signer's info 408 * @cert: x509 certificate 409 * @dbx: Revocation signature database 410 * 411 * Search revocation signature database pointed to by @dbx and find 412 * an entry matching to certificate pointed to by @cert. 413 * 414 * While this entry contains revocation time, we don't support timestamp 415 * protocol at this time and any image will be unconditionally revoked 416 * when this match occurs. 417 * 418 * Return: true if check passed (not found), false otherwise. 419 */ 420static bool efi_signature_check_revocation(struct pkcs7_signed_info *sinfo, 421 struct x509_certificate *cert, 422 struct efi_signature_store *dbx) 423{ 424 struct efi_signature_store *siglist; 425 struct efi_sig_data *sig_data; 426 struct image_region reg[1]; 427 void *hash = NULL; 428 int len = 0; 429 time64_t revoc_time; 430 bool revoked = false; 431 const char *hash_algo = NULL; 432 433 EFI_PRINT("%s: Enter, %p, %p, %p\n", __func__, sinfo, cert, dbx); 434 435 if (!sinfo || !cert || !dbx || !dbx->sig_data_list) 436 goto out; 437 438 EFI_PRINT("Checking revocation against %s\n", cert->subject); 439 for (siglist = dbx; siglist; siglist = siglist->next) { 440 hash_algo = guid_to_sha_str(&siglist->sig_type); 441 if (!hash_algo) 442 continue; 443 444 /* calculate hash of TBSCertificate */ 445 reg[0].data = cert->tbs; 446 reg[0].size = cert->tbs_size; 447 if (!efi_hash_regions(reg, 1, &hash, hash_algo, &len)) 448 goto out; 449 450 for (sig_data = siglist->sig_data_list; sig_data; 451 sig_data = sig_data->next) { 452 /* 453 * struct efi_cert_x509_sha256 { 454 * u8 tbs_hash[256/8]; 455 * time64_t revocation_time; 456 * }; 457 */ 458#ifdef DEBUG 459 if (sig_data->size >= len) { 460 EFI_PRINT("hash in db:\n"); 461 print_hex_dump(" ", DUMP_PREFIX_OFFSET, 462 16, 1, 463 sig_data->data, len, false); 464 } 465#endif 466 if ((sig_data->size < len + sizeof(time64_t)) || 467 memcmp(sig_data->data, hash, len)) 468 continue; 469 470 memcpy(&revoc_time, sig_data->data + len, 471 sizeof(revoc_time)); 472 EFI_PRINT("revocation time: 0x%llx\n", revoc_time); 473 /* 474 * TODO: compare signing timestamp in sinfo 475 * with revocation time 476 */ 477 478 revoked = true; 479 free(hash); 480 goto out; 481 } 482 free(hash); 483 hash = NULL; 484 } 485out: 486 EFI_PRINT("%s: Exit, revoked: %d\n", __func__, revoked); 487 return !revoked; 488} 489 490/* 491 * efi_signature_verify - verify signatures with db and dbx 492 * @regs: List of regions to be authenticated 493 * @msg: Signature 494 * @db: Signature database for trusted certificates 495 * @dbx: Revocation signature database 496 * 497 * All the signature pointed to by @msg against image pointed to by @regs 498 * will be verified by signature database pointed to by @db and @dbx. 499 * 500 * Return: true if verification for all signatures passed, false otherwise 501 */ 502bool efi_signature_verify(struct efi_image_regions *regs, 503 struct pkcs7_message *msg, 504 struct efi_signature_store *db, 505 struct efi_signature_store *dbx) 506{ 507 struct pkcs7_signed_info *sinfo; 508 struct x509_certificate *signer, *root; 509 bool verified = false; 510 int ret; 511 512 EFI_PRINT("%s: Enter, %p, %p, %p, %p\n", __func__, regs, msg, db, dbx); 513 514 if (!regs || !msg || !db || !db->sig_data_list) 515 goto out; 516 517 for (sinfo = msg->signed_infos; sinfo; sinfo = sinfo->next) { 518 EFI_PRINT("Signed Info: digest algo: %s, pkey algo: %s\n", 519 sinfo->sig->hash_algo, sinfo->sig->pkey_algo); 520 521 /* 522 * only for authenticated variable. 523 * 524 * If this function is called for image, 525 * hash calculation will be done in 526 * pkcs7_verify_one(). 527 */ 528 if (!msg->data && 529 !efi_hash_regions(regs->reg, regs->num, 530 (void **)&sinfo->sig->digest, 531 guid_to_sha_str(&efi_guid_sha256), 532 NULL)) { 533 EFI_PRINT("Digesting an image failed\n"); 534 goto out; 535 } 536 537 EFI_PRINT("Verifying certificate chain\n"); 538 signer = NULL; 539 ret = pkcs7_verify_one(msg, sinfo, &signer); 540 if (ret == -ENOPKG) 541 continue; 542 543 if (ret < 0 || !signer) 544 goto out; 545 546 if (sinfo->blacklisted) 547 goto out; 548 549 EFI_PRINT("Verifying last certificate in chain\n"); 550 if (efi_lookup_certificate(signer, db)) 551 if (efi_signature_check_revocation(sinfo, signer, dbx)) 552 break; 553 if (!signer->self_signed && 554 efi_verify_certificate(signer, db, &root)) { 555 bool check; 556 557 check = efi_signature_check_revocation(sinfo, root, 558 dbx); 559 x509_free_certificate(root); 560 if (check) 561 break; 562 } 563 564 EFI_PRINT("Certificate chain didn't reach trusted CA\n"); 565 } 566 if (sinfo) 567 verified = true; 568out: 569 EFI_PRINT("%s: Exit, verified: %d\n", __func__, verified); 570 return verified; 571} 572 573/** 574 * efi_signature_check_signers - check revocation against all signers with dbx 575 * @msg: Signature 576 * @dbx: Revocation signature database 577 * 578 * Determine if none of signers' certificates in @msg are revoked 579 * by signature database pointed to by @dbx. 580 * 581 * Return: true if all signers passed, false otherwise. 582 */ 583bool efi_signature_check_signers(struct pkcs7_message *msg, 584 struct efi_signature_store *dbx) 585{ 586 struct pkcs7_signed_info *sinfo; 587 bool revoked = false; 588 589 EFI_PRINT("%s: Enter, %p, %p\n", __func__, msg, dbx); 590 591 if (!msg || !dbx) 592 goto out; 593 594 for (sinfo = msg->signed_infos; sinfo; sinfo = sinfo->next) { 595 if (sinfo->signer && 596 !efi_signature_check_revocation(sinfo, sinfo->signer, 597 dbx)) { 598 revoked = true; 599 break; 600 } 601 } 602out: 603 EFI_PRINT("%s: Exit, revoked: %d\n", __func__, revoked); 604 return !revoked; 605} 606 607/** 608 * efi_sigstore_free - free signature store 609 * @sigstore: Pointer to signature store structure 610 * 611 * Feee all the memories held in signature store and itself, 612 * which were allocated by efi_sigstore_parse_sigdb(). 613 */ 614void efi_sigstore_free(struct efi_signature_store *sigstore) 615{ 616 struct efi_signature_store *sigstore_next; 617 struct efi_sig_data *sig_data, *sig_data_next; 618 619 while (sigstore) { 620 sigstore_next = sigstore->next; 621 622 sig_data = sigstore->sig_data_list; 623 while (sig_data) { 624 sig_data_next = sig_data->next; 625 free(sig_data->data); 626 free(sig_data); 627 sig_data = sig_data_next; 628 } 629 630 free(sigstore); 631 sigstore = sigstore_next; 632 } 633} 634 635/** 636 * efi_sigstore_parse_siglist - parse a signature list 637 * @name: Pointer to signature list 638 * 639 * Parse signature list and instantiate a signature store structure. 640 * Signature database is a simple concatenation of one or more 641 * signature list(s). 642 * 643 * Return: Pointer to signature store on success, NULL on error 644 */ 645static struct efi_signature_store * 646efi_sigstore_parse_siglist(struct efi_signature_list *esl) 647{ 648 struct efi_signature_store *siglist = NULL; 649 struct efi_sig_data *sig_data, *sig_data_next; 650 struct efi_signature_data *esd; 651 size_t left; 652 653 /* 654 * UEFI specification defines certificate types: 655 * for non-signed images, 656 * EFI_CERT_SHA256_GUID 657 * EFI_CERT_RSA2048_GUID 658 * EFI_CERT_RSA2048_SHA256_GUID 659 * EFI_CERT_SHA1_GUID 660 * EFI_CERT_RSA2048_SHA_GUID 661 * EFI_CERT_SHA224_GUID 662 * EFI_CERT_SHA384_GUID 663 * EFI_CERT_SHA512_GUID 664 * 665 * for signed images, 666 * EFI_CERT_X509_GUID 667 * NOTE: Each certificate will normally be in a separate 668 * EFI_SIGNATURE_LIST as the size may vary depending on 669 * its algo's. 670 * 671 * for timestamp revocation of certificate, 672 * EFI_CERT_X509_SHA512_GUID 673 * EFI_CERT_X509_SHA256_GUID 674 * EFI_CERT_X509_SHA384_GUID 675 */ 676 677 if (esl->signature_list_size 678 <= (sizeof(*esl) + esl->signature_header_size)) { 679 EFI_PRINT("Siglist in wrong format\n"); 680 return NULL; 681 } 682 683 /* Create a head */ 684 siglist = calloc(sizeof(*siglist), 1); 685 if (!siglist) { 686 EFI_PRINT("Out of memory\n"); 687 goto err; 688 } 689 memcpy(&siglist->sig_type, &esl->signature_type, sizeof(efi_guid_t)); 690 691 /* Go through the list */ 692 sig_data_next = NULL; 693 left = esl->signature_list_size 694 - (sizeof(*esl) + esl->signature_header_size); 695 esd = (struct efi_signature_data *) 696 ((u8 *)esl + sizeof(*esl) + esl->signature_header_size); 697 698 while (left > 0) { 699 /* Signature must exist if there is remaining data. */ 700 if (left < esl->signature_size) { 701 EFI_PRINT("Certificate is too small\n"); 702 goto err; 703 } 704 705 sig_data = calloc(esl->signature_size 706 - sizeof(esd->signature_owner), 1); 707 if (!sig_data) { 708 EFI_PRINT("Out of memory\n"); 709 goto err; 710 } 711 712 /* Append signature data */ 713 memcpy(&sig_data->owner, &esd->signature_owner, 714 sizeof(efi_guid_t)); 715 sig_data->size = esl->signature_size 716 - sizeof(esd->signature_owner); 717 sig_data->data = malloc(sig_data->size); 718 if (!sig_data->data) { 719 EFI_PRINT("Out of memory\n"); 720 goto err; 721 } 722 memcpy(sig_data->data, esd->signature_data, sig_data->size); 723 724 sig_data->next = sig_data_next; 725 sig_data_next = sig_data; 726 727 /* Next */ 728 esd = (struct efi_signature_data *) 729 ((u8 *)esd + esl->signature_size); 730 left -= esl->signature_size; 731 } 732 siglist->sig_data_list = sig_data_next; 733 734 return siglist; 735 736err: 737 efi_sigstore_free(siglist); 738 739 return NULL; 740} 741 742/** 743 * efi_sigstore_parse_sigdb - parse the signature list and populate 744 * the signature store 745 * 746 * @sig_list: Pointer to the signature list 747 * @size: Size of the signature list 748 * 749 * Parse the efi signature list and instantiate a signature store 750 * structure. 751 * 752 * Return: Pointer to signature store on success, NULL on error 753 */ 754struct efi_signature_store *efi_build_signature_store(void *sig_list, 755 efi_uintn_t size) 756{ 757 struct efi_signature_list *esl; 758 struct efi_signature_store *sigstore = NULL, *siglist; 759 760 esl = sig_list; 761 while (size > 0) { 762 /* List must exist if there is remaining data. */ 763 if (size < sizeof(*esl)) { 764 EFI_PRINT("Signature list in wrong format\n"); 765 goto err; 766 } 767 768 if (size < esl->signature_list_size) { 769 EFI_PRINT("Signature list in wrong format\n"); 770 goto err; 771 } 772 773 /* Parse a single siglist. */ 774 siglist = efi_sigstore_parse_siglist(esl); 775 if (!siglist) { 776 EFI_PRINT("Parsing of signature list of failed\n"); 777 goto err; 778 } 779 780 /* Append siglist */ 781 siglist->next = sigstore; 782 sigstore = siglist; 783 784 /* Next */ 785 size -= esl->signature_list_size; 786 esl = (void *)esl + esl->signature_list_size; 787 } 788 free(sig_list); 789 790 return sigstore; 791 792err: 793 efi_sigstore_free(sigstore); 794 free(sig_list); 795 796 return NULL; 797} 798 799/** 800 * efi_sigstore_parse_sigdb - parse a signature database variable 801 * @name: Variable's name 802 * 803 * Read in a value of signature database variable pointed to by 804 * @name, parse it and instantiate a signature store structure. 805 * 806 * Return: Pointer to signature store on success, NULL on error 807 */ 808struct efi_signature_store *efi_sigstore_parse_sigdb(u16 *name) 809{ 810 const efi_guid_t *vendor; 811 void *db; 812 efi_uintn_t db_size; 813 814 vendor = efi_auth_var_get_guid(name); 815 db = efi_get_var(name, vendor, &db_size); 816 if (!db) { 817 EFI_PRINT("variable, %ls, not found\n", name); 818 return calloc(sizeof(struct efi_signature_store), 1); 819 } 820 821 return efi_build_signature_store(db, db_size); 822} 823