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