1
2
3
4
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
33 0x30, 0x82, 0x05, 0xc7,
34
35 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02,
36
37 0xa0, 0x82, 0x05, 0xb8,
38};
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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
66
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
78
79
80
81
82
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
119
120
121
122
123
124
125
126
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
165
166
167
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
189
190
191
192
193
194
195
196
197
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
220
221
222 if (dbx && !hash_algo_supported(siglist->sig_type)) {
223 found = true;
224 continue;
225 };
226
227
228
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
236
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
272
273
274
275
276
277
278
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
298
299
300
301 reg[0].data = cert->tbs;
302 reg[0].size = cert->tbs_size;
303
304
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
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
350
351
352
353
354
355
356
357
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
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
408
409
410
411
412
413
414
415
416
417
418
419
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
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
455
456
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
476
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
493
494
495
496
497
498
499
500
501
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
524
525
526
527
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
576
577
578
579
580
581
582
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
610
611
612
613
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
638
639
640
641
642
643
644
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
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
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
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
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
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
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
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
745
746
747
748
749
750
751
752
753
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
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
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
782 siglist->next = sigstore;
783 sigstore = siglist;
784
785
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
802
803
804
805
806
807
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