[PATCH v3] tools: efivar: strip auth descriptor for authenticated variables

Aswin Murugan aswin.murugan at oss.qualcomm.com
Thu May 21 20:31:47 CEST 2026


Hi Ilias

On 5/18/2026 2:07 PM, Ilias Apalodimas wrote:
> On Fri, 15 May 2026 at 16:17, Aswin Murugan
> <aswin.murugan at oss.qualcomm.com> wrote:
>> Hi Ilias,
>>
>> This change has been verified locally with our setups on qcs615 &
>> QCS9100 SOCs
> Ok I am getting the same error here. How did you produce the final binary?
>
> The only test I am doing here is enable secure boot and variable
> preseed. The generate the preseed with
>
> ./tools/efivar.py set -i ubootefi.var -n pk  -d PK.esl  -t file
> ./tools/efivar.py set -i ubootefi.var -n kek -d KEK.esl -t file
> ./tools/efivar.py set -i ubootefi.var -n db  -d db.esl  -t file
> ./tools/efivar.py set -i ubootefi.var -n dbx -d dbx.esl -t file

Similar steps are followed but instead of .esl we pass .auth file to 
efivar tool and sign the kernel using sbsign

tools/efivar.py set --infile ubootefi.var --name PK --attrs nv,bs,rt,at 
--type file --data PK.auth

tools/efivar.py set --infile ubootefi.var --name KEK --attrs nv,bs,rt,at 
--type file --data KEK.auth

tools/efivar.py set --infile ubootefi.var --name db --attrs nv,bs,rt,at 
--type file --data db.auth

tools/efivar.py set --infile ubootefi.var --name dbx --attrs nv,bs,rt,at 
--type file --data dbx.auth

*sign the images to be verified *

sbsign --key db.key --cert db.crt bootaa64.efi --output bootaa64.efi

sbsign --key db.key --cert db.crt linux-iq-9075-evk.efi --output 
linux-iq-9075-evk.efi

Regards,
Aswin M

>
> 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
>>> <aswin.murugan at oss.qualcomm.com> 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 <aswin.murugan at oss.qualcomm.com>
>>>> ---
>>>> 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/20260512194205.1905069-1-aswin.murugan@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/
>>>> ---
>>>>    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'')
>>>>            # 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
>>>>


More information about the U-Boot mailing list