mirror of
https://git.proxmox.com/git/efi-boot-shim
synced 2025-05-29 19:00:57 +00:00
Split out hashing
We want to be able to generate hashes, so split out the hash generation function from the verification function
This commit is contained in:
parent
7fa4dae051
commit
f394b22e86
108
shim.c
108
shim.c
@ -406,46 +406,25 @@ static BOOLEAN secure_mode (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that the signature is valid and matches the binary
|
* Calculate the SHA1 and SHA256 hashes of a binary
|
||||||
*/
|
*/
|
||||||
static EFI_STATUS verify_buffer (char *data, int datasize,
|
|
||||||
PE_COFF_LOADER_IMAGE_CONTEXT *context, int whitelist)
|
static EFI_STATUS generate_hash (char *data, int datasize,
|
||||||
|
PE_COFF_LOADER_IMAGE_CONTEXT *context,
|
||||||
|
UINT8 *sha256hash, UINT8 *sha1hash)
|
||||||
|
|
||||||
{
|
{
|
||||||
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
|
||||||
unsigned int size = datasize;
|
|
||||||
unsigned int sha256ctxsize, sha1ctxsize;
|
unsigned int sha256ctxsize, sha1ctxsize;
|
||||||
|
unsigned int size = datasize;
|
||||||
void *sha256ctx = NULL, *sha1ctx = NULL;
|
void *sha256ctx = NULL, *sha1ctx = NULL;
|
||||||
UINT8 sha256hash[SHA256_DIGEST_SIZE];
|
|
||||||
UINT8 sha1hash[SHA1_DIGEST_SIZE];
|
|
||||||
EFI_STATUS status = EFI_ACCESS_DENIED;
|
|
||||||
char *hashbase;
|
char *hashbase;
|
||||||
unsigned int hashsize;
|
unsigned int hashsize;
|
||||||
WIN_CERTIFICATE_EFI_PKCS *cert;
|
|
||||||
unsigned int SumOfBytesHashed, SumOfSectionBytes;
|
unsigned int SumOfBytesHashed, SumOfSectionBytes;
|
||||||
unsigned int index, pos;
|
unsigned int index, pos;
|
||||||
EFI_IMAGE_SECTION_HEADER *Section;
|
EFI_IMAGE_SECTION_HEADER *Section;
|
||||||
EFI_IMAGE_SECTION_HEADER *SectionHeader = NULL;
|
EFI_IMAGE_SECTION_HEADER *SectionHeader = NULL;
|
||||||
EFI_IMAGE_SECTION_HEADER *SectionCache;
|
EFI_IMAGE_SECTION_HEADER *SectionCache;
|
||||||
unsigned int i;
|
EFI_STATUS status = EFI_SUCCESS;
|
||||||
void *MokListData = NULL;
|
|
||||||
UINTN MokListDataSize = 0;
|
|
||||||
UINT32 MokNum, attributes;
|
|
||||||
MokListNode *list = NULL;
|
|
||||||
|
|
||||||
cert = ImageAddress (data, size, context->SecDir->VirtualAddress);
|
|
||||||
|
|
||||||
if (!cert) {
|
|
||||||
Print(L"Certificate located outside the image\n");
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cert->Hdr.wCertificateType != WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
|
|
||||||
Print(L"Unsupported certificate type %x\n",
|
|
||||||
cert->Hdr.wCertificateType);
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: Check which kind of hash */
|
|
||||||
|
|
||||||
sha256ctxsize = Sha256GetContextSize();
|
sha256ctxsize = Sha256GetContextSize();
|
||||||
sha256ctx = AllocatePool(sha256ctxsize);
|
sha256ctx = AllocatePool(sha256ctxsize);
|
||||||
@ -585,11 +564,58 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (SectionHeader)
|
||||||
|
FreePool(SectionHeader);
|
||||||
|
if (sha1ctx)
|
||||||
|
FreePool(sha1ctx);
|
||||||
|
if (sha256ctx)
|
||||||
|
FreePool(sha256ctx);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that the signature is valid and matches the binary
|
||||||
|
*/
|
||||||
|
static EFI_STATUS verify_buffer (char *data, int datasize,
|
||||||
|
PE_COFF_LOADER_IMAGE_CONTEXT *context, int whitelist)
|
||||||
|
{
|
||||||
|
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||||||
|
UINT8 sha256hash[SHA256_DIGEST_SIZE];
|
||||||
|
UINT8 sha1hash[SHA1_DIGEST_SIZE];
|
||||||
|
EFI_STATUS status = EFI_ACCESS_DENIED;
|
||||||
|
WIN_CERTIFICATE_EFI_PKCS *cert;
|
||||||
|
void *MokListData = NULL;
|
||||||
|
UINTN MokListDataSize = 0;
|
||||||
|
UINT32 MokNum, attributes;
|
||||||
|
MokListNode *list = NULL;
|
||||||
|
unsigned int i;
|
||||||
|
unsigned int size = datasize;
|
||||||
|
|
||||||
|
cert = ImageAddress (data, size, context->SecDir->VirtualAddress);
|
||||||
|
|
||||||
|
if (!cert) {
|
||||||
|
Print(L"Certificate located outside the image\n");
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cert->Hdr.wCertificateType != WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
|
||||||
|
Print(L"Unsupported certificate type %x\n",
|
||||||
|
cert->Hdr.wCertificateType);
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = generate_hash(data, datasize, context, sha256hash, sha1hash);
|
||||||
|
|
||||||
|
if (status != EFI_SUCCESS)
|
||||||
|
return status;
|
||||||
|
|
||||||
status = check_blacklist(cert, sha256hash, sha1hash);
|
status = check_blacklist(cert, sha256hash, sha1hash);
|
||||||
|
|
||||||
if (status != EFI_SUCCESS) {
|
if (status != EFI_SUCCESS) {
|
||||||
Print(L"Binary is blacklisted\n");
|
Print(L"Binary is blacklisted\n");
|
||||||
goto done;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (whitelist) {
|
if (whitelist) {
|
||||||
@ -597,7 +623,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
|||||||
|
|
||||||
if (status == EFI_SUCCESS) {
|
if (status == EFI_SUCCESS) {
|
||||||
Print(L"Binary is whitelisted\n");
|
Print(L"Binary is whitelisted\n");
|
||||||
goto done;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,7 +633,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
|||||||
SHA256_DIGEST_SIZE)) {
|
SHA256_DIGEST_SIZE)) {
|
||||||
status = EFI_SUCCESS;
|
status = EFI_SUCCESS;
|
||||||
Print(L"Binary is verified by the vendor certificate\n");
|
Print(L"Binary is verified by the vendor certificate\n");
|
||||||
goto done;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = get_variable(L"MokList", shim_lock_guid, &attributes,
|
status = get_variable(L"MokList", shim_lock_guid, &attributes,
|
||||||
@ -616,7 +642,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
|||||||
if (status != EFI_SUCCESS || MokListDataSize < sizeof(UINT32)) {
|
if (status != EFI_SUCCESS || MokListDataSize < sizeof(UINT32)) {
|
||||||
status = EFI_ACCESS_DENIED;
|
status = EFI_ACCESS_DENIED;
|
||||||
Print(L"Invalid signature\n");
|
Print(L"Invalid signature\n");
|
||||||
goto done;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
|
if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
|
||||||
@ -625,13 +651,13 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
|||||||
Print(L"Failed to erase MokList\n");
|
Print(L"Failed to erase MokList\n");
|
||||||
}
|
}
|
||||||
status = EFI_ACCESS_DENIED;
|
status = EFI_ACCESS_DENIED;
|
||||||
goto done;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyMem(&MokNum, MokListData, sizeof(UINT32));
|
CopyMem(&MokNum, MokListData, sizeof(UINT32));
|
||||||
if (MokNum == 0) {
|
if (MokNum == 0) {
|
||||||
status = EFI_ACCESS_DENIED;
|
status = EFI_ACCESS_DENIED;
|
||||||
goto done;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
list = build_mok_list(MokNum,
|
list = build_mok_list(MokNum,
|
||||||
@ -641,7 +667,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
|||||||
if (!list) {
|
if (!list) {
|
||||||
Print(L"Failed to construct MOK list\n");
|
Print(L"Failed to construct MOK list\n");
|
||||||
status = EFI_OUT_OF_RESOURCES;
|
status = EFI_OUT_OF_RESOURCES;
|
||||||
goto done;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MokNum; i++) {
|
for (i = 0; i < MokNum; i++) {
|
||||||
@ -651,20 +677,12 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
|||||||
SHA256_DIGEST_SIZE)) {
|
SHA256_DIGEST_SIZE)) {
|
||||||
status = EFI_SUCCESS;
|
status = EFI_SUCCESS;
|
||||||
Print(L"Binary is verified by the machine owner key\n");
|
Print(L"Binary is verified by the machine owner key\n");
|
||||||
goto done;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Print(L"Invalid signature\n");
|
Print(L"Invalid signature\n");
|
||||||
status = EFI_ACCESS_DENIED;
|
status = EFI_ACCESS_DENIED;
|
||||||
|
|
||||||
done:
|
|
||||||
if (SectionHeader)
|
|
||||||
FreePool(SectionHeader);
|
|
||||||
if (sha1ctx)
|
|
||||||
FreePool(sha1ctx);
|
|
||||||
if (sha256ctx)
|
|
||||||
FreePool(sha256ctx);
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user