[PATCH v2] efi_loader: Remove authentication header in GetVariable()

Aswin Murugan aswin.murugan at oss.qualcomm.com
Tue May 12 21:42:05 CEST 2026


Currently, efi_get_variable_mem() returns the raw stored format for
authenticated variables, which includes the EFI_VARIABLE_AUTHENTICATION_2
descriptor . This causes image authentication failures when reading
secure boot variables as callers receive wrong data containing
authentication headers instead of the actual variable payload.

The UEFI Specification Section 8.2.6(EFI_VARIABLE_AUTHENTICATION_2 descriptor)
explicitly states:
"The authentication descriptor is not part of the variable data and is
not returned by subsequent calls to GetVariable()."

This patch implements spec-compliant behavior by detecting variables with
the EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute and
stripping the authentication descriptor before returning data to callers.

Signed-off-by: Aswin Murugan <aswin.murugan at oss.qualcomm.com>
---
Changes in v2:
- Enhanced commit message with explicit UEFI spec reference
Link to v1: https://lore.kernel.org/u-boot/20250725123653.513252-1-aswin.murugan@oss.qualcomm.com/
---
 lib/efi_loader/efi_var_mem.c | 44 +++++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 8 deletions(-)

diff --git a/lib/efi_loader/efi_var_mem.c b/lib/efi_loader/efi_var_mem.c
index 8d5f99f4870..edf4522e51f 100644
--- a/lib/efi_loader/efi_var_mem.c
+++ b/lib/efi_loader/efi_var_mem.c
@@ -336,9 +336,10 @@ efi_get_variable_mem(const u16 *variable_name, const efi_guid_t *vendor,
 		     u32 *attributes, efi_uintn_t *data_size, void *data,
 		     u64 *timep, u32 mask)
 {
-	efi_uintn_t old_size;
+	efi_uintn_t old_size, var_data_size;
 	struct efi_var_entry *var;
 	u16 *pdata;
+	void *var_data;
 
 	if (!variable_name || !vendor || !data_size)
 		return EFI_INVALID_PARAMETER;
@@ -362,19 +363,46 @@ efi_get_variable_mem(const u16 *variable_name, const efi_guid_t *vendor,
 	if (!u16_strcmp(variable_name, vtf))
 		return efi_var_collect_mem(data, data_size, EFI_VARIABLE_NON_VOLATILE);
 
+	for (pdata = var->name; *pdata; ++pdata)
+		;
+	++pdata;
+
+	var_data = (void *)pdata;
+	var_data_size = var->length;
+
+	/* Handle EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS */
+	if (var->attr & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
+		if (var_data_size > sizeof(struct efi_time)) {
+			struct efi_time *timestamp;
+			struct win_certificate_uefi_guid *cert;
+			efi_uintn_t auth_size;
+
+			timestamp = (struct efi_time *)var_data;
+			cert = (struct win_certificate_uefi_guid *)(timestamp + 1);
+			auth_size = sizeof(struct efi_time) + cert->hdr.dwLength;
+			if (var_data_size > auth_size) {
+				var_data = (u8 *)var_data + auth_size;
+				var_data_size -= auth_size;
+			}
+		}
+	}
+	/*
+	 * EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS type is old & not
+	 * expected for auth variables
+	 */
+	else if (var->attr & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
+		return EFI_INVALID_PARAMETER;
+
 	old_size = *data_size;
-	*data_size = var->length;
-	if (old_size < var->length)
+	*data_size = var_data_size;
+
+	if (old_size < var_data_size)
 		return EFI_BUFFER_TOO_SMALL;
 
 	if (!data)
 		return EFI_INVALID_PARAMETER;
 
-	for (pdata = var->name; *pdata; ++pdata)
-		;
-	++pdata;
-
-	efi_memcpy_runtime(data, pdata, var->length);
+	efi_memcpy_runtime(data, var_data, var_data_size);
 
 	return EFI_SUCCESS;
 }
-- 
2.34.1



More information about the U-Boot mailing list