Introduction

For anyone who hasn’t read my previous blog post about UEFI vars, I recommend reading that one before this one as this one builds upon the findings of the last one. Though this one should also be readable without having read the last one.

Most of this research was conducted on a ThinkPad E14 G6, originally shipped with Windows now running arch Linux with SystemdBoot and no secure Boot. So a lot of things might differ on your system. Especially if your Motherboard is from a different vendor.

Also, I have been building some tooling to look at UEFI Vars more efficiently. It can be found on my GitHub under python UEFI var explorer. I have also added a UEFI variable list under the resources section of this site. Furthermore, I will try to keep that one up to date, to highlight what variable belongs to what.

GUID’s

While I had very little to say about GUID’s in my last article only speculating that they are consistent across system I have since then been looking more into them.

EFI_GLOBAL_VARIABLE

The EFI_GLOBAL_VARIABLE is the GUID that should be used for all architectural defined variables 1.

#define EFI_GLOBAL_VARIABLE \
 {0x8BE4DF61,0x93CA,0x11d2,\
   {0xAA,0x0D,0x00,0xE0,0x98,0x03,0x2B,0x8C}}

(adapted form for efivars 8be4df61-93ca-11d2-aa0d-00e098032b8c)

At least on my system

  • ConOut
  • ErrOut
  • OsIndications
  • BootOrder
  • Timeout
  • Boot####
  • Key####
  • PK
  • KEK
  • ConIn
  • PlatformLang
  • BootCurrent
  • OsIndicationsSupported
  • ConInDev
  • ErrOutDev
  • ConOutDev
  • PlatformLangCodes
  • BootOptionSupport
  • VendorKeys
  • SecureBoot
  • SignatureSupport
  • SetupMode

On the weird case of DB and DBX

The db and dbx variables are weird they appear in the UEFI spec but not in the global variable table 1. In the spec itself only the default variables are listed but not the ones that are used and are visi<ble to the user.

Variable NameAttributeDescription
dbDefaultBS, RTThe OEM’s default secure boot signature store. Should be treated as read-only.
dbrDefaultBS, RTThe OEM’s default OS Recovery signature store. Should be treated as read-only.
dbtDefaultBS, RTThe OEM’s default secure boot timestamp signature store. Should be treated as read-only.
dbxDefaultBS, RTThe OEM’s default secure boot blacklist signature store. Should be treated as read-only.
Source

But I only noticed this while looking at the GUID sorted output of all my UEFI variables. Because db and dbx had a different GUID than the EFI_GLOBALE_VARIABEL. Which made me look deeper into them.

--------- d719b2cb-3d3a-4596-a3bc-dad00e67656f ---------
dbx - d719b2cb-3d3a-4596-a3bc-dad00e67656f
db - d719b2cb-3d3a-4596-a3bc-dad00e67656f

But it gets weirder they get mentioned multiple times. Though their update policies are specified 2. Looking a bit deeper it appears that since they are not globally defined variables but rather ones that are defined by the variable service whose implementation is not defined in the UEFI Spec 3.

Interesting finds while sorting by GUID

Sorting all the GUID’s on my System lead to some other interesting discovery. Firstly that even if things possibly come from the same company does not mean they share the same GUID’s. One such example would be

LenovoHiddenSetting - 1827cfc7-4e61-4273-b796-d35f4b0c88fc

and

LenovoAbtStatus - 27d37beb-537d-486f-916c-7ba02cff60f4

Both of which as indicated by the name have been added by Lenovo to the UEFI Vars.

Decoding GUID’s

Though the creation time of the variable can be found out via the given GUID’s since they adhere to RFC 4122 4. Interestingly enough some of the times that are encoded in there could be timestamps when this was first rolled out.

One such timestamp where it would make sense would be the EFI_GLOBALE_VARIABEL when decoded gives out the timestamp 1998-12-15 04:02:08.687498 which lines up with the creation of UEFI when it was still called Intel Boot Initiative because that was also in 1998 5.

Most other timestamps don’t make any sense though, the only ones that I found where realistic where :

MTC - eb704011-1402-11d3-8e77-00a0c969723b

of this variable which decoded would leave you in 1999-05-27 09:08:09.636866 which would be in the timeline. Some other variables are in the 1980’s which does not make any sense and seems to be just pure chance. But most of the ones that where available to be decoded did not give out any useful Info.

Digging through the EDKII Reference implementation

Since not everything is defined in the UEFI specification, some deeper research is needed. Thus, a Look into the edkII reference implementation.

GUID’s

The defines for all possible GUID’s can be found in the header files in this directory MdeModulePkg/Include/Guid.

Random Algorithms

There seems to be a UEFI var that is used when using an unsafe RNG Algorithm

///
/// The implementation of a Random Number Generator might be unsafe, when using
/// a dummy implementation for instance. Allow identifying such implementation
/// with this GUID.
///
#define EDKII_RNG_ALGORITHM_UNSAFE \
{ \
0x869f728c, 0x409d, 0x4ab4, {0xac, 0x03, 0x71, 0xd3, 0x09, 0xc1, 0xb3, 0xf4 } \
}
extern EFI_GUID gEdkiiRngAlgorithmUnSafe;

This can be found under MdeModulePkg/Include/Guid/RngAlgorithm.h.

Though looking for occurrences of the specified EFI_GUID was found in following inf file (SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf), that contained the list of possible GUID’s that can be on a system to specify what Algorithms are supported I presume :


