1
2
3
4
5
6
7
8
9
10#define LOG_CATEGORY LOGC_EFI
11
12#include <common.h>
13#include <cpu_func.h>
14#include <efi_loader.h>
15#include <log.h>
16#include <malloc.h>
17#include <pe.h>
18#include <sort.h>
19#include <crypto/mscode.h>
20#include <crypto/pkcs7_parser.h>
21#include <linux/err.h>
22
23const efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
24const efi_guid_t efi_guid_device_path = EFI_DEVICE_PATH_PROTOCOL_GUID;
25const efi_guid_t efi_guid_loaded_image = EFI_LOADED_IMAGE_PROTOCOL_GUID;
26const efi_guid_t efi_guid_loaded_image_device_path =
27 EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID;
28const efi_guid_t efi_simple_file_system_protocol_guid =
29 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
30const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID;
31
32static int machines[] = {
33#if defined(__aarch64__)
34 IMAGE_FILE_MACHINE_ARM64,
35#elif defined(__arm__)
36 IMAGE_FILE_MACHINE_ARM,
37 IMAGE_FILE_MACHINE_THUMB,
38 IMAGE_FILE_MACHINE_ARMNT,
39#endif
40
41#if defined(__x86_64__)
42 IMAGE_FILE_MACHINE_AMD64,
43#elif defined(__i386__)
44 IMAGE_FILE_MACHINE_I386,
45#endif
46
47#if defined(__riscv) && (__riscv_xlen == 32)
48 IMAGE_FILE_MACHINE_RISCV32,
49#endif
50
51#if defined(__riscv) && (__riscv_xlen == 64)
52 IMAGE_FILE_MACHINE_RISCV64,
53#endif
54 0 };
55
56
57
58
59
60
61
62
63
64
65
66
67static efi_status_t efi_print_image_info(struct efi_loaded_image_obj *obj,
68 struct efi_loaded_image *image,
69 void *pc)
70{
71 printf("UEFI image");
72 printf(" [0x%p:0x%p]",
73 image->image_base, image->image_base + image->image_size - 1);
74 if (pc && pc >= image->image_base &&
75 pc < image->image_base + image->image_size)
76 printf(" pc=0x%zx", pc - image->image_base);
77 if (image->file_path)
78 printf(" '%pD'", image->file_path);
79 printf("\n");
80 return EFI_SUCCESS;
81}
82
83
84
85
86
87
88void efi_print_image_infos(void *pc)
89{
90 struct efi_object *efiobj;
91 struct efi_handler *handler;
92
93 list_for_each_entry(efiobj, &efi_obj_list, link) {
94 list_for_each_entry(handler, &efiobj->protocols, link) {
95 if (!guidcmp(&handler->guid, &efi_guid_loaded_image)) {
96 efi_print_image_info(
97 (struct efi_loaded_image_obj *)efiobj,
98 handler->protocol_interface, pc);
99 }
100 }
101 }
102}
103
104
105
106
107
108
109
110
111
112
113static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
114 unsigned long rel_size, void *efi_reloc,
115 unsigned long pref_address)
116{
117 unsigned long delta = (unsigned long)efi_reloc - pref_address;
118 const IMAGE_BASE_RELOCATION *end;
119 int i;
120
121 if (delta == 0)
122 return EFI_SUCCESS;
123
124 end = (const IMAGE_BASE_RELOCATION *)((const char *)rel + rel_size);
125 while (rel < end && rel->SizeOfBlock) {
126 const uint16_t *relocs = (const uint16_t *)(rel + 1);
127 i = (rel->SizeOfBlock - sizeof(*rel)) / sizeof(uint16_t);
128 while (i--) {
129 uint32_t offset = (uint32_t)(*relocs & 0xfff) +
130 rel->VirtualAddress;
131 int type = *relocs >> EFI_PAGE_SHIFT;
132 uint64_t *x64 = efi_reloc + offset;
133 uint32_t *x32 = efi_reloc + offset;
134 uint16_t *x16 = efi_reloc + offset;
135
136 switch (type) {
137 case IMAGE_REL_BASED_ABSOLUTE:
138 break;
139 case IMAGE_REL_BASED_HIGH:
140 *x16 += ((uint32_t)delta) >> 16;
141 break;
142 case IMAGE_REL_BASED_LOW:
143 *x16 += (uint16_t)delta;
144 break;
145 case IMAGE_REL_BASED_HIGHLOW:
146 *x32 += (uint32_t)delta;
147 break;
148 case IMAGE_REL_BASED_DIR64:
149 *x64 += (uint64_t)delta;
150 break;
151#ifdef __riscv
152 case IMAGE_REL_BASED_RISCV_HI20:
153 *x32 = ((*x32 & 0xfffff000) + (uint32_t)delta) |
154 (*x32 & 0x00000fff);
155 break;
156 case IMAGE_REL_BASED_RISCV_LOW12I:
157 case IMAGE_REL_BASED_RISCV_LOW12S:
158
159 if (delta & 0xfff) {
160 log_err("Unsupported reloc offset\n");
161 return EFI_LOAD_ERROR;
162 }
163 break;
164#endif
165 default:
166 log_err("Unknown Relocation off %x type %x\n",
167 offset, type);
168 return EFI_LOAD_ERROR;
169 }
170 relocs++;
171 }
172 rel = (const IMAGE_BASE_RELOCATION *)relocs;
173 }
174 return EFI_SUCCESS;
175}
176
177void __weak invalidate_icache_all(void)
178{
179
180}
181
182
183
184
185
186
187
188
189
190static void efi_set_code_and_data_type(
191 struct efi_loaded_image *loaded_image_info,
192 uint16_t image_type)
193{
194 switch (image_type) {
195 case IMAGE_SUBSYSTEM_EFI_APPLICATION:
196 loaded_image_info->image_code_type = EFI_LOADER_CODE;
197 loaded_image_info->image_data_type = EFI_LOADER_DATA;
198 break;
199 case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
200 loaded_image_info->image_code_type = EFI_BOOT_SERVICES_CODE;
201 loaded_image_info->image_data_type = EFI_BOOT_SERVICES_DATA;
202 break;
203 case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
204 case IMAGE_SUBSYSTEM_EFI_ROM:
205 loaded_image_info->image_code_type = EFI_RUNTIME_SERVICES_CODE;
206 loaded_image_info->image_data_type = EFI_RUNTIME_SERVICES_DATA;
207 break;
208 default:
209 log_err("invalid image type: %u\n", image_type);
210
211 loaded_image_info->image_code_type = EFI_LOADER_CODE;
212 loaded_image_info->image_data_type = EFI_LOADER_DATA;
213 break;
214 }
215}
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234efi_status_t efi_image_region_add(struct efi_image_regions *regs,
235 const void *start, const void *end,
236 int nocheck)
237{
238 struct image_region *reg;
239 int i, j;
240
241 if (regs->num >= regs->max) {
242 log_err("%s: no more room for regions\n", __func__);
243 return EFI_OUT_OF_RESOURCES;
244 }
245
246 if (end < start)
247 return EFI_INVALID_PARAMETER;
248
249 for (i = 0; i < regs->num; i++) {
250 reg = ®s->reg[i];
251 if (nocheck)
252 continue;
253
254
255 if (start >= reg->data + reg->size)
256 continue;
257
258
259 if (end <= reg->data) {
260 for (j = regs->num - 1; j >= i; j--)
261 memcpy(®s->reg[j + 1], ®s->reg[j],
262 sizeof(*reg));
263 break;
264 }
265
266
267 log_err("%s: new region already part of another\n", __func__);
268 return EFI_INVALID_PARAMETER;
269 }
270
271 reg = ®s->reg[i];
272 reg->data = start;
273 reg->size = end - start;
274 regs->num++;
275
276 return EFI_SUCCESS;
277}
278
279
280
281
282
283
284
285
286
287
288
289
290
291static int cmp_pe_section(const void *arg1, const void *arg2)
292{
293 const IMAGE_SECTION_HEADER *section1, *section2;
294
295 section1 = *((const IMAGE_SECTION_HEADER **)arg1);
296 section2 = *((const IMAGE_SECTION_HEADER **)arg2);
297
298 if (section1->VirtualAddress < section2->VirtualAddress)
299 return -1;
300 else if (section1->VirtualAddress == section2->VirtualAddress)
301 return 0;
302 else
303 return 1;
304}
305
306
307
308
309
310
311
312
313
314
315
316void *efi_prepare_aligned_image(void *efi, u64 *efi_size)
317{
318 size_t new_efi_size;
319 void *new_efi;
320
321
322
323
324
325 if (!IS_ALIGNED(*efi_size, 8)) {
326 new_efi_size = ALIGN(*efi_size, 8);
327 new_efi = calloc(new_efi_size, 1);
328 if (!new_efi)
329 return NULL;
330 memcpy(new_efi, efi, *efi_size);
331 *efi_size = new_efi_size;
332 return new_efi;
333 } else {
334 return efi;
335 }
336}
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp,
354 WIN_CERTIFICATE **auth, size_t *auth_len)
355{
356 struct efi_image_regions *regs;
357 IMAGE_DOS_HEADER *dos;
358 IMAGE_NT_HEADERS32 *nt;
359 IMAGE_SECTION_HEADER *sections, **sorted;
360 int num_regions, num_sections, i;
361 int ctidx = IMAGE_DIRECTORY_ENTRY_SECURITY;
362 u32 align, size, authsz, authoff;
363 size_t bytes_hashed;
364
365 dos = (void *)efi;
366 nt = (void *)(efi + dos->e_lfanew);
367 authoff = 0;
368 authsz = 0;
369
370
371
372
373
374
375 num_regions = 3;
376 num_regions += nt->FileHeader.NumberOfSections;
377 num_regions++;
378
379 regs = calloc(sizeof(*regs) + sizeof(struct image_region) * num_regions,
380 1);
381 if (!regs)
382 goto err;
383 regs->max = num_regions;
384
385
386
387
388
389 if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
390 IMAGE_NT_HEADERS64 *nt64 = (void *)nt;
391 IMAGE_OPTIONAL_HEADER64 *opt = &nt64->OptionalHeader;
392
393
394 efi_image_region_add(regs, efi, &opt->CheckSum, 0);
395 if (nt64->OptionalHeader.NumberOfRvaAndSizes <= ctidx) {
396 efi_image_region_add(regs,
397 &opt->Subsystem,
398 efi + opt->SizeOfHeaders, 0);
399 } else {
400
401 efi_image_region_add(regs,
402 &opt->Subsystem,
403 &opt->DataDirectory[ctidx], 0);
404 efi_image_region_add(regs,
405 &opt->DataDirectory[ctidx] + 1,
406 efi + opt->SizeOfHeaders, 0);
407
408 authoff = opt->DataDirectory[ctidx].VirtualAddress;
409 authsz = opt->DataDirectory[ctidx].Size;
410 }
411
412 bytes_hashed = opt->SizeOfHeaders;
413 align = opt->FileAlignment;
414 } else if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
415 IMAGE_OPTIONAL_HEADER32 *opt = &nt->OptionalHeader;
416
417
418 efi_image_region_add(regs, efi, &opt->CheckSum, 0);
419 if (nt->OptionalHeader.NumberOfRvaAndSizes <= ctidx) {
420 efi_image_region_add(regs,
421 &opt->Subsystem,
422 efi + opt->SizeOfHeaders, 0);
423 } else {
424
425 efi_image_region_add(regs, &opt->Subsystem,
426 &opt->DataDirectory[ctidx], 0);
427 efi_image_region_add(regs,
428 &opt->DataDirectory[ctidx] + 1,
429 efi + opt->SizeOfHeaders, 0);
430
431 authoff = opt->DataDirectory[ctidx].VirtualAddress;
432 authsz = opt->DataDirectory[ctidx].Size;
433 }
434
435 bytes_hashed = opt->SizeOfHeaders;
436 align = opt->FileAlignment;
437 } else {
438 log_err("%s: Invalid optional header magic %x\n", __func__,
439 nt->OptionalHeader.Magic);
440 goto err;
441 }
442
443
444 num_sections = nt->FileHeader.NumberOfSections;
445 sections = (void *)((uint8_t *)&nt->OptionalHeader +
446 nt->FileHeader.SizeOfOptionalHeader);
447 sorted = calloc(sizeof(IMAGE_SECTION_HEADER *), num_sections);
448 if (!sorted) {
449 log_err("%s: Out of memory\n", __func__);
450 goto err;
451 }
452
453
454
455
456 for (i = 0; i < num_sections; i++)
457 sorted[i] = §ions[i];
458 qsort(sorted, num_sections, sizeof(sorted[0]), cmp_pe_section);
459
460 for (i = 0; i < num_sections; i++) {
461 if (!sorted[i]->SizeOfRawData)
462 continue;
463
464 size = (sorted[i]->SizeOfRawData + align - 1) & ~(align - 1);
465 efi_image_region_add(regs, efi + sorted[i]->PointerToRawData,
466 efi + sorted[i]->PointerToRawData + size,
467 0);
468 log_debug("section[%d](%s): raw: 0x%x-0x%x, virt: %x-%x\n",
469 i, sorted[i]->Name,
470 sorted[i]->PointerToRawData,
471 sorted[i]->PointerToRawData + size,
472 sorted[i]->VirtualAddress,
473 sorted[i]->VirtualAddress
474 + sorted[i]->Misc.VirtualSize);
475
476 bytes_hashed += size;
477 }
478 free(sorted);
479
480
481 if (bytes_hashed + authsz < len) {
482 log_debug("extra data for hash: %zu\n",
483 len - (bytes_hashed + authsz));
484 efi_image_region_add(regs, efi + bytes_hashed,
485 efi + len - authsz, 0);
486 }
487
488
489 if (authsz) {
490 if (len < authoff + authsz) {
491 log_err("%s: Size for auth too large: %u >= %zu\n",
492 __func__, authsz, len - authoff);
493 goto err;
494 }
495 if (authsz < sizeof(*auth)) {
496 log_err("%s: Size for auth too small: %u < %zu\n",
497 __func__, authsz, sizeof(*auth));
498 goto err;
499 }
500 *auth = efi + authoff;
501 *auth_len = authsz;
502 log_debug("WIN_CERTIFICATE: 0x%x, size: 0x%x\n", authoff,
503 authsz);
504 } else {
505 *auth = NULL;
506 *auth_len = 0;
507 }
508
509 *regp = regs;
510
511 return true;
512
513err:
514 free(regs);
515
516 return false;
517}
518
519#ifdef CONFIG_EFI_SECURE_BOOT
520
521
522
523
524
525
526
527
528
529
530
531static bool efi_image_verify_digest(struct efi_image_regions *regs,
532 struct pkcs7_message *msg)
533{
534 struct pefile_context ctx;
535 void *hash;
536 int hash_len, ret;
537
538 const void *data;
539 size_t data_len;
540 size_t asn1hdrlen;
541
542
543 ret = pkcs7_get_content_data(msg, &data, &data_len, &asn1hdrlen);
544 if (ret < 0 || !data)
545 return false;
546
547
548 ret = mscode_parse(&ctx, data, data_len, asn1hdrlen);
549 if (ret < 0)
550 return false;
551
552
553 hash = NULL;
554 if (!efi_hash_regions(regs->reg, regs->num, &hash, ctx.digest_algo,
555 &hash_len))
556 return false;
557
558
559 if (ctx.digest_len != hash_len || memcmp(ctx.digest, hash, hash_len))
560 return false;
561
562 return true;
563}
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586static bool efi_image_authenticate(void *efi, size_t efi_size)
587{
588 struct efi_image_regions *regs = NULL;
589 WIN_CERTIFICATE *wincerts = NULL, *wincert;
590 size_t wincerts_len;
591 struct pkcs7_message *msg = NULL;
592 struct efi_signature_store *db = NULL, *dbx = NULL;
593 void *new_efi = NULL;
594 u8 *auth, *wincerts_end;
595 size_t auth_size;
596 bool ret = false;
597
598 log_debug("%s: Enter, %d\n", __func__, ret);
599
600 if (!efi_secure_boot_enabled())
601 return true;
602
603 new_efi = efi_prepare_aligned_image(efi, (u64 *)&efi_size);
604 if (!new_efi)
605 return false;
606
607 if (!efi_image_parse(new_efi, efi_size, ®s, &wincerts,
608 &wincerts_len)) {
609 log_err("Parsing PE executable image failed\n");
610 goto out;
611 }
612
613
614
615
616 db = efi_sigstore_parse_sigdb(u"db");
617 if (!db) {
618 log_err("Getting signature database(db) failed\n");
619 goto out;
620 }
621
622 dbx = efi_sigstore_parse_sigdb(u"dbx");
623 if (!dbx) {
624 log_err("Getting signature database(dbx) failed\n");
625 goto out;
626 }
627
628 if (efi_signature_lookup_digest(regs, dbx, true)) {
629 log_debug("Image's digest was found in \"dbx\"\n");
630 goto out;
631 }
632
633
634
635
636
637
638
639
640
641
642
643 for (wincert = wincerts, wincerts_end = (u8 *)wincerts + wincerts_len;
644 (u8 *)wincert < wincerts_end;
645 wincert = (WIN_CERTIFICATE *)
646 ((u8 *)wincert + ALIGN(wincert->dwLength, 8))) {
647 if ((u8 *)wincert + sizeof(*wincert) >= wincerts_end)
648 break;
649
650 if (wincert->dwLength <= sizeof(*wincert)) {
651 log_debug("dwLength too small: %u < %zu\n",
652 wincert->dwLength, sizeof(*wincert));
653 continue;
654 }
655
656 log_debug("WIN_CERTIFICATE_TYPE: 0x%x\n",
657 wincert->wCertificateType);
658
659 auth = (u8 *)wincert + sizeof(*wincert);
660 auth_size = wincert->dwLength - sizeof(*wincert);
661 if (wincert->wCertificateType == WIN_CERT_TYPE_EFI_GUID) {
662 if (auth + sizeof(efi_guid_t) >= wincerts_end)
663 break;
664
665 if (auth_size <= sizeof(efi_guid_t)) {
666 log_debug("dwLength too small: %u < %zu\n",
667 wincert->dwLength, sizeof(*wincert));
668 continue;
669 }
670 if (guidcmp(auth, &efi_guid_cert_type_pkcs7)) {
671 log_debug("Certificate type not supported: %pUs\n",
672 auth);
673 ret = false;
674 goto out;
675 }
676
677 auth += sizeof(efi_guid_t);
678 auth_size -= sizeof(efi_guid_t);
679 } else if (wincert->wCertificateType
680 != WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
681 log_debug("Certificate type not supported\n");
682 ret = false;
683 goto out;
684 }
685
686 msg = pkcs7_parse_message(auth, auth_size);
687 if (IS_ERR(msg)) {
688 log_err("Parsing image's signature failed\n");
689 msg = NULL;
690 continue;
691 }
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716 if (efi_signature_verify_one(regs, msg, dbx)) {
717 ret = false;
718 log_debug("Signature was rejected by \"dbx\"\n");
719 goto out;
720 }
721
722 if (!efi_signature_check_signers(msg, dbx)) {
723 ret = false;
724 log_debug("Signer(s) in \"dbx\"\n");
725 goto out;
726 }
727
728
729 if (!efi_signature_verify(regs, msg, db, dbx)) {
730 log_debug("Signature was not verified by \"db\"\n");
731 continue;
732 }
733
734
735
736
737
738 if (efi_image_verify_digest(regs, msg)) {
739 ret = true;
740 continue;
741 }
742
743 log_debug("Message digest doesn't match\n");
744 }
745
746
747
748 if (!ret && efi_signature_lookup_digest(regs, db, false))
749 ret = true;
750
751out:
752 efi_sigstore_free(db);
753 efi_sigstore_free(dbx);
754 pkcs7_free_message(msg);
755 free(regs);
756 if (new_efi != efi)
757 free(new_efi);
758
759 log_debug("%s: Exit, %d\n", __func__, ret);
760 return ret;
761}
762#else
763static bool efi_image_authenticate(void *efi, size_t efi_size)
764{
765 return true;
766}
767#endif
768
769
770
771
772
773
774
775
776
777
778efi_status_t efi_check_pe(void *buffer, size_t size, void **nt_header)
779{
780 IMAGE_DOS_HEADER *dos = buffer;
781 IMAGE_NT_HEADERS32 *nt;
782
783 if (size < sizeof(*dos))
784 return EFI_INVALID_PARAMETER;
785
786
787 if (dos->e_magic != IMAGE_DOS_SIGNATURE)
788 return EFI_INVALID_PARAMETER;
789
790
791
792
793
794
795 if (size < dos->e_lfanew + sizeof(IMAGE_NT_HEADERS32))
796 return EFI_INVALID_PARAMETER;
797 nt = (IMAGE_NT_HEADERS32 *)((u8 *)buffer + dos->e_lfanew);
798
799
800 if (nt->Signature != IMAGE_NT_SIGNATURE)
801 return EFI_INVALID_PARAMETER;
802
803 if (nt_header)
804 *nt_header = nt;
805
806 return EFI_SUCCESS;
807}
808
809
810
811
812
813
814
815
816
817
818static u32 section_size(IMAGE_SECTION_HEADER *sec)
819{
820 if (sec->Misc.VirtualSize)
821 return sec->Misc.VirtualSize;
822 else
823 return sec->SizeOfRawData;
824}
825
826
827
828
829
830
831
832
833
834
835
836
837
838efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle,
839 void *efi, size_t efi_size,
840 struct efi_loaded_image *loaded_image_info)
841{
842 IMAGE_NT_HEADERS32 *nt;
843 IMAGE_DOS_HEADER *dos;
844 IMAGE_SECTION_HEADER *sections;
845 int num_sections;
846 void *efi_reloc;
847 int i;
848 const IMAGE_BASE_RELOCATION *rel;
849 unsigned long rel_size;
850 int rel_idx = IMAGE_DIRECTORY_ENTRY_BASERELOC;
851 uint64_t image_base;
852 unsigned long virt_size = 0;
853 int supported = 0;
854 efi_status_t ret;
855
856 ret = efi_check_pe(efi, efi_size, (void **)&nt);
857 if (ret != EFI_SUCCESS) {
858 log_err("Not a PE-COFF file\n");
859 return EFI_LOAD_ERROR;
860 }
861
862 for (i = 0; machines[i]; i++)
863 if (machines[i] == nt->FileHeader.Machine) {
864 supported = 1;
865 break;
866 }
867
868 if (!supported) {
869 log_err("Machine type 0x%04x is not supported\n",
870 nt->FileHeader.Machine);
871 return EFI_LOAD_ERROR;
872 }
873
874 num_sections = nt->FileHeader.NumberOfSections;
875 sections = (void *)&nt->OptionalHeader +
876 nt->FileHeader.SizeOfOptionalHeader;
877
878 if (efi_size < ((void *)sections + sizeof(sections[0]) * num_sections
879 - efi)) {
880 log_err("Invalid number of sections: %d\n", num_sections);
881 return EFI_LOAD_ERROR;
882 }
883
884
885 if (efi_image_authenticate(efi, efi_size)) {
886 handle->auth_status = EFI_IMAGE_AUTH_PASSED;
887 } else {
888 handle->auth_status = EFI_IMAGE_AUTH_FAILED;
889 log_err("Image not authenticated\n");
890 }
891
892
893 for (i = num_sections - 1; i >= 0; i--) {
894 IMAGE_SECTION_HEADER *sec = §ions[i];
895
896 virt_size = max_t(unsigned long, virt_size,
897 sec->VirtualAddress + section_size(sec));
898 }
899
900
901 if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
902 IMAGE_NT_HEADERS64 *nt64 = (void *)nt;
903 IMAGE_OPTIONAL_HEADER64 *opt = &nt64->OptionalHeader;
904 image_base = opt->ImageBase;
905 efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
906 handle->image_type = opt->Subsystem;
907 efi_reloc = efi_alloc_aligned_pages(virt_size,
908 loaded_image_info->image_code_type,
909 opt->SectionAlignment);
910 if (!efi_reloc) {
911 log_err("Out of memory\n");
912 ret = EFI_OUT_OF_RESOURCES;
913 goto err;
914 }
915 handle->entry = efi_reloc + opt->AddressOfEntryPoint;
916 rel_size = opt->DataDirectory[rel_idx].Size;
917 rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
918 } else if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
919 IMAGE_OPTIONAL_HEADER32 *opt = &nt->OptionalHeader;
920 image_base = opt->ImageBase;
921 efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
922 handle->image_type = opt->Subsystem;
923 efi_reloc = efi_alloc_aligned_pages(virt_size,
924 loaded_image_info->image_code_type,
925 opt->SectionAlignment);
926 if (!efi_reloc) {
927 log_err("Out of memory\n");
928 ret = EFI_OUT_OF_RESOURCES;
929 goto err;
930 }
931 handle->entry = efi_reloc + opt->AddressOfEntryPoint;
932 rel_size = opt->DataDirectory[rel_idx].Size;
933 rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
934 } else {
935 log_err("Invalid optional header magic %x\n",
936 nt->OptionalHeader.Magic);
937 ret = EFI_LOAD_ERROR;
938 goto err;
939 }
940
941#if CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL)
942
943 ret = tcg2_measure_pe_image(efi, efi_size, handle, loaded_image_info);
944 if (ret == EFI_SECURITY_VIOLATION) {
945
946
947
948
949 log_err("PE image measurement failed, no tpm device found\n");
950 goto err;
951 }
952
953#endif
954
955
956 memcpy(efi_reloc, efi,
957 sizeof(*dos)
958 + sizeof(*nt)
959 + nt->FileHeader.SizeOfOptionalHeader
960 + num_sections * sizeof(IMAGE_SECTION_HEADER));
961
962
963 for (i = num_sections - 1; i >= 0; i--) {
964 IMAGE_SECTION_HEADER *sec = §ions[i];
965 u32 copy_size = section_size(sec);
966
967 if (copy_size > sec->SizeOfRawData) {
968 copy_size = sec->SizeOfRawData;
969 memset(efi_reloc + sec->VirtualAddress, 0,
970 sec->Misc.VirtualSize);
971 }
972 memcpy(efi_reloc + sec->VirtualAddress,
973 efi + sec->PointerToRawData,
974 copy_size);
975 }
976
977
978 if (efi_loader_relocate(rel, rel_size, efi_reloc,
979 (unsigned long)image_base) != EFI_SUCCESS) {
980 efi_free_pages((uintptr_t) efi_reloc,
981 (virt_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT);
982 ret = EFI_LOAD_ERROR;
983 goto err;
984 }
985
986
987 flush_cache((ulong)efi_reloc,
988 ALIGN(virt_size, EFI_CACHELINE_SIZE));
989 invalidate_icache_all();
990
991
992 loaded_image_info->image_base = efi_reloc;
993 loaded_image_info->image_size = virt_size;
994
995 if (handle->auth_status == EFI_IMAGE_AUTH_PASSED)
996 return EFI_SUCCESS;
997 else
998 return EFI_SECURITY_VIOLATION;
999
1000err:
1001 return ret;
1002}
1003