Pull request for UEFI sub-system for efi-2020-07-rc2

This pull request contains bug fixes needed due to the merged changes for
 EFI secure boot.
 
 Patches are supplied to identify EFI system partitions.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAl6qkUQACgkQxIHbvCwF
 GsRGkQ//R1VltRXNk4RrYiKbsU33biNAIWQB4IhQpm6w1SgsrPAb7yWJEg1xhJ3P
 qhujDlVlW2s2Cz+sMkQOTd5/ln55IegJZ4LFlQuOhJCO22TzEenP8bkziMU7UBu8
 YtbhtV5cru2DBMg8uBQCazw9Lue5WUktzHgWhiNy+yBY5g6j+vkQHjy/+BjpC6RD
 7KT4qfyh+hyhss+O2lLjQYwobVwVxnCfQikWSdfMRqptC8N/lYMGNjiNk42HJssX
 cWy44TNUePgCE5pES1krXmR3q7fT/ocuWW2g8QynEJIqjZSWVTmZqLgdba3pd5Di
 kfleoByXLS0/HS6AgjdJNv+vwRuOot1RBXfbVYnDwb7flFThvu3xBzy55IMHa6uH
 eHDt3v1W3ZSwGnxiTzdbHISH5JidBUJAq+h+S3Zy52plbkgMWplPgFptSscM6+yo
 YrCTlzuj019X/Lm1JfO2X7NqhGPX9/MiMDwfvE+BGnWRhwOHNSu/S6+Iu1XUBrXN
 Q/tnHJxK1FGcoq73a/5VgiSkfnEl1+YdjdAUM8+nJdUPCL5xCWX1jXNxE0vq0l4U
 Y3zsjCj5lM4TnDUJvbOacMM4ltjxSMpBwmkGdleYOcKJxU8WD0YNuhUL2nnUFuDx
 7MYHonEPz5s3T+IiMoNAtYr3BHKcxedHNkmpoJsaPS69zMGq7dM=
 =38oT
 -----END PGP SIGNATURE-----

Merge tag 'efi-2020-07-rc2' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi

Pull request for UEFI sub-system for efi-2020-07-rc2

This pull request contains bug fixes needed due to the merged changes for
EFI secure boot.

Patches are supplied to identify EFI system partitions.
This commit is contained in:
Tom Rini 2020-04-30 15:11:06 -04:00
commit 78021b6337
11 changed files with 179 additions and 140 deletions

View File

@ -625,6 +625,7 @@ F: include/asm-generic/pe.h
F: lib/charset.c F: lib/charset.c
F: lib/efi*/ F: lib/efi*/
F: test/py/tests/test_efi* F: test/py/tests/test_efi*
F: test/py/tests/test_efi*/
F: test/unicode_ut.c F: test/unicode_ut.c
F: cmd/bootefi.c F: cmd/bootefi.c
F: cmd/efidebug.c F: cmd/efidebug.c

View File

@ -481,10 +481,8 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size)
ret = do_bootefi_exec(handle); ret = do_bootefi_exec(handle);
out: out:
if (mem_handle) efi_delete_handle(mem_handle);
efi_delete_handle(mem_handle); efi_free_pool(file_path);
if (file_path)
efi_free_pool(file_path);
return ret; return ret;
} }

View File