[Guids]
  gEfiRngAlgorithmSp80090Hash256Guid  ## SOMETIMES_PRODUCES    ## GUID        # Unique ID of the algorithm for RNG
  gEfiRngAlgorithmSp80090Hmac256Guid  ## SOMETIMES_PRODUCES    ## GUID        # Unique ID of the algorithm for RNG
  gEfiRngAlgorithmSp80090Ctr256Guid   ## SOMETIMES_PRODUCES    ## GUID        # Unique ID of the algorithm for RNG
  gEfiRngAlgorithmX9313DesGuid        ## SOMETIMES_PRODUCES    ## GUID        # Unique ID of the algorithm for RNG
  gEfiRngAlgorithmX931AesGuid         ## SOMETIMES_PRODUCES    ## GUID        # Unique ID of the algorithm for RNG
  gEfiRngAlgorithmRaw                 ## SOMETIMES_PRODUCES    ## GUID        # Unique ID of the algorithm for RNG
  gEdkiiRngAlgorithmUnSafe            ## SOMETIMES_PRODUCES    ## GUID        # Unique ID of the algorithm for RNG

it also specifies the supported architectures of the model :

#
# The following information is for reference only and not required by the build tools.
#
#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
#

MTC (Monotonic Counter)

Is a counter that consists of two parts the high and the low 32 bits. The high 32 bits are nonvolatile and are increased every time the system resets or the lower 32 bit overflow. The lower 32 bit on the other hand are volatile and are reset on every system reset 6.

The implementation can be found under MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounter.c in the EDKII source code.

Though the name of the actual variable can differ between systems. On my Thinkpad it had the following name:

$ xxd MTC-eb704011-1402-11d3-8e77-00a0c969723b
00000000: 0700 0000 7e04 0000                      ....~...

While on another system it was called MonotonicCounter with also using a different GUID

$ xxd MonotonicCounter-01368881-c4ad-4b1d-b631-d57a8ec8db6b 
00000000: 0700 0000 8108 0000   

(second one being an Asus Motherboard) . In my Testing I have not seen any other names for this but my sampling size was not very large either, so help would be appreciated with this. Though I did not observer a change in format between vendors. Theoretically speaking I would also count this towards a variable that is defined by the UEFI spec since all of its definition can be found there.

For people following the blog this variable should already be familiar since while I was writing this blog post I also published a post about the development of bootsecure which uses this variable for detection.

Windows

CurrentPolicy

As far as I can tell this is the variable that stores the Version of the Secure Boot configuration Policy

xxd  /sys/firmware/efi/efivars/CurrentPolicy-77fa9abd-0359-4d32-bd60-28f4e78f784b
00000000: 2700 0000 02                             '....

Since the GUID matches the one mentioned in the following excerpt from a window learn, article. Also, This supposedly returns an integer which would match.

PS C:\> Get-SecureBootPolicy | Format-List
Publisher: 77fa9abd-0359-4d32-bd60-28f4e78f784b
Version  : 1

taken from Microsoft learn

Lenovo

The following section is largely based upon public information.

LenovoWolInfo

Looking at the raw output it looked like a toggle.

b'\x07\x00\x00\x00' - b'\x00'

Further Research uncovers that this is a likely informational toggle for Wake On Lan (The Wol term is also used in Lenovo documentation 7).

Since the Option was not available as a BIOS toggle I can only infer what this option means. So this is currently speculative, that 0 means that Wake on Lan is deactivated and 1 means Wake On LAN is toggled on. If I someone can test this / I find another device where I can test this will be updated.

The following section is based uppon LogoFAIL and Lenovo Logo Changer and would not have been possible without their already published work so go check them out.

LBLDESP

This is a quite straight forward data structure it contains a byte of information if currently a custom logo is set or not. It also contains the max amount of pixel width and height that the image can be, which in my case is the size of the laptop Monitor. Supported formats are also encoded.

Looking at the source code for the Lenovo Logo changer the list of all possible formats that could be supported is :

  • jpg
  • tga
  • pcx
  • gif
  • bmp
  • png

Though it would be interesting to find out if animated GIFs are supported or not because that could lead to some very interesting boot screens.

LBLDVC

This mainly stores the SHA256 sum and some version number and some unknown bits. The version number was relatively high for me for some reason.

Strings can be confusing

Here are some speculations on some things I found with some research to back up my thoughts. Though this should have taken with a grain of salt since this is mostly me speculating even more than the rest of this article.

TdkFlashCommandLine

This is a weird one. It contains the following null terminated string :

/osv SDK0T76530 WIN\x00

Since I didn’t find anything for this in any spec the following description is purely speculative.

This might be a windows activation key stored in the bios 8. Though I don’t think this is the case. I think this is more an identifier for the specific Motherboard, because I have seen it in multiple Hardware compatibility Sites for BSD and Linux 9 10. This would also match more with what the string says. I speculate that osv might mean Operating system Version, then followed by the SDK of the Motherboard and then the OS originally meant for this laptop.

TDK seems to be some flash utility as far as I can tell from weird GitHub repos 11 and what the manufacturer is reporting 12.

SimpleBootFlag

This just allows communication between UEFI firmware and the OS for settings like if debugging should be turned on. The before mentioned Basic Input Output Blog post goes into more detail. I have not seen this in my system since this is a relatively obscure standard. But I wanted to include it since I found the spec of it. Also, it should use the global EFI GUID.

Closing Remarks

For now this will conclude my research into UEFI vars. Further research will probably only be contained in updates to the Software I wrote instead of blog posts. So keep an eye out of updates to that tool.