summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_variable.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/efi_loader/efi_variable.c')
-rw-r--r--lib/efi_loader/efi_variable.c93
1 files changed, 4 insertions, 89 deletions
diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index 0c689cfb47..ba0874e9e7 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -24,91 +24,6 @@
#include <asm/sections.h>
#ifdef CONFIG_EFI_SECURE_BOOT
-static u8 pkcs7_hdr[] = {
- /* SEQUENCE */
- 0x30, 0x82, 0x05, 0xc7,
- /* OID: pkcs7-signedData */
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02,
- /* Context Structured? */
- 0xa0, 0x82, 0x05, 0xb8,
-};
-
-/**
- * efi_variable_parse_signature - parse a signature in variable
- * @buf: Pointer to variable's value
- * @buflen: Length of @buf
- * @tmpbuf: Pointer to temporary buffer
- *
- * Parse a signature embedded in variable's value and instantiate
- * a pkcs7_message structure. Since pkcs7_parse_message() accepts only
- * pkcs7's signedData, some header needed be prepended for correctly
- * parsing authentication data, particularly for variable's.
- * A temporary buffer will be allocated if needed, and it should be
- * kept valid during the authentication because some data in the buffer
- * will be referenced by efi_signature_verify().
- *
- * Return: Pointer to pkcs7_message structure on success, NULL on error
- */
-static struct pkcs7_message *efi_variable_parse_signature(const void *buf,
- size_t buflen,
- u8 **tmpbuf)
-{
- u8 *ebuf;
- size_t ebuflen, len;
- struct pkcs7_message *msg;
-
- /*
- * This is the best assumption to check if the binary is
- * already in a form of pkcs7's signedData.
- */
- if (buflen > sizeof(pkcs7_hdr) &&
- !memcmp(&((u8 *)buf)[4], &pkcs7_hdr[4], 11)) {
- msg = pkcs7_parse_message(buf, buflen);
- if (IS_ERR(msg))
- return NULL;
- return msg;
- }
-
- /*
- * Otherwise, we should add a dummy prefix sequence for pkcs7
- * message parser to be able to process.
- * NOTE: EDK2 also uses similar hack in WrapPkcs7Data()
- * in CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c
- * TODO:
- * The header should be composed in a more refined manner.
- */
- EFI_PRINT("Makeshift prefix added to authentication data\n");
- ebuflen = sizeof(pkcs7_hdr) + buflen;
- if (ebuflen <= 0x7f) {
- EFI_PRINT("Data is too short\n");
- return NULL;
- }
-
- ebuf = malloc(ebuflen);
- if (!ebuf) {
- EFI_PRINT("Out of memory\n");
- return NULL;
- }
-
- memcpy(ebuf, pkcs7_hdr, sizeof(pkcs7_hdr));
- memcpy(ebuf + sizeof(pkcs7_hdr), buf, buflen);
- len = ebuflen - 4;
- ebuf[2] = (len >> 8) & 0xff;
- ebuf[3] = len & 0xff;
- len = ebuflen - 0x13;
- ebuf[0x11] = (len >> 8) & 0xff;
- ebuf[0x12] = len & 0xff;
-
- msg = pkcs7_parse_message(ebuf, ebuflen);
-
- if (IS_ERR(msg)) {
- free(ebuf);
- return NULL;
- }
-
- *tmpbuf = ebuf;
- return msg;
-}
/**
* efi_variable_authenticate - authenticate a variable
@@ -215,10 +130,10 @@ static efi_status_t efi_variable_authenticate(u16 *variable,
goto err;
/* ebuf should be kept valid during the authentication */
- var_sig = efi_variable_parse_signature(auth->auth_info.cert_data,
- auth->auth_info.hdr.dwLength
- - sizeof(auth->auth_info),
- &ebuf);
+ var_sig = efi_parse_pkcs7_header(auth->auth_info.cert_data,
+ auth->auth_info.hdr.dwLength
+ - sizeof(auth->auth_info),
+ &ebuf);
if (!var_sig) {
EFI_PRINT("Parsing variable's signature failed\n");
goto err;