@ -395,6 +395,7 @@ static const char * const efi_mem_type_string[] = {
[EFI_MMAP_IO] = "IO", [EFI_MMAP_IO] = "IO",
[EFI_MMAP_IO_PORT] = "IO PORT", [EFI_MMAP_IO_PORT] = "IO PORT",
[EFI_PAL_CODE] = "PAL", [EFI_PAL_CODE] = "PAL",
[EFI_PERSISTENT_MEMORY_TYPE] = "PERSISTENT",
}; };
static const struct efi_mem_attrs { static const struct efi_mem_attrs {
@ -482,7 +483,7 @@ static int do_efi_show_memmap(cmd_tbl_t *cmdtp, int flag,
printf("================ %.*s %.*s ==========\n", printf("================ %.*s %.*s ==========\n",
EFI_PHYS_ADDR_WIDTH, sep, EFI_PHYS_ADDR_WIDTH, sep); EFI_PHYS_ADDR_WIDTH, sep, EFI_PHYS_ADDR_WIDTH, sep);
for (i = 0, map = memmap; i < map_size / sizeof(*map); map++, i++) { for (i = 0, map = memmap; i < map_size / sizeof(*map); map++, i++) {
if (map->type < EFI_MAX_MEMORY_TYPE) if (map->type < ARRAY_SIZE(efi_mem_type_string))
type = efi_mem_type_string[map->type]; type = efi_mem_type_string[map->type];
else else
type = "(unknown)"; type = "(unknown)";
@ -682,13 +683,13 @@ static int do_efi_boot_rm(cmd_tbl_t *cmdtp, int flag,
/** /**
* show_efi_boot_opt_data() - dump UEFI load option * show_efi_boot_opt_data() - dump UEFI load option
* *
* @id: load option number * @varname16: variable name
* @data: value of UEFI load option variable * @data: value of UEFI load option variable
* @size: size of the boot option * @size: size of the boot option
* *
* Decode the value of UEFI load option variable and print information. * Decode the value of UEFI load option variable and print information.
*/ */
static void show_efi_boot_opt_data(int id, void *data, size_t size) static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t size)
{ {
struct efi_load_option lo; struct efi_load_option lo;
char *label, *p; char *label, *p;
@ -705,8 +706,8 @@ static void show_efi_boot_opt_data(int id, void *data, size_t size)
p = label; p = label;
utf16_utf8_strncpy(&p, lo.label, label_len16); utf16_utf8_strncpy(&p, lo.label, label_len16);
printf("Boot%04X:\n", id); printf("%ls:\nattributes: %c%c%c (0x%08x)\n",
printf(" attributes: %c%c%c (0x%08x)\n", varname16,
/* ACTIVE */ /* ACTIVE */
lo.attributes & LOAD_OPTION_ACTIVE ? 'A' : '-', lo.attributes & LOAD_OPTION_ACTIVE ? 'A' : '-',
/* FORCE RECONNECT */ /* FORCE RECONNECT */
@ -730,37 +731,32 @@ static void show_efi_boot_opt_data(int id, void *data, size_t size)
/** /**
* show_efi_boot_opt() - dump UEFI load option * show_efi_boot_opt() - dump UEFI load option
* *
* @id: Load option number * @varname16: variable name
* *
* Dump information defined by UEFI load option. * Dump information defined by UEFI load option.
*/ */
static void show_efi_boot_opt(int id) static void show_efi_boot_opt(u16 *varname16)
{ {
char var_name[9]; void *data;
u16 var_name16[9], *p;
efi_guid_t guid;
void *data = NULL;
efi_uintn_t size; efi_uintn_t size;
efi_status_t ret; efi_status_t ret;
sprintf(var_name, "Boot%04X", id);
p = var_name16;
utf8_utf16_strncpy(&p, var_name, 9);
guid = efi_global_variable_guid;
size = 0; size = 0;
ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, NULL)); ret = EFI_CALL(efi_get_variable(varname16, &efi_global_variable_guid,
NULL, &size, NULL));
if (ret == EFI_BUFFER_TOO_SMALL) { if (ret == EFI_BUFFER_TOO_SMALL) {
data = malloc(size); data = malloc(size);
ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, if (!data) {
data)); printf("ERROR: Out of memory\n");
return;
}
ret = EFI_CALL(efi_get_variable(varname16,
&efi_global_variable_guid,
NULL, &size, data));
if (ret == EFI_SUCCESS)
show_efi_boot_opt_data(varname16, data, size);
free(data);
} }
if (ret == EFI_SUCCESS)
show_efi_boot_opt_data(id, data, size);
else if (ret == EFI_NOT_FOUND)
printf("Boot%04X: not found\n", id);
free(data);
} }
static int u16_tohex(u16 c) static int u16_tohex(u16 c)
@ -839,7 +835,7 @@ static int do_efi_boot_dump(cmd_tbl_t *cmdtp, int flag,
id = (id << 4) + digit; id = (id << 4) + digit;
} }
if (i == 4 && !var_name16[8]) if (i == 4 && !var_name16[8])
show_efi_boot_opt(id); show_efi_boot_opt(var_name16);
} }
free(var_name16); free(var_name16);
@ -856,8 +852,7 @@ static int do_efi_boot_dump(cmd_tbl_t *cmdtp, int flag,
*/ */
static int show_efi_boot_order(void) static int show_efi_boot_order(void)
{ {
efi_guid_t guid; u16 *bootorder;
u16 *bootorder = NULL;
efi_uintn_t size; efi_uintn_t size;
int num, i; int num, i;
char var_name[9]; char var_name[9];
@ -868,20 +863,25 @@ static int show_efi_boot_order(void)
size_t label_len16, label_len; size_t label_len16, label_len;
efi_status_t ret; efi_status_t ret;
guid = efi_global_variable_guid;
size = 0; size = 0;
ret = EFI_CALL(RT->get_variable(L"BootOrder", &guid, NULL, &size, ret = EFI_CALL(RT->get_variable(L"BootOrder", &efi_global_variable_guid,
NULL)); NULL, &size, NULL));
if (ret == EFI_BUFFER_TOO_SMALL) { if (ret != EFI_BUFFER_TOO_SMALL) {
bootorder = malloc(size); if (ret == EFI_NOT_FOUND) {
ret = EFI_CALL(RT->get_variable(L"BootOrder", &guid, NULL, printf("BootOrder not defined\n");
&size, bootorder)); return CMD_RET_SUCCESS;
} else {
return CMD_RET_FAILURE;
}
} }
if (ret == EFI_NOT_FOUND) { bootorder = malloc(size);
printf("BootOrder not defined\n"); if (!bootorder) {
ret = CMD_RET_SUCCESS; printf("ERROR: Out of memory\n");
goto out; return CMD_RET_FAILURE;
} else if (ret != EFI_SUCCESS) { }
ret = EFI_CALL(efi_get_variable(L"BootOrder", &efi_global_variable_guid,
NULL, &size, bootorder));
if (ret != EFI_SUCCESS) {
ret = CMD_RET_FAILURE; ret = CMD_RET_FAILURE;
goto out; goto out;
} }
@ -893,11 +893,11 @@ static int show_efi_boot_order(void)
utf8_utf16_strncpy(&p16, var_name, 9); utf8_utf16_strncpy(&p16, var_name, 9);
size = 0; size = 0;
ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, ret = EFI_CALL(efi_get_variable(var_name16,
NULL)); &efi_global_variable_guid, NULL,
&size, NULL));
if (ret != EFI_BUFFER_TOO_SMALL) { if (ret != EFI_BUFFER_TOO_SMALL) {
printf("%2d: Boot%04X: (not defined)\n", printf("%2d: %s: (not defined)\n", i + 1, var_name);
i + 1, bootorder[i]);
continue; continue;
} }
@ -906,8 +906,9 @@ static int show_efi_boot_order(void)
ret = CMD_RET_FAILURE; ret = CMD_RET_FAILURE;
goto out; goto out;
} }
ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, ret = EFI_CALL(efi_get_variable(var_name16,
data)); &efi_global_variable_guid, NULL,
&size, data));
if (ret != EFI_SUCCESS) { if (ret != EFI_SUCCESS) {
free(data); free(data);
ret = CMD_RET_FAILURE; ret = CMD_RET_FAILURE;
@ -926,7 +927,7 @@ static int show_efi_boot_order(void)
} }
p = label; p = label;
utf16_utf8_strncpy(&p, lo.label, label_len16); utf16_utf8_strncpy(&p, lo.label, label_len16);
printf("%2d: Boot%04X: %s\n", i + 1, bootorder[i], label); printf("%2d: %s: %s\n", i + 1, var_name, label);
free(label); free(label);
free(data); free(data);

