mirror of
https://git.proxmox.com/git/efi-boot-shim
synced 2025-07-09 19:21:12 +00:00
Use the machine owner keys to verify images
This commit is contained in:
parent
333bd97743
commit
1342297309
94
shim.c
94
shim.c
@ -60,6 +60,11 @@ typedef enum {
|
|||||||
VAR_NOT_FOUND
|
VAR_NOT_FOUND
|
||||||
} CHECK_STATUS;
|
} CHECK_STATUS;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UINT32 MokSize;
|
||||||
|
UINT8 *Mok;
|
||||||
|
} MokListNode;
|
||||||
|
|
||||||
static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes,
|
static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes,
|
||||||
UINTN *size, void **buffer)
|
UINTN *size, void **buffer)
|
||||||
{
|
{
|
||||||
@ -97,6 +102,37 @@ static EFI_STATUS delete_variable (CHAR16 *name, EFI_GUID guid)
|
|||||||
return efi_status;
|
return efi_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
|
||||||
|
MokListNode *list;
|
||||||
|
int i, remain = DataSize;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
list = AllocatePool(sizeof(MokListNode) * num);
|
||||||
|
|
||||||
|
if (!list) {
|
||||||
|
Print(L"Unable to allocate MOK list\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = Data;
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
if (remain < 0) {
|
||||||
|
Print(L"MOK list was corrupted\n");
|
||||||
|
FreePool(list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem(&list[i].MokSize, ptr, sizeof(UINT32));
|
||||||
|
ptr += sizeof(UINT32);
|
||||||
|
list[i].Mok = ptr;
|
||||||
|
ptr += list[i].MokSize;
|
||||||
|
|
||||||
|
remain -= sizeof(UINT32) + list[i].MokSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform basic bounds checking of the intra-image pointers
|
* Perform basic bounds checking of the intra-image pointers
|
||||||
*/
|
*/
|
||||||
@ -373,6 +409,7 @@ static BOOLEAN secure_mode (void)
|
|||||||
static EFI_STATUS verify_buffer (char *data, int datasize,
|
static EFI_STATUS verify_buffer (char *data, int datasize,
|
||||||
PE_COFF_LOADER_IMAGE_CONTEXT *context, int whitelist)
|
PE_COFF_LOADER_IMAGE_CONTEXT *context, int whitelist)
|
||||||
{
|
{
|
||||||
|
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||||||
unsigned int size = datasize;
|
unsigned int size = datasize;
|
||||||
unsigned int ctxsize;
|
unsigned int ctxsize;
|
||||||
void *ctx = NULL;
|
void *ctx = NULL;
|
||||||
@ -386,6 +423,11 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
|||||||
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;
|
||||||
|
void *MokListData = NULL;
|
||||||
|
UINTN MokListDataSize = 0;
|
||||||
|
UINT32 MokNum, attributes;
|
||||||
|
MokListNode *list = NULL;
|
||||||
|
|
||||||
cert = ImageAddress (data, size, context->SecDir->VirtualAddress);
|
cert = ImageAddress (data, size, context->SecDir->VirtualAddress);
|
||||||
|
|
||||||
@ -547,15 +589,59 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AuthenticodeVerify(cert->CertData,
|
if (AuthenticodeVerify(cert->CertData,
|
||||||
context->SecDir->Size - sizeof(cert->Hdr),
|
context->SecDir->Size - sizeof(cert->Hdr),
|
||||||
vendor_cert, vendor_cert_size, hash,
|
vendor_cert, vendor_cert_size, hash,
|
||||||
SHA256_DIGEST_SIZE)) {
|
SHA256_DIGEST_SIZE)) {
|
||||||
|
status = EFI_SUCCESS;
|
||||||
|
Print(L"Binary is verified by the vendor certificate\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = get_variable(L"MokList", shim_lock_guid, &attributes,
|
||||||
|
&MokListDataSize, &MokListData);
|
||||||
|
|
||||||
|
if (status != EFI_SUCCESS) {
|
||||||
|
status = EFI_ACCESS_DENIED;
|
||||||
|
Print(L"Invalid signature\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
|
||||||
|
Print(L"MokList is compromised!\nErase all keys in MokList!\n");
|
||||||
|
if (delete_variable(L"MokList", shim_lock_guid) != EFI_SUCCESS) {
|
||||||
|
Print(L"Failed to erase MokList\n");
|
||||||
|
}
|
||||||
|
status = EFI_ACCESS_DENIED;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem(&MokNum, MokListData, sizeof(UINT32));
|
||||||
|
if (MokNum == 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
list = build_mok_list(MokNum,
|
||||||
|
(void *)MokListData + sizeof(UINT32),
|
||||||
|
MokListDataSize - sizeof(UINT32));
|
||||||
|
|
||||||
|
if (!list) {
|
||||||
|
Print(L"Failed to construct MOK list\n");
|
||||||
|
status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MokNum; i++) {
|
||||||
|
if (AuthenticodeVerify(cert->CertData,
|
||||||
|
context->SecDir->Size - sizeof(cert->Hdr),
|
||||||
|
list[i].Mok, list[i].MokSize, hash,
|
||||||
|
SHA256_DIGEST_SIZE)) {
|
||||||
|
status = EFI_SUCCESS;
|
||||||
|
Print(L"Binary is verified by the machine owner key\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
Print(L"Invalid signature\n");
|
Print(L"Invalid signature\n");
|
||||||
status = EFI_ACCESS_DENIED;
|
status = EFI_ACCESS_DENIED;
|
||||||
} else {
|
|
||||||
status = EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (SectionHeader)
|
if (SectionHeader)
|
||||||
|
Loading…
Reference in New Issue
Block a user