efi_loader: split unrelated code from efi_bootmgr.c
[J-u-boot.git] / lib / efi_loader / efi_helper.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2020, Linaro Limited
4  */
5
6 #define LOG_CATEGORY LOGC_EFI
7 #include <bootm.h>
8 #include <env.h>
9 #include <image.h>
10 #include <log.h>
11 #include <malloc.h>
12 #include <mapmem.h>
13 #include <dm.h>
14 #include <fs.h>
15 #include <efi_api.h>
16 #include <efi_load_initrd.h>
17 #include <efi_loader.h>
18 #include <efi_variable.h>
19 #include <linux/libfdt.h>
20 #include <linux/list.h>
21
22 #if defined(CONFIG_CMD_EFIDEBUG) || defined(CONFIG_EFI_LOAD_FILE2_INITRD)
23 /* GUID used by Linux to identify the LoadFile2 protocol with the initrd */
24 const efi_guid_t efi_lf2_initrd_guid = EFI_INITRD_MEDIA_GUID;
25 #endif
26
27 /**
28  * efi_create_current_boot_var() - Return Boot#### name were #### is replaced by
29  *                                 the value of BootCurrent
30  *
31  * @var_name:           variable name
32  * @var_name_size:      size of var_name
33  *
34  * Return:      Status code
35  */
36 static efi_status_t efi_create_current_boot_var(u16 var_name[],
37                                                 size_t var_name_size)
38 {
39         efi_uintn_t boot_current_size;
40         efi_status_t ret;
41         u16 boot_current;
42         u16 *pos;
43
44         boot_current_size = sizeof(boot_current);
45         ret = efi_get_variable_int(u"BootCurrent",
46                                    &efi_global_variable_guid, NULL,
47                                    &boot_current_size, &boot_current, NULL);
48         if (ret != EFI_SUCCESS)
49                 goto out;
50
51         pos = efi_create_indexed_name(var_name, var_name_size, "Boot",
52                                       boot_current);
53         if (!pos) {
54                 ret = EFI_OUT_OF_RESOURCES;
55                 goto out;
56         }
57
58 out:
59         return ret;
60 }
61
62 /**
63  * efi_get_dp_from_boot() - Retrieve and return a device path from an EFI
64  *                          Boot### variable.
65  *                          A boot option may contain an array of device paths.
66  *                          We use a VenMedia() with a specific GUID to identify
67  *                          the usage of the array members. This function is
68  *                          used to extract a specific device path
69  *
70  * @guid:       vendor GUID of the VenMedia() device path node identifying the
71  *              device path
72  *
73  * Return:      device path or NULL. Caller must free the returned value
74  */
75 struct efi_device_path *efi_get_dp_from_boot(const efi_guid_t guid)
76 {
77         struct efi_load_option lo;
78         void *var_value;
79         efi_uintn_t size;
80         efi_status_t ret;
81         u16 var_name[16];
82
83         ret = efi_create_current_boot_var(var_name, sizeof(var_name));
84         if (ret != EFI_SUCCESS)
85                 return NULL;
86
87         var_value = efi_get_var(var_name, &efi_global_variable_guid, &size);
88         if (!var_value)
89                 return NULL;
90
91         ret = efi_deserialize_load_option(&lo, var_value, &size);
92         if (ret != EFI_SUCCESS)
93                 goto err;
94
95         return efi_dp_from_lo(&lo, &guid);
96
97 err:
98         free(var_value);
99         return NULL;
100 }
101
102 const struct guid_to_hash_map {
103         efi_guid_t guid;
104         const char algo[32];
105         u32 bits;
106 } guid_to_hash[] = {
107         {
108                 EFI_CERT_X509_SHA256_GUID,
109                 "sha256",
110                 SHA256_SUM_LEN * 8,
111         },
112         {
113                 EFI_CERT_SHA256_GUID,
114                 "sha256",
115                 SHA256_SUM_LEN * 8,
116         },
117         {
118                 EFI_CERT_X509_SHA384_GUID,
119                 "sha384",
120                 SHA384_SUM_LEN * 8,
121         },
122         {
123                 EFI_CERT_X509_SHA512_GUID,
124                 "sha512",
125                 SHA512_SUM_LEN * 8,
126         },
127 };
128
129 #define MAX_GUID_TO_HASH_COUNT ARRAY_SIZE(guid_to_hash)
130
131 /** guid_to_sha_str - return the sha string e.g "sha256" for a given guid
132  *                    used on EFI security databases
133  *
134  * @guid: guid to check
135  *
136  * Return: len or 0 if no match is found
137  */
138 const char *guid_to_sha_str(const efi_guid_t *guid)
139 {
140         size_t i;
141
142         for (i = 0; i < MAX_GUID_TO_HASH_COUNT; i++) {
143                 if (!guidcmp(guid, &guid_to_hash[i].guid))
144                         return guid_to_hash[i].algo;
145         }
146
147         return NULL;
148 }
149
150 /** algo_to_len - return the sha size in bytes for a given string
151  *
152  * @algo: string indicating hashing algorithm to check
153  *
154  * Return: length of hash in bytes or 0 if no match is found
155  */
156 int algo_to_len(const char *algo)
157 {
158         size_t i;
159
160         for (i = 0; i < MAX_GUID_TO_HASH_COUNT; i++) {
161                 if (!strcmp(algo, guid_to_hash[i].algo))
162                         return guid_to_hash[i].bits / 8;
163         }
164
165         return 0;
166 }
167
168 /** efi_link_dev - link the efi_handle_t and udevice
169  *
170  * @handle:     efi handle to associate with udevice
171  * @dev:        udevice to associate with efi handle
172  *
173  * Return:      0 on success, negative on failure
174  */
175 int efi_link_dev(efi_handle_t handle, struct udevice *dev)
176 {
177         handle->dev = dev;
178         return dev_tag_set_ptr(dev, DM_TAG_EFI, handle);
179 }
180
181 /**
182  * efi_unlink_dev() - unlink udevice and handle
183  *
184  * @handle:     EFI handle to unlink
185  *
186  * Return:      0 on success, negative on failure
187  */
188 int efi_unlink_dev(efi_handle_t handle)
189 {
190         int ret;
191
192         ret = dev_tag_del(handle->dev, DM_TAG_EFI);
193         if (ret)
194                 return ret;
195         handle->dev = NULL;
196
197         return 0;
198 }
199
200 static int u16_tohex(u16 c)
201 {
202         if (c >= '0' && c <= '9')
203                 return c - '0';
204         if (c >= 'A' && c <= 'F')
205                 return c - 'A' + 10;
206
207         /* not hexadecimal */
208         return -1;
209 }
210
211 bool efi_varname_is_load_option(u16 *var_name16, int *index)
212 {
213         int id, i, digit;
214
215         if (memcmp(var_name16, u"Boot", 8))
216                 return false;
217
218         for (id = 0, i = 0; i < 4; i++) {
219                 digit = u16_tohex(var_name16[4 + i]);
220                 if (digit < 0)
221                         break;
222                 id = (id << 4) + digit;
223         }
224         if (i == 4 && !var_name16[8]) {
225                 if (index)
226                         *index = id;
227                 return true;
228         }
229
230         return false;
231 }
232
233 /**
234  * efi_next_variable_name() - get next variable name
235  *
236  * This function is a wrapper of efi_get_next_variable_name_int().
237  * If efi_get_next_variable_name_int() returns EFI_BUFFER_TOO_SMALL,
238  * @size and @buf are updated by new buffer size and realloced buffer.
239  *
240  * @size:       pointer to the buffer size
241  * @buf:        pointer to the buffer
242  * @guid:       pointer to the guid
243  * Return:      status code
244  */
245 efi_status_t efi_next_variable_name(efi_uintn_t *size, u16 **buf, efi_guid_t *guid)
246 {
247         u16 *p;
248         efi_status_t ret;
249         efi_uintn_t buf_size = *size;
250
251         ret = efi_get_next_variable_name_int(&buf_size, *buf, guid);
252         if (ret == EFI_NOT_FOUND)
253                 return ret;
254         if (ret == EFI_BUFFER_TOO_SMALL) {
255                 p = realloc(*buf, buf_size);
256                 if (!p)
257                         return EFI_OUT_OF_RESOURCES;
258
259                 *buf = p;
260                 *size = buf_size;
261                 ret = efi_get_next_variable_name_int(&buf_size, *buf, guid);
262         }
263
264         return ret;
265 }
266
267 /**
268  * efi_search_bootorder() - search the boot option index in BootOrder
269  *
270  * @bootorder:  pointer to the BootOrder variable
271  * @num:        number of BootOrder entry
272  * @target:     target boot option index to search
273  * @index:      pointer to store the index of BootOrder variable
274  * Return:      true if exists, false otherwise
275  */
276 bool efi_search_bootorder(u16 *bootorder, efi_uintn_t num, u32 target, u32 *index)
277 {
278         u32 i;
279
280         for (i = 0; i < num; i++) {
281                 if (target == bootorder[i]) {
282                         if (index)
283                                 *index = i;
284
285                         return true;
286                 }
287         }
288
289         return false;
290 }
291
292 /**
293  * efi_env_set_load_options() - set load options from environment variable
294  *
295  * @handle:             the image handle
296  * @env_var:            name of the environment variable
297  * @load_options:       pointer to load options (output)
298  * Return:              status code
299  */
300 efi_status_t efi_env_set_load_options(efi_handle_t handle,
301                                       const char *env_var,
302                                       u16 **load_options)
303 {
304         const char *env = env_get(env_var);
305         size_t size;
306         u16 *pos;
307         efi_status_t ret;
308
309         *load_options = NULL;
310         if (!env)
311                 return EFI_SUCCESS;
312         size = sizeof(u16) * (utf8_utf16_strlen(env) + 1);
313         pos = calloc(size, 1);
314         if (!pos)
315                 return EFI_OUT_OF_RESOURCES;
316         *load_options = pos;
317         utf8_utf16_strcpy(&pos, env);
318         ret = efi_set_load_options(handle, size, *load_options);
319         if (ret != EFI_SUCCESS) {
320                 free(*load_options);
321                 *load_options = NULL;
322         }
323         return ret;
324 }
325
326 /**
327  * copy_fdt() - Copy the device tree to a new location available to EFI
328  *
329  * The FDT is copied to a suitable location within the EFI memory map.
330  * Additional 12 KiB are added to the space in case the device tree needs to be
331  * expanded later with fdt_open_into().
332  *
333  * @fdtp:       On entry a pointer to the flattened device tree.
334  *              On exit a pointer to the copy of the flattened device tree.
335  *              FDT start
336  * Return:      status code
337  */
338 static efi_status_t copy_fdt(void **fdtp)
339 {
340         unsigned long fdt_ram_start = -1L, fdt_pages;
341         efi_status_t ret = 0;
342         void *fdt, *new_fdt;
343         u64 new_fdt_addr;
344         uint fdt_size;
345         int i;
346
347         for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
348                 u64 ram_start = gd->bd->bi_dram[i].start;
349                 u64 ram_size = gd->bd->bi_dram[i].size;
350
351                 if (!ram_size)
352                         continue;
353
354                 if (ram_start < fdt_ram_start)
355                         fdt_ram_start = ram_start;
356         }
357
358         /*
359          * Give us at least 12 KiB of breathing room in case the device tree
360          * needs to be expanded later.
361          */
362         fdt = *fdtp;
363         fdt_pages = efi_size_in_pages(fdt_totalsize(fdt) + 0x3000);
364         fdt_size = fdt_pages << EFI_PAGE_SHIFT;
365
366         ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
367                                  EFI_ACPI_RECLAIM_MEMORY, fdt_pages,
368                                  &new_fdt_addr);
369         if (ret != EFI_SUCCESS) {
370                 log_err("ERROR: Failed to reserve space for FDT\n");
371                 goto done;
372         }
373         new_fdt = (void *)(uintptr_t)new_fdt_addr;
374         memcpy(new_fdt, fdt, fdt_totalsize(fdt));
375         fdt_set_totalsize(new_fdt, fdt_size);
376
377         *fdtp = (void *)(uintptr_t)new_fdt_addr;
378 done:
379         return ret;
380 }
381
382 /**
383  * get_config_table() - get configuration table
384  *
385  * @guid:       GUID of the configuration table
386  * Return:      pointer to configuration table or NULL
387  */
388 static void *get_config_table(const efi_guid_t *guid)
389 {
390         size_t i;
391
392         for (i = 0; i < systab.nr_tables; i++) {
393                 if (!guidcmp(guid, &systab.tables[i].guid))
394                         return systab.tables[i].table;
395         }
396         return NULL;
397 }
398
399 /**
400  * efi_install_fdt() - install device tree
401  *
402  * If fdt is not EFI_FDT_USE_INTERNAL, the device tree located at that memory
403  * address will be installed as configuration table, otherwise the device
404  * tree located at the address indicated by environment variable fdt_addr or as
405  * fallback fdtcontroladdr will be used.
406  *
407  * On architectures using ACPI tables device trees shall not be installed as
408  * configuration table.
409  *
410  * @fdt:        address of device tree or EFI_FDT_USE_INTERNAL to use
411  *              the hardware device tree as indicated by environment variable
412  *              fdt_addr or as fallback the internal device tree as indicated by
413  *              the environment variable fdtcontroladdr
414  * Return:      status code
415  */
416 efi_status_t efi_install_fdt(void *fdt)
417 {
418         struct bootm_headers img = { 0 };
419         efi_status_t ret;
420
421         /*
422          * The EBBR spec requires that we have either an FDT or an ACPI table
423          * but not both.
424          */
425         if (CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) && fdt)
426                 log_warning("WARNING: Can't have ACPI table and device tree - ignoring DT.\n");
427
428         if (fdt == EFI_FDT_USE_INTERNAL) {
429                 const char *fdt_opt;
430                 uintptr_t fdt_addr;
431
432                 /* Look for device tree that is already installed */
433                 if (get_config_table(&efi_guid_fdt))
434                         return EFI_SUCCESS;
435                 /* Check if there is a hardware device tree */
436                 fdt_opt = env_get("fdt_addr");
437                 /* Use our own device tree as fallback */
438                 if (!fdt_opt) {
439                         fdt_opt = env_get("fdtcontroladdr");
440                         if (!fdt_opt) {
441                                 log_err("ERROR: need device tree\n");
442                                 return EFI_NOT_FOUND;
443                         }
444                 }
445                 fdt_addr = hextoul(fdt_opt, NULL);
446                 if (!fdt_addr) {
447                         log_err("ERROR: invalid $fdt_addr or $fdtcontroladdr\n");
448                         return EFI_LOAD_ERROR;
449                 }
450                 fdt = map_sysmem(fdt_addr, 0);
451         }
452
453         /* Install device tree */
454         if (fdt_check_header(fdt)) {
455                 log_err("ERROR: invalid device tree\n");
456                 return EFI_LOAD_ERROR;
457         }
458
459         /* Create memory reservations as indicated by the device tree */
460         efi_carve_out_dt_rsv(fdt);
461
462         if (CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE))
463                 return EFI_SUCCESS;
464
465         /* Prepare device tree for payload */
466         ret = copy_fdt(&fdt);
467         if (ret) {
468                 log_err("ERROR: out of memory\n");
469                 return EFI_OUT_OF_RESOURCES;
470         }
471
472         if (image_setup_libfdt(&img, fdt, NULL)) {
473                 log_err("ERROR: failed to process device tree\n");
474                 return EFI_LOAD_ERROR;
475         }
476
477         efi_try_purge_kaslr_seed(fdt);
478
479         if (CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL_MEASURE_DTB)) {
480                 ret = efi_tcg2_measure_dtb(fdt);
481                 if (ret == EFI_SECURITY_VIOLATION) {
482                         log_err("ERROR: failed to measure DTB\n");
483                         return ret;
484                 }
485         }
486
487         /* Install device tree as UEFI table */
488         ret = efi_install_configuration_table(&efi_guid_fdt, fdt);
489         if (ret != EFI_SUCCESS) {
490                 log_err("ERROR: failed to install device tree\n");
491                 return ret;
492         }
493
494         return EFI_SUCCESS;
495 }
496
497 /**
498  * do_bootefi_exec() - execute EFI binary
499  *
500  * The image indicated by @handle is started. When it returns the allocated
501  * memory for the @load_options is freed.
502  *
503  * @handle:             handle of loaded image
504  * @load_options:       load options
505  * Return:              status code
506  *
507  * Load the EFI binary into a newly assigned memory unwinding the relocation
508  * information, install the loaded image protocol, and call the binary.
509  */
510 efi_status_t do_bootefi_exec(efi_handle_t handle, void *load_options)
511 {
512         efi_status_t ret;
513         efi_uintn_t exit_data_size = 0;
514         u16 *exit_data = NULL;
515         struct efi_event *evt;
516
517         /* On ARM switch from EL3 or secure mode to EL2 or non-secure mode */
518         switch_to_non_secure_mode();
519
520         /*
521          * The UEFI standard requires that the watchdog timer is set to five
522          * minutes when invoking an EFI boot option.
523          *
524          * Unified Extensible Firmware Interface (UEFI), version 2.7 Errata A
525          * 7.5. Miscellaneous Boot Services - EFI_BOOT_SERVICES.SetWatchdogTimer
526          */
527         ret = efi_set_watchdog(300);
528         if (ret != EFI_SUCCESS) {
529                 log_err("ERROR: Failed to set watchdog timer\n");
530                 goto out;
531         }
532
533         /* Call our payload! */
534         ret = EFI_CALL(efi_start_image(handle, &exit_data_size, &exit_data));
535         if (ret != EFI_SUCCESS) {
536                 log_err("## Application failed, r = %lu\n",
537                         ret & ~EFI_ERROR_MASK);
538                 if (exit_data) {
539                         log_err("## %ls\n", exit_data);
540                         efi_free_pool(exit_data);
541                 }
542         }
543
544         efi_restore_gd();
545
546 out:
547         free(load_options);
548
549         if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD)) {
550                 if (efi_initrd_deregister() != EFI_SUCCESS)
551                         log_err("Failed to remove loadfile2 for initrd\n");
552         }
553
554         /* Notify EFI_EVENT_GROUP_RETURN_TO_EFIBOOTMGR event group. */
555         list_for_each_entry(evt, &efi_events, link) {
556                 if (evt->group &&
557                     !guidcmp(evt->group,
558                              &efi_guid_event_group_return_to_efibootmgr)) {
559                         efi_signal_event(evt);
560                         EFI_CALL(systab.boottime->close_event(evt));
561                         break;
562                 }
563         }
564
565         /* Control is returned to U-Boot, disable EFI watchdog */
566         efi_set_watchdog(0);
567
568         return ret;
569 }
This page took 0.060309 seconds and 4 git commands to generate.