Skip to content

Commit

Permalink
Restore ExtendTCI Test
Browse files Browse the repository at this point in the history
Restore the ExtendTCI test removed in chipsalliance#251. Since TagTCI was removed,
this tests needed to be refactored a bit.
  • Loading branch information
jhand2 committed Nov 21, 2023
1 parent fb105d9 commit 83fdd92
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 14 deletions.
19 changes: 11 additions & 8 deletions verification/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
108 changes: 102 additions & 6 deletions verification/extendTCI.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -43,23 +43,119 @@ 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 {
hasher = sha512.New384()
}
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)
}
Expand Down
4 changes: 4 additions & 0 deletions verification/verification.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{},
}
Expand All @@ -59,6 +62,7 @@ var AllTestCases = []TestCase{
CertifyKeySimulationTestCase,
GetCertificateChainTestCase,
ExtendTCITestCase,
ExtendDerivedTciTestCase,
GetProfileTestCase,
InitializeContextTestCase,
InitializeContextSimulationTestCase,
Expand Down

0 comments on commit 83fdd92

Please sign in to comment.