mirror of
https://github.com/u-boot/u-boot.git
synced 2024-12-04 01:53:27 +08:00
Pull request for efi-2023-01-rc2-2
UEFI: * add UEFI Secure Boot Key enrollment interface to eficonfig command * fix buffer underflow in FatToStr() implementation -----BEGIN PGP SIGNATURE----- iQJWBAABCABAFiEEK7wKXt3/btL6/yA+hO4vgnE3U0sFAmN8zgoiHGhlaW5yaWNo LnNjaHVjaGFyZHRAY2Fub25pY2FsLmNvbQAKCRCE7i+CcTdTS8UwD/93S4Kgy6mE /Jlkp3YKGheBDDGvRyr9bkcGm0h4qheBYyXG1vbNQU2hDCfVSik174CCng234Kyv ssiy52KpkScl9vOD55MTa5iBkxEmOw6/CwBla7tSWdoGvv5JwB9adjJXNqX4Gr/B 0vCagjk2qo3Jc52TvPXNBNrI5pegdzhx1ysSTp72sskdrqLe7NrH3/O1+g+Cl81Q kzXm0KCXZPelyXpT1mHOzyKTQtV+WRuxy27qxCtHQO4D/dijX5n/2tmLj77hEPKL 2A9B/fO+G+2/KTGY0qG7aq7PjJFKHeEo/EXfuiRofg0Ys0kL2uEzJr36s4eTjJfc nrD9V2O8d2FhhRrOXnTqQGHKHktLimkZzM3XkeHZBTQxGhxOl6pusEhI/fgq+jCN hJ4psa2F1ygr6jYFg+xGX04jWdbZ8HWna6kZwcD+nR1K1epSKMhMc9gRlHnWx7B3 FalH56KQR5AEz/Jb9wjG+4LoiVj0Yi8iyaiOBEQrkkooEsJk/IsdpGs/h2Li5bcQ nZ6+6fpprGqGxy8X0ynUOWvTjHmh89Agcw0uhjY1yR5LKZlWVz9KqWo4Mc0pzs/q cVcwfoN/eG26m3FShtQdTjg8Zpb/Tug0Hcsitgi6Dr83gLMv1t1X8GhdIR6M1n5z tQfciN7fRXGy1wgtQdF/+I6DATNr3apsdA== =AhXz -----END PGP SIGNATURE----- Merge tag 'efi-2023-01-rc2-2' of https://source.denx.de/u-boot/custodians/u-boot-efi Pull request for efi-2023-01-rc2-2 UEFI: * add UEFI Secure Boot Key enrollment interface to eficonfig command * fix buffer underflow in FatToStr() implementation
This commit is contained in:
commit
536c642ffe
@ -66,6 +66,11 @@ obj-$(CONFIG_CMD_EEPROM) += eeprom.o
|
||||
obj-$(CONFIG_EFI) += efi.o
|
||||
obj-$(CONFIG_CMD_EFIDEBUG) += efidebug.o
|
||||
obj-$(CONFIG_CMD_EFICONFIG) += eficonfig.o
|
||||
ifdef CONFIG_CMD_EFICONFIG
|
||||
ifdef CONFIG_EFI_MM_COMM_TEE
|
||||
obj-$(CONFIG_EFI_SECURE_BOOT) += eficonfig_sbkey.o
|
||||
endif
|
||||
endif
|
||||
obj-$(CONFIG_CMD_ELF) += elf.o
|
||||
obj-$(CONFIG_CMD_EROFS) += erofs.o
|
||||
obj-$(CONFIG_HUSH_PARSER) += exit.o
|
||||
|
244
cmd/eficonfig.c
244
cmd/eficonfig.c
@ -93,20 +93,14 @@ struct eficonfig_boot_selection_data {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct eficonfig_boot_order - structure to be used to update BootOrder variable
|
||||
* struct eficonfig_boot_order_data - structure to be used to update BootOrder variable
|
||||
*
|
||||
* @num: index in the menu entry
|
||||
* @description: pointer to the description string
|
||||
* @boot_index: boot option index
|
||||
* @active: flag to include the boot option into BootOrder variable
|
||||
* @list: list structure
|
||||
*/
|
||||
struct eficonfig_boot_order {
|
||||
u32 num;
|
||||
u16 *description;
|
||||
struct eficonfig_boot_order_data {
|
||||
u32 boot_index;
|
||||
bool active;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -263,7 +257,7 @@ efi_status_t eficonfig_process_quit(void *data)
|
||||
}
|
||||
|
||||
/**
|
||||
* append_entry() - append menu item
|
||||
* eficonfig_append_menu_entry() - append menu item
|
||||
*
|
||||
* @efi_menu: pointer to the efimenu structure
|
||||
* @title: pointer to the entry title
|
||||
@ -271,8 +265,9 @@ efi_status_t eficonfig_process_quit(void *data)
|
||||
* @data: pointer to the data to be passed to each entry callback
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t append_entry(struct efimenu *efi_menu,
|
||||
char *title, eficonfig_entry_func func, void *data)
|
||||
efi_status_t eficonfig_append_menu_entry(struct efimenu *efi_menu,
|
||||
char *title, eficonfig_entry_func func,
|
||||
void *data)
|
||||
{
|
||||
struct eficonfig_entry *entry;
|
||||
|
||||
@ -295,12 +290,12 @@ static efi_status_t append_entry(struct efimenu *efi_menu,
|
||||
}
|
||||
|
||||
/**
|
||||
* append_quit_entry() - append quit entry
|
||||
* eficonfig_append_quit_entry() - append quit entry
|
||||
*
|
||||
* @efi_menu: pointer to the efimenu structure
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t append_quit_entry(struct efimenu *efi_menu)
|
||||
efi_status_t eficonfig_append_quit_entry(struct efimenu *efi_menu)
|
||||
{
|
||||
char *title;
|
||||
efi_status_t ret;
|
||||
@ -309,7 +304,7 @@ static efi_status_t append_quit_entry(struct efimenu *efi_menu)
|
||||
if (!title)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
ret = append_entry(efi_menu, title, eficonfig_process_quit, NULL);
|
||||
ret = eficonfig_append_menu_entry(efi_menu, title, eficonfig_process_quit, NULL);
|
||||
if (ret != EFI_SUCCESS)
|
||||
free(title);
|
||||
|
||||
@ -341,7 +336,7 @@ void *eficonfig_create_fixed_menu(const struct eficonfig_item *items, int count)
|
||||
if (!title)
|
||||
goto out;
|
||||
|
||||
ret = append_entry(efi_menu, title, iter->func, iter->data);
|
||||
ret = eficonfig_append_menu_entry(efi_menu, title, iter->func, iter->data);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
free(title);
|
||||
goto out;
|
||||
@ -441,14 +436,15 @@ static efi_status_t eficonfig_volume_selected(void *data)
|
||||
}
|
||||
|
||||
/**
|
||||
* create_selected_device_path() - create device path
|
||||
* eficonfig_create_device_path() - create device path
|
||||
*
|
||||
* @file_info: pointer to the selected file information
|
||||
* @dp_volume: pointer to the volume
|
||||
* @current_path: pointer to the file path u16 string
|
||||
* Return:
|
||||
* device path or NULL. Caller must free the returned value
|
||||
*/
|
||||
static
|
||||
struct efi_device_path *create_selected_device_path(struct eficonfig_select_file_info *file_info)
|
||||
struct efi_device_path *eficonfig_create_device_path(struct efi_device_path *dp_volume,
|
||||
u16 *current_path)
|
||||
{
|
||||
char *p;
|
||||
void *buf;
|
||||
@ -457,7 +453,7 @@ struct efi_device_path *create_selected_device_path(struct eficonfig_select_file
|
||||
struct efi_device_path_file_path *fp;
|
||||
|
||||
fp_size = sizeof(struct efi_device_path) +
|
||||
((u16_strlen(file_info->current_path) + 1) * sizeof(u16));
|
||||
((u16_strlen(current_path) + 1) * sizeof(u16));
|
||||
buf = calloc(1, fp_size + sizeof(END));
|
||||
if (!buf)
|
||||
return NULL;
|
||||
@ -466,13 +462,13 @@ struct efi_device_path *create_selected_device_path(struct eficonfig_select_file
|
||||
fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE,
|
||||
fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH,
|
||||
fp->dp.length = (u16)fp_size;
|
||||
u16_strcpy(fp->str, file_info->current_path);
|
||||
u16_strcpy(fp->str, current_path);
|
||||
|
||||
p = buf;
|
||||
p += fp_size;
|
||||
*((struct efi_device_path *)p) = END;
|
||||
|
||||
dp = efi_dp_append(file_info->dp_volume, (struct efi_device_path *)buf);
|
||||
dp = efi_dp_append(dp_volume, (struct efi_device_path *)buf);
|
||||
free(buf);
|
||||
|
||||
return dp;
|
||||
@ -634,14 +630,15 @@ static efi_status_t eficonfig_select_volume(struct eficonfig_select_file_info *f
|
||||
info->v = v;
|
||||
info->dp = device_path;
|
||||
info->file_info = file_info;
|
||||
ret = append_entry(efi_menu, devname, eficonfig_volume_selected, info);
|
||||
ret = eficonfig_append_menu_entry(efi_menu, devname, eficonfig_volume_selected,
|
||||
info);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
free(info);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = append_quit_entry(efi_menu);
|
||||
ret = eficonfig_append_quit_entry(efi_menu);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
@ -699,14 +696,14 @@ eficonfig_create_file_entry(struct efimenu *efi_menu, u32 count,
|
||||
u32 i, entry_num = 0;
|
||||
struct eficonfig_file_entry_data *info;
|
||||
|
||||
efi_file_setpos_int(f, 0);
|
||||
EFI_CALL(f->setpos(f, 0));
|
||||
/* Read directory and construct menu structure */
|
||||
for (i = 0; i < count; i++) {
|
||||
if (entry_num >= EFICONFIG_ENTRY_NUM_MAX - 1)
|
||||
break;
|
||||
|
||||
len = sizeof(struct efi_file_info) + EFICONFIG_FILE_PATH_BUF_SIZE;
|
||||
ret = efi_file_read_int(f, &len, buf);
|
||||
ret = EFI_CALL(f->read(f, &len, buf));
|
||||
if (ret != EFI_SUCCESS || len == 0)
|
||||
break;
|
||||
|
||||
@ -745,8 +742,8 @@ eficonfig_create_file_entry(struct efimenu *efi_menu, u32 count,
|
||||
(int (*)(const void *, const void *))sort_file);
|
||||
|
||||
for (i = 0; i < entry_num; i++) {
|
||||
ret = append_entry(efi_menu, tmp_infos[i]->file_name,
|
||||
eficonfig_file_selected, tmp_infos[i]);
|
||||
ret = eficonfig_append_menu_entry(efi_menu, tmp_infos[i]->file_name,
|
||||
eficonfig_file_selected, tmp_infos[i]);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
}
|
||||
@ -756,14 +753,14 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* eficonfig_select_file() - construct the file selection menu
|
||||
* eficonfig_show_file_selection() - construct the file selection menu
|
||||
*
|
||||
* @file_info: pointer to the file selection structure
|
||||
* @root: pointer to the file handle
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t eficonfig_select_file(struct eficonfig_select_file_info *file_info,
|
||||
struct efi_file_handle *root)
|
||||
static efi_status_t eficonfig_show_file_selection(struct eficonfig_select_file_info *file_info,
|
||||
struct efi_file_handle *root)
|
||||
{
|
||||
u32 count = 0, i;
|
||||
efi_uintn_t len;
|
||||
@ -785,7 +782,8 @@ static efi_status_t eficonfig_select_file(struct eficonfig_select_file_info *fil
|
||||
}
|
||||
INIT_LIST_HEAD(&efi_menu->list);
|
||||
|
||||
ret = efi_file_open_int(root, &f, file_info->current_path, EFI_FILE_MODE_READ, 0);
|
||||
ret = EFI_CALL(root->open(root, &f, file_info->current_path,
|
||||
EFI_FILE_MODE_READ, 0));
|
||||
if (ret != EFI_SUCCESS) {
|
||||
eficonfig_print_msg("Reading volume failed!");
|
||||
free(efi_menu);
|
||||
@ -796,7 +794,7 @@ static efi_status_t eficonfig_select_file(struct eficonfig_select_file_info *fil
|
||||
/* Count the number of directory entries */
|
||||
for (;;) {
|
||||
len = sizeof(struct efi_file_info) + EFICONFIG_FILE_PATH_BUF_SIZE;
|
||||
ret = efi_file_read_int(f, &len, buf);
|
||||
ret = EFI_CALL(f->read(f, &len, buf));
|
||||
if (ret != EFI_SUCCESS || len == 0)
|
||||
break;
|
||||
|
||||
@ -815,13 +813,13 @@ static efi_status_t eficonfig_select_file(struct eficonfig_select_file_info *fil
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto err;
|
||||
|
||||
ret = append_quit_entry(efi_menu);
|
||||
ret = eficonfig_append_quit_entry(efi_menu);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto err;
|
||||
|
||||
ret = eficonfig_process_common(efi_menu, " ** Select File **");
|
||||
err:
|
||||
efi_file_close_int(f);
|
||||
EFI_CALL(f->close(f));
|
||||
eficonfig_destroy(efi_menu);
|
||||
|
||||
if (tmp_infos) {
|
||||
@ -938,17 +936,6 @@ static efi_status_t eficonfig_boot_edit_save(void *data)
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* eficonfig_process_select_file() - callback function for "Select File" entry
|
||||
*
|
||||
* @data: pointer to the data
|
||||
* Return: status code
|
||||
*/
|
||||
efi_status_t eficonfig_process_select_file(void *data)
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* eficonfig_process_clear_file_selection() - callback function for "Clear" entry
|
||||
*
|
||||
@ -973,19 +960,19 @@ static struct eficonfig_item select_file_menu_items[] = {
|
||||
{"Quit", eficonfig_process_quit},
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* eficonfig_display_select_file_option() - display select file option
|
||||
* eficonfig_process_show_file_option() - display select file option
|
||||
*
|
||||
* @file_info: pointer to the file information structure
|
||||
* Return: status code
|
||||
*/
|
||||
efi_status_t eficonfig_display_select_file_option(struct eficonfig_select_file_info *file_info)
|
||||
efi_status_t eficonfig_process_show_file_option(void *data)
|
||||
{
|
||||
efi_status_t ret;
|
||||
struct efimenu *efi_menu;
|
||||
|
||||
select_file_menu_items[1].data = file_info;
|
||||
select_file_menu_items[0].data = data;
|
||||
select_file_menu_items[1].data = data;
|
||||
efi_menu = eficonfig_create_fixed_menu(select_file_menu_items,
|
||||
ARRAY_SIZE(select_file_menu_items));
|
||||
if (!efi_menu)
|
||||
@ -1001,12 +988,12 @@ efi_status_t eficonfig_display_select_file_option(struct eficonfig_select_file_i
|
||||
}
|
||||
|
||||
/**
|
||||
* eficonfig_select_file_handler() - handle user file selection
|
||||
* eficonfig_process_select_file() - handle user file selection
|
||||
*
|
||||
* @data: pointer to the data
|
||||
* Return: status code
|
||||
*/
|
||||
efi_status_t eficonfig_select_file_handler(void *data)
|
||||
efi_status_t eficonfig_process_select_file(void *data)
|
||||
{
|
||||
size_t len;
|
||||
efi_status_t ret;
|
||||
@ -1016,10 +1003,6 @@ efi_status_t eficonfig_select_file_handler(void *data)
|
||||
struct eficonfig_select_file_info *tmp = NULL;
|
||||
struct eficonfig_select_file_info *file_info = data;
|
||||
|
||||
ret = eficonfig_display_select_file_option(file_info);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return ret;
|
||||
|
||||
tmp = calloc(1, sizeof(struct eficonfig_select_file_info));
|
||||
if (!tmp)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
@ -1042,11 +1025,11 @@ efi_status_t eficonfig_select_file_handler(void *data)
|
||||
if (!tmp->current_volume)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
ret = efi_open_volume_int(tmp->current_volume, &root);
|
||||
ret = EFI_CALL(tmp->current_volume->open_volume(tmp->current_volume, &root));
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
ret = eficonfig_select_file(tmp, root);
|
||||
ret = eficonfig_show_file_selection(tmp, root);
|
||||
if (ret == EFI_ABORTED)
|
||||
continue;
|
||||
if (ret != EFI_SUCCESS)
|
||||
@ -1221,7 +1204,7 @@ static efi_status_t create_boot_option_entry(struct efimenu *efi_menu, char *tit
|
||||
utf16_utf8_strcpy(&p, val);
|
||||
}
|
||||
|
||||
return append_entry(efi_menu, buf, func, data);
|
||||
return eficonfig_append_menu_entry(efi_menu, buf, func, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1284,7 +1267,7 @@ static efi_status_t prepare_file_selection_entry(struct efimenu *efi_menu, char
|
||||
utf8_utf16_strcpy(&p, devname);
|
||||
u16_strlcat(file_name, file_info->current_path, len);
|
||||
ret = create_boot_option_entry(efi_menu, title, file_name,
|
||||
eficonfig_select_file_handler, file_info);
|
||||
eficonfig_process_show_file_option, file_info);
|
||||
out:
|
||||
free(devname);
|
||||
free(file_name);
|
||||
@ -1491,7 +1474,8 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
|
||||
}
|
||||
|
||||
if (bo->initrd_info.dp_volume) {
|
||||
dp = create_selected_device_path(&bo->initrd_info);
|
||||
dp = eficonfig_create_device_path(bo->initrd_info.dp_volume,
|
||||
bo->initrd_info.current_path);
|
||||
if (!dp) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
@ -1500,7 +1484,7 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
|
||||
efi_free_pool(dp);
|
||||
}
|
||||
|
||||
dp = create_selected_device_path(&bo->file_info);
|
||||
dp = eficonfig_create_device_path(bo->file_info.dp_volume, bo->file_info.current_path);
|
||||
if (!dp) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
@ -1678,7 +1662,7 @@ static efi_status_t eficonfig_add_boot_selection_entry(struct efimenu *efi_menu,
|
||||
utf16_utf8_strcpy(&p, lo.label);
|
||||
info->boot_index = boot_index;
|
||||
info->selected = selected;
|
||||
ret = append_entry(efi_menu, buf, eficonfig_process_boot_selected, info);
|
||||
ret = eficonfig_append_menu_entry(efi_menu, buf, eficonfig_process_boot_selected, info);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
free(load_option);
|
||||
free(info);
|
||||
@ -1737,7 +1721,7 @@ static efi_status_t eficonfig_show_boot_selection(unsigned int *selected)
|
||||
break;
|
||||
}
|
||||
|
||||
ret = append_quit_entry(efi_menu);
|
||||
ret = eficonfig_append_quit_entry(efi_menu);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
@ -1813,7 +1797,7 @@ static void eficonfig_display_change_boot_order(struct efimenu *efi_menu)
|
||||
{
|
||||
bool reverse;
|
||||
struct list_head *pos, *n;
|
||||
struct eficonfig_boot_order *entry;
|
||||
struct eficonfig_entry *entry;
|
||||
|
||||
printf(ANSI_CLEAR_CONSOLE ANSI_CURSOR_POSITION
|
||||
"\n ** Change Boot Order **\n"
|
||||
@ -1829,7 +1813,7 @@ static void eficonfig_display_change_boot_order(struct efimenu *efi_menu)
|
||||
|
||||
/* draw boot option list */
|
||||
list_for_each_safe(pos, n, &efi_menu->list) {
|
||||
entry = list_entry(pos, struct eficonfig_boot_order, list);
|
||||
entry = list_entry(pos, struct eficonfig_entry, list);
|
||||
reverse = (entry->num == efi_menu->active);
|
||||
|
||||
printf(ANSI_CURSOR_POSITION, entry->num + 4, 7);
|
||||
@ -1838,13 +1822,13 @@ static void eficonfig_display_change_boot_order(struct efimenu *efi_menu)
|
||||
puts(ANSI_COLOR_REVERSE);
|
||||
|
||||
if (entry->num < efi_menu->count - 2) {
|
||||
if (entry->active)
|
||||
if (((struct eficonfig_boot_order_data *)entry->data)->active)
|
||||
printf("[*] ");
|
||||
else
|
||||
printf("[ ] ");
|
||||
}
|
||||
|
||||
printf("%ls", entry->description);
|
||||
printf("%s", entry->title);
|
||||
|
||||
if (reverse)
|
||||
puts(ANSI_COLOR_RESET);
|
||||
@ -1861,9 +1845,8 @@ static efi_status_t eficonfig_choice_change_boot_order(struct efimenu *efi_menu)
|
||||
{
|
||||
int esc = 0;
|
||||
struct list_head *pos, *n;
|
||||
struct eficonfig_boot_order *tmp;
|
||||
enum bootmenu_key key = KEY_NONE;
|
||||
struct eficonfig_boot_order *entry;
|
||||
struct eficonfig_entry *entry, *tmp;
|
||||
|
||||
while (1) {
|
||||
bootmenu_loop(NULL, &key, &esc);
|
||||
@ -1872,11 +1855,11 @@ static efi_status_t eficonfig_choice_change_boot_order(struct efimenu *efi_menu)
|
||||
case KEY_PLUS:
|
||||
if (efi_menu->active > 0) {
|
||||
list_for_each_safe(pos, n, &efi_menu->list) {
|
||||
entry = list_entry(pos, struct eficonfig_boot_order, list);
|
||||
entry = list_entry(pos, struct eficonfig_entry, list);
|
||||
if (entry->num == efi_menu->active)
|
||||
break;
|
||||
}
|
||||
tmp = list_entry(pos->prev, struct eficonfig_boot_order, list);
|
||||
tmp = list_entry(pos->prev, struct eficonfig_entry, list);
|
||||
entry->num--;
|
||||
tmp->num++;
|
||||
list_del(&tmp->list);
|
||||
@ -1890,11 +1873,11 @@ static efi_status_t eficonfig_choice_change_boot_order(struct efimenu *efi_menu)
|
||||
case KEY_MINUS:
|
||||
if (efi_menu->active < efi_menu->count - 3) {
|
||||
list_for_each_safe(pos, n, &efi_menu->list) {
|
||||
entry = list_entry(pos, struct eficonfig_boot_order, list);
|
||||
entry = list_entry(pos, struct eficonfig_entry, list);
|
||||
if (entry->num == efi_menu->active)
|
||||
break;
|
||||
}
|
||||
tmp = list_entry(pos->next, struct eficonfig_boot_order, list);
|
||||
tmp = list_entry(pos->next, struct eficonfig_entry, list);
|
||||
entry->num++;
|
||||
tmp->num--;
|
||||
list_del(&entry->list);
|
||||
@ -1920,9 +1903,11 @@ static efi_status_t eficonfig_choice_change_boot_order(struct efimenu *efi_menu)
|
||||
case KEY_SPACE:
|
||||
if (efi_menu->active < efi_menu->count - 2) {
|
||||
list_for_each_safe(pos, n, &efi_menu->list) {
|
||||
entry = list_entry(pos, struct eficonfig_boot_order, list);
|
||||
entry = list_entry(pos, struct eficonfig_entry, list);
|
||||
if (entry->num == efi_menu->active) {
|
||||
entry->active = entry->active ? false : true;
|
||||
struct eficonfig_boot_order_data *data = entry->data;
|
||||
|
||||
data->active = !data->active;
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
}
|
||||
@ -1948,12 +1933,13 @@ static efi_status_t eficonfig_choice_change_boot_order(struct efimenu *efi_menu)
|
||||
static efi_status_t eficonfig_add_change_boot_order_entry(struct efimenu *efi_menu,
|
||||
u32 boot_index, bool active)
|
||||
{
|
||||
char *title, *p;
|
||||
efi_status_t ret;
|
||||
efi_uintn_t size;
|
||||
void *load_option;
|
||||
struct efi_load_option lo;
|
||||
u16 varname[] = u"Boot####";
|
||||
struct eficonfig_boot_order *entry;
|
||||
struct eficonfig_boot_order_data *data;
|
||||
|
||||
efi_create_indexed_name(varname, sizeof(varname), "Boot", boot_index);
|
||||
load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
|
||||
@ -1961,31 +1947,38 @@ static efi_status_t eficonfig_add_change_boot_order_entry(struct efimenu *efi_me
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ret = efi_deserialize_load_option(&lo, load_option, &size);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
data = calloc(1, sizeof(*data));
|
||||
if (!data) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
|
||||
title = calloc(1, utf16_utf8_strlen(lo.label) + 1);
|
||||
if (!title) {
|
||||
free(data);
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
p = title;
|
||||
utf16_utf8_strcpy(&p, lo.label);
|
||||
|
||||
data->boot_index = boot_index;
|
||||
data->active = active;
|
||||
|
||||
ret = eficonfig_append_menu_entry(efi_menu, title, NULL, data);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
free(load_option);
|
||||
return ret;
|
||||
free(data);
|
||||
free(title);
|
||||
goto out;
|
||||
}
|
||||
|
||||
entry = calloc(1, sizeof(struct eficonfig_boot_order));
|
||||
if (!entry) {
|
||||
free(load_option);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
entry->description = u16_strdup(lo.label);
|
||||
if (!entry->description) {
|
||||
free(load_option);
|
||||
free(entry);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
entry->num = efi_menu->count++;
|
||||
entry->boot_index = boot_index;
|
||||
entry->active = active;
|
||||
list_add_tail(&entry->list, &efi_menu->list);
|
||||
|
||||
out:
|
||||
free(load_option);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2000,8 +1993,8 @@ static efi_status_t eficonfig_create_change_boot_order_entry(struct efimenu *efi
|
||||
u16 *bootorder, efi_uintn_t num)
|
||||
{
|
||||
u32 i;
|
||||
char *title;
|
||||
efi_status_t ret;
|
||||
struct eficonfig_boot_order *entry;
|
||||
|
||||
/* list the load option in the order of BootOrder variable */
|
||||
for (i = 0; i < num; i++) {
|
||||
@ -2028,27 +2021,25 @@ static efi_status_t eficonfig_create_change_boot_order_entry(struct efimenu *efi
|
||||
}
|
||||
|
||||
/* add "Save" and "Quit" entries */
|
||||
entry = calloc(1, sizeof(struct eficonfig_boot_order));
|
||||
if (!entry)
|
||||
title = strdup("Save");
|
||||
if (!title) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = eficonfig_append_menu_entry(efi_menu, title, NULL, NULL);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
entry->num = efi_menu->count++;
|
||||
entry->description = u16_strdup(u"Save");
|
||||
list_add_tail(&entry->list, &efi_menu->list);
|
||||
|
||||
entry = calloc(1, sizeof(struct eficonfig_boot_order));
|
||||
if (!entry)
|
||||
ret = eficonfig_append_quit_entry(efi_menu);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
entry->num = efi_menu->count++;
|
||||
entry->description = u16_strdup(u"Quit");
|
||||
list_add_tail(&entry->list, &efi_menu->list);
|
||||
|
||||
efi_menu->active = 0;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
out:
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2064,7 +2055,7 @@ static efi_status_t eficonfig_process_change_boot_order(void *data)
|
||||
efi_status_t ret;
|
||||
efi_uintn_t num, size;
|
||||
struct list_head *pos, *n;
|
||||
struct eficonfig_boot_order *entry;
|
||||
struct eficonfig_entry *entry;
|
||||
struct efimenu *efi_menu;
|
||||
|
||||
efi_menu = calloc(1, sizeof(struct efimenu));
|
||||
@ -2095,9 +2086,16 @@ static efi_status_t eficonfig_process_change_boot_order(void *data)
|
||||
/* create new BootOrder */
|
||||
count = 0;
|
||||
list_for_each_safe(pos, n, &efi_menu->list) {
|
||||
entry = list_entry(pos, struct eficonfig_boot_order, list);
|
||||
if (entry->active)
|
||||
new_bootorder[count++] = entry->boot_index;
|
||||
struct eficonfig_boot_order_data *data;
|
||||
|
||||
entry = list_entry(pos, struct eficonfig_entry, list);
|
||||
/* exit the loop when iteration reaches "Save" */
|
||||
if (!strncmp(entry->title, "Save", strlen("Save")))
|
||||
break;
|
||||
|
||||
data = entry->data;
|
||||
if (data->active)
|
||||
new_bootorder[count++] = data->boot_index;
|
||||
}
|
||||
|
||||
size = count * sizeof(u16);
|
||||
@ -2116,15 +2114,12 @@ static efi_status_t eficonfig_process_change_boot_order(void *data)
|
||||
}
|
||||
}
|
||||
out:
|
||||
list_for_each_safe(pos, n, &efi_menu->list) {
|
||||
entry = list_entry(pos, struct eficonfig_boot_order, list);
|
||||
list_del(&entry->list);
|
||||
free(entry->description);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
free(bootorder);
|
||||
free(efi_menu);
|
||||
list_for_each_safe(pos, n, &efi_menu->list) {
|
||||
entry = list_entry(pos, struct eficonfig_entry, list);
|
||||
free(entry->data);
|
||||
}
|
||||
eficonfig_destroy(efi_menu);
|
||||
|
||||
/* to stay the parent menu */
|
||||
ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret;
|
||||
@ -2441,6 +2436,9 @@ static const struct eficonfig_item maintenance_menu_items[] = {
|
||||
{"Edit Boot Option", eficonfig_process_edit_boot_option},
|
||||
{"Change Boot Order", eficonfig_process_change_boot_order},
|
||||
{"Delete Boot Option", eficonfig_process_delete_boot_option},
|
||||
#if (CONFIG_IS_ENABLED(EFI_SECURE_BOOT) && CONFIG_IS_ENABLED(EFI_MM_COMM_TEE))
|
||||
{"Secure Boot Configuration", eficonfig_process_secure_boot_config},
|
||||
#endif
|
||||
{"Quit", eficonfig_process_quit},
|
||||
};
|
||||
|
||||
|
498
cmd/eficonfig_sbkey.c
Normal file
498
cmd/eficonfig_sbkey.c
Normal file
@ -0,0 +1,498 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Menu-driven UEFI Secure Boot Key Maintenance
|
||||
*
|
||||
* Copyright (c) 2022 Masahisa Kojima, Linaro Limited
|
||||
*/
|
||||
|
||||
#include <ansi.h>
|
||||
#include <common.h>
|
||||
#include <charset.h>
|
||||
#include <hexdump.h>
|
||||
#include <log.h>
|
||||
#include <malloc.h>
|
||||
#include <menu.h>
|
||||
#include <efi_loader.h>
|
||||
#include <efi_config.h>
|
||||
#include <efi_variable.h>
|
||||
#include <crypto/pkcs7_parser.h>
|
||||
|
||||
struct eficonfig_sig_data {
|
||||
struct efi_signature_list *esl;
|
||||
struct efi_signature_data *esd;
|
||||
struct list_head list;
|
||||
u16 *varname;
|
||||
};
|
||||
|
||||
enum efi_sbkey_signature_type {
|
||||
SIG_TYPE_X509 = 0,
|
||||
SIG_TYPE_HASH,
|
||||
SIG_TYPE_CRL,
|
||||
SIG_TYPE_RSA2048,
|
||||
};
|
||||
|
||||
struct eficonfig_sigtype_to_str {
|
||||
efi_guid_t sig_type;
|
||||
char *str;
|
||||
enum efi_sbkey_signature_type type;
|
||||
};
|
||||
|
||||
static const struct eficonfig_sigtype_to_str sigtype_to_str[] = {
|
||||
{EFI_CERT_X509_GUID, "X509", SIG_TYPE_X509},
|
||||
{EFI_CERT_SHA256_GUID, "SHA256", SIG_TYPE_HASH},
|
||||
{EFI_CERT_X509_SHA256_GUID, "X509_SHA256 CRL", SIG_TYPE_CRL},
|
||||
{EFI_CERT_X509_SHA384_GUID, "X509_SHA384 CRL", SIG_TYPE_CRL},
|
||||
{EFI_CERT_X509_SHA512_GUID, "X509_SHA512 CRL", SIG_TYPE_CRL},
|
||||
/* U-Boot does not support the following signature types */
|
||||
/* {EFI_CERT_RSA2048_GUID, "RSA2048", SIG_TYPE_RSA2048}, */
|
||||
/* {EFI_CERT_RSA2048_SHA256_GUID, "RSA2048_SHA256", SIG_TYPE_RSA2048}, */
|
||||
/* {EFI_CERT_SHA1_GUID, "SHA1", SIG_TYPE_HASH}, */
|
||||
/* {EFI_CERT_RSA2048_SHA_GUID, "RSA2048_SHA", SIG_TYPE_RSA2048 }, */
|
||||
/* {EFI_CERT_SHA224_GUID, "SHA224", SIG_TYPE_HASH}, */
|
||||
/* {EFI_CERT_SHA384_GUID, "SHA384", SIG_TYPE_HASH}, */
|
||||
/* {EFI_CERT_SHA512_GUID, "SHA512", SIG_TYPE_HASH}, */
|
||||
};
|
||||
|
||||
/**
|
||||
* file_have_auth_header() - check file has EFI_VARIABLE_AUTHENTICATION_2 header
|
||||
* @buf: pointer to file
|
||||
* @size: file size
|
||||
* Return: true if file has auth header, false otherwise
|
||||
*/
|
||||
static bool file_have_auth_header(void *buf, efi_uintn_t size)
|
||||
{
|
||||
struct efi_variable_authentication_2 *auth = buf;
|
||||
|
||||
if (auth->auth_info.hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID)
|
||||
return false;
|
||||
|
||||
if (guidcmp(&auth->auth_info.cert_type, &efi_guid_cert_type_pkcs7))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* eficonfig_process_enroll_key() - enroll key into signature database
|
||||
*
|
||||
* @data: pointer to the data for each entry
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t eficonfig_process_enroll_key(void *data)
|
||||
{
|
||||
u32 attr;
|
||||
char *buf = NULL;
|
||||
efi_uintn_t size;
|
||||
efi_status_t ret;
|
||||
struct efi_file_handle *f = NULL;
|
||||
struct efi_device_path *full_dp = NULL;
|
||||
struct eficonfig_select_file_info file_info;
|
||||
|
||||
file_info.current_path = calloc(1, EFICONFIG_FILE_PATH_BUF_SIZE);
|
||||
if (!file_info.current_path) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = eficonfig_process_select_file(&file_info);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
full_dp = eficonfig_create_device_path(file_info.dp_volume, file_info.current_path);
|
||||
if (!full_dp) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
f = efi_file_from_path(full_dp);
|
||||
if (!f) {
|
||||
ret = EFI_NOT_FOUND;
|
||||
goto out;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
ret = EFI_CALL(f->getinfo(f, &efi_file_info_guid, &size, NULL));
|
||||
if (ret != EFI_BUFFER_TOO_SMALL)
|
||||
goto out;
|
||||
|
||||
buf = malloc(size);
|
||||
if (!buf) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
ret = EFI_CALL(f->getinfo(f, &efi_file_info_guid, &size, buf));
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
size = ((struct efi_file_info *)buf)->file_size;
|
||||
free(buf);
|
||||
|
||||
if (!size) {
|
||||
eficonfig_print_msg("ERROR! File is empty.");
|
||||
ret = EFI_INVALID_PARAMETER;
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf = malloc(size);
|
||||
if (!buf) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = EFI_CALL(f->read(f, &size, buf));
|
||||
if (ret != EFI_SUCCESS) {
|
||||
eficonfig_print_msg("ERROR! Failed to read file.");
|
||||
goto out;
|
||||
}
|
||||
if (!file_have_auth_header(buf, size)) {
|
||||
eficonfig_print_msg("ERROR! Invalid file format. Only .auth variables is allowed.");
|
||||
ret = EFI_INVALID_PARAMETER;
|
||||
goto out;
|
||||
}
|
||||
|
||||
attr = EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS |
|
||||
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
|
||||
|
||||
/* PK can enroll only one certificate */
|
||||
if (u16_strcmp(data, u"PK")) {
|
||||
efi_uintn_t db_size = 0;
|
||||
|
||||
/* check the variable exists. If exists, add APPEND_WRITE attribute */
|
||||
ret = efi_get_variable_int(data, efi_auth_var_get_guid(data), NULL,
|
||||
&db_size, NULL, NULL);
|
||||
if (ret == EFI_BUFFER_TOO_SMALL)
|
||||
attr |= EFI_VARIABLE_APPEND_WRITE;
|
||||
}
|
||||
|
||||
ret = efi_set_variable_int((u16 *)data, efi_auth_var_get_guid((u16 *)data),
|
||||
attr, size, buf, false);
|
||||
if (ret != EFI_SUCCESS)
|
||||
eficonfig_print_msg("ERROR! Failed to update signature database");
|
||||
|
||||
out:
|
||||
free(file_info.current_path);
|
||||
free(buf);
|
||||
efi_free_pool(full_dp);
|
||||
if (f)
|
||||
EFI_CALL(f->close(f));
|
||||
|
||||
/* return to the parent menu */
|
||||
ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* eficonfig_process_show_siglist() - show signature list content
|
||||
*
|
||||
* @data: pointer to the data for each entry
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t eficonfig_process_show_siglist(void *data)
|
||||
{
|
||||
u32 i;
|
||||
struct eficonfig_sig_data *sg = data;
|
||||
|
||||
puts(ANSI_CURSOR_HIDE);
|
||||
puts(ANSI_CLEAR_CONSOLE);
|
||||
printf(ANSI_CURSOR_POSITION, 1, 1);
|
||||
|
||||
printf("\n ** Show Signature Database (%ls) **\n\n"
|
||||
" Owner GUID:\n"
|
||||
" %pUL\n",
|
||||
sg->varname, sg->esd->signature_owner.b);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sigtype_to_str); i++) {
|
||||
if (!guidcmp(&sg->esl->signature_type, &sigtype_to_str[i].sig_type)) {
|
||||
printf(" Signature Type:\n"
|
||||
" %s\n", sigtype_to_str[i].str);
|
||||
|
||||
switch (sigtype_to_str[i].type) {
|
||||
case SIG_TYPE_X509:
|
||||
{
|
||||
struct x509_certificate *cert_tmp;
|
||||
|
||||
cert_tmp = x509_cert_parse(sg->esd->signature_data,
|
||||
sg->esl->signature_size);
|
||||
printf(" Subject:\n"
|
||||
" %s\n"
|
||||
" Issuer:\n"
|
||||
" %s\n",
|
||||
cert_tmp->subject, cert_tmp->issuer);
|
||||
break;
|
||||
}
|
||||
case SIG_TYPE_CRL:
|
||||
{
|
||||
u32 hash_size = sg->esl->signature_size - sizeof(efi_guid_t) -
|
||||
sizeof(struct efi_time);
|
||||
struct efi_time *time =
|
||||
(struct efi_time *)((u8 *)sg->esd->signature_data +
|
||||
hash_size);
|
||||
|
||||
printf(" ToBeSignedHash:\n");
|
||||
print_hex_dump(" ", DUMP_PREFIX_NONE, 16, 1,
|
||||
sg->esd->signature_data, hash_size, false);
|
||||
printf(" TimeOfRevocation:\n"
|
||||
" %d-%d-%d %02d:%02d:%02d\n",
|
||||
time->year, time->month, time->day,
|
||||
time->hour, time->minute, time->second);
|
||||
break;
|
||||
}
|
||||
case SIG_TYPE_HASH:
|
||||
{
|
||||
u32 hash_size = sg->esl->signature_size - sizeof(efi_guid_t);
|
||||
|
||||
printf(" Hash:\n");
|
||||
print_hex_dump(" ", DUMP_PREFIX_NONE, 16, 1,
|
||||
sg->esd->signature_data, hash_size, false);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
eficonfig_print_msg("ERROR! Unsupported format.");
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (tstc())
|
||||
getchar();
|
||||
|
||||
printf("\n\n Press any key to continue");
|
||||
getchar();
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* prepare_signature_list_menu() - create the signature list menu entry
|
||||
*
|
||||
* @efimenu: pointer to the efimenu structure
|
||||
* @varname: pointer to the variable name
|
||||
* @db: pointer to the variable raw data
|
||||
* @db_size: variable data size
|
||||
* @func: callback of each entry
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t prepare_signature_list_menu(struct efimenu *efi_menu, void *varname,
|
||||
void *db, efi_uintn_t db_size,
|
||||
eficonfig_entry_func func)
|
||||
{
|
||||
u32 num = 0;
|
||||
efi_uintn_t size;
|
||||
struct eficonfig_sig_data *sg;
|
||||
struct efi_signature_list *esl;
|
||||
struct efi_signature_data *esd;
|
||||
efi_status_t ret = EFI_SUCCESS;
|
||||
|
||||
INIT_LIST_HEAD(&efi_menu->list);
|
||||
|
||||
esl = db;
|
||||
size = db_size;
|
||||
while (size > 0) {
|
||||
u32 remain;
|
||||
|
||||
esd = (struct efi_signature_data *)((u8 *)esl +
|
||||
(sizeof(struct efi_signature_list) +
|
||||
esl->signature_header_size));
|
||||
remain = esl->signature_list_size - sizeof(struct efi_signature_list) -
|
||||
esl->signature_header_size;
|
||||
for (; remain > 0; remain -= esl->signature_size) {
|
||||
char buf[37];
|
||||
char *title;
|
||||
|
||||
if (num >= EFICONFIG_ENTRY_NUM_MAX - 1) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sg = calloc(1, sizeof(struct eficonfig_sig_data));
|
||||
if (!sg) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto err;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "%pUL", &esd->signature_owner);
|
||||
title = strdup(buf);
|
||||
if (!title) {
|
||||
free(sg);
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto err;
|
||||
}
|
||||
|
||||
sg->esl = esl;
|
||||
sg->esd = esd;
|
||||
sg->varname = varname;
|
||||
ret = eficonfig_append_menu_entry(efi_menu, title, func, sg);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
free(sg);
|
||||
free(title);
|
||||
goto err;
|
||||
}
|
||||
esd = (struct efi_signature_data *)((u8 *)esd + esl->signature_size);
|
||||
num++;
|
||||
}
|
||||
|
||||
size -= esl->signature_list_size;
|
||||
esl = (struct efi_signature_list *)((u8 *)esl + esl->signature_list_size);
|
||||
}
|
||||
out:
|
||||
ret = eficonfig_append_quit_entry(efi_menu);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* enumerate_and_show_signature_database() - enumerate and show the signature database
|
||||
*
|
||||
* @data: pointer to the data for each entry
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t enumerate_and_show_signature_database(void *varname)
|
||||
{
|
||||
void *db;
|
||||
char buf[50];
|
||||
efi_status_t ret;
|
||||
efi_uintn_t db_size;
|
||||
struct efimenu *efi_menu;
|
||||
struct list_head *pos, *n;
|
||||
struct eficonfig_entry *entry;
|
||||
|
||||
db = efi_get_var(varname, efi_auth_var_get_guid(varname), &db_size);
|
||||
if (!db) {
|
||||
eficonfig_print_msg("There is no entry in the signature database.");
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
efi_menu = calloc(1, sizeof(struct efimenu));
|
||||
if (!efi_menu) {
|
||||
free(db);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
ret = prepare_signature_list_menu(efi_menu, varname, db, db_size,
|
||||
eficonfig_process_show_siglist);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
snprintf(buf, sizeof(buf), " ** Show Signature Database (%ls) **", (u16 *)varname);
|
||||
ret = eficonfig_process_common(efi_menu, buf);
|
||||
out:
|
||||
list_for_each_safe(pos, n, &efi_menu->list) {
|
||||
entry = list_entry(pos, struct eficonfig_entry, list);
|
||||
free(entry->data);
|
||||
}
|
||||
eficonfig_destroy(efi_menu);
|
||||
free(db);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* eficonfig_process_show_signature_database() - process show signature database
|
||||
*
|
||||
* @data: pointer to the data for each entry
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t eficonfig_process_show_signature_database(void *data)
|
||||
{
|
||||
efi_status_t ret;
|
||||
|
||||
while (1) {
|
||||
ret = enumerate_and_show_signature_database(data);
|
||||
if (ret != EFI_SUCCESS && ret != EFI_NOT_READY)
|
||||
break;
|
||||
}
|
||||
|
||||
/* return to the parent menu */
|
||||
ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct eficonfig_item key_config_menu_items[] = {
|
||||
{"Enroll New Key", eficonfig_process_enroll_key},
|
||||
{"Show Signature Database", eficonfig_process_show_signature_database},
|
||||
{"Quit", eficonfig_process_quit},
|
||||
};
|
||||
|
||||
/**
|
||||
* eficonfig_process_set_secure_boot_key() - display the key configuration menu
|
||||
*
|
||||
* @data: pointer to the data for each entry
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t eficonfig_process_set_secure_boot_key(void *data)
|
||||
{
|
||||
u32 i;
|
||||
efi_status_t ret;
|
||||
char header_str[32];
|
||||
struct efimenu *efi_menu;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(key_config_menu_items); i++)
|
||||
key_config_menu_items[i].data = data;
|
||||
|
||||
snprintf(header_str, sizeof(header_str), " ** Configure %ls **", (u16 *)data);
|
||||
|
||||
while (1) {
|
||||
efi_menu = eficonfig_create_fixed_menu(key_config_menu_items,
|
||||
ARRAY_SIZE(key_config_menu_items));
|
||||
|
||||
ret = eficonfig_process_common(efi_menu, header_str);
|
||||
eficonfig_destroy(efi_menu);
|
||||
|
||||
if (ret == EFI_ABORTED)
|
||||
break;
|
||||
}
|
||||
|
||||
/* return to the parent menu */
|
||||
ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct eficonfig_item secure_boot_menu_items[] = {
|
||||
{"PK", eficonfig_process_set_secure_boot_key, u"PK"},
|
||||
{"KEK", eficonfig_process_set_secure_boot_key, u"KEK"},
|
||||
{"db", eficonfig_process_set_secure_boot_key, u"db"},
|
||||
{"dbx", eficonfig_process_set_secure_boot_key, u"dbx"},
|
||||
{"Quit", eficonfig_process_quit},
|
||||
};
|
||||
|
||||
/**
|
||||
* eficonfig_process_secure_boot_config() - display the key list menu
|
||||
*
|
||||
* @data: pointer to the data for each entry
|
||||
* Return: status code
|
||||
*/
|
||||
efi_status_t eficonfig_process_secure_boot_config(void *data)
|
||||
{
|
||||
efi_status_t ret;
|
||||
struct efimenu *efi_menu;
|
||||
|
||||
while (1) {
|
||||
char header_str[64];
|
||||
|
||||
snprintf(header_str, sizeof(header_str),
|
||||
" ** UEFI Secure Boot Key Configuration (SecureBoot : %s) **",
|
||||
(efi_secure_boot_enabled() ? "ON" : "OFF"));
|
||||
|
||||
efi_menu = eficonfig_create_fixed_menu(secure_boot_menu_items,
|
||||
ARRAY_SIZE(secure_boot_menu_items));
|
||||
if (!efi_menu) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = eficonfig_process_common(efi_menu, header_str);
|
||||
eficonfig_destroy(efi_menu);
|
||||
|
||||
if (ret == EFI_ABORTED)
|
||||
break;
|
||||
}
|
||||
|
||||
/* return to the parent menu */
|
||||
ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret;
|
||||
|
||||
return ret;
|
||||
}
|
@ -14,20 +14,20 @@ Description
|
||||
-----------
|
||||
|
||||
The cmp command is used to compare two memory areas. By default it works on
|
||||
four byte tuples. By appending .b, .w, .l, .q the size of the tuples is
|
||||
controlled:
|
||||
four byte (32-bit) values. By appending .b, .w, .l, .q the size of the
|
||||
values is controlled:
|
||||
|
||||
cmp.b
|
||||
compare 1 byte tuples
|
||||
compare 1 byte (8-bit) values
|
||||
|
||||
cmp.w
|
||||
compare 2 byte tuples
|
||||
compare 2 byte (16-bit) values
|
||||
|
||||
cmp.l
|
||||
compare 4 byte tuples
|
||||
compare 4 byte (32-bit) values
|
||||
|
||||
cmp.q
|
||||
compare 8 byte tuples
|
||||
compare 8 byte (64-bit) values
|
||||
|
||||
The parameters are used as follows:
|
||||
|
||||
|
@ -89,10 +89,21 @@ void eficonfig_print_msg(char *msg);
|
||||
void eficonfig_destroy(struct efimenu *efi_menu);
|
||||
efi_status_t eficonfig_process_quit(void *data);
|
||||
efi_status_t eficonfig_process_common(struct efimenu *efi_menu, char *menu_header);
|
||||
efi_status_t eficonfig_select_file_handler(void *data);
|
||||
efi_status_t eficonfig_process_select_file(void *data);
|
||||
efi_status_t eficonfig_get_unused_bootoption(u16 *buf,
|
||||
efi_uintn_t buf_size, u32 *index);
|
||||
efi_status_t eficonfig_append_bootorder(u16 index);
|
||||
efi_status_t eficonfig_generate_media_device_boot_option(void);
|
||||
|
||||
efi_status_t eficonfig_append_menu_entry(struct efimenu *efi_menu,
|
||||
char *title, eficonfig_entry_func func,
|
||||
void *data);
|
||||
efi_status_t eficonfig_append_quit_entry(struct efimenu *efi_menu);
|
||||
struct efi_device_path *eficonfig_create_device_path(struct efi_device_path *dp_volume,
|
||||
u16 *current_path);
|
||||
void *eficonfig_create_fixed_menu(const struct eficonfig_item *items, int count);
|
||||
#ifdef CONFIG_EFI_SECURE_BOOT
|
||||
efi_status_t eficonfig_process_secure_boot_config(void *data);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -131,7 +131,7 @@ u16 *efi_st_translate_code(u16 code);
|
||||
* @buf2: char string
|
||||
* Return: 0 if both buffers contain equivalent strings
|
||||
*/
|
||||
int efi_st_strcmp_16_8(const u16 *buf1, const char *buf2);
|
||||
int efi_st_strcmp_16_8(const u16 *buf1, const unsigned char *buf2);
|
||||
|
||||
/**
|
||||
* efi_st_get_config_table() - get configuration table
|
||||
|
@ -257,7 +257,7 @@ static void EFIAPI efi_fat_to_str(struct efi_unicode_collation_protocol *this,
|
||||
for (i = 0; i < fat_size; ++i) {
|
||||
c = (unsigned char)fat[i];
|
||||
if (c > 0x80)
|
||||
c = codepage[i - 0x80];
|
||||
c = codepage[c - 0x80];
|
||||
string[i] = c;
|
||||
if (!c)
|
||||
break;
|
||||
|
@ -184,6 +184,18 @@ static int test_fat_to_str(void)
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
|
||||
boottime->set_mem(str, sizeof(str), 0);
|
||||
unicode_collation_protocol->fat_to_str(unicode_collation_protocol, 13,
|
||||
"Kafb\240tur\000xyz", str);
|
||||
if (str[10]) {
|
||||
efi_st_error("fat_to_str returned to many characters\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
if (efi_st_strcmp_16_8(str, "Kafb\341tur")) {
|
||||
efi_st_error("fat_to_str returned \"%ps\"\n", str);
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
|
||||
return EFI_ST_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ u16 *efi_st_translate_code(u16 code)
|
||||
return efi_st_unknown;
|
||||
}
|
||||
|
||||
int efi_st_strcmp_16_8(const u16 *buf1, const char *buf2)
|
||||
int efi_st_strcmp_16_8(const u16 *buf1, const unsigned char *buf2)
|
||||
{
|
||||
for (; *buf1 || *buf2; ++buf1, ++buf2) {
|
||||
if (*buf1 != *buf2)
|
||||
|
@ -352,6 +352,7 @@ def test_efi_eficonfig(u_boot_console, efi_eficonfig_data):
|
||||
press_up_down_enter_and_wait(0, 1, True, 'Quit')
|
||||
press_up_down_enter_and_wait(0, 0, True, 'No block device found!')
|
||||
press_escape_key(False)
|
||||
press_escape_key(False)
|
||||
check_current_is_maintenance_menu()
|
||||
# Return to U-Boot console
|
||||
press_escape_key(True)
|
||||
|
Loading…
Reference in New Issue
Block a user