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