diff options
| -rw-r--r-- | MokManager.c | 70 | ||||
| -rw-r--r-- | shim.c | 51 |
2 files changed, 91 insertions, 30 deletions
diff --git a/MokManager.c b/MokManager.c index f7504d0d..eb5bb919 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); } @@ -694,15 +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; - - LibDeleteVariable(L"MokSB", &shim_lock_guid); + UINT8 pos1, pos2, pos3; if (MokSBSize != sizeof(MokSBvar)) { Print(L"Invalid MokSB variable contents\n"); @@ -711,23 +710,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); + + Print(L"Enter password character %d: ", pos1 + 1); + get_line(&length, &pass1, 1, 0); - pos = pos % var->PWLen; + Print(L"Enter password character %d: ", pos2 + 1); + get_line(&length, &pass2, 1, 0); - Print(L"Enter password character %d: ", pos + 1); - get_line(&length, password, 1, 0); + Print(L"Enter password character %d: ", pos3 + 1); + get_line(&length, &pass3, 1, 0); - if (password[0] != var->Password[pos]) { + 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) { @@ -761,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, @@ -789,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); @@ -842,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, @@ -82,8 +82,7 @@ static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes, return efi_status; } - if (allocate) - *buffer = AllocatePool(*size); + *buffer = AllocatePool(*size); if (!*buffer) { Print(L"Unable to allocate variable buffer\n"); @@ -545,7 +544,8 @@ static EFI_STATUS generate_hash (char *data, int datasize, if (!hashbase) { Print(L"Malformed section header\n"); - return EFI_INVALID_PARAMETER; + status = EFI_INVALID_PARAMETER; + goto done; } if (!(Sha256Update(sha256ctx, hashbase, hashsize)) || @@ -625,6 +625,11 @@ static EFI_STATUS verify_buffer (char *data, int datasize, WIN_CERTIFICATE_EFI_PKCS *cert; unsigned int size = datasize; + if (context->SecDir->Size == 0) { + Print(L"Empty security header\n"); + return EFI_INVALID_PARAMETER; + } + cert = ImageAddress (data, size, context->SecDir->VirtualAddress); if (!cert) { @@ -683,9 +688,19 @@ static EFI_STATUS read_header(void *data, unsigned int datasize, EFI_IMAGE_DOS_HEADER *DosHdr = data; EFI_IMAGE_OPTIONAL_HEADER_UNION *PEHdr = data; + if (datasize < sizeof(EFI_IMAGE_DOS_HEADER)) { + Print(L"Invalid image\n"); + return EFI_UNSUPPORTED; + } + if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) PEHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((char *)data + DosHdr->e_lfanew); + if ((((UINT8 *)PEHdr - (UINT8 *)data) + sizeof(EFI_IMAGE_OPTIONAL_HEADER_UNION)) > datasize) { + Print(L"Invalid image\n"); + return EFI_UNSUPPORTED; + } + if (PEHdr->Te.Signature != EFI_IMAGE_NT_SIGNATURE) { Print(L"Unsupported image type\n"); return EFI_UNSUPPORTED; @@ -712,13 +727,18 @@ static EFI_STATUS read_header(void *data, unsigned int datasize, context->FirstSection = (EFI_IMAGE_SECTION_HEADER *)((char *)PEHdr + PEHdr->Pe32.FileHeader.SizeOfOptionalHeader + sizeof(UINT32) + sizeof(EFI_IMAGE_FILE_HEADER)); context->SecDir = (EFI_IMAGE_DATA_DIRECTORY *) &PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]; - if (context->SecDir->VirtualAddress >= datasize) { - Print(L"Malformed security header\n"); - return EFI_INVALID_PARAMETER; + if (context->ImageSize < context->SizeOfHeaders) { + Print(L"Invalid image\n"); + return EFI_UNSUPPORTED; } - if (context->SecDir->Size == 0) { - Print(L"Empty security header\n"); + if (((UINT8 *)context->SecDir - (UINT8 *)data) > (datasize - sizeof(EFI_IMAGE_DATA_DIRECTORY))) { + Print(L"Invalid image\n"); + return EFI_UNSUPPORTED; + } + + if (context->SecDir->VirtualAddress >= datasize) { + Print(L"Malformed security header\n"); return EFI_INVALID_PARAMETER; } @@ -831,7 +851,7 @@ static EFI_STATUS generate_path(EFI_LOADED_IMAGE *li, CHAR16 *ImagePath, bootpath[i+1] = '\0'; - if (bootpath[i-i] == '\\') + if (i == 0 || bootpath[i-i] == '\\') bootpath[i] = '\0'; *PathName = AllocatePool(StrSize(bootpath) + StrSize(ImagePath)); @@ -904,6 +924,7 @@ static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data, &buffersize, fileinfo); if (efi_status == EFI_BUFFER_TOO_SMALL) { + FreePool(fileinfo); fileinfo = AllocatePool(buffersize); if (!fileinfo) { Print(L"Unable to allocate file info buffer\n"); @@ -946,6 +967,8 @@ static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data, *datasize = buffersize; + FreePool(fileinfo); + return EFI_SUCCESS; error: if (*data) { @@ -983,7 +1006,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath) EFI_STATUS efi_status; EFI_LOADED_IMAGE *li, li_bak; EFI_DEVICE_PATH *path; - CHAR16 *PathName; + CHAR16 *PathName = NULL; void *data = NULL; int datasize; @@ -1019,10 +1042,16 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath) goto done; } - efi_status = uefi_call_wrapper(entry_point, 3, image_handle, systab); + efi_status = uefi_call_wrapper(entry_point, 2, image_handle, systab); CopyMem(li, &li_bak, sizeof(li_bak)); done: + if (PathName) + FreePool(PathName); + + if (data) + FreePool(data); + return efi_status; } |
