From 83fdd9267a2e0f38fa1f480ad7669fa620acf0a7 Mon Sep 17 00:00:00 2001 From: Jordan Hand Date: Mon, 20 Nov 2023 17:18:59 -0800 Subject: [PATCH] Restore ExtendTCI Test Restore the ExtendTCI test removed in #251. Since TagTCI was removed, this tests needed to be refactored a bit. --- verification/certs.go | 19 +++--- verification/extendTCI.go | 108 +++++++++++++++++++++++++++++++++-- verification/verification.go | 4 ++ 3 files changed, 117 insertions(+), 14 deletions(-) diff --git a/verification/certs.go b/verification/certs.go index 7307c044..1dc83a8b 100644 --- a/verification/certs.go +++ b/verification/certs.go @@ -31,39 +31,42 @@ func getMultiTcbInfo(c *x509.Certificate) (TcgMultiTcbInfo, error) { return multiTcbInfo, nil } -func getTcbInfoForHandle(c DPEClient, handle *ContextHandle) (DiceTcbInfo, error) { +func getTcbInfoForHandle(c DPEClient, handle *ContextHandle) (*ContextHandle, DiceTcbInfo, error) { + outHandle := handle + // Get digest size profile, err := c.GetProfile() if err != nil { - return DiceTcbInfo{}, err + return outHandle, DiceTcbInfo{}, fmt.Errorf("Cannot get profile: %s", err) } digestLen := profile.Profile.GetDigestSize() label := make([]byte, digestLen) - certifiedKey, err := c.CertifyKey(handle, label, CertifyKeyX509, 0) + certifiedKey, err := c.CertifyKey(outHandle, label, CertifyKeyX509, 0) if err != nil { - return DiceTcbInfo{}, err + return outHandle, DiceTcbInfo{}, fmt.Errorf("Could not certify key: %s", err) } + outHandle = &certifiedKey.Handle leafCertBytes := certifiedKey.Certificate var leafCert *x509.Certificate // Check whether certificate is DER encoded. if leafCert, err = x509.ParseCertificate(leafCertBytes); err != nil { - return DiceTcbInfo{}, err + return outHandle, DiceTcbInfo{}, err } // Get DICE information from MultiTcbInfo Extension multiTcbInfo, err := getMultiTcbInfo(leafCert) if err != nil { - return DiceTcbInfo{}, err + return outHandle, DiceTcbInfo{}, err } if len(multiTcbInfo) == 0 { - return DiceTcbInfo{}, fmt.Errorf("Certificate MutliTcbInfo is empty") + return outHandle, DiceTcbInfo{}, fmt.Errorf("Certificate MutliTcbInfo is empty") } - return multiTcbInfo[0], nil + return outHandle, multiTcbInfo[0], nil } diff --git a/verification/extendTCI.go b/verification/extendTCI.go index 3397ca3b..e46d1cdb 100644 --- a/verification/extendTCI.go +++ b/verification/extendTCI.go @@ -31,7 +31,7 @@ func TestExtendTCI(d TestDPEInstance, c DPEClient, t *testing.T) { tciValue[i] = byte(i) } - tcbInfo, err := getTcbInfoForHandle(c, handle) + handle, tcbInfo, err := getTcbInfoForHandle(c, handle) if err != nil { t.Fatal(err) } @@ -43,8 +43,14 @@ func TestExtendTCI(d TestDPEInstance, c DPEClient, t *testing.T) { t.Fatalf("[FATAL]: Could not extend TCI: %v", err) } - // Compute expected cumulative + // Check current and cumulative measurement by CertifyKey + expectedCumulative := computeExpectedCumulative(lastCumulative, tciValue) + verifyMeasurements(c, t, handle, tciValue, expectedCumulative) +} + +func computeExpectedCumulative(lastCumulative []byte, tciValue []byte) []byte { var hasher hash.Hash + digestLen := len(lastCumulative) if digestLen == 32 { hasher = sha256.New() } else if digestLen == 48 { @@ -52,14 +58,104 @@ func TestExtendTCI(d TestDPEInstance, c DPEClient, t *testing.T) { } hasher.Write(lastCumulative) hasher.Write(tciValue) - expectedCumulative := hasher.Sum(nil) + return hasher.Sum(nil) +} - // Cross-check current and cumulative measurement by CertifyKey - verifyMeasurements(c, t, handle, tciValue, expectedCumulative) +// Check whether the ExtendTCI command with derived child context. +func TestExtendTciOnDerivedContexts(d TestDPEInstance, c DPEClient, t *testing.T) { + useSimulation := false // To indicate that simulation context is not used + + // Get default context handle + handle := getInitialContextHandle(d, c, t, useSimulation) + + // Get digest size + profile, err := GetTransportProfile(d) + if err != nil { + t.Fatalf("[FATAL]: Could not get profile: %v", err) + } + digestLen := profile.GetDigestSize() + + // Initialize TCI inputs + tciValue := make([]byte, digestLen) + for i := range tciValue { + tciValue[i] = byte(i + 1) + } + + extendTciValue := make([]byte, digestLen) + for i := range extendTciValue { + extendTciValue[i] = byte(i + 2) + } + + // Preserve parent context to restore for subsequent tests. + parentHandle, err := c.RotateContextHandle(handle, RotateContextHandleFlags(0)) + if err != nil { + t.Errorf("[ERROR]: Error while rotating parent context handle, this may cause failure in subsequent tests: %s", err) + } + + // Change parent back to default context + defer func() { + _, err = c.RotateContextHandle(parentHandle, RotateContextHandleFlags(TargetIsDefault)) + if err != nil { + t.Errorf("[ERROR]: Error while restoring parent context handle as default context handle, this may cause failure in subsequent tests: %s", err) + } + }() + + // Derive Child context with input data, tag it and check TCI_CUMULATIVE + childCtx, err := c.DeriveChild(parentHandle, tciValue, DeriveChildFlags(RetainParent|InputAllowX509), 0, 0) + if err != nil { + t.Fatalf("[FATAL]: Error while creating default child handle in default context: %s", err) + } + + childHandle := &childCtx.NewContextHandle + parentHandle = &childCtx.ParentContextHandle + + // Clean up contexts + defer func() { + err := c.DestroyContext(childHandle, DestroyDescendants) + if err != nil { + t.Errorf("[ERROR]: Error while cleaning up derived context, this may cause failure in subsequent tests: %s", err) + } + }() + + childHandle, childTcbInfo, err := getTcbInfoForHandle(c, childHandle) + if err != nil { + t.Fatalf("[FATAL]: Could not get TcbInfo: %v", err) + } + + if !bytes.Equal(childTcbInfo.Fwids[0].Digest, tciValue) { + t.Errorf("[ERROR]: Got current TCI %x, expected %x", childTcbInfo.Fwids[0].Digest, tciValue) + } + + // Check TCI_CUMULATIVE after creating child context + wantCumulativeTCI := computeExpectedCumulative(make([]byte, digestLen), childTcbInfo.Fwids[0].Digest) + if !bytes.Equal(childTcbInfo.Fwids[1].Digest, wantCumulativeTCI) { + t.Errorf("[ERROR]: Child node's cumulative TCI %x, expected %x", childTcbInfo.Fwids[1].Digest, wantCumulativeTCI) + } + + // Set current TCI value + lastCumulative := childTcbInfo.Fwids[1].Digest + childHandle, err = c.ExtendTCI(childHandle, extendTciValue) + if err != nil { + t.Fatalf("[FATAL]: Could not extend TCI: %v", err) + } + + childHandle, childTcbInfo, err = getTcbInfoForHandle(c, childHandle) + if err != nil { + t.Fatalf("[FATAL]: Could not get TcbInfo: %v", err) + } + + if !bytes.Equal(childTcbInfo.Fwids[0].Digest, extendTciValue) { + t.Errorf("[ERROR]: Got current TCI %x, expected %x", childTcbInfo.Fwids[0].Digest, extendTciValue) + } + + wantCumulativeTCI = computeExpectedCumulative(lastCumulative, extendTciValue) + if !bytes.Equal(childTcbInfo.Fwids[1].Digest, wantCumulativeTCI) { + t.Errorf("[ERROR]: Child node's cumulative TCI %x, expected %x", childTcbInfo.Fwids[1].Digest, wantCumulativeTCI) + } } func verifyMeasurements(c DPEClient, t *testing.T, handle *ContextHandle, expectedCurrent []byte, expectedCumulative []byte) { - tcbInfo, err := getTcbInfoForHandle(c, handle) + handle, tcbInfo, err := getTcbInfoForHandle(c, handle) if err != nil { t.Fatal(err) } diff --git a/verification/verification.go b/verification/verification.go index a955dc61..7b83fb46 100644 --- a/verification/verification.go +++ b/verification/verification.go @@ -38,6 +38,9 @@ var GetCertificateChainTestCase = TestCase{ var ExtendTCITestCase = TestCase{ "ExtendTCITestCase", TestExtendTCI, []string{"AutoInit", "ExtendTci"}, } +var ExtendDerivedTciTestCase = TestCase{ + "ExtendDerivedTciTestCase", TestExtendTciOnDerivedContexts, []string{"AutoInit", "ExtendTci"}, +} var GetProfileTestCase = TestCase{ "GetProfile", TestGetProfile, []string{}, } @@ -59,6 +62,7 @@ var AllTestCases = []TestCase{ CertifyKeySimulationTestCase, GetCertificateChainTestCase, ExtendTCITestCase, + ExtendDerivedTciTestCase, GetProfileTestCase, InitializeContextTestCase, InitializeContextSimulationTestCase,