From dd3a5d71252a1f94e37f1a4c8841d253630b305a Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 23 Jul 2020 12:36:56 -0400 Subject: Add support for vendor_db built-in shim authorized list. Potential new signing strategies ( for example signing grub, fwupdate and vmlinuz with separate certificates ) require shim to support a vendor provided bundle of trusted certificates and hashes, which allows shim to trust EFI binaries matching either certificate by signature or hash in the vendor_db. Functionality is similar to vendor_dbx. This also improves the mirroring quite a bit. Upstream: pr#206 --- lib/variables.c | 55 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 14 deletions(-) (limited to 'lib/variables.c') diff --git a/lib/variables.c b/lib/variables.c index 9c2e7d0a..8123ae60 100644 --- a/lib/variables.c +++ b/lib/variables.c @@ -25,32 +25,59 @@ #include "shim.h" EFI_STATUS -variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner, - void **out, int *outlen) +fill_esl(const uint8_t *data, const size_t data_len, + const EFI_GUID *type, const EFI_GUID *owner, + uint8_t *out, size_t *outlen) { - *outlen = cert_len + sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID); + EFI_SIGNATURE_LIST *sl; + EFI_SIGNATURE_DATA *sd; + size_t needed = 0; - *out = AllocateZeroPool(*outlen); - if (!*out) - return EFI_OUT_OF_RESOURCES; + if (!data || !data_len || !type || !outlen) + return EFI_INVALID_PARAMETER; + + needed = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID) + data_len; + if (!out || *outlen < needed) { + *outlen = needed; + return EFI_BUFFER_TOO_SMALL; + } - EFI_SIGNATURE_LIST *sl = *out; + *outlen = needed; + sl = (EFI_SIGNATURE_LIST *)out; sl->SignatureHeaderSize = 0; sl->SignatureType = *type; - sl->SignatureSize = cert_len + sizeof(EFI_GUID); - sl->SignatureListSize = *outlen; - - EFI_SIGNATURE_DATA *sd = *out + sizeof(EFI_SIGNATURE_LIST); + sl->SignatureSize = sizeof(EFI_GUID) + data_len; + sl->SignatureListSize = needed; + sd = (EFI_SIGNATURE_DATA *)(out + sizeof(EFI_SIGNATURE_LIST)); if (owner) sd->SignatureOwner = *owner; - CopyMem(sd->SignatureData, cert, cert_len); + CopyMem(sd->SignatureData, data, data_len); return EFI_SUCCESS; } +EFI_STATUS +variable_create_esl(const uint8_t *data, const size_t data_len, + const EFI_GUID *type, const EFI_GUID *owner, + uint8_t **out, size_t *outlen) +{ + EFI_STATUS efi_status; + + *outlen = 0; + efi_status = fill_esl(data, data_len, type, owner, NULL, outlen); + if (efi_status != EFI_BUFFER_TOO_SMALL) + return efi_status; + + *out = AllocateZeroPool(*outlen); + if (!*out) + return EFI_OUT_OF_RESOURCES; + + return fill_esl(data, data_len, type, owner, *out, outlen); +} + EFI_STATUS CreateTimeBasedPayload(IN OUT UINTN * DataSize, IN OUT UINT8 ** Data) { @@ -137,9 +164,9 @@ SetSecureVariable(CHAR16 *var, UINT8 *Data, UINTN len, EFI_GUID owner, return EFI_SECURITY_VIOLATION; if (createtimebased) { - int ds; + size_t ds; efi_status = variable_create_esl(Data, len, &X509_GUID, NULL, - (void **)&Cert, &ds); + (uint8_t **)&Cert, &ds); if (EFI_ERROR(efi_status)) { console_print(L"Failed to create %s certificate %d\n", var, efi_status); -- cgit v1.2.3