mirror of
https://git.proxmox.com/git/efi-boot-shim
synced 2025-07-27 05:02:29 +00:00
MokManager: support crypt() password hash
The password format is introduced for the password hash generated by crypt(), so that the user can import the password hash from /etc/shadow. The packager, especially those who packages 3rd party drivers, can utilize this feature to import a 3rd party certificate without interfering the package installation. This commit implements the sha256-based crypt() hash function. Conflicts: Makefile MokManager.c
This commit is contained in:
parent
4a7f9bd4a6
commit
afb61e7902
6
Makefile
6
Makefile
@ -36,8 +36,8 @@ TARGET = shim.efi MokManager.efi.signed fallback.efi.signed
|
|||||||
OBJS = shim.o netboot.o cert.o dbx.o
|
OBJS = shim.o netboot.o cert.o dbx.o
|
||||||
KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key
|
KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key
|
||||||
SOURCES = shim.c shim.h netboot.c signature.h PeImage.h
|
SOURCES = shim.c shim.h netboot.c signature.h PeImage.h
|
||||||
MOK_OBJS = MokManager.o
|
MOK_OBJS = MokManager.o PasswordCrypt.o
|
||||||
MOK_SOURCES = MokManager.c shim.h console_control.h
|
MOK_SOURCES = MokManager.c shim.h console_control.h PasswordCrypt.c PasswordCrypt.h
|
||||||
FALLBACK_OBJS = fallback.o
|
FALLBACK_OBJS = fallback.o
|
||||||
FALLBACK_SRCS = fallback.c
|
FALLBACK_SRCS = fallback.c
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ fallback.o: $(FALLBACK_SRCS)
|
|||||||
fallback.so: $(FALLBACK_OBJS)
|
fallback.so: $(FALLBACK_OBJS)
|
||||||
$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS)
|
$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS)
|
||||||
|
|
||||||
MokManager.o: $(SOURCES)
|
MokManager.o: $(MOK_SOURCES)
|
||||||
|
|
||||||
MokManager.so: $(MOK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
|
MokManager.so: $(MOK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
|
||||||
$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) lib/lib.a
|
$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) lib/lib.a
|
||||||
|
151
MokManager.c
151
MokManager.c
@ -2,17 +2,18 @@
|
|||||||
#include <efilib.h>
|
#include <efilib.h>
|
||||||
#include <Library/BaseCryptLib.h>
|
#include <Library/BaseCryptLib.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
|
#include "console_control.h"
|
||||||
#include "shim.h"
|
#include "shim.h"
|
||||||
#include "signature.h"
|
#include "signature.h"
|
||||||
#include "PeImage.h"
|
#include "PeImage.h"
|
||||||
#include "console_control.h"
|
#include "PasswordCrypt.h"
|
||||||
|
|
||||||
#include "include/console.h"
|
#include "include/console.h"
|
||||||
#include "include/simple_file.h"
|
#include "include/simple_file.h"
|
||||||
|
|
||||||
#define PASSWORD_MAX 16
|
#define PASSWORD_MAX 256
|
||||||
#define PASSWORD_MIN 8
|
#define PASSWORD_MIN 1
|
||||||
#define SB_PASSWORD_LEN 8
|
#define SB_PASSWORD_LEN 16
|
||||||
|
|
||||||
#ifndef SHIM_VENDOR
|
#ifndef SHIM_VENDOR
|
||||||
#define SHIM_VENDOR L"Shim"
|
#define SHIM_VENDOR L"Shim"
|
||||||
@ -43,7 +44,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 MokSBState;
|
UINT32 MokSBState;
|
||||||
UINT32 PWLen;
|
UINT32 PWLen;
|
||||||
CHAR16 Password[PASSWORD_MAX];
|
CHAR16 Password[SB_PASSWORD_LEN];
|
||||||
} __attribute__ ((packed)) MokSBvar;
|
} __attribute__ ((packed)) MokSBvar;
|
||||||
|
|
||||||
static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes,
|
static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes,
|
||||||
@ -586,7 +587,7 @@ static UINT8 get_line (UINT32 *length, CHAR16 *line, UINT32 line_max, UINT8 show
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EFI_STATUS compute_pw_hash (void *MokNew, UINTN MokNewSize, CHAR16 *password,
|
static EFI_STATUS compute_pw_hash (void *Data, UINTN DataSize, UINT8 *password,
|
||||||
UINT32 pw_length, UINT8 *hash)
|
UINT32 pw_length, UINT8 *hash)
|
||||||
{
|
{
|
||||||
EFI_STATUS status;
|
EFI_STATUS status;
|
||||||
@ -607,15 +608,15 @@ static EFI_STATUS compute_pw_hash (void *MokNew, UINTN MokNewSize, CHAR16 *passw
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MokNew && MokNewSize) {
|
if (Data && DataSize) {
|
||||||
if (!(Sha256Update(ctx, MokNew, MokNewSize))) {
|
if (!(Sha256Update(ctx, Data, DataSize))) {
|
||||||
console_notify(L"Unable to generate hash");
|
console_notify(L"Unable to generate hash");
|
||||||
status = EFI_OUT_OF_RESOURCES;
|
status = EFI_OUT_OF_RESOURCES;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(Sha256Update(ctx, password, pw_length * sizeof(CHAR16)))) {
|
if (!(Sha256Update(ctx, password, pw_length))) {
|
||||||
console_notify(L"Unable to generate hash");
|
console_notify(L"Unable to generate hash");
|
||||||
status = EFI_OUT_OF_RESOURCES;
|
status = EFI_OUT_OF_RESOURCES;
|
||||||
goto done;
|
goto done;
|
||||||
@ -632,15 +633,34 @@ done:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EFI_STATUS match_password (void *Data, UINTN DataSize,
|
static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
|
||||||
UINT8 auth[SHA256_DIGEST_SIZE],
|
void *Data, UINTN DataSize,
|
||||||
CHAR16 *prompt)
|
UINT8 *auth, CHAR16 *prompt)
|
||||||
{
|
{
|
||||||
EFI_STATUS efi_status;
|
EFI_STATUS status;
|
||||||
UINT8 hash[SHA256_DIGEST_SIZE];
|
UINT8 hash[SHA256_DIGEST_SIZE];
|
||||||
|
UINT8 *auth_hash;
|
||||||
|
UINT32 auth_size;
|
||||||
CHAR16 password[PASSWORD_MAX];
|
CHAR16 password[PASSWORD_MAX];
|
||||||
UINT32 pw_length;
|
UINT32 pw_length;
|
||||||
UINT8 fail_count = 0;
|
UINT8 fail_count = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (pw_crypt) {
|
||||||
|
/*
|
||||||
|
* Only support sha256 now
|
||||||
|
*/
|
||||||
|
if(pw_crypt->method != SHA256_BASED)
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
auth_hash = pw_crypt->hash;
|
||||||
|
/* FIXME assign auth_size according to pw_crypt->method */
|
||||||
|
auth_size = SHA256_DIGEST_SIZE;
|
||||||
|
} else if (auth) {
|
||||||
|
auth_hash = auth;
|
||||||
|
auth_size = SHA256_DIGEST_SIZE;
|
||||||
|
} else {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
while (fail_count < 3) {
|
while (fail_count < 3) {
|
||||||
if (prompt) {
|
if (prompt) {
|
||||||
@ -656,16 +676,30 @@ static EFI_STATUS match_password (void *Data, UINTN DataSize,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
efi_status = compute_pw_hash(Data, DataSize, password,
|
/*
|
||||||
pw_length, hash);
|
* Compute password hash
|
||||||
|
*/
|
||||||
|
if (pw_crypt) {
|
||||||
|
char pw_ascii[PASSWORD_MAX + 1];
|
||||||
|
for (i = 0; i < pw_length; i++)
|
||||||
|
pw_ascii[i] = (char)password[i];
|
||||||
|
pw_ascii[pw_length] = '\0';
|
||||||
|
|
||||||
if (efi_status != EFI_SUCCESS) {
|
status = password_crypt(pw_ascii, pw_length, pw_crypt, hash);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* For backward compatibility
|
||||||
|
*/
|
||||||
|
status = compute_pw_hash(Data, DataSize, (UINT8 *)password,
|
||||||
|
pw_length * sizeof(CHAR16), hash);
|
||||||
|
}
|
||||||
|
if (status != EFI_SUCCESS) {
|
||||||
Print(L"Unable to generate password hash\n");
|
Print(L"Unable to generate password hash\n");
|
||||||
fail_count++;
|
fail_count++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CompareMem(auth, hash, SHA256_DIGEST_SIZE) != 0) {
|
if (CompareMem(auth_hash, hash, auth_size) != 0) {
|
||||||
Print(L"Password doesn't match\n");
|
Print(L"Password doesn't match\n");
|
||||||
fail_count++;
|
fail_count++;
|
||||||
continue;
|
continue;
|
||||||
@ -684,23 +718,29 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
|
|||||||
{
|
{
|
||||||
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||||||
EFI_STATUS efi_status;
|
EFI_STATUS efi_status;
|
||||||
UINT8 auth[SHA256_DIGEST_SIZE];
|
UINT8 auth[PASSWORD_CRYPT_SIZE];
|
||||||
UINTN auth_size;
|
UINTN auth_size = PASSWORD_CRYPT_SIZE;
|
||||||
UINT32 attributes;
|
UINT32 attributes;
|
||||||
|
|
||||||
if (authenticate) {
|
if (authenticate) {
|
||||||
auth_size = SHA256_DIGEST_SIZE;
|
|
||||||
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth",
|
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth",
|
||||||
&shim_lock_guid,
|
&shim_lock_guid,
|
||||||
&attributes, &auth_size, auth);
|
&attributes, &auth_size, auth);
|
||||||
|
|
||||||
|
if (efi_status != EFI_SUCCESS ||
|
||||||
if (efi_status != EFI_SUCCESS || auth_size != SHA256_DIGEST_SIZE) {
|
(auth_size != SHA256_DIGEST_SIZE &&
|
||||||
|
auth_size != PASSWORD_CRYPT_SIZE)) {
|
||||||
console_error(L"Failed to get MokAuth", efi_status);
|
console_error(L"Failed to get MokAuth", efi_status);
|
||||||
return efi_status;
|
return efi_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
efi_status = match_password(MokNew, MokNewSize, auth, NULL);
|
if (auth_size == PASSWORD_CRYPT_SIZE) {
|
||||||
|
efi_status = match_password((PASSWORD_CRYPT *)auth,
|
||||||
|
NULL, 0, NULL, NULL);
|
||||||
|
} else {
|
||||||
|
efi_status = match_password(NULL, MokNew, MokNewSize,
|
||||||
|
auth, NULL);
|
||||||
|
}
|
||||||
if (efi_status != EFI_SUCCESS)
|
if (efi_status != EFI_SUCCESS)
|
||||||
return EFI_ACCESS_DENIED;
|
return EFI_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
@ -854,8 +894,8 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
|
|||||||
{
|
{
|
||||||
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||||||
EFI_STATUS efi_status;
|
EFI_STATUS efi_status;
|
||||||
UINT8 auth[SHA256_DIGEST_SIZE];
|
UINT8 auth[PASSWORD_CRYPT_SIZE];
|
||||||
UINTN auth_size = SHA256_DIGEST_SIZE;
|
UINTN auth_size = PASSWORD_CRYPT_SIZE;
|
||||||
UINT32 attributes;
|
UINT32 attributes;
|
||||||
void *MokListData = NULL;
|
void *MokListData = NULL;
|
||||||
UINTN MokListDataSize = 0;
|
UINTN MokListDataSize = 0;
|
||||||
@ -867,12 +907,18 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
|
|||||||
&shim_lock_guid,
|
&shim_lock_guid,
|
||||||
&attributes, &auth_size, auth);
|
&attributes, &auth_size, auth);
|
||||||
|
|
||||||
if (efi_status != EFI_SUCCESS || auth_size != SHA256_DIGEST_SIZE) {
|
if (efi_status != EFI_SUCCESS ||
|
||||||
|
(auth_size != SHA256_DIGEST_SIZE && auth_size != PASSWORD_CRYPT_SIZE)) {
|
||||||
console_error(L"Failed to get MokDelAuth", efi_status);
|
console_error(L"Failed to get MokDelAuth", efi_status);
|
||||||
return efi_status;
|
return efi_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
efi_status = match_password(MokDel, MokDelSize, auth, NULL);
|
if (auth_size == PASSWORD_CRYPT_SIZE) {
|
||||||
|
efi_status = match_password((PASSWORD_CRYPT *)auth, NULL, 0,
|
||||||
|
NULL, NULL);
|
||||||
|
} else {
|
||||||
|
efi_status = match_password(NULL, MokDel, MokDelSize, auth, NULL);
|
||||||
|
}
|
||||||
if (efi_status != EFI_SUCCESS)
|
if (efi_status != EFI_SUCCESS)
|
||||||
return EFI_ACCESS_DENIED;
|
return EFI_ACCESS_DENIED;
|
||||||
|
|
||||||
@ -1045,18 +1091,27 @@ static INTN mok_sb_prompt (void *MokSB, UINTN MokSBSize) {
|
|||||||
static INTN mok_pw_prompt (void *MokPW, UINTN MokPWSize) {
|
static INTN mok_pw_prompt (void *MokPW, UINTN MokPWSize) {
|
||||||
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||||||
EFI_STATUS efi_status;
|
EFI_STATUS efi_status;
|
||||||
UINT8 hash[SHA256_DIGEST_SIZE];
|
UINT8 hash[PASSWORD_CRYPT_SIZE];
|
||||||
|
UINT8 clear = 0;
|
||||||
|
|
||||||
if (MokPWSize != SHA256_DIGEST_SIZE) {
|
if (MokPWSize != SHA256_DIGEST_SIZE && MokPWSize != PASSWORD_CRYPT_SIZE) {
|
||||||
console_notify(L"Invalid MokPW variable contents");
|
console_notify(L"Invalid MokPW variable contents");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||||
|
|
||||||
SetMem(hash, SHA256_DIGEST_SIZE, 0);
|
SetMem(hash, PASSWORD_CRYPT_SIZE, 0);
|
||||||
|
|
||||||
if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) == 0) {
|
if (MokPWSize == PASSWORD_CRYPT_SIZE) {
|
||||||
|
if (CompareMem(MokPW, hash, PASSWORD_CRYPT_SIZE) == 0)
|
||||||
|
clear = 1;
|
||||||
|
} else {
|
||||||
|
if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) == 0)
|
||||||
|
clear = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clear) {
|
||||||
if (console_yes_no((CHAR16 *[]){L"Clear MOK password?", NULL}) == 0)
|
if (console_yes_no((CHAR16 *[]){L"Clear MOK password?", NULL}) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1065,7 +1120,14 @@ static INTN mok_pw_prompt (void *MokPW, UINTN MokPWSize) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
efi_status = match_password(NULL, 0, MokPW, L"Confirm MOK passphrase: ");
|
if (MokPWSize == PASSWORD_CRYPT_SIZE) {
|
||||||
|
efi_status = match_password((PASSWORD_CRYPT *)MokPW, NULL, 0,
|
||||||
|
NULL, L"Confirm MOK passphrase: ");
|
||||||
|
} else {
|
||||||
|
efi_status = match_password(NULL, NULL, 0, MokPW,
|
||||||
|
L"Confirm MOK passphrase: ");
|
||||||
|
}
|
||||||
|
|
||||||
if (efi_status != EFI_SUCCESS) {
|
if (efi_status != EFI_SUCCESS) {
|
||||||
console_notify(L"Password limit reached");
|
console_notify(L"Password limit reached");
|
||||||
return -1;
|
return -1;
|
||||||
@ -1280,8 +1342,8 @@ static BOOLEAN verify_pw(void)
|
|||||||
{
|
{
|
||||||
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||||||
EFI_STATUS efi_status;
|
EFI_STATUS efi_status;
|
||||||
UINT8 pwhash[SHA256_DIGEST_SIZE];
|
UINT8 pwhash[PASSWORD_CRYPT_SIZE];
|
||||||
UINTN size = SHA256_DIGEST_SIZE;
|
UINTN size = PASSWORD_CRYPT_SIZE;
|
||||||
UINT32 attributes;
|
UINT32 attributes;
|
||||||
|
|
||||||
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPWStore",
|
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPWStore",
|
||||||
@ -1293,7 +1355,8 @@ static BOOLEAN verify_pw(void)
|
|||||||
* known value, so there's no safety advantage in failing to validate
|
* known value, so there's no safety advantage in failing to validate
|
||||||
* purely because of a failure to read the variable
|
* purely because of a failure to read the variable
|
||||||
*/
|
*/
|
||||||
if (efi_status != EFI_SUCCESS)
|
if (efi_status != EFI_SUCCESS ||
|
||||||
|
(size != SHA256_DIGEST_SIZE && size != PASSWORD_CRYPT_SIZE))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (attributes & EFI_VARIABLE_RUNTIME_ACCESS)
|
if (attributes & EFI_VARIABLE_RUNTIME_ACCESS)
|
||||||
@ -1301,7 +1364,13 @@ static BOOLEAN verify_pw(void)
|
|||||||
|
|
||||||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||||
|
|
||||||
efi_status = match_password(NULL, 0, pwhash, L"Enter MOK password: ");
|
if (size == PASSWORD_CRYPT_SIZE) {
|
||||||
|
efi_status = match_password((PASSWORD_CRYPT *)pwhash, NULL, 0,
|
||||||
|
NULL, L"Enter MOK password: ");
|
||||||
|
} else {
|
||||||
|
efi_status = match_password(NULL, NULL, 0, pwhash,
|
||||||
|
L"Enter MOK password: ");
|
||||||
|
}
|
||||||
if (efi_status != EFI_SUCCESS) {
|
if (efi_status != EFI_SUCCESS) {
|
||||||
console_notify(L"Password limit reached");
|
console_notify(L"Password limit reached");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -1335,8 +1404,8 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
|||||||
UINTN menucount = 3, i = 0;
|
UINTN menucount = 3, i = 0;
|
||||||
EFI_STATUS efi_status;
|
EFI_STATUS efi_status;
|
||||||
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||||||
UINT8 auth[SHA256_DIGEST_SIZE];
|
UINT8 auth[PASSWORD_CRYPT_SIZE];
|
||||||
UINTN auth_size = SHA256_DIGEST_SIZE;
|
UINTN auth_size = PASSWORD_CRYPT_SIZE;
|
||||||
UINT32 attributes;
|
UINT32 attributes;
|
||||||
EFI_STATUS ret = EFI_SUCCESS;
|
EFI_STATUS ret = EFI_SUCCESS;
|
||||||
|
|
||||||
@ -1347,14 +1416,16 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
|||||||
&shim_lock_guid,
|
&shim_lock_guid,
|
||||||
&attributes, &auth_size, auth);
|
&attributes, &auth_size, auth);
|
||||||
|
|
||||||
if ((efi_status == EFI_SUCCESS) && (auth_size == SHA256_DIGEST_SIZE))
|
if ((efi_status == EFI_SUCCESS) &&
|
||||||
|
(auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE))
|
||||||
MokAuth = 1;
|
MokAuth = 1;
|
||||||
|
|
||||||
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth",
|
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth",
|
||||||
&shim_lock_guid,
|
&shim_lock_guid,
|
||||||
&attributes, &auth_size, auth);
|
&attributes, &auth_size, auth);
|
||||||
|
|
||||||
if ((efi_status == EFI_SUCCESS) && (auth_size == SHA256_DIGEST_SIZE))
|
if ((efi_status == EFI_SUCCESS) &&
|
||||||
|
(auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE))
|
||||||
MokDelAuth = 1;
|
MokDelAuth = 1;
|
||||||
|
|
||||||
if (MokNew || MokAuth)
|
if (MokNew || MokAuth)
|
||||||
|
124
PasswordCrypt.c
Normal file
124
PasswordCrypt.c
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
#include <efi.h>
|
||||||
|
#include <efilib.h>
|
||||||
|
#include <Library/BaseCryptLib.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
#include "PasswordCrypt.h"
|
||||||
|
|
||||||
|
static EFI_STATUS sha256_crypt (const char *key, UINT32 key_len,
|
||||||
|
const char *salt, UINT32 salt_size,
|
||||||
|
const UINT32 rounds, UINT8 *hash)
|
||||||
|
{
|
||||||
|
SHA256_CTX ctx, alt_ctx;
|
||||||
|
UINT8 alt_result[SHA256_DIGEST_SIZE];
|
||||||
|
UINT8 tmp_result[SHA256_DIGEST_SIZE];
|
||||||
|
UINT8 *cp, *p_bytes, *s_bytes;
|
||||||
|
UINTN cnt;
|
||||||
|
|
||||||
|
SHA256_Init(&ctx);
|
||||||
|
SHA256_Update(&ctx, key, key_len);
|
||||||
|
SHA256_Update(&ctx, salt, salt_size);
|
||||||
|
|
||||||
|
SHA256_Init(&alt_ctx);
|
||||||
|
SHA256_Update(&alt_ctx, key, key_len);
|
||||||
|
SHA256_Update(&alt_ctx, salt, salt_size);
|
||||||
|
SHA256_Update(&alt_ctx, key, key_len);
|
||||||
|
SHA256_Final(alt_result, &alt_ctx);
|
||||||
|
|
||||||
|
for (cnt = key_len; cnt > 32; cnt -= 32)
|
||||||
|
SHA256_Update(&ctx, alt_result, 32);
|
||||||
|
SHA256_Update(&ctx, alt_result, cnt);
|
||||||
|
|
||||||
|
for (cnt = key_len; cnt > 0; cnt >>= 1) {
|
||||||
|
if ((cnt & 1) != 0) {
|
||||||
|
SHA256_Update(&ctx, alt_result, 32);
|
||||||
|
} else {
|
||||||
|
SHA256_Update(&ctx, key, key_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SHA256_Final(alt_result, &ctx);
|
||||||
|
|
||||||
|
SHA256_Init(&alt_ctx);
|
||||||
|
for (cnt = 0; cnt < key_len; ++cnt)
|
||||||
|
SHA256_Update(&alt_ctx, key, key_len);
|
||||||
|
SHA256_Final(tmp_result, &alt_ctx);
|
||||||
|
|
||||||
|
cp = p_bytes = AllocatePool(key_len);
|
||||||
|
for (cnt = key_len; cnt >= 32; cnt -= 32) {
|
||||||
|
CopyMem(cp, tmp_result, 32);
|
||||||
|
cp += 32;
|
||||||
|
}
|
||||||
|
CopyMem(cp, tmp_result, cnt);
|
||||||
|
|
||||||
|
SHA256_Init(&alt_ctx);
|
||||||
|
for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
|
||||||
|
SHA256_Update(&alt_ctx, salt, salt_size);
|
||||||
|
SHA256_Final(tmp_result, &alt_ctx);
|
||||||
|
|
||||||
|
cp = s_bytes = AllocatePool(salt_size);
|
||||||
|
for (cnt = salt_size; cnt >= 32; cnt -= 32) {
|
||||||
|
CopyMem(cp, tmp_result, 32);
|
||||||
|
cp += 32;
|
||||||
|
}
|
||||||
|
CopyMem(cp, tmp_result, cnt);
|
||||||
|
|
||||||
|
for (cnt = 0; cnt < rounds; ++cnt) {
|
||||||
|
SHA256_Init(&ctx);
|
||||||
|
|
||||||
|
if ((cnt & 1) != 0)
|
||||||
|
SHA256_Update(&ctx, p_bytes, key_len);
|
||||||
|
else
|
||||||
|
SHA256_Update(&ctx, alt_result, 32);
|
||||||
|
|
||||||
|
if (cnt % 3 != 0)
|
||||||
|
SHA256_Update(&ctx, s_bytes, salt_size);
|
||||||
|
|
||||||
|
if (cnt % 7 != 0)
|
||||||
|
SHA256_Update(&ctx, p_bytes, key_len);
|
||||||
|
|
||||||
|
if ((cnt & 1) != 0)
|
||||||
|
SHA256_Update(&ctx, alt_result, 32);
|
||||||
|
else
|
||||||
|
SHA256_Update(&ctx, p_bytes, key_len);
|
||||||
|
|
||||||
|
SHA256_Final(alt_result, &ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem(hash, alt_result, SHA256_DIGEST_SIZE);
|
||||||
|
|
||||||
|
FreePool(p_bytes);
|
||||||
|
FreePool(s_bytes);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS password_crypt (const char *password, UINT32 pw_length,
|
||||||
|
const PASSWORD_CRYPT *pw_crypt, UINT8 *hash)
|
||||||
|
{
|
||||||
|
EFI_STATUS status;
|
||||||
|
|
||||||
|
if (!pw_crypt)
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
switch (pw_crypt->method) {
|
||||||
|
case TRANDITIONAL_DES:
|
||||||
|
case EXTEND_BSDI_DES:
|
||||||
|
case MD5_BASED:
|
||||||
|
/* TODO unsupported */
|
||||||
|
status = EFI_UNSUPPORTED;
|
||||||
|
break;
|
||||||
|
case SHA256_BASED:
|
||||||
|
status = sha256_crypt(password, pw_length, (char *)pw_crypt->salt,
|
||||||
|
pw_crypt->salt_size, pw_crypt->iter_count,
|
||||||
|
hash);
|
||||||
|
break;
|
||||||
|
case SHA512_BASED:
|
||||||
|
case BLOWFISH_BASED:
|
||||||
|
/* TODO unsupported */
|
||||||
|
status = EFI_UNSUPPORTED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
26
PasswordCrypt.h
Normal file
26
PasswordCrypt.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef __PASSWORD_CRYPT_H__
|
||||||
|
#define __PASSWORD_CRYPT_H__
|
||||||
|
|
||||||
|
enum HashMethod {
|
||||||
|
TRANDITIONAL_DES = 0,
|
||||||
|
EXTEND_BSDI_DES,
|
||||||
|
MD5_BASED,
|
||||||
|
SHA256_BASED,
|
||||||
|
SHA512_BASED,
|
||||||
|
BLOWFISH_BASED
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UINT16 method;
|
||||||
|
UINT64 iter_count;
|
||||||
|
UINT16 salt_size;
|
||||||
|
UINT8 salt[32];
|
||||||
|
UINT8 hash[128];
|
||||||
|
} __attribute__ ((packed)) PASSWORD_CRYPT;
|
||||||
|
|
||||||
|
#define PASSWORD_CRYPT_SIZE sizeof(PASSWORD_CRYPT)
|
||||||
|
|
||||||
|
EFI_STATUS password_crypt (const char *password, UINT32 pw_length,
|
||||||
|
const PASSWORD_CRYPT *pw_hash, UINT8 *hash);
|
||||||
|
|
||||||
|
#endif /* __PASSWORD_CRYPT_H__ */
|
Loading…
Reference in New Issue
Block a user