diff options
| author | Gary Ching-Pang Lin <glin@suse.com> | 2012-09-24 15:48:01 +0800 |
|---|---|---|
| committer | Gary Ching-Pang Lin <glin@suse.com> | 2012-09-24 15:48:01 +0800 |
| commit | 215e462b10134c421a8c1d041a420feec1e0a1cf (patch) | |
| tree | f17ba423c276c18da5d90082c133ac249decffb6 /MokManager.c | |
| parent | 5d328c6c4545bddd789e136be63d12beed0cd6af (diff) | |
| download | efi-boot-shim-215e462b10134c421a8c1d041a420feec1e0a1cf.tar.gz efi-boot-shim-215e462b10134c421a8c1d041a420feec1e0a1cf.zip | |
Request a password to verify the key list
The password must contain 8 characters at least and 16 characters
at most and will be hashed with the key list altogether. The keys
in MokNew won't be allowed to be enrolled unless the user provides
the correct password.
Diffstat (limited to 'MokManager.c')
| -rw-r--r-- | MokManager.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/MokManager.c b/MokManager.c index ea2a94ec..ce577465 100644 --- a/MokManager.c +++ b/MokManager.c @@ -466,10 +466,144 @@ static UINT8 mok_deletion_prompt () { return 0; } +static UINT8 get_password (UINT32 *length, CHAR16 *password) +{ + EFI_INPUT_KEY key; + CHAR16 input[16]; + int count = 0; + + do { + key = get_keystroke(); + + if ((count >= 16 && key.UnicodeChar != CHAR_BACKSPACE) || + key.UnicodeChar == CHAR_NULL || + key.UnicodeChar == CHAR_TAB || + key.UnicodeChar == CHAR_LINEFEED) { + continue; + } + + if (count == 0 && key.UnicodeChar == CHAR_BACKSPACE) { + continue; + } else if (key.UnicodeChar == CHAR_BACKSPACE) { + Print(L"%c", CHAR_BACKSPACE); + input[--count] = '\0'; + continue; + } + + input[count++] = key.UnicodeChar; + } while (key.UnicodeChar != CHAR_CARRIAGE_RETURN); + Print(L"\n"); + + *length = count; + CopyMem(password, input, count * sizeof(CHAR16)); + + return 1; +} + +static EFI_STATUS compute_pw_hash (void *MokNew, UINTN MokNewSize, CHAR16 *password, + UINT32 pw_length, UINT8 *hash) +{ + EFI_STATUS status; + unsigned int ctxsize; + void *ctx = NULL; + + ctxsize = Sha256GetContextSize(); + ctx = AllocatePool(ctxsize); + + if (!ctx) { + Print(L"Unable to allocate memory for hash context\n"); + return EFI_OUT_OF_RESOURCES; + } + + if (!Sha256Init(ctx)) { + Print(L"Unable to initialise hash\n"); + status = EFI_OUT_OF_RESOURCES; + goto done; + } + + if (!(Sha256Update(ctx, MokNew, MokNewSize))) { + Print(L"Unable to generate hash\n"); + status = EFI_OUT_OF_RESOURCES; + goto done; + } + + if (!(Sha256Update(ctx, password, pw_length * sizeof(CHAR16)))) { + Print(L"Unable to generate hash\n"); + status = EFI_OUT_OF_RESOURCES; + goto done; + } + + if (!(Sha256Final(ctx, hash))) { + Print(L"Unable to finalise hash\n"); + status = EFI_OUT_OF_RESOURCES; + goto done; + } + + status = EFI_SUCCESS; +done: + return status; +} + +static UINT8 compare_hash (UINT8 *hash1, UINT8 *hash2, UINT32 size) +{ + int i; + + for (i = 0; i < size; i++) { + if (hash1[i] != hash2[i]) { + return 0; + } + } + + return 1; +} + static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize) { EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; EFI_STATUS efi_status; + UINT8 hash[SHA256_DIGEST_SIZE]; + UINT8 auth[SHA256_DIGEST_SIZE]; + UINTN auth_size; + UINT32 attributes; + CHAR16 password[16]; + UINT32 pw_length; + UINT8 fail_count = 0; + + auth_size = SHA256_DIGEST_SIZE; + efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth", + &shim_lock_guid, + &attributes, &auth_size, auth); + + + if (efi_status != EFI_SUCCESS || auth_size != SHA256_DIGEST_SIZE) { + Print(L"Failed to get MokAuth %d\n", efi_status); + return efi_status; + } + + while (fail_count < 3) { + Print(L"Password: "); + get_password(&pw_length, password); + + if (pw_length < 8) { + Print(L"At 8 characters for the password\n"); + } + + efi_status = compute_pw_hash(MokNew, MokNewSize, password, + pw_length, hash); + + if (efi_status != EFI_SUCCESS) { + return efi_status; + } + + if (!compare_hash(auth, hash, SHA256_DIGEST_SIZE)) { + fail_count++; + } else { + break; + } + } + + if (fail_count >= 3) + return EFI_ACCESS_DENIED; /* Write new MOK */ efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList", @@ -534,6 +668,7 @@ error: } FreePool (MokNew); } + delete_variable(L"MokAuth", shim_lock_guid); return EFI_SUCCESS; } |
