From 1bc1cd96e43f73d75b4a0346532c86260cd33748 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Sat, 13 Oct 2012 01:07:43 -0400 Subject: Add section headers Provide a little more contextual information when people are in shim menus. --- MokManager.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index 1d84a2d9..f538a56c 100644 --- a/MokManager.c +++ b/MokManager.c @@ -15,6 +15,9 @@ #define EFI_VARIABLE_APPEND_WRITE 0x00000040 +#define CERT_STRING L"Select an X509 certificate to enroll:\n\n" +#define HASH_STRING L"Select a file to trust:\n\n" + struct menu_item { CHAR16 *text; INTN (* callback)(void *data, void *data2, void *data3); @@ -678,7 +681,8 @@ static INTN mok_deletion_prompt (void *MokNew, void *data2, void *data3) { return 0; } -static UINTN draw_menu (struct menu_item *items, UINTN count) { +static UINTN draw_menu (CHAR16 *header, UINTN lines, struct menu_item *items, + UINTN count) { UINTN i; uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); @@ -688,6 +692,9 @@ static UINTN draw_menu (struct menu_item *items, UINTN count) { Print(L"%s UEFI key management\n\n", SHIM_VENDOR); + if (header) + Print(L"%s", header); + for (i = 0; i < count; i++) { uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, items[i].colour | EFI_BACKGROUND_BLACK); @@ -697,7 +704,7 @@ static UINTN draw_menu (struct menu_item *items, UINTN count) { uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0, 0); uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, TRUE); - return 2; + return 2 + lines; } static void free_menu (struct menu_item *items, UINTN count) { @@ -711,7 +718,8 @@ static void free_menu (struct menu_item *items, UINTN count) { FreePool(items); } -static void run_menu (struct menu_item *items, UINTN count, UINTN timeout) { +static void run_menu (CHAR16 *header, UINTN lines, struct menu_item *items, + UINTN count, UINTN timeout) { UINTN index, pos = 0, wait = 0, offset; EFI_INPUT_KEY key; EFI_STATUS status; @@ -722,7 +730,7 @@ static void run_menu (struct menu_item *items, UINTN count, UINTN timeout) { while (1) { uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); - offset = draw_menu (items, count); + offset = draw_menu (header, lines, items, count); uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, @@ -783,7 +791,7 @@ static void run_menu (struct menu_item *items, UINTN count, UINTN timeout) { items[pos].callback(items[pos].data, items[pos].data2, items[pos].data3); - draw_menu (items, count); + draw_menu (header, lines, items, count); pos = 0; break; } @@ -937,6 +945,7 @@ static INTN directory_callback (void *data, void *data2, void *data3) { EFI_FILE *dir; CHAR16 *filename = data; EFI_FILE *root = data2; + BOOLEAN hash = !!data3; status = uefi_call_wrapper(root->Open, 5, root, &dir, filename, EFI_FILE_MODE_READ, 0); @@ -1023,7 +1032,10 @@ static INTN directory_callback (void *data, void *data2, void *data3) { buffer = NULL; } - run_menu(dircontent, dircount, 0); + if (hash) + run_menu(HASH_STRING, 2, dircontent, dircount, 0); + else + run_menu(CERT_STRING, 2, dircontent, dircount, 0); return 0; } @@ -1035,6 +1047,7 @@ static INTN filesystem_callback (void *data, void *data2, void *data3) { UINTN dircount = 0, i = 0; struct menu_item *dircontent; EFI_FILE *root = data; + BOOLEAN hash = !!data3; uefi_call_wrapper(root->SetPosition, 2, root, 0); @@ -1117,7 +1130,10 @@ static INTN filesystem_callback (void *data, void *data2, void *data3) { buffersize = 0; } - run_menu(dircontent, dircount, 0); + if (hash) + run_menu(HASH_STRING, 2, dircontent, dircount, 0); + else + run_menu(CERT_STRING, 2, dircontent, dircount, 0); return 0; } @@ -1128,6 +1144,7 @@ static INTN find_fs (void *data, void *data2, void *data3) { UINTN OldSize, NewSize; EFI_HANDLE **filesystem_handles; struct menu_item *filesystems; + BOOLEAN hash = !!data3; uefi_call_wrapper(BS->LocateHandleBuffer, 5, ByProtocol, &fs_guid, NULL, &count, &filesystem_handles); @@ -1208,7 +1225,10 @@ static INTN find_fs (void *data, void *data2, void *data3) { uefi_call_wrapper(BS->FreePool, 1, filesystem_handles); - run_menu(filesystems, count, 0); + if (hash) + run_menu(HASH_STRING, 2, filesystems, count, 0); + else + run_menu(CERT_STRING, 2, filesystems, count, 0); return 0; } @@ -1275,7 +1295,7 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, menucount++; - run_menu(menu_item, menucount, 10); + run_menu(NULL, 0, menu_item, menucount, 10); uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); -- cgit v1.2.3 From 9272bc5b847bf30f89d9bef49fcc5b04c780460e Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Thu, 18 Oct 2012 17:41:52 -0400 Subject: Add support for disabling signature verification Provide a mechanism for a physically present end user to disable signature verification. This is handled by the OS passing down a variable that contains a UINT32 and a SHA256 hash. If this variable is present, MokManager prompts the user to choose whether to enable or disable signature validation (depending on the value of the UINT32). They are then asked to type the passphrase that matches the hash. This then saves a boot services variable which is checked by shim, and if set will skip verification of signatures. --- MokManager.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++---------- shim.c | 29 ++++++---- 2 files changed, 166 insertions(+), 42 deletions(-) (limited to 'MokManager.c') 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; diff --git a/shim.c b/shim.c index 4eab87ac..bffad137 100644 --- a/shim.c +++ b/shim.c @@ -1033,7 +1033,7 @@ done: EFI_STATUS check_mok_request(EFI_HANDLE image_handle) { EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; - EFI_STATUS efi_status; + EFI_STATUS moknew_status, moksb_status, efi_status; UINTN size = sizeof(UINT32); UINT32 MokNew; UINT32 attributes; @@ -1041,22 +1041,27 @@ EFI_STATUS check_mok_request(EFI_HANDLE image_handle) if (!secure_mode()) return EFI_SUCCESS; - efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokNew", - &shim_lock_guid, &attributes, - &size, (void *)&MokNew); + moknew_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokNew", + &shim_lock_guid, &attributes, + &size, (void *)&MokNew); - if (efi_status != EFI_SUCCESS && efi_status != EFI_BUFFER_TOO_SMALL) - goto done; + moksb_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokSB", + &shim_lock_guid, &attributes, + &size, (void *)&MokNew); - efi_status = start_image(image_handle, MOK_MANAGER); + if (moknew_status == EFI_SUCCESS || + moknew_status == EFI_BUFFER_TOO_SMALL || + moksb_status == EFI_SUCCESS || + moksb_status == EFI_BUFFER_TOO_SMALL) { + efi_status = start_image(image_handle, MOK_MANAGER); - if (efi_status != EFI_SUCCESS) { - Print(L"Failed to start MokManager\n"); - goto done; + if (efi_status != EFI_SUCCESS) { + Print(L"Failed to start MokManager\n"); + return efi_status; + } } -done: - return efi_status; + return EFI_SUCCESS; } EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab) -- cgit v1.2.3 From d08ea5363cec6f0159112aec1658d57fbaf1e471 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Thu, 18 Oct 2012 17:43:53 -0400 Subject: Pause on callback failures If a callback returns any kind of failure, wait for a keypress in order to give the user an opportunity to read any failure messages. --- MokManager.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index fb203526..88a08f72 100644 --- a/MokManager.c +++ b/MokManager.c @@ -819,6 +819,7 @@ static void run_menu (CHAR16 *header, UINTN lines, struct menu_item *items, UINTN index, pos = 0, wait = 0, offset; EFI_INPUT_KEY key; EFI_STATUS status; + INTN ret; if (timeout) wait = 10000000; @@ -885,8 +886,13 @@ static void run_menu (CHAR16 *header, UINTN lines, struct menu_item *items, return; } - items[pos].callback(items[pos].data, items[pos].data2, - items[pos].data3); + ret = items[pos].callback(items[pos].data, + items[pos].data2, + items[pos].data3); + if (ret < 0) { + Print(L"Press a key to continue\n"); + Pause(); + } draw_menu (header, lines, items, count); pos = 0; break; -- cgit v1.2.3 From 801d1b936be96f0d22fd5b91af973cafc1fcb68c Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Thu, 18 Oct 2012 17:43:53 -0400 Subject: Add MOK password auth Add support for setting an MOK password. The OS passes down a password hash. MokManager then presents an option for setting a password. Selecting it prompts the user for the same password again. If they match, the hash is enrolled into a boot services variable and MokManager will prompt for the password whenever it's started. --- MokManager.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- shim.c | 16 ++++-- 2 files changed, 180 insertions(+), 9 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index 88a08f72..18992f27 100644 --- a/MokManager.c +++ b/MokManager.c @@ -777,6 +777,86 @@ static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) { return -1; } + +static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) { + EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; + EFI_STATUS efi_status; + UINTN MokPWSize = (UINTN)data2; + UINT8 fail_count = 0; + UINT8 hash[SHA256_DIGEST_SIZE]; + CHAR16 password[PASSWORD_MAX]; + UINT32 length; + CHAR16 line[1]; + + if (MokPWSize != SHA256_DIGEST_SIZE) { + Print(L"Invalid MokPW variable contents\n"); + return -1; + } + + LibDeleteVariable(L"MokPW", &shim_lock_guid); + + while (fail_count < 3) { + Print(L"Confirm MOK passphrase: "); + get_line(&length, password, PASSWORD_MAX, 0); + + if ((length < PASSWORD_MIN) || (length > PASSWORD_MAX)) { + 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(MokPW, 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; + } + + Print(L"Set MOK password? (y/n): "); + + do { + get_line (&length, line, 1, 1); + + if (line[0] == 'Y' || line[0] == 'y') { + efi_status = uefi_call_wrapper(RT->SetVariable, 5, + L"MokPWStore", + &shim_lock_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS, + MokPWSize, MokPW); + if (efi_status != EFI_SUCCESS) { + Print(L"Failed to set MOK password\n"); + return -1; + } + + 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 0; +} + static UINTN draw_menu (CHAR16 *header, UINTN lines, struct menu_item *items, UINTN count) { UINTN i; @@ -1335,9 +1415,67 @@ static INTN find_fs (void *data, void *data2, void *data3) { return 0; } +static BOOLEAN verify_pw(void) +{ + EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; + EFI_STATUS efi_status; + CHAR16 password[PASSWORD_MAX]; + UINT8 fail_count = 0; + UINT8 hash[SHA256_DIGEST_SIZE]; + UINT8 pwhash[SHA256_DIGEST_SIZE]; + UINTN size = SHA256_DIGEST_SIZE; + UINT32 length; + UINT32 attributes; + + efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPWStore", + &shim_lock_guid, &attributes, &size, + pwhash); + + /* + * If anything can attack the password it could just set it to a + * known value, so there's no safety advantage in failing to validate + * purely because of a failure to read the variable + */ + if (efi_status != EFI_SUCCESS) + return TRUE; + + if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) + return TRUE; + + while (fail_count < 3) { + Print(L"Enter MOK password: "); + get_line(&length, password, PASSWORD_MAX, 0); + + if (length < PASSWORD_MIN || length > PASSWORD_MAX) { + Print(L"Invalid password length\n"); + fail_count++; + continue; + } + + efi_status = compute_pw_hash(NULL, 0, password, length, hash); + + if (efi_status != EFI_SUCCESS) { + Print(L"Unable to generate password hash\n"); + fail_count++; + continue; + } + + if (CompareMem(pwhash, hash, SHA256_DIGEST_SIZE) != 0) { + Print(L"Password doesn't match\n"); + fail_count++; + continue; + } + + return TRUE; + } + + Print(L"Password limit reached\n"); + return FALSE; +} + static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, UINTN MokNewSize, void *MokSB, - UINTN MokSBSize) + UINTN MokSBSize, void *MokPW, UINTN MokPWSize) { struct menu_item *menu_item; UINT32 MokAuth = 0; @@ -1348,6 +1486,9 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, UINTN auth_size = SHA256_DIGEST_SIZE; UINT32 attributes; + if (verify_pw() == FALSE) + return EFI_ACCESS_DENIED; + efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth", &shim_lock_guid, &attributes, &auth_size, auth); @@ -1361,6 +1502,9 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, if (MokSB) menucount++; + if (MokPW) + menucount++; + menu_item = AllocateZeroPool(sizeof(struct menu_item) * menucount); if (!menu_item) @@ -1396,6 +1540,15 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, i++; } + if (MokPW) { + menu_item[i].text = StrDuplicate(L"Set MOK password"); + menu_item[i].colour = EFI_WHITE; + menu_item[i].callback = mok_pw_prompt; + menu_item[i].data = MokPW; + menu_item[i].data2 = (void *)MokPWSize; + i++; + } + menu_item[i].text = StrDuplicate(L"Enroll key from disk"); menu_item[i].colour = EFI_WHITE; menu_item[i].callback = find_fs; @@ -1420,15 +1573,19 @@ 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, MokSBSize = 0; + UINTN MokNewSize = 0, MokSBSize = 0, MokPWSize = 0; void *MokNew = NULL; void *MokSB = NULL; + void *MokPW = NULL; MokNew = LibGetVariableAndSize(L"MokNew", &shim_lock_guid, &MokNewSize); - MokSB = LibGetVariableAndSize(L"MokSB", &shim_lock_guid, &MokSBSize); + MokSB = LibGetVariableAndSize(L"MokSB", &shim_lock_guid, &MokSBSize); + + MokPW = LibGetVariableAndSize(L"MokPW", &shim_lock_guid, &MokPWSize); - enter_mok_menu(image_handle, MokNew, MokNewSize, MokSB, MokSBSize); + enter_mok_menu(image_handle, MokNew, MokNewSize, MokSB, MokSBSize, + MokPW, MokPWSize); if (MokNew) { if (LibDeleteVariable(L"MokNew", &shim_lock_guid) != EFI_SUCCESS) { @@ -1443,6 +1600,14 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) } FreePool (MokNew); } + + if (MokPW) { + if (LibDeleteVariable(L"MokPW", &shim_lock_guid) != EFI_SUCCESS) { + Print(L"Failed to delete MokPW\n"); + } + FreePool (MokNew); + } + LibDeleteVariable(L"MokAuth", &shim_lock_guid); return EFI_SUCCESS; diff --git a/shim.c b/shim.c index 39ad9bba..dbe5e849 100644 --- a/shim.c +++ b/shim.c @@ -1038,23 +1038,29 @@ done: EFI_STATUS check_mok_request(EFI_HANDLE image_handle) { EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; - EFI_STATUS moknew_status, moksb_status, efi_status; + EFI_STATUS moknew_status, moksb_status, mokpw_status, efi_status; UINTN size = sizeof(UINT32); - UINT32 MokNew; + UINT32 MokVar; UINT32 attributes; moknew_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokNew", &shim_lock_guid, &attributes, - &size, (void *)&MokNew); + &size, (void *)&MokVar); moksb_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokSB", &shim_lock_guid, &attributes, - &size, (void *)&MokNew); + &size, (void *)&MokVar); + + mokpw_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPW", + &shim_lock_guid, &attributes, + &size, (void *)&MokVar); if (moknew_status == EFI_SUCCESS || moknew_status == EFI_BUFFER_TOO_SMALL || moksb_status == EFI_SUCCESS || - moksb_status == EFI_BUFFER_TOO_SMALL) { + moksb_status == EFI_BUFFER_TOO_SMALL || + mokpw_status == EFI_SUCCESS || + mokpw_status == EFI_BUFFER_TOO_SMALL) { efi_status = start_image(image_handle, MOK_MANAGER); if (efi_status != EFI_SUCCESS) { -- cgit v1.2.3 From 37635f541465578e29c2c6e908a24e74f240d728 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Thu, 18 Oct 2012 17:43:53 -0400 Subject: Clean up timeout counter handling Reduce menu redrawing by only redrawing the invalidated section of the menu during the timeout countdown. --- MokManager.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index 18992f27..23ed80eb 100644 --- a/MokManager.c +++ b/MokManager.c @@ -894,6 +894,28 @@ static void free_menu (struct menu_item *items, UINTN count) { FreePool(items); } +static void update_time (UINTN position, UINTN timeout) +{ + uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0, + position); + + uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, + EFI_BLACK | EFI_BACKGROUND_BLACK); + + Print(L" ", timeout); + + uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0, + position); + + uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, + EFI_WHITE | EFI_BACKGROUND_BLACK); + + if (timeout > 1) + Print(L"Booting in %d seconds\n", timeout); + else if (timeout) + Print(L"Booting in %d second\n", timeout); +} + static void run_menu (CHAR16 *header, UINTN lines, struct menu_item *items, UINTN count, UINTN timeout) { UINTN index, pos = 0, wait = 0, offset; @@ -904,23 +926,10 @@ static void run_menu (CHAR16 *header, UINTN lines, struct menu_item *items, if (timeout) wait = 10000000; - while (1) { - uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); - - offset = draw_menu (header, lines, items, count); - - uefi_call_wrapper(ST->ConOut->SetAttribute, 2, - ST->ConOut, - EFI_WHITE | EFI_BACKGROUND_BLACK); + offset = draw_menu (header, lines, items, count); - if (timeout) { - uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, - ST->ConOut, 0, count + 1 + offset); - if (timeout > 1) - Print(L"Booting in %d seconds\n", timeout); - else - Print(L"Booting in %d second\n", timeout); - } + while (1) { + update_time(count + offset + 1, timeout); uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0, pos + offset); -- cgit v1.2.3 From 16c512f9b5930da742e4014dbe26d3c895d689c3 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Thu, 18 Oct 2012 17:43:53 -0400 Subject: Don't print SHA1 sum when calculating file fingerprints There's no point in printing the SHA1 of a SHA256... --- MokManager.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index 23ed80eb..bc62cd08 100644 --- a/MokManager.c +++ b/MokManager.c @@ -317,8 +317,8 @@ static void show_mok_info (void *Mok, UINTN MokSize) return; if (MokSize != 48) { - if (X509ConstructCertificate(Mok, MokSize, (UINT8 **) &X509Cert) && - X509Cert != NULL) { + if (X509ConstructCertificate(Mok, MokSize, + (UINT8 **) &X509Cert) && X509Cert != NULL) { show_x509_info(X509Cert); X509_free(X509Cert); } else { @@ -326,6 +326,20 @@ static void show_mok_info (void *Mok, UINTN MokSize) ((UINT32 *)Mok)[0]); return; } + + efi_status = get_sha1sum(Mok, MokSize, hash); + + if (efi_status != EFI_SUCCESS) { + Print(L"Failed to compute MOK fingerprint\n"); + return; + } + + Print(L" Fingerprint (SHA1):\n "); + for (i = 0; i < SHA1_DIGEST_SIZE; i++) { + Print(L" %02x", hash[i]); + if (i % 10 == 9) + Print(L"\n "); + } } else { Print(L"SHA256 hash:\n "); for (i = 0; i < SHA256_DIGEST_SIZE; i++) { @@ -335,19 +349,7 @@ static void show_mok_info (void *Mok, UINTN MokSize) } Print(L"\n"); } - efi_status = get_sha1sum(Mok, MokSize, hash); - - if (efi_status != EFI_SUCCESS) { - Print(L"Failed to compute MOK fingerprint\n"); - return; - } - Print(L" Fingerprint (SHA1):\n "); - for (i = 0; i < SHA1_DIGEST_SIZE; i++) { - Print(L" %02x", hash[i]); - if (i % 10 == 9) - Print(L"\n "); - } Print(L"\n"); } -- cgit v1.2.3 From 34f0c4abc0a0e43656155be587428639bbf87710 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Thu, 18 Oct 2012 17:43:53 -0400 Subject: Clear screen before prompting We were drawing prompts on top of existing text, which was less than ideal. --- MokManager.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index bc62cd08..08e1d363 100644 --- a/MokManager.c +++ b/MokManager.c @@ -708,6 +708,8 @@ static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) { return -1; } + uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); + while (fail_count < 3) { Print(L"Enter Secure Boot passphrase: "); get_line(&length, password, SB_PASSWORD_LEN, 0); @@ -797,6 +799,8 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) { LibDeleteVariable(L"MokPW", &shim_lock_guid); + uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); + while (fail_count < 3) { Print(L"Confirm MOK passphrase: "); get_line(&length, password, PASSWORD_MAX, 0); @@ -1453,6 +1457,8 @@ static BOOLEAN verify_pw(void) if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) return TRUE; + uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); + while (fail_count < 3) { Print(L"Enter MOK password: "); get_line(&length, password, PASSWORD_MAX, 0); -- cgit v1.2.3 From 3a5933619965b4ba8c3aa0e3abbb4755bb80dc78 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 23 Oct 2012 13:00:40 -0400 Subject: Fix key database parsing The pointer to the certificate needs to be incremented by the size of the entire certificate, not just the certificate data. --- MokManager.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index 08e1d363..282fbc6a 100644 --- a/MokManager.c +++ b/MokManager.c @@ -108,7 +108,7 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) { (CompareGuid (&CertList->SignatureType, &HashType) != 0)) { dbsize -= CertList->SignatureListSize; CertList = (EFI_SIGNATURE_LIST *)((UINT8 *) CertList + - CertList->SignatureSize); + CertList->SignatureListSize); continue; } @@ -116,7 +116,7 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) { (CertList->SignatureSize != 48)) { dbsize -= CertList->SignatureListSize; CertList = (EFI_SIGNATURE_LIST *)((UINT8 *) CertList + - CertList->SignatureSize); + CertList->SignatureListSize); continue; } @@ -129,7 +129,7 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) { count++; dbsize -= CertList->SignatureListSize; CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + - CertList->SignatureSize); + CertList->SignatureListSize); } return list; @@ -414,7 +414,7 @@ static UINT8 list_keys (void *MokNew, UINTN MokNewSize) Print(L"Doesn't look like a key or hash\n"); dbsize -= CertList->SignatureListSize; CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + - CertList->SignatureSize); + CertList->SignatureListSize); continue; } @@ -423,14 +423,14 @@ static UINT8 list_keys (void *MokNew, UINTN MokNewSize) Print(L"Doesn't look like a valid hash\n"); dbsize -= CertList->SignatureListSize; CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + - CertList->SignatureSize); + CertList->SignatureListSize); continue; } MokNum++; dbsize -= CertList->SignatureListSize; CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + - CertList->SignatureSize); + CertList->SignatureListSize); } keys = build_mok_list(MokNum, MokNew, MokNewSize); -- cgit v1.2.3 From 868d5b903801fded444d03a92c7a371af6fe32ce Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 23 Oct 2012 13:01:48 -0400 Subject: Delete MokList properly A cut and paste error meant that attempts to delete MokList were instead appending a zero-length addition. --- MokManager.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index 282fbc6a..9e2fdf82 100644 --- a/MokManager.c +++ b/MokManager.c @@ -615,8 +615,7 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate) efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList", &shim_lock_guid, EFI_VARIABLE_NON_VOLATILE - | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_APPEND_WRITE, + | EFI_VARIABLE_BOOTSERVICE_ACCESS, 0, NULL); } else { /* Write new MOK */ -- cgit v1.2.3 From 79a5aa039dc185870b2159418b0eda30731c141d Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 23 Oct 2012 15:43:10 -0400 Subject: Update image validation enable/disable Update this to match the new mokutil behaviour --- MokManager.c | 66 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 23 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index 9e2fdf82..d764bf6e 100644 --- a/MokManager.c +++ b/MokManager.c @@ -35,7 +35,8 @@ typedef struct { typedef struct { UINT32 MokSBState; - UINT8 hash[SHA256_DIGEST_SIZE]; + UINT32 PWLen; + CHAR16 Password[PASSWORD_MAX]; } __attribute__ ((packed)) MokSBvar; static EFI_INPUT_KEY get_keystroke (void) @@ -693,12 +694,13 @@ static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) { EFI_STATUS efi_status; UINTN MokSBSize = (UINTN)data2; MokSBvar *var = MokSB; - CHAR16 password[SB_PASSWORD_LEN]; - UINT8 fail_count = 0; + CHAR16 password[1]; + UINT8 correct = 0, fail_count = 0; UINT8 hash[SHA256_DIGEST_SIZE]; UINT32 length; CHAR16 line[1]; UINT8 sbval = 1; + UINT8 pos; LibDeleteVariable(L"MokSB", &shim_lock_guid); @@ -709,32 +711,23 @@ static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) { uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); - while (fail_count < 3) { - Print(L"Enter Secure Boot passphrase: "); - get_line(&length, password, SB_PASSWORD_LEN, 0); + while (correct < 3) { + RandomBytes (&pos, sizeof(pos)); - 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); + pos = pos % var->PWLen; - if (efi_status != EFI_SUCCESS) { - Print(L"Unable to generate password hash\n"); - fail_count++; - continue; - } + Print(L"Enter password character %d: ", pos + 1); + get_line(&length, password, 1, 0); - if (CompareMem(var->hash, hash, SHA256_DIGEST_SIZE) != 0) { - Print(L"Password doesn't match\n"); + if (password[0] != var->Password[pos]) { + Print(L"Invalid character\n"); fail_count++; - continue; + } else { + correct++; } - break; + if (fail_count >= 3) + break; } if (fail_count >= 3) { @@ -1629,12 +1622,39 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) return EFI_SUCCESS; } +static EFI_STATUS setup_rand (void) +{ + EFI_TIME time; + EFI_STATUS efi_status; + UINT64 seed; + BOOLEAN status; + + efi_status = uefi_call_wrapper(RT->GetTime, 2, &time, NULL); + + if (efi_status != EFI_SUCCESS) + return efi_status; + + seed = ((UINT64)time.Year << 48) | ((UINT64)time.Month << 40) | + ((UINT64)time.Day << 32) | ((UINT64)time.Hour << 24) | + ((UINT64)time.Minute << 16) | ((UINT64)time.Second << 8) | + ((UINT64)time.Daylight); + + status = RandomSeed((UINT8 *)&seed, sizeof(seed)); + + if (!status) + return EFI_ABORTED; + + return EFI_SUCCESS; +} + EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab) { EFI_STATUS efi_status; InitializeLib(image_handle, systab); + setup_rand(); + efi_status = check_mok_request(image_handle); return efi_status; -- cgit v1.2.3 From 254c04bcddd722fd839962b46e6207b743aa432b Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 23 Oct 2012 15:43:29 -0400 Subject: Fix password hash calculation This was hardcoded, rather than being based on the actual password length, resulting in incorrect hashes being generated. --- MokManager.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index d764bf6e..f7504d0d 100644 --- a/MokManager.c +++ b/MokManager.c @@ -803,8 +803,7 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) { continue; } - efi_status = compute_pw_hash(NULL, 0, password, - SB_PASSWORD_LEN, hash); + efi_status = compute_pw_hash(NULL, 0, password, length, hash); if (efi_status != EFI_SUCCESS) { Print(L"Unable to generate password hash\n"); -- cgit v1.2.3 From 6e05b32d0717ebc2541048de7269ce807a2fa12d Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 23 Oct 2012 23:46:44 -0400 Subject: Add another missing screen clearing Another case where we were drawing text over existing text. --- MokManager.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index f7504d0d..f9acb0c5 100644 --- a/MokManager.c +++ b/MokManager.c @@ -664,7 +664,9 @@ static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) { } static INTN mok_enrollment_prompt_callback (void *MokNew, void *data2, - void *data3) { + void *data3) +{ + uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); return mok_enrollment_prompt(MokNew, (UINTN)data2, TRUE); } -- cgit v1.2.3 From 8a1690683f2d5691e3a58bef2a24f347d762f91d Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 24 Oct 2012 01:05:45 -0400 Subject: Improve signature validation enable/disable The logic used in checking the signature validation password was a bit ugly. Improve that so it behaves rather more as expected. --- MokManager.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index f9acb0c5..2fbda848 100644 --- a/MokManager.c +++ b/MokManager.c @@ -696,13 +696,12 @@ static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) { EFI_STATUS efi_status; UINTN MokSBSize = (UINTN)data2; MokSBvar *var = MokSB; - CHAR16 password[1]; - UINT8 correct = 0, fail_count = 0; - UINT8 hash[SHA256_DIGEST_SIZE]; + CHAR16 pass1, pass2, pass3; + UINT8 fail_count = 0; UINT32 length; CHAR16 line[1]; UINT8 sbval = 1; - UINT8 pos; + UINT8 pos1, pos2, pos3; LibDeleteVariable(L"MokSB", &shim_lock_guid); @@ -713,23 +712,37 @@ static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) { uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); - while (correct < 3) { - RandomBytes (&pos, sizeof(pos)); + 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); - pos = pos % var->PWLen; + Print(L"Enter password character %d: ", pos1 + 1); + get_line(&length, &pass1, 1, 0); - Print(L"Enter password character %d: ", pos + 1); - get_line(&length, password, 1, 0); + Print(L"Enter password character %d: ", pos2 + 1); + get_line(&length, &pass2, 1, 0); - if (password[0] != var->Password[pos]) { + Print(L"Enter password character %d: ", pos3 + 1); + get_line(&length, &pass3, 1, 0); + + if (pass1 != var->Password[pos1] || + pass2 != var->Password[pos2] || + pass3 != var->Password[pos3]) { Print(L"Invalid character\n"); fail_count++; } else { - correct++; - } - - if (fail_count >= 3) break; + } } if (fail_count >= 3) { -- cgit v1.2.3 From d77f421bccf00722192a0cc90dddae05b1b74f91 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 24 Oct 2012 01:14:50 -0400 Subject: Clean up password setting Permit clearing of the password, and avoid a case where choosing not to set a password would result in an error message on exit. Fix the same problem with MokSB. --- MokManager.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index 2fbda848..eb5bb919 100644 --- a/MokManager.c +++ b/MokManager.c @@ -703,8 +703,6 @@ static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) { UINT8 sbval = 1; UINT8 pos1, pos2, pos3; - LibDeleteVariable(L"MokSB", &shim_lock_guid); - if (MokSBSize != sizeof(MokSBvar)) { Print(L"Invalid MokSB variable contents\n"); return -1; @@ -776,6 +774,8 @@ static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) { &shim_lock_guid); } + LibDeleteVariable(L"MokSB", &shim_lock_guid); + Print(L"Press a key to reboot system\n"); Pause(); uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, @@ -804,10 +804,25 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) { return -1; } - LibDeleteVariable(L"MokPW", &shim_lock_guid); - uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); + SetMem(hash, SHA256_DIGEST_SIZE, 0); + + if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) == 0) { + Print(L"Clear MOK password? (y/n): "); + + do { + get_line (&length, line, 1, 1); + + if (line[0] == 'Y' || line[0] == 'y') { + LibDeleteVariable(L"MokPWStore", &shim_lock_guid); + LibDeleteVariable(L"MokPW", &shim_lock_guid); + } + } while (line[0] != 'N' && line[0] != 'n'); + + return 0; + } + while (fail_count < 3) { Print(L"Confirm MOK passphrase: "); get_line(&length, password, PASSWORD_MAX, 0); @@ -857,6 +872,8 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) { return -1; } + LibDeleteVariable(L"MokPW", &shim_lock_guid); + Print(L"Press a key to reboot system\n"); Pause(); uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, -- cgit v1.2.3 From ed711b02ec18fecbf8b627b563e8cdfe1253170a Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Thu, 1 Nov 2012 09:46:51 -0400 Subject: Fix up some types Type-checking the UEFI calls picked up a couple of problems. Fix them up. --- MokManager.c | 6 +++--- shim.c | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'MokManager.c') diff --git a/MokManager.c b/MokManager.c index eb5bb919..5802d274 100644 --- a/MokManager.c +++ b/MokManager.c @@ -1362,7 +1362,7 @@ static INTN find_fs (void *data, void *data2, void *data3) { EFI_GUID fs_guid = SIMPLE_FILE_SYSTEM_PROTOCOL; UINTN count, i; UINTN OldSize, NewSize; - EFI_HANDLE **filesystem_handles; + EFI_HANDLE *filesystem_handles = NULL; struct menu_item *filesystems; BOOLEAN hash = !!data3; @@ -1383,7 +1383,7 @@ static INTN find_fs (void *data, void *data2, void *data3) { filesystems[0].colour = EFI_YELLOW; for (i=1; iHandleProtocol, 3, fs, &fs_guid, - &fs_interface); + (void **)&fs_interface); if (status != EFI_SUCCESS || !fs_interface) continue; diff --git a/shim.c b/shim.c index 2f7f8c2e..8fbc0708 100644 --- a/shim.c +++ b/shim.c @@ -890,7 +890,8 @@ static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data, device = li->DeviceHandle; efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, device, - &simple_file_system_protocol, &drive); + &simple_file_system_protocol, + (void **)&drive); if (efi_status != EFI_SUCCESS) { Print(L"Failed to find fs\n"); @@ -1011,7 +1012,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath) int datasize; efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle, - &loaded_image_protocol, &li); + &loaded_image_protocol, (void **)&li); if (efi_status != EFI_SUCCESS) { Print(L"Unable to init protocol\n"); -- cgit v1.2.3