Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 54 additions & 27 deletions internal/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,19 @@ var FirmwareMRTDs = []FirmwareMRTD{
},
}

// Region contains NVME driver measurements that vary by GCP region
type Region struct {
// bootVariant contains NVMe driver boot option measurements.
type bootVariant struct {
Boot0001 []byte
Boot0002 []byte
}

// Regions maps region names to their NVME driver measurements
var Regions = map[string]Region{
"us": {
var bootVariants = []bootVariant{
{
Boot0001: mustDecodeHex("A25333C7AEC2E0993034938C7F11893B3C2BCAF67E88C342A3D586F6F7FAE2C6A1247A9ED86988080A6D4BE497D4FBB6"),
Boot0002: mustDecodeHex("9068065754FF3AE3DD58A5897535EEAF62A19A6757D82DD91349C41BAE2E3F208E268ABBA2A4378BC5C8D1ACF2FD260F"),
},
"europe": {
Boot0001: mustDecodeHex("AD073F06C3E96A1FD95AD8FF602B913155384775C6D258B6290F3D995CD3882F243E2D1A38182EB102857CA417CEA960"),
Boot0002: mustDecodeHex("E501398B9DCEFA43727503A8B1161225FB9413C39CE91126D2A9A3588AE7ECDFA7A9FCBFFC6A1CBC3E0EC92CBD4810E7"),
},
}

// boot0000Hash is the same across all regions
var boot0000Hash = mustDecodeHex("23ADA07F5261F12F34A0BD8E46760962D6B4D576A416F1FEA1C64BC656B1D28EACF7047AE6E967C58FD2A98BFA74C298")

// Hardcoded SHA384 hashes of TDX EFI variables
Expand All @@ -69,31 +63,64 @@ var (
dbxHash = mustDecodeHex("C61BAE1A3F7B7E6CC3B9B03F630B77292EBD232AE60E0E1916F980955EC38459529574B49F1898C367EAF6D8A62311F5")
)

// acpiHashes holds the measured hashes for one set of ACPI tables (tied to a specific firmware version).
// A machine configuration may have multiple valid sets when GCP updates their firmware.
type acpiHashes struct {
AcpiLoaderHash []byte
AcpiRsdpHash []byte
AcpiTablesHash []byte
}

// configurationEvents maps machine configuration to hardcoded TD HOB and ACPI table hashes
type configurationEvents struct {
TdHobHash []byte
AcpiTablesHash []byte
AcpiRsdpHash []byte
AcpiLoaderHash []byte
TdHobHash []byte
AcpiHashes []acpiHashes
}

var machineConfigurations = map[string]configurationEvents{
"c3-standard-4": {
TdHobHash: mustDecodeHex("458994DAA60DEAC8DEA19DBA79748F6FF93FD0AEBB8E3E0BE5A65EB12309D342C3CE31CC67AF7BBD22AF1A44E7D9FE21"),
AcpiTablesHash: mustDecodeHex("0F0B426CBD5BD9C2A4A5E640E6C4556B8DF071DCC973DCF95465AE5514C0EBA6DC960A6B7B21D29099CADA75DC1B46D5"),
AcpiRsdpHash: mustDecodeHex("509DCFE10BEB5D470C40F25E30895370948831B9CF79DB15D977E7BBA8EB42F7200212071AD8B19D6011759779ECED5A"),
AcpiLoaderHash: mustDecodeHex("F29E022D067DA7289C935EEC2477C46032F2E0659A11E658F0AE05068AEA420189E77E302B715084DACC7C0C4C118EA6"),
TdHobHash: mustDecodeHex("458994DAA60DEAC8DEA19DBA79748F6FF93FD0AEBB8E3E0BE5A65EB12309D342C3CE31CC67AF7BBD22AF1A44E7D9FE21"),
AcpiHashes: []acpiHashes{
{
// Pre-March 2026 firmware
AcpiLoaderHash: mustDecodeHex("F29E022D067DA7289C935EEC2477C46032F2E0659A11E658F0AE05068AEA420189E77E302B715084DACC7C0C4C118EA6"),
AcpiRsdpHash: mustDecodeHex("509DCFE10BEB5D470C40F25E30895370948831B9CF79DB15D977E7BBA8EB42F7200212071AD8B19D6011759779ECED5A"),
AcpiTablesHash: mustDecodeHex("0F0B426CBD5BD9C2A4A5E640E6C4556B8DF071DCC973DCF95465AE5514C0EBA6DC960A6B7B21D29099CADA75DC1B46D5"),
},
{
// March 2026 firmware (from mripper 2026-03-13)
AcpiLoaderHash: mustDecodeHex("02D9B85E7DF1E92D15D85988B161FDF60626BFF433AF8055F367B134260D59F6A0DAB0965254627AECB1367373D74B3A"),
AcpiRsdpHash: mustDecodeHex("BA3706E632A5CB239F1C85FEBAFCFEADEBDFE3ED1A4D716D46387AD0803B4C4A7FECBCAD2C05CD390E5F4F3548E303DC"),
AcpiTablesHash: mustDecodeHex("D221BAE226ED9811EC5977C8F15DBE8C97FF80D67BBD4246D5ECF60F7C61081E597E18DF601A657A46CBDEB773AB8F88"),
},
},
},
"c3-standard-8": {
TdHobHash: mustDecodeHex("AA9E81FEEB58A9EB3A9F4110CC7B5696240437EA4C1A9C30518CFC44FA305183E6473E6BC02DDC4DE09D0C49C49FADB5"),
AcpiTablesHash: mustDecodeHex("1AC9F951EEE9D683C797EAC588B786C5D1FA140F4E69ADE6DC2A4537900E3257A4F172F03EC722C7349F8E6636EDD05F"),
AcpiRsdpHash: mustDecodeHex("4274FEDFA6ABEFE0062C5734FF82CD2C9092CDB51134EC4762D5C802D743316C9F0CDAA497A843811D0D5620CC252562"),
AcpiLoaderHash: mustDecodeHex("65B39FEC4F65FE6F1F03A9525AF00B38D8C285EA7697B75A267AA671A9B2B10907138BD6DA63E10C37997D689AD95421"),
"c3-standard-22": {
TdHobHash: mustDecodeHex("A5BE8ECD74020972E328FBBE94D2886817EF0D2E8A4E94E9572E8E1B221F3F608CDDC868CF8B08E8E645E4AAEBA68279"),
AcpiHashes: []acpiHashes{
{
// March 2026 firmware (from mripper 2026-03-13)
AcpiLoaderHash: mustDecodeHex("29342AB42C2814109D694110D1C9A7558E08C7C87E478B348FC4944FCAE2105C708813DC0A01FD29A2189D760D41AD03"),
AcpiRsdpHash: mustDecodeHex("440EEF6064096F13201108D30C9B466C0C6B6ED207C8028F7425442C164E80080D8A9BBB6F6B56BE48FDF2C830D99F86"),
AcpiTablesHash: mustDecodeHex("2A42ACBB09B7D0E59B59E09F775CB5B7748D0906D87BB886CF87081B6AA1213E42BB745E1AC19064C0CEA19A6CFA5AEB"),
},
},
},
"c3-standard-44": {
TdHobHash: mustDecodeHex("21092EADB73948AEBB405B826354C23C3025635C89A8D91F85905AFB120B7D98025A6C3083E8E82B5320695B253CE341"),
AcpiTablesHash: mustDecodeHex("C4AE73D7E84F15AA17F7FCF50C83B2846E7E6628CFF7F993531B6D8DE129BD84359E234FEEAF5E4C4A4C87A167161960"),
AcpiRsdpHash: mustDecodeHex("C104E3179249648403077F70784B26C9844394177179145E28844B2DC7E40B34D0FAD0BA22B3A3CEF00197D2BD58F4C4"),
AcpiLoaderHash: mustDecodeHex("8B8256B4DD618EA330A3C499FD211B9FA681B8205C470013B9C13CA3263C5DA5B2E253F89EE0CA5111A41F8054856DF3"),
TdHobHash: mustDecodeHex("21092EADB73948AEBB405B826354C23C3025635C89A8D91F85905AFB120B7D98025A6C3083E8E82B5320695B253CE341"),
AcpiHashes: []acpiHashes{
{
// Pre-March 2026 firmware
AcpiLoaderHash: mustDecodeHex("8B8256B4DD618EA330A3C499FD211B9FA681B8205C470013B9C13CA3263C5DA5B2E253F89EE0CA5111A41F8054856DF3"),
AcpiRsdpHash: mustDecodeHex("C104E3179249648403077F70784B26C9844394177179145E28844B2DC7E40B34D0FAD0BA22B3A3CEF00197D2BD58F4C4"),
AcpiTablesHash: mustDecodeHex("C4AE73D7E84F15AA17F7FCF50C83B2846E7E6628CFF7F993531B6D8DE129BD84359E234FEEAF5E4C4A4C87A167161960"),
},
{
// March 2026 firmware (from mripper 2026-03-13)
AcpiLoaderHash: mustDecodeHex("0FB22EA8315F50939D88E835E425B083B4E87C5A738B6B09E03191D0583BBA7E35091DE84770CE643BD17828C96A50E6"),
AcpiRsdpHash: mustDecodeHex("EB2ECD4E4FF962F12888ED1E0209437D1C1DBD9CCE050286E10DD79B33D000075BD4287B6066C482A1D4851C07485E97"),
AcpiTablesHash: mustDecodeHex("0381C7A53B1FA332467E6EA7240FB38B8EA5E6740AF0B5C496C8D66E0647DA7706B6E149B9FD00C420572B419FFC9608"),
},
},
},
}
52 changes: 22 additions & 30 deletions internal/mr.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,18 +185,13 @@ func measureTdxEfiVariable(vendorGUID string, varName string) []byte {
return measureSha384(data)
}

// MeasureRTMR0 computes RTMR0 values for a given firmware across all configuration/region combinations.
func MeasureRTMR0(fwData []byte, configurations []string, regions []string, debug bool) ([][]byte, error) {
// MeasureRTMR0 computes RTMR0 values for a given firmware across all configuration/boot variant/ACPI variant combinations.
func MeasureRTMR0(fwData []byte, configurations []string, debug bool) ([][]byte, error) {
if configurations == nil {
for name := range machineConfigurations {
configurations = append(configurations, name)
}
}
if regions == nil {
for name := range Regions {
regions = append(regions, name)
}
}

cfvImageHash, err := GetExpectedCfvSha384(fwData)
if err != nil {
Expand All @@ -210,30 +205,27 @@ func MeasureRTMR0(fwData []byte, configurations []string, regions []string, debu
return nil, fmt.Errorf("unknown machine configuration: %s", configName)
}

for _, regionName := range regions {
region, ok := Regions[regionName]
if !ok {
return nil, fmt.Errorf("unknown region: %s", regionName)
}

rtmr0Log := [][]byte{
configEvents.TdHobHash,
cfvImageHash,
secureBootHash,
pkHash,
kekHash,
dbHash,
dbxHash,
measureSha384([]byte{0x00, 0x00, 0x00, 0x00}), // Separator.
configEvents.AcpiLoaderHash,
configEvents.AcpiRsdpHash,
configEvents.AcpiTablesHash,
measureSha384([]byte{0x01, 0x00, 0x02, 0x00, 0x00, 0x00}), // BootOrder: 0001,0002,0000
region.Boot0001,
region.Boot0002,
boot0000Hash,
for _, acpi := range configEvents.AcpiHashes {
for _, boot := range bootVariants {
rtmr0Log := [][]byte{
configEvents.TdHobHash,
cfvImageHash,
secureBootHash,
pkHash,
kekHash,
dbHash,
dbxHash,
measureSha384([]byte{0x00, 0x00, 0x00, 0x00}), // Separator.
acpi.AcpiLoaderHash,
acpi.AcpiRsdpHash,
acpi.AcpiTablesHash,
measureSha384([]byte{0x01, 0x00, 0x02, 0x00, 0x00, 0x00}), // BootOrder: 0001,0002,0000
boot.Boot0001,
boot.Boot0002,
boot0000Hash,
}
rtmr0s = append(rtmr0s, measureLog(rtmr0Log, debug, "RTMR0"))
}
rtmr0s = append(rtmr0s, measureLog(rtmr0Log, debug, "RTMR0"))
}
}

Expand Down
11 changes: 2 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,26 +70,19 @@ func main() {
ukiPath string
debug bool
config string
region string
)

// flag.StringVar(&fwPath, "fw", "", "Path to firmware file")
flag.StringVar(&ukiPath, "uki", "", "Path to UKI (Unified Kernel Image) file")
flag.BoolVar(&debug, "debug", false, "Enable debug output")
flag.StringVar(&config, "config", "", "Machine configurations (comma-separated, e.g., c3-standard-4,c3-standard-8)")
flag.StringVar(&region, "region", "", "Regions (comma-separated, e.g., us,europe)")
flag.StringVar(&config, "config", "", "Machine configurations (comma-separated, e.g., c3-standard-4,c3-standard-22)")
flag.Parse()

var configurations []string
if config != "" {
configurations = strings.Split(config, ",")
}

var regions []string
if region != "" {
regions = strings.Split(region, ",")
}

ukiData, err := os.ReadFile(ukiPath)
if err != nil {
fmt.Printf("Error reading UKI file: %v\n", err)
Expand Down Expand Up @@ -120,7 +113,7 @@ func main() {
os.Exit(1)
}

rtmr0Hashes, err := internal.MeasureRTMR0(fwData, configurations, regions, debug)
rtmr0Hashes, err := internal.MeasureRTMR0(fwData, configurations, debug)
if err != nil {
fmt.Printf("Error calculating RTMR0: %v\n", err)
os.Exit(1)
Expand Down