From 2ec5eafb4a23b7e6262b99e5ba56e7eec06aee62 Mon Sep 17 00:00:00 2001 From: Sree Revoori Date: Tue, 13 Feb 2024 04:53:05 +0000 Subject: [PATCH] Add DeriveContext recursive=true verification tests These are just the old ExtendTci tests with a few changes. --- verification/testing/deriveContext.go | 174 ++++++++++++++++++++++++++ verification/testing/simulator.go | 12 +- verification/testing/verification.go | 11 ++ 3 files changed, 196 insertions(+), 1 deletion(-) diff --git a/verification/testing/deriveContext.go b/verification/testing/deriveContext.go index 80be8bdc..2d3eb554 100644 --- a/verification/testing/deriveContext.go +++ b/verification/testing/deriveContext.go @@ -3,7 +3,11 @@ package verification import ( + "bytes" + "crypto/sha256" + "crypto/sha512" "errors" + "hash" "testing" "github.com/chipsalliance/caliptra-dpe/verification/client" @@ -308,3 +312,173 @@ func TestDeriveContextSimulation(d client.TestDPEInstance, c client.DPEClient, t } handle = &resp.NewContextHandle } + +// TestDeriveContextRecursive checks whether the DeriveContext command updates the current TCI +// and cumulative TCI when the recursive flag is set. +func TestDeriveContextRecursive(d client.TestDPEInstance, c client.DPEClient, t *testing.T) { + var err error + 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 := client.GetTransportProfile(d) + if err != nil { + t.Fatalf("[FATAL]: Could not get profile: %v", err) + } + digestLen := profile.GetDigestSize() + + tciValue := make([]byte, digestLen) + for i := range tciValue { + tciValue[i] = byte(i) + } + + handle, tcbInfo, err := getTcbInfoForHandle(c, handle) + if err != nil { + t.Fatal(err) + } + lastCumulative := tcbInfo.Fwids[1].Digest + + // Set current TCI value + _, err = c.DeriveContext(handle, + tciValue, + client.DeriveContextFlags(client.Recursive), + 0, 0) + if err != nil { + t.Fatalf("[FATAL]: Could not set TCI value: %v", err) + } + + // Check current and cumulative measurement by CertifyKey + expectedCumulative := computeExpectedCumulative(lastCumulative, tciValue) + verifyMeasurements(c, t, handle, tciValue, expectedCumulative) +} + +// TestDeriveContextRecursiveOnDerivedContexts tests the DeriveContext command with +// the recursive flag on derived child contexts. +func TestDeriveContextRecursiveOnDerivedContexts(d client.TestDPEInstance, c client.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 := client.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, client.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, client.RotateContextHandleFlags(client.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) + } + }() + + // DeriveContext with input data, tag it and check TCI_CUMULATIVE + childCtx, err := c.DeriveContext(parentHandle, tciValue, client.DeriveContextFlags(client.RetainParentContext|client.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) + 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 + resp, err := c.DeriveContext(childHandle, + extendTciValue, + client.DeriveContextFlags(client.Recursive), + 0, 0) + if err != nil { + t.Fatalf("[FATAL]: Could not set TCI value: %v", err) + } + childHandle = &resp.ParentContextHandle + + 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 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) + return hasher.Sum(nil) +} + +func verifyMeasurements(c client.DPEClient, t *testing.T, handle *client.ContextHandle, expectedCurrent []byte, expectedCumulative []byte) { + handle, tcbInfo, err := getTcbInfoForHandle(c, handle) + if err != nil { + t.Fatal(err) + } + + // Check that the last TcbInfo current/cumulative are as expected + current := tcbInfo.Fwids[0].Digest + cumulative := tcbInfo.Fwids[1].Digest + if !bytes.Equal(current, expectedCurrent) { + t.Errorf("[ERROR]: Unexpected TCI_CURRENT digest, want %v but got %v", expectedCurrent, current) + } + + if !bytes.Equal(cumulative, expectedCumulative) { + t.Errorf("[ERROR]: Unexpected cumulative TCI value, want %v but got %v", expectedCumulative, cumulative) + } +} diff --git a/verification/testing/simulator.go b/verification/testing/simulator.go index 50ed86ef..fa091d71 100644 --- a/verification/testing/simulator.go +++ b/verification/testing/simulator.go @@ -255,7 +255,7 @@ func GetSimulatorTargets() []TestTarget { }, { "DefaultSupport", - getTestTarget([]string{"AutoInit", "Simulation", "X509", "Csr", "IsCA", "RotateContext", "Recursive", "IsSymmetric"}), + getTestTarget([]string{"AutoInit", "Simulation", "X509", "Csr", "IsCA", "RotateContext", "Recursive", "IsSymmetric", "RetainParentContext"}), AllTestCases, }, { @@ -368,6 +368,16 @@ func GetSimulatorTargets() []TestTarget { getTestTarget([]string{"AutoInit", "Simulation"}), []TestCase{DeriveContextLocalityTestCase}, }, + { + "DeriveContext_Recursive", + getTestTarget([]string{"AutoInit", "Recursive", "X509"}), + []TestCase{DeriveContextRecursiveTestCase}, + }, + { + "DeriveContext_RecursiveOnDerivedContexts", + getTestTarget([]string{"AutoInit", "Recursive", "RetainParentContext", "X509", "RotateContext"}), + []TestCase{DeriveContextRecursiveOnDerivedContextsTestCase}, + }, } } diff --git a/verification/testing/verification.go b/verification/testing/verification.go index 57926c76..6bdfbe37 100644 --- a/verification/testing/verification.go +++ b/verification/testing/verification.go @@ -142,6 +142,16 @@ var DeriveContextInputFlagsTestCase = TestCase{ "DeriveContext_InputFlagsSupport", TestInternalInputFlags, []string{"AutoInit", "InternalDice", "InternalInfo"}, } +// DeriveContextRecursiveTestCase tests DeriveContext with the Recursive input flag +var DeriveContextRecursiveTestCase = TestCase{ + "DeriveContext_Recursive", TestDeriveContextRecursive, []string{"AutoInit", "Recursive", "X509"}, +} + +// DeriveContextRecursiveOnDerivedContextsTestCase tests DeriveContext with the Recursive input flag on derived contexts +var DeriveContextRecursiveOnDerivedContextsTestCase = TestCase{ + "DeriveContext_RecursiveOnDerivedContexts", TestDeriveContextRecursiveOnDerivedContexts, []string{"AutoInit", "Recursive", "RetainParentContext", "X509", "RotateContext"}, +} + // AllTestCases contains all DPE test cases var AllTestCases = []TestCase{ CertifyKeyTestCase, @@ -166,6 +176,7 @@ var IrreversibleTestCases = []TestCase{ DeriveContextLocalityTestCase, DeriveContextPrivilegeEscalationTestCase, DeriveContextMaxTCIsTestCase, + DeriveContextRecursiveTestCase, } // RunTargetTestCases runs all test cases for target