| diff --git a/mok.c b/mok.c |
| index 3867521..2b081f5 100644 |
| --- a/mok.c |
| +++ b/mok.c |
| @@ -79,6 +79,7 @@ struct mok_state_variable { |
| #define MOK_MIRROR_DELETE_FIRST 0x02 |
| #define MOK_VARIABLE_MEASURE 0x04 |
| #define MOK_VARIABLE_LOG 0x08 |
| +#define MOK_USE_BUILTIN 0x10 |
| |
| struct mok_state_variable mok_state_variables[] = { |
| {.name = L"MokList", |
| @@ -91,7 +92,8 @@ struct mok_state_variable mok_state_variables[] = { |
| .addend_source = &vendor_cert, |
| .addend_size = &vendor_cert_size, |
| .flags = MOK_MIRROR_KEYDB | |
| - MOK_VARIABLE_LOG, |
| + MOK_VARIABLE_LOG | |
| + MOK_USE_BUILTIN, |
| .pcr = 14, |
| }, |
| {.name = L"MokListX", |
| @@ -130,6 +132,63 @@ struct mok_state_variable mok_state_variables[] = { |
| { NULL, } |
| }; |
| |
| + |
| +static EFI_STATUS builtin_one_mok_variable(struct mok_state_variable *v) |
| +{ |
| + EFI_STATUS efi_status = EFI_SUCCESS; |
| + void *FullData = NULL; |
| + UINTN FullDataSize = 0; |
| + uint8_t *p = NULL; |
| + |
| + if ((v->flags & MOK_MIRROR_KEYDB) && |
| + v->addend_source && *v->addend_source && |
| + v->addend_size && *v->addend_size) { |
| + EFI_SIGNATURE_LIST *CertList = NULL; |
| + EFI_SIGNATURE_DATA *CertData = NULL; |
| + FullDataSize = sizeof (*CertList) |
| + + sizeof (EFI_GUID) |
| + + *v->addend_size; |
| + FullData = AllocatePool(FullDataSize); |
| + if (!FullData) { |
| + perror(L"Failed to allocate space for MokListRT\n"); |
| + return EFI_OUT_OF_RESOURCES; |
| + } |
| + p = FullData; |
| + |
| + CertList = (EFI_SIGNATURE_LIST *)p; |
| + p += sizeof (*CertList); |
| + CertData = (EFI_SIGNATURE_DATA *)p; |
| + p += sizeof (EFI_GUID); |
| + |
| + CertList->SignatureType = EFI_CERT_TYPE_X509_GUID; |
| + CertList->SignatureListSize = *v->addend_size |
| + + sizeof (*CertList) |
| + + sizeof (*CertData) |
| + -1; |
| + CertList->SignatureHeaderSize = 0; |
| + CertList->SignatureSize = *v->addend_size + sizeof (EFI_GUID); |
| + |
| + CertData->SignatureOwner = SHIM_LOCK_GUID; |
| + CopyMem(p, *v->addend_source, *v->addend_size); |
| + } else if (v->state) { |
| + FullDataSize = sizeof (UINT8); |
| + FullData = v->state; |
| + } |
| + |
| + if (FullDataSize) { |
| + efi_status = gRT->SetVariable(v->rtname, v->guid, |
| + EFI_VARIABLE_BOOTSERVICE_ACCESS | |
| + EFI_VARIABLE_RUNTIME_ACCESS, |
| + FullDataSize, FullData); |
| + if (EFI_ERROR(efi_status)) { |
| + perror(L"Failed to set %s: %r\n", |
| + v->rtname, efi_status); |
| + } |
| + } |
| + |
| + return efi_status; |
| +} |
| + |
| static EFI_STATUS mirror_one_mok_variable(struct mok_state_variable *v) |
| { |
| EFI_STATUS efi_status = EFI_SUCCESS; |
| @@ -226,8 +285,16 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle) |
| efi_status = get_variable_attr(v->name, |
| &v->data, &v->data_size, |
| *v->guid, &attrs); |
| - if (efi_status == EFI_NOT_FOUND) |
| + if (efi_status == EFI_NOT_FOUND) { |
| + if (v->flags & MOK_USE_BUILTIN) { |
| + efi_status = builtin_one_mok_variable(v); |
| + if (EFI_ERROR(efi_status) && |
| + ret != EFI_SECURITY_VIOLATION) |
| + ret = efi_status; |
| + } |
| continue; |
| + } |
| + |
| if (EFI_ERROR(efi_status)) { |
| perror(L"Could not verify %s: %r\n", v->name, |
| efi_status); |