diff options
Diffstat (limited to 'MokManager.c')
| -rw-r--r-- | MokManager.c | 179 |
1 files changed, 149 insertions, 30 deletions
diff --git a/MokManager.c b/MokManager.c index f538a56c..fb203526 100644 --- a/MokManager.c +++ b/MokManager.c @@ -8,6 +8,7 @@ #define PASSWORD_MAX 16 #define PASSWORD_MIN 8 +#define SB_PASSWORD_LEN 8 #ifndef SHIM_VENDOR #define SHIM_VENDOR L"Shim" @@ -32,6 +33,11 @@ typedef struct { UINT8 *Mok; } __attribute__ ((packed)) MokListNode; +typedef struct { + UINT32 MokSBState; + UINT8 hash[SHA256_DIGEST_SIZE]; +} __attribute__ ((packed)) MokSBvar; + static EFI_INPUT_KEY get_keystroke (void) { EFI_INPUT_KEY key; @@ -681,6 +687,96 @@ static INTN mok_deletion_prompt (void *MokNew, void *data2, void *data3) { return 0; } +static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) { + EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; + EFI_STATUS efi_status; + UINTN MokSBSize = (UINTN)data2; + MokSBvar *var = MokSB; + CHAR16 password[SB_PASSWORD_LEN]; + UINT8 fail_count = 0; + UINT8 hash[SHA256_DIGEST_SIZE]; + UINT32 length; + CHAR16 line[1]; + UINT8 sbval = 1; + + LibDeleteVariable(L"MokSB", &shim_lock_guid); + + if (MokSBSize != sizeof(MokSBvar)) { + Print(L"Invalid MokSB variable contents\n"); + return -1; + } + + while (fail_count < 3) { + Print(L"Enter Secure Boot passphrase: "); + get_line(&length, password, SB_PASSWORD_LEN, 0); + + if (length != SB_PASSWORD_LEN) { + Print(L"Invalid password length\n"); + fail_count++; + continue; + } + + efi_status = compute_pw_hash(NULL, 0, password, + SB_PASSWORD_LEN, hash); + + if (efi_status != EFI_SUCCESS) { + Print(L"Unable to generate password hash\n"); + fail_count++; + continue; + } + + if (CompareMem(var->hash, hash, SHA256_DIGEST_SIZE) != 0) { + Print(L"Password doesn't match\n"); + fail_count++; + continue; + } + + break; + } + + if (fail_count >= 3) { + Print(L"Password limit reached\n"); + return -1; + } + + if (var->MokSBState == 0) { + Print(L"Disable Secure Boot? (y/n): "); + } else { + Print(L"Enable Secure Boot? (y/n): "); + } + + do { + get_line (&length, line, 1, 1); + + if (line[0] == 'Y' || line[0] == 'y') { + if (var->MokSBState == 0) { + efi_status = uefi_call_wrapper(RT->SetVariable, + 5, L"MokSBState", + &shim_lock_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS, + 1, &sbval); + if (efi_status != EFI_SUCCESS) { + Print(L"Failed to set Secure Boot state\n"); + return -1; + } + } else { + LibDeleteVariable(L"MokSBState", + &shim_lock_guid); + } + + Print(L"Press a key to reboot system\n"); + Pause(); + uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, + EFI_SUCCESS, 0, NULL); + Print(L"Failed to reboot\n"); + return -1; + } + } while (line[0] != 'N' && line[0] != 'n'); + + return -1; +} + static UINTN draw_menu (CHAR16 *header, UINTN lines, struct menu_item *items, UINTN count) { UINTN i; @@ -1234,11 +1330,12 @@ static INTN find_fs (void *data, void *data2, void *data3) { } static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, - UINTN MokNewSize) + UINTN MokNewSize, void *MokSB, + UINTN MokSBSize) { struct menu_item *menu_item; UINT32 MokAuth = 0; - UINTN menucount = 0; + UINTN menucount = 3, i = 0; EFI_STATUS efi_status; EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; UINT8 auth[SHA256_DIGEST_SIZE]; @@ -1253,47 +1350,59 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, MokAuth = 1; if (MokNew || MokAuth) - menu_item = AllocateZeroPool(sizeof(struct menu_item) * 4); - else - menu_item = AllocateZeroPool(sizeof(struct menu_item) * 3); + menucount++; + + if (MokSB) + menucount++; + + menu_item = AllocateZeroPool(sizeof(struct menu_item) * menucount); if (!menu_item) return EFI_OUT_OF_RESOURCES; - menu_item[0].text = StrDuplicate(L"Continue boot"); - menu_item[0].colour = EFI_WHITE; - menu_item[0].callback = NULL; + menu_item[i].text = StrDuplicate(L"Continue boot"); + menu_item[i].colour = EFI_WHITE; + menu_item[i].callback = NULL; - menucount++; + i++; if (MokNew || MokAuth) { if (!MokNew) { - menu_item[1].text = StrDuplicate(L"Delete MOK"); - menu_item[1].colour = EFI_WHITE; - menu_item[1].callback = mok_deletion_prompt; + menu_item[i].text = StrDuplicate(L"Delete MOK"); + menu_item[i].colour = EFI_WHITE; + menu_item[i].callback = mok_deletion_prompt; } else { - menu_item[1].text = StrDuplicate(L"Enroll MOK"); - menu_item[1].colour = EFI_WHITE; - menu_item[1].data = MokNew; - menu_item[1].data2 = (void *)MokNewSize; - menu_item[1].callback = mok_enrollment_prompt_callback; + menu_item[i].text = StrDuplicate(L"Enroll MOK"); + menu_item[i].colour = EFI_WHITE; + menu_item[i].data = MokNew; + menu_item[i].data2 = (void *)MokNewSize; + menu_item[i].callback = mok_enrollment_prompt_callback; } - menucount++; + i++; + } + + if (MokSB) { + menu_item[i].text = StrDuplicate(L"Change Secure Boot state"); + menu_item[i].colour = EFI_WHITE; + menu_item[i].callback = mok_sb_prompt; + menu_item[i].data = MokSB; + menu_item[i].data2 = (void *)MokSBSize; + i++; } - menu_item[menucount].text = StrDuplicate(L"Enroll key from disk"); - menu_item[menucount].colour = EFI_WHITE; - menu_item[menucount].callback = find_fs; - menu_item[menucount].data3 = (void *)FALSE; + menu_item[i].text = StrDuplicate(L"Enroll key from disk"); + menu_item[i].colour = EFI_WHITE; + menu_item[i].callback = find_fs; + menu_item[i].data3 = (void *)FALSE; - menucount++; + i++; - menu_item[menucount].text = StrDuplicate(L"Enroll hash from disk"); - menu_item[menucount].colour = EFI_WHITE; - menu_item[menucount].callback = find_fs; - menu_item[menucount].data3 = (void *)TRUE; + menu_item[i].text = StrDuplicate(L"Enroll hash from disk"); + menu_item[i].colour = EFI_WHITE; + menu_item[i].callback = find_fs; + menu_item[i].data3 = (void *)TRUE; - menucount++; + i++; run_menu(NULL, 0, menu_item, menucount, 10); @@ -1305,12 +1414,15 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) { EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; - UINTN MokNewSize = 0; + UINTN MokNewSize = 0, MokSBSize = 0; void *MokNew = NULL; + void *MokSB = NULL; MokNew = LibGetVariableAndSize(L"MokNew", &shim_lock_guid, &MokNewSize); - enter_mok_menu(image_handle, MokNew, MokNewSize); + MokSB = LibGetVariableAndSize(L"MokSB", &shim_lock_guid, &MokSBSize); + + enter_mok_menu(image_handle, MokNew, MokNewSize, MokSB, MokSBSize); if (MokNew) { if (LibDeleteVariable(L"MokNew", &shim_lock_guid) != EFI_SUCCESS) { @@ -1318,6 +1430,13 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) } FreePool (MokNew); } + + if (MokSB) { + if (LibDeleteVariable(L"MokSB", &shim_lock_guid) != EFI_SUCCESS) { + Print(L"Failed to delete MokSB\n"); + } + FreePool (MokNew); + } LibDeleteVariable(L"MokAuth", &shim_lock_guid); return EFI_SUCCESS; |
