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