diff options
| author | Eric Snowberg <eric.snowberg@oracle.com> | 2021-10-05 12:06:05 -0400 |
|---|---|---|
| committer | Peter Jones <pjones@redhat.com> | 2021-11-03 11:30:28 -0400 |
| commit | 4e513405b4f1641710115780d19dcec130c5208f (patch) | |
| tree | 57d9202d6155a4e6601acb9fdab1f0fa57e996a6 | |
| parent | 899314b90113abaaa4b22cd1d82a0fcb2a971850 (diff) | |
| download | efi-boot-shim-4e513405b4f1641710115780d19dcec130c5208f.tar.gz efi-boot-shim-4e513405b4f1641710115780d19dcec130c5208f.zip | |
Introduce a new MOK variable called MokListTrustedRT
Introduce a new MOK variable called MokListTrustedRT. It allows an end-user
to decide if they want to trust MOKList keys within the soon to be booted
Linux kernel. This variable does not change any functionality within shim
itself. When Linux boots, if MokListTrustedRT is set and
EFI_VARIABLE_NON_VOLATILE is not set, keys in MokListRT are loaded into the
.machine keyring instead of the .platform keyring.
Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
| -rw-r--r-- | MokManager.c | 167 | ||||
| -rw-r--r-- | MokVars.txt | 6 | ||||
| -rw-r--r-- | globals.c | 1 | ||||
| -rw-r--r-- | mok.c | 17 | ||||
| -rw-r--r-- | shim.h | 1 |
5 files changed, 187 insertions, 5 deletions
diff --git a/MokManager.c b/MokManager.c index 08b15d6d..c195cadc 100644 --- a/MokManager.c +++ b/MokManager.c @@ -41,6 +41,12 @@ typedef struct { } __attribute__ ((packed)) MokDBvar; typedef struct { + UINT32 MokTMLState; + UINT32 PWLen; + CHAR16 Password[SB_PASSWORD_LEN]; +} __attribute__ ((packed)) MokTMLvar; + +typedef struct { INT32 Timeout; } __attribute__ ((packed)) MokTimeoutvar; @@ -1678,6 +1684,121 @@ static EFI_STATUS mok_db_prompt(void *MokDB, UINTN MokDBSize) return EFI_SUCCESS; } +static EFI_STATUS mok_tml_prompt(void *MokTML, UINTN MokTMLSize) +{ + EFI_STATUS efi_status; + SIMPLE_TEXT_OUTPUT_MODE SavedMode; + MokTMLvar *var = MokTML; + CHAR16 *message[4]; + CHAR16 pass1, pass2, pass3; + CHAR16 *str; + UINT8 fail_count = 0; + UINT8 dbval = 1; + UINT8 pos1, pos2, pos3; + int ret; + CHAR16 *untrust_tml[] = { L"Do not trust the MOK list", NULL }; + CHAR16 *trust_tml[] = { L"Trust the MOK list", NULL }; + + if (MokTMLSize != sizeof(MokTMLvar)) { + console_notify(L"Invalid MokTML variable contents"); + return EFI_INVALID_PARAMETER; + } + + clear_screen(); + + message[0] = L"Change Trusted MOK List Keyring state"; + message[1] = NULL; + + console_save_and_set_mode(&SavedMode); + console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1); + console_restore_mode(&SavedMode); + + while (fail_count < 3) { + RandomBytes(&pos1, sizeof(pos1)); + pos1 = (pos1 % var->PWLen); + + do { + RandomBytes(&pos2, sizeof(pos2)); + pos2 = (pos2 % var->PWLen); + } while (pos2 == pos1); + + do { + RandomBytes(&pos3, sizeof(pos3)); + pos3 = (pos3 % var->PWLen); + } while (pos3 == pos2 || pos3 == pos1); + + str = PoolPrint(L"Enter password character %d: ", pos1 + 1); + if (!str) { + console_errorbox(L"Failed to allocate buffer"); + return EFI_OUT_OF_RESOURCES; + } + pass1 = get_password_charater(str); + FreePool(str); + + str = PoolPrint(L"Enter password character %d: ", pos2 + 1); + if (!str) { + console_errorbox(L"Failed to allocate buffer"); + return EFI_OUT_OF_RESOURCES; + } + pass2 = get_password_charater(str); + FreePool(str); + + str = PoolPrint(L"Enter password character %d: ", pos3 + 1); + if (!str) { + console_errorbox(L"Failed to allocate buffer"); + return EFI_OUT_OF_RESOURCES; + } + pass3 = get_password_charater(str); + FreePool(str); + + if (pass1 != var->Password[pos1] || + pass2 != var->Password[pos2] || + pass3 != var->Password[pos3]) { + console_print(L"Invalid character\n"); + fail_count++; + } else { + break; + } + } + + if (fail_count >= 3) { + console_notify(L"Password limit reached"); + return EFI_ACCESS_DENIED; + } + + if (var->MokTMLState == 0) + ret = console_yes_no(trust_tml); + else + ret = console_yes_no(untrust_tml); + + if (ret == 0) { + LibDeleteVariable(L"MokListTrustedNew", &SHIM_LOCK_GUID); + return EFI_ABORTED; + } + + if (var->MokTMLState == 0) { + efi_status = RT->SetVariable(L"MokListTrusted", &SHIM_LOCK_GUID, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS, + 1, &dbval); + if (EFI_ERROR(efi_status)) { + console_notify(L"Failed to set MokListTrusted state"); + return efi_status; + } + } else { + efi_status = RT->SetVariable(L"MokListTrusted", &SHIM_LOCK_GUID, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS, + 0, NULL); + if (EFI_ERROR(efi_status)) { + console_notify(L"Failed to delete MokListTrusted state"); + return efi_status; + } + } + + return EFI_SUCCESS; +} + static EFI_STATUS mok_pw_prompt(void *MokPW, UINTN MokPWSize) { EFI_STATUS efi_status; @@ -2076,7 +2197,8 @@ typedef enum { MOK_SET_PW, MOK_CHANGE_DB, MOK_KEY_ENROLL, - MOK_HASH_ENROLL + MOK_HASH_ENROLL, + MOK_CHANGE_TML } mok_menu_item; static void free_menu(mok_menu_item * menu_item, CHAR16 ** menu_strings) @@ -2095,7 +2217,8 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle UNUSED, void *MokPW, UINTN MokPWSize, void *MokDB, UINTN MokDBSize, void *MokXNew, UINTN MokXNewSize, - void *MokXDel, UINTN MokXDelSize) + void *MokXDel, UINTN MokXDelSize, + void *MokTML, UINTN MokTMLSize) { CHAR16 **menu_strings = NULL; mok_menu_item *menu_item = NULL; @@ -2171,6 +2294,9 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle UNUSED, if (MokDB) menucount++; + if (MokTML) + menucount++; + menu_strings = AllocateZeroPool(sizeof(CHAR16 *) * (menucount + 1)); if (!menu_strings) @@ -2242,6 +2368,12 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle UNUSED, i++; } + if (MokTML) { + menu_strings[i] = L"Change MOK List Trusted State"; + menu_item[i] = MOK_CHANGE_TML; + i++; + } + menu_strings[i] = L"Enroll key from disk"; menu_item[i] = MOK_KEY_ENROLL; i++; @@ -2352,6 +2484,17 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle UNUSED, case MOK_HASH_ENROLL: efi_status = mok_hash_enroll(); break; + case MOK_CHANGE_TML: + if (!MokTML) { + console_print(L"MokManager: internal error: %s", + L"MokListTrusted was ! NULL bs is now NULL\n"); + ret = EFI_ABORTED; + goto out; + } + efi_status = mok_tml_prompt(MokTML, MokTMLSize); + if (!EFI_ERROR(efi_status)) + MokTML = NULL; + break; } if (!EFI_ERROR(efi_status)) @@ -2376,7 +2519,7 @@ out: static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) { UINTN MokNewSize = 0, MokDelSize = 0, MokSBSize = 0, MokPWSize = 0; - UINTN MokDBSize = 0, MokXNewSize = 0, MokXDelSize = 0; + UINTN MokDBSize = 0, MokXNewSize = 0, MokXDelSize = 0, MokTMLSize = 0; void *MokNew = NULL; void *MokDel = NULL; void *MokSB = NULL; @@ -2384,6 +2527,7 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) void *MokDB = NULL; void *MokXNew = NULL; void *MokXDel = NULL; + void *MokTML = NULL; EFI_STATUS efi_status; efi_status = get_variable(L"MokNew", (UINT8 **) & MokNew, &MokNewSize, @@ -2436,6 +2580,18 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) console_error(L"Could not retrieve MokDB", efi_status); } + efi_status = get_variable(L"MokListTrustedNew", (UINT8 **) & MokTML, + &MokTMLSize, SHIM_LOCK_GUID); + if (!EFI_ERROR(efi_status)) { + efi_status = LibDeleteVariable(L"MokListTrustedNew", + &SHIM_LOCK_GUID); + if (EFI_ERROR(efi_status)) + console_notify(L"Failed to delete MokListTrustedNew"); + } else if (EFI_ERROR(efi_status) && efi_status != EFI_NOT_FOUND) { + console_error(L"Could not retrieve MokListTrustedNew", + efi_status); + } + efi_status = get_variable(L"MokXNew", (UINT8 **) & MokXNew, &MokXNewSize, SHIM_LOCK_GUID); if (!EFI_ERROR(efi_status)) { @@ -2458,7 +2614,7 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) enter_mok_menu(image_handle, MokNew, MokNewSize, MokDel, MokDelSize, MokSB, MokSBSize, MokPW, MokPWSize, MokDB, MokDBSize, - MokXNew, MokXNewSize, MokXDel, MokXDelSize); + MokXNew, MokXNewSize, MokXDel, MokXDelSize, MokTML, MokTMLSize); if (MokNew) FreePool(MokNew); @@ -2481,6 +2637,9 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) if (MokXDel) FreePool(MokXDel); + if (MokTML) + FreePool(MokTML); + LibDeleteVariable(L"MokAuth", &SHIM_LOCK_GUID); LibDeleteVariable(L"MokDelAuth", &SHIM_LOCK_GUID); LibDeleteVariable(L"MokXAuth", &SHIM_LOCK_GUID); diff --git a/MokVars.txt b/MokVars.txt index 4b80a413..cdfec2c8 100644 --- a/MokVars.txt +++ b/MokVars.txt @@ -77,3 +77,9 @@ or not to import DB certs for its own verification purposes. MokPWStore: A SHA-256 representation of the password set by the user via MokPW. The user will be prompted to enter this password in order to interact with MokManager. + +MokListTrusted: An 8-bit unsigned integer. If 1, it signifies to Linux +to trust CA keys in the MokList. BS,NV + +MokListTrustedRT: A copy of MokListTrusted made available to the kernel +at runtime. RT @@ -25,6 +25,7 @@ int loader_is_participating; UINT8 user_insecure_mode; UINT8 ignore_db; +UINT8 trust_mok_list; UINT32 verbose = 0; @@ -46,7 +46,7 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) check_var(L"MokPW") || check_var(L"MokAuth") || check_var(L"MokDel") || check_var(L"MokDB") || check_var(L"MokXNew") || check_var(L"MokXDel") || - check_var(L"MokXAuth")) { + check_var(L"MokXAuth") || check_var(L"MokListTrustedNew")) { efi_status = start_image(image_handle, MOK_MANAGER); if (EFI_ERROR(efi_status)) { @@ -166,6 +166,20 @@ struct mok_state_variable mok_state_variable_data[] = { MOK_VARIABLE_MEASURE, .pcr = 7, }, + {.name = L"MokListTrusted", + .name8 = "MokListTrusted", + .rtname = L"MokListTrustedRT", + .rtname8 = "MokListTrustedRT", + .guid = &SHIM_LOCK_GUID, + .yes_attr = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_NON_VOLATILE, + .no_attr = EFI_VARIABLE_RUNTIME_ACCESS, + .flags = MOK_MIRROR_DELETE_FIRST | + MOK_VARIABLE_MEASURE | + MOK_VARIABLE_LOG, + .pcr = 14, + .state = &trust_mok_list, + }, { NULL, } }; size_t n_mok_state_variables = sizeof(mok_state_variable_data) / sizeof(mok_state_variable_data[0]); @@ -897,6 +911,7 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle) user_insecure_mode = 0; ignore_db = 0; + trust_mok_list = 0; UINT64 config_sz = 0; UINT8 *config_table = NULL; @@ -255,6 +255,7 @@ extern UINT8 *build_cert; extern UINT8 user_insecure_mode; extern UINT8 ignore_db; +extern UINT8 trust_mok_list; extern UINT8 in_protocol; extern void *load_options; extern UINT32 load_options_size; |
