On 5/15/26 15:31, Ilias Apalodimas wrote:
On Fri, 15 May 2026 at 16:17, Aswin Murugan
<[email protected]> wrote:
Hi Ilias,
This change has been verified locally with our setups on qcs615 &
QCS9100 SOCs
Alright, I'll have another look in case I missed something.
Thanks
/Ilias
Regards,
Aswin
On 5/15/2026 4:02 PM, Ilias Apalodimas wrote:
Hi Ashwin,
On Thu, 14 May 2026 at 20:17, Aswin Murugan
<[email protected]> wrote:
efivar.py currently stores authenticated variables including the
EFI_VARIABLE_AUTHENTICATION_2 descriptor (timestamp + WIN_CERTIFICATE)
along with the payload.
When variables are set via U-Boot, SetVariable() validates and strips
this authentication descriptor before persisting the variable data,
resulting in only the payload being stored and returned by GetVariable().
This mismatch causes efivar.py-generated stores to differ from U-Boot
runtime behavior and leads to incorrect GetVariable() results.
Update efivar.py to strip the authentication descriptor and store only
the payload for authenticated variables, ensuring consistency with
U-Boot behavior and compliance with UEFI expectations.
The approach is fine, but when I use the tool now to create signatures
and enable secure boot I am getting
=> bootefi bootmgr
Getting signature database(db) failed"
Have you tried a built that worked locally?
Thanks
/Ilias
Signed-off-by: Aswin Murugan <[email protected]>
---
Changes in v3:
- Previously stripped the authentication descriptor at GetVariable(),
now moved to strip it in efivar.py during variable pre-seeding/set.
Link to v2:
https://lore.kernel.org/u-boot/[email protected]/
Changes in v2:
- Enhanced commit message with explicit UEFI spec reference
Link to v1:
https://lore.kernel.org/u-boot/[email protected]/
---
tools/efivar.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/tools/efivar.py b/tools/efivar.py
index 67729fa8505..d248cd868ba 100755
--- a/tools/efivar.py
+++ b/tools/efivar.py
@@ -79,6 +79,50 @@ class EfiVariable:
def calc_crc32(buf):
return zlib.crc32(buf) & 0xffffffff
+def strip_auth_descriptor(data, attrs):
+ """
+ Strip the EFI auth descriptor from authenticated variable data.
+
+ This is used during efivar.py-based pre-seeding of ubootefi.var to
+ match U-Boot SetVariable() behavior, where the authentication header
+ is consumed during validation and only the payload is stored.
+
+ For variables with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS:
+ - Input format: [EFI_VARIABLE_AUTHENTICATION_2 | payload]
+ - Stored format: [payload only]
+
+ Auth header size calculation (aligned with U-Boot
efi_variable_authenticate()):
+ auth_size = sizeof(EFI_TIME) + WIN_CERTIFICATE.dwLength
+
+ Only the payload portion is retained after stripping the header.
+ """
+ if not (attrs & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS):
+ return data
+ if not data:
+ return data
+
+ efi = EfiStruct()
+ if len(data) < efi.var_time_size:
+ return data
+
+ offset = efi.var_time_size
+ if len(data) < offset + efi.var_win_cert_size:
+ return data
+
+ try:
+ cert_hdr = struct.unpack_from(efi.var_win_cert_fmt, data, offset)
+ dwLength = cert_hdr[0]
+ except struct.error:
+ return data
+
+ auth_size = efi.var_time_size + dwLength
+ if auth_size <= 0 or auth_size > len(data):
+ return data
+
+ if len(data) <= auth_size:
+ return b''
+ return data[auth_size:]
+
class EfiVariableStore:
def __init__(self, infile):
self.infile = infile
@@ -172,8 +216,12 @@ class EfiVariableStore:
break
offs = loffs
+ if data and (attrs &
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS):
+ data = strip_auth_descriptor(data, attrs)
+ size = len(data) if data else 0
+
tsec = int(time.time()) if attrs &
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS else 0
- nd = name.encode('utf_16_le') + b"\x00\x00" + data
+ nd = name.encode('utf_16_le') + b"\x00\x00" + (data if data else b'')
The EFI specification for SetVariable() has:
"A variable must contain one or more bytes of Data."
We should throw an error if data is empty (possibly after stripping an
authentication header).
Best regards
Heinrich
# U-Boot variable format requires the name + data blob to be 8-byte
aligned
pad = ((len(nd) + 7) & ~7) - len(nd)
nd += bytes([0] * pad)
--
2.34.1