Documentation
¶
Overview ¶
Package filesystem_uefi provides read/write access to UEFI variable stores in the OVMF/EDK2 NvVar binary format (non-authenticated variant).
Overview ¶
UEFI firmware stores runtime configuration variables (boot order, Secure Boot keys, timeout, …) in a binary NvVar store on a dedicated pflash chip or in a file (e.g. OVMF_VARS.fd, QEMU_VARS.fd). This package lets you open such a file, enumerate, read, write, and delete variables without requiring root privileges, external binaries, or CGO.
Getting started ¶
import fsuefi "github.com/go-filesystems/uefi/src"
s, err := fsuefi.Open("OVMF_VARS.fd")
if err != nil { log.Fatal(err) }
defer s.Close()
// List all variables
for _, v := range s.List() {
fmt.Printf("%s attrs=%#x size=%d\n", v.Name, v.Attributes, len(v.Data))
}
// Write a variable
err = s.Set(fsuefi.Variable{
Name: "MyVar",
GUID: fsuefi.DefaultNamespaceGUID,
Attributes: fsuefi.AttrNonVolatile | fsuefi.AttrBootServiceAccess | fsuefi.AttrRuntimeAccess,
Data: []byte{0x01, 0x02},
})
Interfaces ¶
Open returns a Store interface — callers never hold a concrete struct pointer. Store combines two sub-interfaces:
- VariableStore: UEFI-specific operations (List, Get, Set, Delete).
- filesystem.Filesystem (from github.com/go-filesystems/interface): generic filesystem operations (ReadFile, WriteFile, ListDir, Stat, …). Variable names are used as paths; DefaultNamespaceGUID is the namespace.
Binary format ¶
The store starts with a VARIABLE_STORE_HEADER (28 bytes) followed by zero or more VARIABLE_HEADERs (32 bytes each). Variable names are encoded as null-terminated UTF-16LE; data payloads follow the name with 4-byte alignment. Deleted variables are skipped on read; writes reconstruct the full file from the surviving variables.
Supported store signatures: EFIVariableGUID (non-authenticated) and EFIAuthenticatedVariableGUID (authenticated). Authenticated write validation (time-based signatures) is not performed.
Secure Boot use case ¶
See docs/uefi-secure-boot-qemu.md in the parent repository for a step-by-step guide to enrolling PK / KEK / db keys into OVMF_VARS.fd and launching a Secure Boot VM under QEMU on x86-64 and arm64.
Package filesystem_uefi provides read/write access to UEFI variable stores in the OVMF/EDK2 NvVar binary format (non-authenticated variant).
Index ¶
- Constants
- Variables
- func AddBootEntry(store VariableStore, lo *LoadOption) (uint16, error)
- func BootCurrent(store VariableStore) (uint16, error)
- func BootNext(store VariableStore) (uint16, bool, error)
- func BootOrder(store VariableStore) ([]uint16, error)
- func BuildAuthentication2(name string, guid GUID, attrs Attributes, data []byte, ts EFITime, ...) ([]byte, error)
- func BuildEFISignatureList(ownerGUID GUID, certDER []byte) []byte
- func ClearBootNext(store VariableStore) error
- func DecodeUTF16LE(b []byte) (string, error)
- func DeleteBootEntry(store VariableStore, n uint16) error
- func DevicePathText(nodes []DevicePathNode) string
- func EncodeUTF16LE(s string) []byte
- func EnrollSecureBootKeys(store VariableStore, keys SecureBootKeys) error
- func ListBootEntries(store VariableStore) (map[uint16]*LoadOption, []uint16, error)
- func MarshalDevicePath(nodes []DevicePathNode) ([]byte, error)
- func SetBootCurrent(store VariableStore, n uint16) error
- func SetBootEntry(store VariableStore, n uint16, lo *LoadOption) error
- func SetBootNext(store VariableStore, n uint16) error
- func SetBootOrder(store VariableStore, order []uint16) error
- func SetTimeout(store VariableStore, seconds uint16) error
- func Timeout(store VariableStore) (uint16, bool, error)
- func WriteAuthenticatedVariable(s VariableStore, name string, guid GUID, attrs Attributes, data []byte, ...) error
- type Attributes
- type AuthSigner
- type Authentication2
- type DevicePathNode
- type EFITime
- type GUID
- type HardDriveNode
- type LoadOption
- type OVMFFlavor
- type SecureBootKeys
- type Store
- type Variable
- type VariableStore
Constants ¶
const ( LoadOptionActive uint32 = 0x00000001 // LOAD_OPTION_ACTIVE LoadOptionForceReconnect uint32 = 0x00000002 // LOAD_OPTION_FORCE_RECONNECT LoadOptionHidden uint32 = 0x00000008 // LOAD_OPTION_HIDDEN LoadOptionCategoryMask uint32 = 0x00001F00 // LOAD_OPTION_CATEGORY LoadOptionCategoryBoot uint32 = 0x00000000 // LOAD_OPTION_CATEGORY_BOOT LoadOptionCategoryApp uint32 = 0x00000100 // LOAD_OPTION_CATEGORY_APP )
Load-option attribute flags (EFI_LOAD_OPTION.Attributes, UEFI spec §3.1.3).
const ( DevPathTypeHardware uint8 = 0x01 DevPathTypeACPI uint8 = 0x02 DevPathTypeMessaging uint8 = 0x03 DevPathTypeMedia uint8 = 0x04 DevPathTypeBIOS uint8 = 0x05 DevPathTypeEnd uint8 = 0x7F )
EFI_DEVICE_PATH_PROTOCOL node Type values (UEFI spec §10.3).
const ( DevPathEndInstance uint8 = 0x01 // end of one path instance, more follow DevPathEndEntire uint8 = 0xFF // end of the entire device path )
SubType values for the End-of-path node (Type 0x7F).
const ( HDMBRTypePCAT uint8 = 0x01 // legacy MBR partition table HDMBRTypeGPT uint8 = 0x02 // GUID partition table )
MBRType values for a Hard Drive (HD) media node.
const ( HDSigTypeNone uint8 = 0x00 // no disk signature HDSigTypeMBR uint8 = 0x01 // 4-byte MBR (NT) disk signature HDSigTypeGUID uint8 = 0x02 // 16-byte GPT disk GUID )
SignatureType values for a Hard Drive (HD) media node.
const ( // VarsSizeX86_64 is the standard OVMF_VARS.fd size for x86-64 (512 KiB). VarsSizeX86_64 = int64(512 * 1024) // VarsSizeARM64 is the standard QEMU_VARS.fd size for arm64 (64 MiB). VarsSizeARM64 = int64(64 * 1024 * 1024) )
Standard UEFI variable store sizes used by QEMU firmware images.
const ( VariableData = 0x55AA // VARIABLE_DATA start marker StoreFormatted = 0x5A // VARIABLE_STORE_FORMATTED StoreHealthy = 0xFE // VARIABLE_STORE_HEALTHY VarAdded = 0x3F // complete, valid variable VarDeleted = 0xFD // obsolete/deleted StoreHeaderSize = 28 // sizeof(VARIABLE_STORE_HEADER) VarHeaderSize = 32 // sizeof(VARIABLE_HEADER) — non-auth variant AuthVarHeaderSize = 60 // sizeof(AUTHENTICATED_VARIABLE_HEADER) — adds // FvHeaderSize is the on-disk size of an EFI_FIRMWARE_VOLUME_HEADER // with exactly one block-map entry plus the (0, 0) terminator. Both // QEMU's edk2-i386-vars.fd and the OVMF aarch64 NvVar region use this // 72-byte layout (HeaderLength field = 0x48). FvHeaderSize = 72 )
Binary format constants derived from EDK2 MdeModulePkg/Include/Guid/VariableFormat.h.
Variables ¶
var ( // EFIGlobalVariableGUID is the namespace for PK and KEK variables. // {8be4df61-93ca-11d2-aa0d-00e098032b8c} EFIGlobalVariableGUID = GUID{ 0x61, 0xdf, 0xe4, 0x8b, 0xca, 0x93, 0xd2, 0x11, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c, } // EFIImageSecurityDatabaseGUID is the namespace for db and dbx variables. // {d719b2cb-3d3a-4596-a3bc-dad00e67656f} EFIImageSecurityDatabaseGUID = GUID{ 0xcb, 0xb2, 0x19, 0xd7, 0x3a, 0x3d, 0x96, 0x45, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f, } // EFICertX509GUID is the SignatureType GUID for X.509 certificates in an // EFI_SIGNATURE_LIST. {a5c059a1-94e4-4aa7-87b5-ab155c2bf072} EFICertX509GUID = GUID{ 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, 0xa7, 0x4a, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72, } )
Well-known GUIDs for Secure Boot variable management.
var DefaultNamespaceGUID = GUID{
0x61, 0xdf, 0xe4, 0x8b,
0xca, 0x93,
0xd2, 0x11,
0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c,
}
DefaultNamespaceGUID is used by the filesystem.Filesystem adapter when no GUID is embedded in the path. It equals EFI_GLOBAL_VARIABLE_GUID.
{8be4df61-93ca-11d2-aa0d-00e098032b8c}
var EFIAuthenticatedVariableGUID = GUID{
0x78, 0x2c, 0xf3, 0xaa,
0x7b, 0x94,
0x9a, 0x43,
0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
}
EFIAuthenticatedVariableGUID is the store signature GUID for authenticated NvVar stores. {0xaaf32c78, 0x947b, 0x439a, {0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92}}
var EFICertTypePKCS7GUID = GUID{
0x9d, 0xd2, 0xaf, 0x4a,
0xdf, 0x68,
0xee, 0x49,
0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7,
}
EFICertTypePKCS7GUID is EFI_CERT_TYPE_PKCS7_GUID, the WIN_CERTIFICATE_UEFI_GUID CertType for a PKCS#7 SignedData payload. {4aafd29d-68df-49ee-8aa9-347d375665a7}
var EFISystemNvDataFvGUID = GUID{
0x8d, 0x2b, 0xf1, 0xff,
0x96, 0x76,
0x8b, 0x4c,
0xa9, 0x85, 0x27, 0x47, 0x07, 0x5b, 0x4f, 0x50,
}
EFISystemNvDataFvGUID is the FvHeader.FileSystemGuid used for the NvVar firmware volume in both QEMU x86_64 (edk2-i386-vars.fd) and QEMU aarch64 (the varstore region of edk2-aarch64-code.fd / QEMU_VARS.fd) prebuilt OVMF images. EDK2 calls it `gEfiSystemNvDataFvGuid`.
{FFF12B8D-7696-4C8B-A985-2747075B4F50}
Wire encoding follows the standard EFI mixed-endian rule:
Data1 (uint32, LE) = 0xFFF12B8D → bytes 8d 2b f1 ff Data2 (uint16, LE) = 0x7696 → bytes 96 76 Data3 (uint16, LE) = 0x4C8B → bytes 8b 4c Data4 (8 raw bytes) → a9 85 27 47 07 5b 4f 50
var EFIVariableGUID = GUID{
0x16, 0x36, 0xcf, 0xdd,
0x75, 0x32,
0x64, 0x41,
0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
}
EFIVariableGUID is the store signature GUID for non-authenticated NvVar stores. {0xddcf3616, 0x3275, 0x4164, {0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d}}
Functions ¶
func AddBootEntry ¶
func AddBootEntry(store VariableStore, lo *LoadOption) (uint16, error)
AddBootEntry writes lo to the lowest free Boot#### number, appends that number to the end of BootOrder, and returns the assigned number.
func BootCurrent ¶
func BootCurrent(store VariableStore) (uint16, error)
BootCurrent returns the entry number the firmware booted from this session (the read-only BootCurrent variable). Returns an error if it is absent.
func BootNext ¶
func BootNext(store VariableStore) (uint16, bool, error)
BootNext returns the one-shot next-boot entry number and ok=true if the BootNext variable is set.
func BootOrder ¶
func BootOrder(store VariableStore) ([]uint16, error)
BootOrder returns the platform boot order: the packed UINT16 LE array stored in the BootOrder variable. A missing BootOrder yields an empty slice.
func BuildAuthentication2 ¶
func BuildAuthentication2(name string, guid GUID, attrs Attributes, data []byte, ts EFITime, signer AuthSigner) ([]byte, error)
BuildAuthentication2 constructs the serialized EFI_VARIABLE_AUTHENTICATION_2 descriptor for an authenticated write of variable name/guid carrying attrs and data, signed by signer at timestamp ts.
The returned bytes are the descriptor only (EFI_TIME + WIN_CERTIFICATE_UEFI_GUID); to perform the write, prepend them to data — see WriteAuthenticatedVariable.
attrs must include AttrTimeBasedAuthenticatedWriteAccess; the signature is bound to the exact attribute value, so the caller must pass the same attrs it will write.
func BuildEFISignatureList ¶
BuildEFISignatureList encodes a single DER-encoded X.509 certificate into an EFI_SIGNATURE_LIST binary blob suitable for writing into PK, KEK, db or dbx.
ownerGUID identifies the entity that owns the certificate (e.g. EFIGlobalVariableGUID for vendor keys). certDER must be a valid DER-encoded X.509 certificate; no structural validation is performed.
Layout (all little-endian):
0-15 SignatureType GUID (EFICertX509GUID) 16-19 SignatureListSize 20-23 SignatureHeaderSize (always 0 for X.509) 24-27 SignatureSize = 16 + len(certDER) 28-43 SignatureOwner GUID 44-… certDER bytes
func ClearBootNext ¶
func ClearBootNext(store VariableStore) error
ClearBootNext deletes the BootNext variable. A missing BootNext is not an error (the one-shot is simply already clear).
func DecodeUTF16LE ¶
DecodeUTF16LE converts a UTF-16LE byte slice (may include null terminator) to a Go string.
func DeleteBootEntry ¶
func DeleteBootEntry(store VariableStore, n uint16) error
DeleteBootEntry removes the Boot#### variable. It does NOT touch BootOrder; use SetBootOrder to drop the number from the order if desired.
func DevicePathText ¶
func DevicePathText(nodes []DevicePathNode) string
DevicePathText renders a node list in the canonical UEFI text form, e.g.:
PciRoot(0x0)/Pci(0x1,0x0)/HD(1,GPT,<guid>,0x800,0x100000)/File(\EFI\BOOT\BOOTX64.EFI)
Typed renderers are emitted for the common production nodes (Hardware/PCI, ACPI, Messaging MAC/IPv4/IPv6, Media HD/File/CD-ROM); any other node is rendered generically as Path(<type>,<subtype>,<hexdata>) so the text form is always total and never loses information about node identity.
func EncodeUTF16LE ¶
EncodeUTF16LE converts a Go string to UTF-16LE bytes with null terminator.
func EnrollSecureBootKeys ¶
func EnrollSecureBootKeys(store VariableStore, keys SecureBootKeys) error
EnrollSecureBootKeys writes PK, KEK and db into the variable store at store. Variables are enrolled in the order db → KEK → PK: writing PK last causes OVMF to leave Setup Mode and activate Secure Boot (User Mode). After that, any PK or KEK change must be signed with the previous key.
func ListBootEntries ¶
func ListBootEntries(store VariableStore) (map[uint16]*LoadOption, []uint16, error)
ListBootEntries returns every parseable Boot#### entry, keyed by number, and a slice of numbers in BootOrder sequence (BootOrder entries first, in order; any Boot#### present in the store but absent from BootOrder is appended in ascending numeric order). Entries whose load option fails to parse are skipped rather than aborting the whole listing.
func MarshalDevicePath ¶
func MarshalDevicePath(nodes []DevicePathNode) ([]byte, error)
MarshalDevicePath encodes a node list back to its on-disk byte form, appending the entire-path End node (0x7F/0xFF, length 4). It is the exact inverse of ParseDevicePath: MarshalDevicePath(ParseDevicePath(b)) == b for any well-formed b that ends in a single entire-path terminator.
func SetBootCurrent ¶
func SetBootCurrent(store VariableStore, n uint16) error
SetBootCurrent writes the BootCurrent variable. Firmware sets this itself in practice; the setter exists for crafting test fixtures and mock stores.
func SetBootEntry ¶
func SetBootEntry(store VariableStore, n uint16, lo *LoadOption) error
SetBootEntry writes a load option into Boot####.
func SetBootNext ¶
func SetBootNext(store VariableStore, n uint16) error
SetBootNext sets the one-shot BootNext entry number.
func SetBootOrder ¶
func SetBootOrder(store VariableStore, order []uint16) error
SetBootOrder writes the BootOrder variable from a UINT16 slice.
func SetTimeout ¶
func SetTimeout(store VariableStore, seconds uint16) error
SetTimeout writes the boot-manager menu timeout in seconds.
func Timeout ¶
func Timeout(store VariableStore) (uint16, bool, error)
Timeout returns the boot-manager menu timeout in seconds (the Timeout variable). Returns ok=false if unset.
func WriteAuthenticatedVariable ¶
func WriteAuthenticatedVariable(s VariableStore, name string, guid GUID, attrs Attributes, data []byte, ts EFITime, signer AuthSigner) error
WriteAuthenticatedVariable performs a time-based authenticated write of a Secure Boot variable into store. It builds the EFI_VARIABLE_AUTHENTICATION_2 descriptor, signs the time-to-be-signed payload with signer, prepends the descriptor to data and writes the result with the AttrTimeBasedAuthenticatedWriteAccess attribute set.
The resulting on-disk variable Data is exactly what edk2's VariableServicesSmm expects from a SetVariable() call with an EFI_VARIABLE_AUTHENTICATION_2 prefix: [descriptor || data].
This constructs and signs the payload only; the store backend does not itself verify the signature (firmware does that at runtime). attrs, if zero, defaults to the standard Secure Boot attribute set plus the time-based-auth flag.
Types ¶
type Attributes ¶
type Attributes uint32
Attributes holds EFI variable attribute flags.
const ( AttrNonVolatile Attributes = 0x00000001 AttrBootServiceAccess Attributes = 0x00000002 AttrRuntimeAccess Attributes = 0x00000004 AttrHardwareErrorRecord Attributes = 0x00000008 AttrTimeBasedAuthenticatedWriteAccess Attributes = 0x00000020 AttrAppendWrite Attributes = 0x00000040 )
type AuthSigner ¶
type AuthSigner struct {
// Key is the signing private key. Only *rsa.PrivateKey is supported,
// which is what every shipping Secure Boot tool (sbsign, efitools) and
// edk2's authenticated SetVariable verifier accept.
Key *rsa.PrivateKey
// Cert is the signer certificate, included in the PKCS#7 SignedData.
Cert *x509.Certificate
}
AuthSigner holds the private key and certificate used to sign an authenticated variable write. The certificate's public key must match the private key, and the certificate (or its issuer chain) must be enrolled in the relevant key database (PK signs PK/KEK, KEK signs db/dbx, …).
type Authentication2 ¶
type Authentication2 struct {
// TimeStamp is the EFI_TIME the signature was bound to.
TimeStamp EFITime
// CertType is the WIN_CERTIFICATE_UEFI_GUID CertType (PKCS#7 for Secure Boot).
CertType GUID
// PKCS7 is the raw DER PKCS#7 SignedData blob (CertData).
PKCS7 []byte
}
Authentication2 is a parsed EFI_VARIABLE_AUTHENTICATION_2 descriptor.
func ParseAuthentication2 ¶
func ParseAuthentication2(b []byte) (Authentication2, error)
ParseAuthentication2 decodes a serialized EFI_VARIABLE_AUTHENTICATION_2 descriptor produced by BuildAuthentication2. It validates the WIN_CERTIFICATE header fields and returns the timestamp, cert type and the embedded PKCS#7 blob. It does not verify the signature.
type DevicePathNode ¶
DevicePathNode is a single EFI_DEVICE_PATH_PROTOCOL node. Data holds the node-specific bytes that follow the 4-byte header (i.e. everything after Type/SubType/Length). Unknown node types are preserved losslessly via this generic representation.
func FilePathNode ¶
func FilePathNode(path string) DevicePathNode
FilePathNode builds a Media/File Path node (Type 0x04, SubType 0x04) whose Data is the UCS-2 (UTF-16LE) NUL-terminated path, e.g. \EFI\BOOT\BOOTX64.EFI.
func ParseDevicePath ¶
func ParseDevicePath(b []byte) ([]DevicePathNode, error)
ParseDevicePath decodes a complete EFI_DEVICE_PATH_PROTOCOL node list from b. Parsing stops after the entire-path End node (Type 0x7F, SubType 0xFF); the returned slice does NOT include that terminator (MarshalDevicePath re-appends it). The input is treated as untrusted: every length field is bounds-checked via safeio so malformed or truncated data yields an error rather than a panic or out-of-bounds read.
func (DevicePathNode) FilePath ¶
func (n DevicePathNode) FilePath() (string, bool)
FilePath returns the UCS-2 path of a Media/File Path node, or false if n is not a file-path node (or its data is malformed).
func (DevicePathNode) HardDrive ¶
func (n DevicePathNode) HardDrive() (HardDriveNode, bool)
HardDrive returns the typed HD view of n, or false if n is not a well-formed Media/Hard Drive node.
func (DevicePathNode) Length ¶
func (n DevicePathNode) Length() int
Length returns the on-disk node length (header + Data), as written into the 2-byte Length field.
type EFITime ¶
type EFITime struct {
Year uint16
Month uint8
Day uint8
Hour uint8
Minute uint8
Second uint8
Nanosecond uint32
TimeZone int16
Daylight uint8
}
EFITime mirrors EFI_TIME. Only the fields UEFI authenticated writes care about are populated; Nanosecond/TimeZone/Daylight are written as zero, which is what edk2 SetVariable produces for an authenticated payload.
func EFITimeFromGoTime ¶
EFITimeFromGoTime converts a Go time (interpreted in UTC) into the EFI_TIME fields UEFI authenticated writes use. Sub-second precision and time-zone offsets are dropped to zero, matching edk2's authenticated SetVariable.
type GUID ¶
type GUID [16]byte
GUID represents a 16-byte EFI GUID stored in mixed-endian on-disk format. Bytes 0-3: Data1 LE, 4-5: Data2 LE, 6-7: Data3 LE, 8-15: Data4 big-endian.
type HardDriveNode ¶
type HardDriveNode struct {
PartitionNumber uint32
PartitionStart uint64 // starting LBA
PartitionSize uint64 // size in LBAs
Signature [16]byte
MBRType uint8 // HDMBRTypePCAT or HDMBRTypeGPT
SignatureType uint8 // HDSigTypeNone / HDSigTypeMBR / HDSigTypeGUID
}
HardDriveNode describes a Media/Hard Drive (HD) device-path node — the typed view of the partition that a load option boots from.
func (HardDriveNode) Node ¶
func (hd HardDriveNode) Node() DevicePathNode
HardDriveNodeFrom builds the on-disk Media/HD node for hd. The fixed 42-byte layout (UEFI spec Table 10.x) is:
0..4 PartitionNumber (u32 LE) 4..12 PartitionStart (u64 LE) 12..20 PartitionSize (u64 LE) 20..36 Signature (16 raw bytes) 36 MBRType 37 SignatureType
type LoadOption ¶
type LoadOption struct {
Attributes uint32
Description string
DevicePath []DevicePathNode
OptionalData []byte
}
LoadOption is a parsed EFI_LOAD_OPTION — the value of a Boot#### (or Driver####/SysPrep####) variable. On-disk layout (UEFI spec §3.1.3, all multi-byte fields little-endian):
0..4 Attributes (u32 LE) 4..6 FilePathListLength (u16 LE) — byte length of DevicePath 6.. Description (UCS-2, NUL-terminated) (after desc) DevicePath (FilePathListLength bytes) (remaining) OptionalData (everything left over)
func BootEntry ¶
func BootEntry(store VariableStore, n uint16) (*LoadOption, error)
BootEntry returns the parsed EFI_LOAD_OPTION stored in Boot####.
func ParseLoadOption ¶
func ParseLoadOption(b []byte) (*LoadOption, error)
ParseLoadOption decodes an EFI_LOAD_OPTION from untrusted bytes. Every length field is validated with safeio so malformed/truncated input yields a graceful error rather than a panic or out-of-bounds read.
func (*LoadOption) Marshal ¶
func (lo *LoadOption) Marshal() ([]byte, error)
Marshal encodes the load option to its exact on-disk byte form. It is the inverse of ParseLoadOption: Marshal(ParseLoadOption(b)) == b for any well-formed b.
func (*LoadOption) Text ¶
func (lo *LoadOption) Text() string
Text renders the load option's device path in canonical UEFI text form.
type OVMFFlavor ¶
type OVMFFlavor int
OVMFFlavor selects between the two observed OVMF varstore layouts.
const ( // OVMFX86_64 — the layout used by QEMU's edk2-i386-vars.fd. FvLength // equals the file size; BlockMap is a single span covering the same // range; the NvVar store fills the FV minus the 72-byte header. // Typical file size: 512 KiB. OVMFX86_64 OVMFFlavor = iota // OVMFAArch64 — the layout used by QEMU's ArmVirt prebuilt. The // pflash slot is large (64 MiB on Homebrew QEMU) but the firmware // only uses 768 KiB at offset 0 as the NvVar FV, split as // 256 KiB (Variable region) + 256 KiB (FTW working) + 256 KiB (FTW // spare). FvLength is fixed at 0xC0000, BlockMap covers the entire // pflash slot, and the NvVar VARIABLE_STORE_HEADER.Size is // 0x3FFB8 (256 KiB − the 72-byte FV header). OVMFAArch64 )
type SecureBootKeys ¶
type SecureBootKeys struct {
// PK is the Platform Key certificate. Writing PK last activates User Mode.
PK []byte
// KEK is the Key Exchange Key certificate.
KEK []byte
// DB is the allowed-signatures database certificate.
DB []byte
}
SecureBootKeys holds the three certificates required to activate Secure Boot. All certificates must be DER-encoded X.509.
type Store ¶
type Store interface {
VariableStore
filesystem.Filesystem
}
Store is the full interface returned by Open. It combines UEFI variable operations (VariableStore) with the generic filesystem.Filesystem surface, allowing the store to be used by tooling that operates on any filesystem driver in this repository.
func Format ¶
Format creates a new empty UEFI NvVar variable store file at path with the given total size, in the legacy *raw non-auth* format: signature GUID at offset 0, no FV wrapper, non-authenticated variable records.
Use FormatOVMF instead when targeting a real QEMU OVMF varstore on either x86_64 or aarch64 — both prebuilts (edk2-i386-vars.fd and the NvVar region of edk2-aarch64-code.fd) use the FV-wrapped + auth layout, and OVMF will reformat any other layout on first boot.
The returned Store is open and ready for use; call Close when done. sizeBytes must be at least StoreHeaderSize + 4 bytes.
func FormatOVMF ¶
func FormatOVMF(path string, sizeBytes int64, flavor OVMFFlavor) (Store, error)
FormatOVMF creates a new empty UEFI NvVar variable store file at path in the format real QEMU OVMF prebuilts use: a 72-byte EFI_FIRMWARE_VOLUME header at offset 0, a VARIABLE_STORE_HEADER with the EFIAuthenticatedVariableGUID signature at offset 72, and 0xFF padding (erased flash) for the rest of the FV.
flavor picks the FV layout — see OVMFFlavor constants. Use OVMFX86_64 for OVMF_VARS.fd and OVMFAArch64 for QEMU_VARS.fd (ArmVirt).
sizeBytes is the full file size to produce — for x86_64 this equals the FV size; for aarch64 it's typically 64 MiB (the pflash slot) and only the first 768 KiB is the FV.
Variables created via Set on the returned Store are written with the 60-byte AUTHENTICATED_VARIABLE_HEADER (MonotonicCount + TimeStamp + PubKeyIndex zeros), matching how OVMF itself stores non-authenticated SetVariable calls inside an auth-format store.
func Open ¶
Open opens a UEFI variable store file and parses its contents. It returns a Store, which combines VariableStore and filesystem.Filesystem.
Auto-detects the on-disk format: raw NvVar vs FV-wrapped, and authenticated vs non-authenticated variable records. The detection is sticky — flush() preserves whatever flavor was found at Open time so the file stays compatible with the firmware that owns it.
type Variable ¶
type Variable struct {
Name string
GUID GUID
Attributes Attributes
Data []byte
}
Variable is a single parsed UEFI variable.
type VariableStore ¶
type VariableStore interface {
// Close releases any resources held by the store.
Close() error
// List returns a copy of all valid (non-deleted) variables in the store.
List() []Variable
// Get retrieves a variable by name and GUID namespace.
Get(name string, guid GUID) (Variable, error)
// Set creates or replaces a variable; the backing file is rewritten.
Set(v Variable) error
// Delete removes a variable by name and GUID; returns an error if not found.
Delete(name string, guid GUID) error
}
VariableStore provides read/write access to a UEFI NvVar variable store. All write operations (Set, Delete) serialize through the backing file.