View File

@ -245,7 +245,7 @@ static void print_gpt_info(void)
printf("Block size %lu, name %s\n", curr->gpt_part_info.blksz, printf("Block size %lu, name %s\n", curr->gpt_part_info.blksz,
curr->gpt_part_info.name); curr->gpt_part_info.name);
printf("Type %s, bootable %d\n", curr->gpt_part_info.type, printf("Type %s, bootable %d\n", curr->gpt_part_info.type,
curr->gpt_part_info.bootable); curr->gpt_part_info.bootable & PART_BOOTABLE);
#ifdef CONFIG_PARTITION_UUIDS #ifdef CONFIG_PARTITION_UUIDS
printf("UUID %s\n", curr->gpt_part_info.uuid); printf("UUID %s\n", curr->gpt_part_info.uuid);
#endif #endif
@ -535,7 +535,7 @@ static int set_gpt_info(struct blk_desc *dev_desc,
/* bootable */ /* bootable */
if (found_key(tok, "bootable")) if (found_key(tok, "bootable"))
parts[i].bootable = 1; parts[i].bootable = PART_BOOTABLE;
} }
*parts_count = p_count; *parts_count = p_count;

View File

@ -45,9 +45,15 @@ static inline int is_extended(int part_type)
part_type == 0x85); part_type == 0x85);
} }
static inline int is_bootable(dos_partition_t *p) static int get_bootable(dos_partition_t *p)
{ {
return (p->sys_ind == 0xef) || (p->boot_ind == 0x80); int ret = 0;
if (p->sys_ind == 0xef)
ret |= PART_EFI_SYSTEM_PARTITION;
if (p->boot_ind == 0x80)
ret |= PART_BOOTABLE;
return ret;
} }
static void print_one_part(dos_partition_t *p, lbaint_t ext_part_sector, static void print_one_part(dos_partition_t *p, lbaint_t ext_part_sector,
@ -60,7 +66,7 @@ static void print_one_part(dos_partition_t *p, lbaint_t ext_part_sector,
"u\t%08x-%02x\t%02x%s%s\n", "u\t%08x-%02x\t%02x%s%s\n",
part_num, lba_start, lba_size, disksig, part_num, p->sys_ind, part_num, lba_start, lba_size, disksig, part_num, p->sys_ind,
(is_extended(p->sys_ind) ? " Extd" : ""), (is_extended(p->sys_ind) ? " Extd" : ""),
(is_bootable(p) ? " Boot" : "")); (get_bootable(p) ? " Boot" : ""));
} }
static int test_block_type(unsigned char *buffer) static int test_block_type(unsigned char *buffer)
@ -258,7 +264,7 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
(char *)info->name); (char *)info->name);
/* sprintf(info->type, "%d, pt->sys_ind); */ /* sprintf(info->type, "%d, pt->sys_ind); */
strcpy((char *)info->type, "U-Boot"); strcpy((char *)info->type, "U-Boot");
info->bootable = is_bootable(pt); info->bootable = get_bootable(pt);
#if CONFIG_IS_ENABLED(PARTITION_UUIDS) #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
sprintf(info->uuid, "%08x-%02x", disksig, part_num); sprintf(info->uuid, "%08x-%02x", disksig, part_num);
#endif #endif

