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:
commit
78021b6337
@ -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
|
||||||
|
@ -481,9 +481,7 @@ 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);
|
||||||
if (file_path)
|
|
||||||
efi_free_pool(file_path);
|
efi_free_pool(file_path);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
if (ret == EFI_SUCCESS)
|
||||||
show_efi_boot_opt_data(id, data, size);
|
show_efi_boot_opt_data(varname16, data, size);
|
||||||
else if (ret == EFI_NOT_FOUND)
|
|
||||||
printf("Boot%04X: not found\n", id);
|
|
||||||
|
|
||||||
free(data);
|
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);
|
|
||||||
ret = EFI_CALL(RT->get_variable(L"BootOrder", &guid, NULL,
|
|
||||||
&size, bootorder));
|
|
||||||
}
|
|
||||||
if (ret == EFI_NOT_FOUND) {
|
if (ret == EFI_NOT_FOUND) {
|
||||||
printf("BootOrder not defined\n");
|
printf("BootOrder not defined\n");
|
||||||
ret = CMD_RET_SUCCESS;
|
return CMD_RET_SUCCESS;
|
||||||
goto out;
|
} else {
|
||||||
} else if (ret != EFI_SUCCESS) {
|
return CMD_RET_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bootorder = malloc(size);
|
||||||
|
if (!bootorder) {
|
||||||
|
printf("ERROR: Out of memory\n");
|
||||||
|
return CMD_RET_FAILURE;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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 */
|
||||||
|
@ -100,47 +100,57 @@ 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:
|
||||||
|
|
||||||
|
The platform key
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_PK/ \
|
||||||
-keyout PK.key -out PK.crt -nodes -days 365
|
-keyout PK.key -out PK.crt -nodes -days 365
|
||||||
$ cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc \
|
cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc \
|
||||||
PK.crt PK.esl;
|
PK.crt PK.esl;
|
||||||
$ sign-efi-sig-list -c PK.crt -k PK.key PK PK.esl PK.auth
|
sign-efi-sig-list -c PK.crt -k PK.key PK PK.esl PK.auth
|
||||||
|
|
||||||
for KEK::
|
The key exchange keys
|
||||||
|
|
||||||
$ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_KEK/ \
|
.. code-block:: bash
|
||||||
|
|
||||||
|
openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_KEK/ \
|
||||||
-keyout KEK.key -out KEK.crt -nodes -days 365
|
-keyout KEK.key -out KEK.crt -nodes -days 365
|
||||||
$ cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc \
|
cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc \
|
||||||
KEK.crt KEK.esl
|
KEK.crt KEK.esl
|
||||||
$ sign-efi-sig-list -c PK.crt -k PK.key KEK KEK.esl KEK.auth
|
sign-efi-sig-list -c PK.crt -k PK.key KEK KEK.esl KEK.auth
|
||||||
|
|
||||||
for db::
|
The whitelist database
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
$ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_db/ \
|
$ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_db/ \
|
||||||
-keyout db.key -out db.crt -nodes -days 365
|
-keyout db.key -out db.crt -nodes -days 365
|
||||||
@ -148,31 +158,35 @@ and environment.):
|
|||||||
db.crt db.esl
|
db.crt db.esl
|
||||||
$ sign-efi-sig-list -c KEK.crt -k KEK.key db db.esl db.auth
|
$ 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.
|
Copy the \*.auth files to media, say mmc, that is accessible from U-Boot.
|
||||||
|
|
||||||
3. Sign an image with one key in "db" on your host::
|
Sign an image with one of the keys in "db" on your host
|
||||||
|
|
||||||
$ sbsign --key db.key --cert db.crt helloworld.efi
|
.. code-block:: bash
|
||||||
|
|
||||||
4. Install keys on your board::
|
sbsign --key db.key --cert db.crt helloworld.efi
|
||||||
|
|
||||||
==> fatload mmc 0:1 <tmpaddr> PK.auth
|
Now in U-Boot install the keys on your board::
|
||||||
==> 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
|
|
||||||
|
|
||||||
5. Set up boot parameters 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
|
||||||
|
|
||||||
==> efidebug boot add 1 HELLO mmc 0:1 /helloworld.efi.signed ""
|
Set up boot parameters on your board::
|
||||||
|
|
||||||
Then your board runs that image from Boot manager (See below).
|
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
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -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) */
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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:
|
|
||||||
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"'
|
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,11 +121,6 @@ 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('udisksctl unmount -b %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 umount %s' % loop_dev, shell=True)
|
||||||
check_call('sudo losetup -d %s' % loop_dev, shell=True)
|
check_call('sudo losetup -d %s' % loop_dev, shell=True)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user