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 Name | Attribute | Description |
|---|---|---|
| dbDefault | BS, RT | The OEM’s default secure boot signature store. Should be treated as read-only. |
| dbrDefault | BS, RT | The OEM’s default OS Recovery signature store. Should be treated as read-only. |
| dbtDefault | BS, RT | The OEM’s default secure boot timestamp signature store. Should be treated as read-only. |
| dbxDefault | BS, RT | The 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.
Logo
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.
https://uefi.org/specs/UEFI/2.11/03_Boot_Manager.html#globally-defined-variables ↩︎ ↩︎
https://uefi.org/specs/UEFI/2.11/32_Secure_Boot_and_Driver_Signing.html#signature-database-update ↩︎
https://uefi.org/specs/UEFI/2.11/08_Services_Runtime_Services.html#variable-services ↩︎
https://uefi.org/specs/UEFI/2.11/Apx_A_GUID_and_Time_Formats.html# ↩︎
https://uefi.org/specs/UEFI/2.11/08_Services_Runtime_Services.html#get-next-high-monotonic-count ↩︎
https://support.lenovo.com/us/en/solutions/ht514894-how-to-enable-and-test-wake-on-lan-in-windows ↩︎
https://bsd-hardware.info/?id=board:lenovo-lnvnb161216-sdk0t76530-win ↩︎
https://github.com/trfiladelfo/tdk/blob/master/lm-flash/ReleaseNotes.txt I don’t think this is official but leaked in some way ↩︎
https://www.micronas.tdk.com/en/node/33020 I assume this is the manufacturer of my chip that contains the UEFI vars and such. ↩︎