View File

@ -71,11 +71,15 @@ static char *print_efiname(gpt_entry *pte)
static const efi_guid_t system_guid = PARTITION_SYSTEM_GUID; static const efi_guid_t system_guid = PARTITION_SYSTEM_GUID;
static inline int is_bootable(gpt_entry *p) static int get_bootable(gpt_entry *p)
{ {
return p->attributes.fields.legacy_bios_bootable || int ret = 0;
!memcmp(&(p->partition_type_guid), &system_guid,
sizeof(efi_guid_t)); if (!memcmp(&p->partition_type_guid, &system_guid, sizeof(efi_guid_t)))
ret |= PART_EFI_SYSTEM_PARTITION;
if (p->attributes.fields.legacy_bios_bootable)
ret |= PART_BOOTABLE;
return ret;
} }
static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba, static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba,
@ -286,7 +290,7 @@ int part_get_info_efi(struct blk_desc *dev_desc, int part,
snprintf((char *)info->name, sizeof(info->name), "%s", snprintf((char *)info->name, sizeof(info->name), "%s",
print_efiname(&gpt_pte[part - 1])); print_efiname(&gpt_pte[part - 1]));
strcpy((char *)info->type, "U-Boot"); strcpy((char *)info->type, "U-Boot");
info->bootable = is_bootable(&gpt_pte[part - 1]); info->bootable = get_bootable(&gpt_pte[part - 1]);
#if CONFIG_IS_ENABLED(PARTITION_UUIDS) #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid, uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid,
UUID_STR_FORMAT_GUID); UUID_STR_FORMAT_GUID);
@ -501,7 +505,7 @@ int gpt_fill_pte(struct blk_desc *dev_desc,
memset(&gpt_e[i].attributes, 0, memset(&gpt_e[i].attributes, 0,
sizeof(gpt_entry_attributes)); sizeof(gpt_entry_attributes));
if (partitions[i].bootable) if (partitions[i].bootable & PART_BOOTABLE)
gpt_e[i].attributes.fields.legacy_bios_bootable = 1; gpt_e[i].attributes.fields.legacy_bios_bootable = 1;
/* partition name */ /* partition name */

View File

@ -100,79 +100,93 @@ See doc/uImage.FIT/howto.txt for an introduction to FIT images.
Configuring UEFI secure boot Configuring UEFI secure boot
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UEFI specification[1] defines a secure way of executing UEFI images The UEFI specification[1] defines a secure way of executing UEFI images
by verifying a signature (or message digest) of image with certificates. by verifying a signature (or message digest) of image with certificates.
This feature on U-Boot is enabled with:: This feature on U-Boot is enabled with::
CONFIG_UEFI_SECURE_BOOT=y CONFIG_UEFI_SECURE_BOOT=y
To make the boot sequence safe, you need to establish a chain of trust; To make the boot sequence safe, you need to establish a chain of trust;
In UEFI secure boot, you can make it with the UEFI variables, "PK" In UEFI secure boot the chain trust is defined by the following UEFI variables
(Platform Key), "KEK" (Key Exchange Keys), "db" (white list database)
and "dbx" (black list database).
There are many online documents that describe what UEFI secure boot is * PK - Platform Key
and how it works. Please consult some of them for details. * KEK - Key Exchange Keys
* db - white list database
* dbx - black list database
Here is a simple example that you can follow for your initial attempt An in depth description of UEFI secure boot is beyond the scope of this
(Please note that the actual steps would absolutely depend on your system document. Please, refer to the UEFI specification and available online
and environment.): documentation. Here is a simple example that you can follow for your initial
attempt (Please note that the actual steps will depend on your system and
environment.):
1. Install utility commands on your host Install the required tools on your host
* openssl
* efitools
* sbsigntool
2. Create signing keys and key database files on your host * openssl
for PK:: * efitools
* sbsigntool
$ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_PK/ \ Create signing keys and the key database on your host:
-keyout PK.key -out PK.crt -nodes -days 365
$ cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc \
PK.crt PK.esl;
$ sign-efi-sig-list -c PK.crt -k PK.key PK PK.esl PK.auth
for KEK:: The platform key
$ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_KEK/ \ .. code-block:: bash
-keyout KEK.key -out KEK.crt -nodes -days 365
$ cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc \
KEK.crt KEK.esl
$ sign-efi-sig-list -c PK.crt -k PK.key KEK KEK.esl KEK.auth
for db:: openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_PK/ \
-keyout PK.key -out PK.crt -nodes -days 365
cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc \
PK.crt PK.esl;
sign-efi-sig-list -c PK.crt -k PK.key PK PK.esl PK.auth
$ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_db/ \ The key exchange keys
-keyout db.key -out db.crt -nodes -days 365
$ cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc \
db.crt db.esl
$ sign-efi-sig-list -c KEK.crt -k KEK.key db db.esl db.auth
Copy \*.auth to media, say mmc, that is accessible from U-Boot. .. code-block:: bash
3. Sign an image with one key in "db" on your host:: openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_KEK/ \
-keyout KEK.key -out KEK.crt -nodes -days 365
cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc \
KEK.crt KEK.esl
sign-efi-sig-list -c PK.crt -k PK.key KEK KEK.esl KEK.auth
$ sbsign --key db.key --cert db.crt helloworld.efi The whitelist database
4. Install keys on your board:: .. code-block:: bash
==> fatload mmc 0:1 <tmpaddr> PK.auth $ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_db/ \
==> setenv -e -nv -bs -rt -at -i <tmpaddr>,$filesize PK -keyout db.key -out db.crt -nodes -days 365
==> fatload mmc 0:1 <tmpaddr> KEK.auth $ cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc \
==> setenv -e -nv -bs -rt -at -i <tmpaddr>,$filesize KEK db.crt db.esl
==> fatload mmc 0:1 <tmpaddr> db.auth $ sign-efi-sig-list -c KEK.crt -k KEK.key db db.esl db.auth
==> setenv -e -nv -bs -rt -at -i <tmpaddr>,$filesize db
5. Set up boot parameters on your board:: Copy the \*.auth files to media, say mmc, that is accessible from U-Boot.
==> efidebug boot add 1 HELLO mmc 0:1 /helloworld.efi.signed "" Sign an image with one of the keys in "db" on your host
Then your board runs that image from Boot manager (See below). .. code-block:: bash
sbsign --key db.key --cert db.crt helloworld.efi
Now in U-Boot install the keys on your board::
fatload mmc 0:1 <tmpaddr> PK.auth
setenv -e -nv -bs -rt -at -i <tmpaddr>,$filesize PK
fatload mmc 0:1 <tmpaddr> KEK.auth
setenv -e -nv -bs -rt -at -i <tmpaddr>,$filesize KEK
fatload mmc 0:1 <tmpaddr> db.auth
setenv -e -nv -bs -rt -at -i <tmpaddr>,$filesize db
Set up boot parameters on your board::
efidebug boot add 1 HELLO mmc 0:1 /helloworld.efi.signed ""
Now your board can run the signed image via the boot manager (see below).
You can also try this sequence by running Pytest, test_efi_secboot, You can also try this sequence by running Pytest, test_efi_secboot,
on sandbox:: on the sandbox
$ cd <U-Boot source directory> .. code-block:: bash
$ pytest.py test/py/tests/test_efi_secboot/test_signed.py --bd sandbox
cd <U-Boot source directory>
pytest.py test/py/tests/test_efi_secboot/test_signed.py --bd sandbox
Executing the boot manager Executing the boot manager
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -11,6 +11,7 @@
#include <common.h> #include <common.h>
#include <part_efi.h> #include <part_efi.h>
#include <efi_api.h> #include <efi_api.h>
#include <image.h>
#include <pe.h> #include <pe.h>
static inline int guidcmp(const void *g1, const void *g2) static inline int guidcmp(const void *g1, const void *g2)
@ -47,6 +48,13 @@ static inline void *guidcpy(void *dst, const void *src)
/* Root node */ /* Root node */
extern efi_handle_t efi_root; extern efi_handle_t efi_root;
/* EFI system partition */
extern struct efi_system_partition {
enum if_type if_type;
int devnum;
u8 part;
} efi_system_partition;
int __efi_entry_check(void); int __efi_entry_check(void);
int __efi_exit_check(void); int __efi_exit_check(void);
const char *__efi_nesting(void); const char *__efi_nesting(void);
@ -695,9 +703,6 @@ void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data);
unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data); unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data);
efi_status_t efi_bootmgr_load(efi_handle_t *handle); efi_status_t efi_bootmgr_load(efi_handle_t *handle);
#ifdef CONFIG_EFI_SECURE_BOOT
#include <image.h>
/** /**
* efi_image_regions - A list of memory regions * efi_image_regions - A list of memory regions
* *
@ -767,7 +772,6 @@ bool efi_secure_boot_enabled(void);
bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp, bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp,
WIN_CERTIFICATE **auth, size_t *auth_len); WIN_CERTIFICATE **auth, size_t *auth_len);
#endif /* CONFIG_EFI_SECURE_BOOT */
#else /* CONFIG_IS_ENABLED(EFI_LOADER) */ #else /* CONFIG_IS_ENABLED(EFI_LOADER) */

View File

@ -51,13 +51,22 @@ struct block_drvr {
#define PART_TYPE_LEN 32 #define PART_TYPE_LEN 32
#define MAX_SEARCH_PARTITIONS 64 #define MAX_SEARCH_PARTITIONS 64
#define PART_BOOTABLE ((int)BIT(0))
#define PART_EFI_SYSTEM_PARTITION ((int)BIT(1))
typedef struct disk_partition { typedef struct disk_partition {
lbaint_t start; /* # of first block in partition */ lbaint_t start; /* # of first block in partition */
lbaint_t size; /* number of blocks in partition */ lbaint_t size; /* number of blocks in partition */
ulong blksz; /* block size in bytes */ ulong blksz; /* block size in bytes */
uchar name[PART_NAME_LEN]; /* partition name */ uchar name[PART_NAME_LEN]; /* partition name */
uchar type[PART_TYPE_LEN]; /* string type description */ uchar type[PART_TYPE_LEN]; /* string type description */
int bootable; /* Active/Bootable flag is set */ /*
* The bootable is a bitmask with the following fields:
*
* PART_BOOTABLE the MBR bootable flag is set
* PART_EFI_SYSTEM_PARTITION the partition is an EFI system partition
*/
int bootable;
#if CONFIG_IS_ENABLED(PARTITION_UUIDS) #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
char uuid[UUID_STR_LEN + 1]; /* filesystem UUID as string, if exists */ char uuid[UUID_STR_LEN + 1]; /* filesystem UUID as string, if exists */
#endif #endif

View File

@ -13,6 +13,8 @@
#include <part.h> #include <part.h>
#include <malloc.h> #include <malloc.h>
struct efi_system_partition efi_system_partition;
const efi_guid_t efi_block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID; const efi_guid_t efi_block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
/** /**
@ -418,6 +420,24 @@ static efi_status_t efi_disk_add_dev(
diskobj->ops.media = &diskobj->media; diskobj->ops.media = &diskobj->media;
if (disk) if (disk)
*disk = diskobj; *disk = diskobj;
/* Store first EFI system partition */
if (part && !efi_system_partition.if_type) {
int r;
disk_partition_t info;
r = part_get_info(desc, part, &info);
if (r)
return EFI_DEVICE_ERROR;
if (info.bootable & PART_EFI_SYSTEM_PARTITION) {
efi_system_partition.if_type = desc->if_type;
efi_system_partition.devnum = desc->devnum;
efi_system_partition.part = part;
EFI_PRINT("EFI system partition: %s %d:%d\n",
blk_get_if_type_name(desc->if_type),
desc->devnum, part);
}
}
return EFI_SUCCESS; return EFI_SUCCESS;
} }

View File

@ -43,7 +43,8 @@ def efi_boot_env(request, u_boot_config):
HELLO_PATH = u_boot_config.build_dir + '/lib/efi_loader/helloworld.efi' HELLO_PATH = u_boot_config.build_dir + '/lib/efi_loader/helloworld.efi'
try: try:
non_root = tool_is_in_path('udisksctl') mnt_point = u_boot_config.persistent_data_dir + '/mnt_efisecure'
check_call('mkdir -p {}'.format(mnt_point), shell=True)
# create a disk/partition # create a disk/partition
check_call('dd if=/dev/zero of=%s bs=1MiB count=%d' check_call('dd if=/dev/zero of=%s bs=1MiB count=%d'
@ -57,25 +58,11 @@ def efi_boot_env(request, u_boot_config):
check_call('dd if=%s.tmp of=%s bs=1MiB seek=1 count=%d conv=notrunc' check_call('dd if=%s.tmp of=%s bs=1MiB seek=1 count=%d conv=notrunc'
% (image_path, image_path, 1), shell=True) % (image_path, image_path, 1), shell=True)
check_call('rm %s.tmp' % image_path, shell=True) check_call('rm %s.tmp' % image_path, shell=True)
if non_root: loop_dev = check_output('sudo losetup -o 1MiB --sizelimit %dMiB --show -f %s | tr -d "\n"'
out_data = check_output('udisksctl loop-setup -f %s -o %d'
% (image_path, 1048576), shell=True).decode()
m = re.search('(?<= as )(.*)\.', out_data)
loop_dev = m.group(1)
# print 'loop device is: %s' % loop_dev
out_data = check_output('udisksctl info -b %s'
% loop_dev, shell=True).decode()
m = re.search('MountPoints:[ \t]+(.*)', out_data)
mnt_point = m.group(1)
else:
loop_dev = check_output('sudo losetup -o 1MiB --sizelimit %dMiB --show -f %s | tr -d "\n"'
% (part_size, image_path), shell=True).decode() % (part_size, image_path), shell=True).decode()
mnt_point = '/mnt' check_output('sudo mount -t %s -o umask=000 %s %s'
check_output('sudo mount -t %s -o umask=000 %s %s'
% (fs_type, loop_dev, mnt_point), shell=True) % (fs_type, loop_dev, mnt_point), shell=True)
# print 'mount point is: %s' % mnt_point
# suffix # suffix
# *.key: RSA private key in PEM # *.key: RSA private key in PEM
# *.crt: X509 certificate (self-signed) in PEM # *.crt: X509 certificate (self-signed) in PEM
@ -134,13 +121,8 @@ def efi_boot_env(request, u_boot_config):
% (mnt_point, EFITOOLS_PATH, EFITOOLS_PATH), % (mnt_point, EFITOOLS_PATH, EFITOOLS_PATH),
shell=True) shell=True)
if non_root: check_call('sudo umount %s' % loop_dev, shell=True)
check_call('udisksctl unmount -b %s' % loop_dev, shell=True) check_call('sudo losetup -d %s' % loop_dev, shell=True)
# not needed
# check_call('udisksctl loop-delete -b %s' % loop_dev, shell=True)
else:
check_call('sudo umount %s' % loop_dev, shell=True)
check_call('sudo losetup -d %s' % loop_dev, shell=True)
except CalledProcessError as e: except CalledProcessError as e:
pytest.skip('Setup failed: %s' % e.cmd) pytest.skip('Setup failed: %s' % e.cmd)