From b85ae0b3ee84603f15f3e6e15f99a51174911cc4 Mon Sep 17 00:00:00 2001 From: hpya93 Date: Fri, 3 Nov 2023 09:10:14 +0530 Subject: [PATCH 01/10] extendtci command as separate branch --- verification/abi.go | 218 ++++++++++++++++++++++++++-- verification/certifyKey.go | 24 +--- verification/client.go | 10 ++ verification/initializeContext.go | 25 ++++ verification/simulator.go | 2 +- verification/tagTCI.go | 226 +++++++++++++++++++++++++----- verification/verification.go | 10 +- 7 files changed, 449 insertions(+), 66 deletions(-) diff --git a/verification/abi.go b/verification/abi.go index 57c0d880..f6ee5cb0 100755 --- a/verification/abi.go +++ b/verification/abi.go @@ -3,11 +3,12 @@ package verification import ( - "errors" "fmt" "reflect" ) +var DefaultContextHandle = ContextHandle{0} + const ( CmdMagic uint32 = 0x44504543 RespMagic uint32 = 0x44504552 @@ -35,9 +36,13 @@ type Support struct { const ( CommandGetProfile CommandCode = 0x1 CommandInitializeContext CommandCode = 0x7 + CommandDeriveChild CommandCode = 0x8 CommandCertifyKey CommandCode = 0x9 + CommandSign CommandCode = 0xa + CommandRotateContextHandle CommandCode = 0xe CommandDestroyContext CommandCode = 0xf CommandGetCertificateChain CommandCode = 0x80 + CommandExtendTCI CommandCode = 0x81 CommandTagTCI CommandCode = 0x82 CommandGetTaggedTCI CommandCode = 0x83 ) @@ -67,6 +72,21 @@ const ( type ContextHandle [16]byte +type RotateContextHandleFlags uint32 + +const ( + TargetIsDefault RotateContextHandleFlags = 1 << 31 +) + +type RotateContextHandleCmd struct { + Handle ContextHandle + Flags RotateContextHandleFlags +} + +type RotatedContextHandle struct { + NewContextHandle ContextHandle +} + type DestroyCtxFlags uint32 const ( @@ -100,6 +120,31 @@ type GetProfileResp struct { Flags uint32 } +type DeriveChildFlags uint32 + +const ( + InternalInputInfo DeriveChildFlags = 1 << 31 + InternalInputDice DeriveChildFlags = 1 << 30 + RetainParent DeriveChildFlags = 1 << 29 + MakeDefault DeriveChildFlags = 1 << 28 + ChangeLocality DeriveChildFlags = 1 << 27 + InputAllowCA DeriveChildFlags = 1 << 26 + InputAllowX509 DeriveChildFlags = 1 << 25 +) + +type DeriveChildReq[Digest DigestAlgorithm] struct { + ContextHandle ContextHandle + InputData Digest + Flags DeriveChildFlags + TciType uint32 + TargetLocality uint32 +} + +type DeriveChildResp struct { + NewContextHandle ContextHandle + ParentContextHandle ContextHandle +} + type CertifyKeyFlags uint32 const ( @@ -127,6 +172,25 @@ type CertifyKeyResp[CurveParameter Curve, Digest DigestAlgorithm] struct { Certificate []byte } +type SignFlags uint32 + +const ( + IsSymmetric SignFlags = 1 << 30 +) + +type SignReq[Digest DigestAlgorithm] struct { + ContextHandle ContextHandle + Label Digest + Flags SignFlags + ToBeSigned Digest +} + +type SignResp[Digest DigestAlgorithm] struct { + NewContextHandle ContextHandle + HmacOrSignatureR Digest + SignatureS Digest +} + type GetCertificateChainReq struct { Offset uint32 Size uint32 @@ -156,6 +220,15 @@ type GetTaggedTCIResp[Digest DigestAlgorithm] struct { CurrentTCI Digest } +type ExtendTCIReq[Digest DigestAlgorithm] struct { + ContextHandle ContextHandle + InputData Digest +} + +type ExtendTCIResp struct { + NewContextHandle ContextHandle +} + // dpeABI is a connection to a DPE instance, parameterized by hash algorithm and ECC curve. type dpeABI[CurveParameter Curve, Digest DigestAlgorithm] struct { transport Transport @@ -191,12 +264,12 @@ func dpeProfileImplementsTypeConstraints[C Curve, D DigestAlgorithm](profile Pro } else if isP384 && isSHA384 { targetProfile = ProfileP384SHA384 } else { - return fmt.Errorf("Client requested (Curve = %v, Digest = %v), this is an invalid DPE profile", + return fmt.Errorf("client requested (Curve = %v, Digest = %v), this is an invalid DPE profile", reflect.TypeOf(c), reflect.TypeOf(d)) } if profile != targetProfile { - fmt.Errorf("Expected profile %v, got profile %v", targetProfile, profile) + return fmt.Errorf("expected profile %v, got profile %v", targetProfile, profile) } return nil @@ -331,6 +404,42 @@ func (c *dpeABI[CurveParameter, Digest]) CertifyKeyABI(cmd *CertifyKeyReq[Digest }, nil } +// DeriveChild calls DPE DeriveChild command. +func (c *dpeABI[_, Digest]) DeriveChildABI(cmd *DeriveChildReq[Digest]) (*DeriveChildResp, error) { + var respStruct DeriveChildResp + + _, err := execCommand(c.transport, CommandDeriveChild, c.Profile, cmd, &respStruct) + if err != nil { + return nil, err + } + + return &respStruct, err +} + +// RotateContext calls DPE RotateContextABI command. +func (c *dpeABI[_, Digest]) RotateContextABI(cmd *RotateContextHandleCmd) (*RotatedContextHandle, error) { + var respStruct RotatedContextHandle + + _, err := execCommand(c.transport, CommandRotateContextHandle, c.Profile, cmd, &respStruct) + if err != nil { + return nil, err + } + + return &respStruct, err +} + +// Sign calls the DPE Sign command. +func (c *dpeABI[_, Digest]) SignABI(cmd *SignReq[Digest]) (*SignResp[Digest], error) { + var respStruct SignResp[Digest] + + _, err := execCommand(c.transport, CommandSign, c.Profile, cmd, &respStruct) + if err != nil { + return nil, err + } + + return &respStruct, nil +} + // GetCertificateChain calls the DPE GetCertificateChain command. func (c *dpeABI[_, _]) GetCertificateChainABI() (*GetCertificateChainResp, error) { var certs GetCertificateChainResp @@ -365,7 +474,7 @@ func (c *dpeABI[_, _]) GetCertificateChainABI() (*GetCertificateChainResp, error } if len(certs.CertificateChain) == 0 { - return nil, errors.New("empty certificate chain") + return nil, fmt.Errorf("empty certificate chain returned") } return &certs, nil } @@ -394,6 +503,18 @@ func (c *dpeABI[_, Digest]) GetTaggedTCIABI(cmd *GetTaggedTCIReq) (*GetTaggedTCI return &respStruct, nil } +// ExtendTCI calls the DPE ExtendTCI command. +func (c *dpeABI[_, Digest]) ExtendTCIABI(cmd *ExtendTCIReq[Digest]) (*ExtendTCIResp, error) { + var respStruct ExtendTCIResp + + _, err := execCommand(c.transport, CommandExtendTCI, c.Profile, cmd, &respStruct) + if err != nil { + return nil, err + } + + return &respStruct, nil +} + func (c *dpeABI[_, _]) InitializeContext(flags InitCtxFlags) (*ContextHandle, error) { cmd := InitCtxCmd{flags: flags} resp, err := c.InitializeContextABI(&cmd) @@ -409,6 +530,10 @@ func (c *dpeABI[_, _]) GetProfile() (*GetProfileResp, error) { } func (c *dpeABI[_, Digest]) CertifyKey(handle *ContextHandle, label []byte, format CertifyKeyFormat, flags CertifyKeyFlags) (*CertifiedKey, error) { + if len(label) != len(Digest(label)) { + return nil, fmt.Errorf("invalid digest length") + } + cmd := CertifyKeyReq[Digest]{ ContextHandle: *handle, Flags: flags, @@ -416,10 +541,6 @@ func (c *dpeABI[_, Digest]) CertifyKey(handle *ContextHandle, label []byte, form Format: format, } - if len(label) != len(cmd.Label) { - return nil, fmt.Errorf("Invalid digest length") - } - resp, err := c.CertifyKeyABI(&cmd) if err != nil { return nil, err @@ -437,6 +558,68 @@ func (c *dpeABI[_, Digest]) CertifyKey(handle *ContextHandle, label []byte, form return key, nil } +func (c *dpeABI[_, Digest]) DeriveChild(handle *ContextHandle, inputData []byte, flags DeriveChildFlags, tciType uint32, targetLocality uint32) (*DeriveChildResp, error) { + cmd := DeriveChildReq[Digest]{ + ContextHandle: *handle, + InputData: Digest(inputData), + Flags: flags, + TciType: tciType, + TargetLocality: targetLocality, + } + + if len(inputData) != len(cmd.InputData) { + return nil, fmt.Errorf("invalid digest length") + } + + resp, err := c.DeriveChildABI(&cmd) + if err != nil { + return nil, err + } + + return resp, nil +} + +func (c *dpeABI[_, _]) RotateContextHandle(handle *ContextHandle, flags RotateContextHandleFlags) (*ContextHandle, error) { + cmd := RotateContextHandleCmd{ + Handle: *handle, + Flags: flags, + } + resp, err := c.RotateContextABI(&cmd) + if err != nil { + return nil, err + } + return &resp.NewContextHandle, nil +} + +func (c *dpeABI[_, Digest]) Sign(handle *ContextHandle, label []byte, flags SignFlags, toBeSigned []byte) (*DPESignedHash, error) { + if len(label) != len(Digest(label)) { + return nil, fmt.Errorf("invalid digest length") + } + + if len(toBeSigned) != len(Digest(toBeSigned)) { + return nil, fmt.Errorf("invalid toBeSigned length") + } + + cmd := SignReq[Digest]{ + ContextHandle: *handle, + Label: Digest(label), + Flags: flags, + ToBeSigned: Digest(toBeSigned), + } + resp, err := c.SignABI(&cmd) + if err != nil { + return nil, err + } + + signedResp := &DPESignedHash{ + Handle: resp.NewContextHandle, + HmacOrSignatureR: resp.HmacOrSignatureR.Bytes(), + SignatureS: resp.SignatureS.Bytes(), + } + + return signedResp, nil +} + func (c *dpeABI[_, _]) TagTCI(handle *ContextHandle, tag TCITag) (*ContextHandle, error) { cmd := TagTCIReq{ ContextHandle: *handle, @@ -467,6 +650,25 @@ func (c *dpeABI[_, _]) GetTaggedTCI(tag TCITag) (*DPETCI, error) { }, nil } +func (c *dpeABI[_, Digest]) ExtendTCI(handle *ContextHandle, inputData []byte) (*ContextHandle, error) { + + if len(inputData) != len(Digest(inputData)) { + return nil, fmt.Errorf("invalid digest length") + } + + cmd := ExtendTCIReq[Digest]{ + ContextHandle: *handle, + InputData: Digest(inputData), + } + + resp, err := c.ExtendTCIABI(&cmd) + if err != nil { + return nil, err + } + + return &resp.NewContextHandle, nil +} + func (c *dpeABI[_, _]) DestroyContext(handle *ContextHandle, flags DestroyCtxFlags) error { cmd := DestroyCtxCmd{ handle: *handle, diff --git a/verification/certifyKey.go b/verification/certifyKey.go index 3e83e05d..a77b9b68 100755 --- a/verification/certifyKey.go +++ b/verification/certifyKey.go @@ -432,26 +432,7 @@ func checkCertificateStructure(t *testing.T, certBytes []byte) *x509.Certificate } func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, use_simulation bool) { - var ctx ContextHandle - if use_simulation { - if d.GetSupport().Simulation { - handle, err := client.InitializeContext(InitIsSimulation) - if err != nil { - t.Fatal("The instance should be able to create a simulation context.") - } - // Could prove difficult to prove it is a cryptographically secure random. - if *handle == ContextHandle([16]byte{0}) { - t.Fatal("Incorrect simulation context handle.") - } - - defer client.DestroyContext(handle, 0) - } else { - t.Errorf("[ERROR]: DPE instance doesn't support simulation contexts.") - } - } else { - //default context - ctx = [16]byte{0} - } + ctx := getContextHandle(d, client, t, use_simulation) type Params struct { Label []byte @@ -476,7 +457,7 @@ func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, use_simul for _, params := range certifyKeyParams { // Get DPE leaf certificate from CertifyKey - certifyKeyResp, err := client.CertifyKey(&ctx, params.Label, CertifyKeyX509, params.Flags) + certifyKeyResp, err := client.CertifyKey(ctx, params.Label, CertifyKeyX509, params.Flags) if err != nil { t.Fatalf("[FATAL]: Could not certify key: %v", err) } @@ -501,6 +482,7 @@ func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, use_simul validateLeafCertChain(t, certChain, leafCert) // TODO: When DeriveChild is implemented, call it here to add more TCIs and call CertifyKey again. + ctx = &certifyKeyResp.Handle } } diff --git a/verification/client.go b/verification/client.go index 96cde995..1a5bbbee 100755 --- a/verification/client.go +++ b/verification/client.go @@ -33,14 +33,24 @@ type DPETCI struct { CurrentTCI []byte } +type DPESignedHash struct { + Handle ContextHandle + HmacOrSignatureR []byte + SignatureS []byte +} + type DPEClient interface { InitializeContext(flags InitCtxFlags) (*ContextHandle, error) GetProfile() (*GetProfileResp, error) + DeriveChild(handle *ContextHandle, inputData []byte, flags DeriveChildFlags, tciType uint32, targetLocality uint32) (*DeriveChildResp, error) CertifyKey(handle *ContextHandle, label []byte, format CertifyKeyFormat, flags CertifyKeyFlags) (*CertifiedKey, error) GetCertificateChain() ([]byte, error) TagTCI(handle *ContextHandle, tag TCITag) (*ContextHandle, error) GetTaggedTCI(tag TCITag) (*DPETCI, error) + ExtendTCI(handle *ContextHandle, inputData []byte) (*ContextHandle, error) DestroyContext(handle *ContextHandle, flags DestroyCtxFlags) error + RotateContextHandle(handle *ContextHandle, flags RotateContextHandleFlags) (*ContextHandle, error) + Sign(handle *ContextHandle, label []byte, flags SignFlags, toBeSigned []byte) (*DPESignedHash, error) } func NewClient(t Transport, p Profile) (DPEClient, error) { diff --git a/verification/initializeContext.go b/verification/initializeContext.go index 68edbda4..764cc5ed 100644 --- a/verification/initializeContext.go +++ b/verification/initializeContext.go @@ -67,3 +67,28 @@ func testInitContext(d TestDPEInstance, client DPEClient, t *testing.T, simulati } } } + +func getContextHandle(d TestDPEInstance, c DPEClient, t *testing.T, simulation bool) *ContextHandle { + var handle *ContextHandle + var err error + if simulation { + if d.GetSupport().Simulation { + handle, err = c.InitializeContext(InitIsSimulation) + if err != nil { + t.Fatal("The instance should be able to create a simulation context.") + } + // Could prove difficult to prove it is a cryptographically secure random. + if *handle == ContextHandle([16]byte{0}) { + t.Fatal("Incorrect simulation context handle.") + } + } else { + t.Fatal("[FATAL]: DPE instance doesn't support simulation contexts.") + } + } else { + //default context + defaultContext := ContextHandle{0} + handle = &defaultContext + } + + return handle +} diff --git a/verification/simulator.go b/verification/simulator.go index 97ac04c5..3c3d044b 100644 --- a/verification/simulator.go +++ b/verification/simulator.go @@ -230,7 +230,7 @@ func GetSimulatorTargets() []TestTarget { }, { "DefaultSupport", - getTestTarget([]string{"AutoInit", "Simulation", "X509", "IsCA", "Tagging"}), + getTestTarget([]string{"AutoInit", "Simulation", "X509", "IsCA", "Tagging", "ExtendTci"}), AllTestCases, }, { diff --git a/verification/tagTCI.go b/verification/tagTCI.go index 367a77d2..8c6849e2 100644 --- a/verification/tagTCI.go +++ b/verification/tagTCI.go @@ -3,65 +3,227 @@ package verification import ( + "bytes" + "crypto/sha256" + "crypto/sha512" "errors" + "hash" + //"reflect" "testing" ) // This file is used to test the tagTCI command. -func TestTagTCI(d TestDPEInstance, client DPEClient, t *testing.T) { - // Try to create the default context if isn't done automatically. - if !d.GetSupport().AutoInit { - handle, err := client.InitializeContext(InitIsDefault) - if err != nil { - t.Fatalf("Failed to initialize default context: %v", err) - } - defer client.DestroyContext(handle, DestroyDescendants) +func TestTagTCI(d TestDPEInstance, c DPEClient, t *testing.T) { + var err error + // Tag the default context + handle := getContextHandle(d, c, t, false) + + // Get digest size + profile, err := GetTransportProfile(d) + if err != nil { + t.Fatalf("Could not get profile: %v", err) } + digestLen := profile.GetDigestSize() + tag := TCITag(12345) // Check to see our tag is not yet found. - if _, err := client.GetTaggedTCI(tag); !errors.Is(err, StatusBadTag) { + if _, err := c.GetTaggedTCI(tag); !errors.Is(err, StatusBadTag) { t.Fatalf("GetTaggedTCI returned %v, want %v", err, StatusBadTag) } - // Tag the default context - var ctx ContextHandle + // Make sure using wrong locality reports error + testTagTCIWrongLocality(d, c, t, handle) + + // Make sure default handle returns same handle when extended + testTagTCIHandle(d, c, t, handle, digestLen, tag) + + // Make sure the current TCI is updated + // For profiles which use auto-initialization, we don't know the expected TCIs so we can check only current TCI + testCurrentAndCumulativeTCI(d, c, t, handle, digestLen, tag) - handle, err := client.TagTCI(&ctx, tag) + // Make sure some other tag is still not found. + if _, err := c.GetTaggedTCI(TCITag(98765)); !errors.Is(err, StatusBadTag) { + t.Fatalf("GetTaggedTCI returned %v, want %v", err, StatusBadTag) + } + + // Pass TCI input to DerivedChild context and check cumulative TCI + testForDerivedChildContexts(d, c, t, handle, digestLen, tag) +} + +// Checks whether error is reported when the caller from one locality makes call to another locality. +func testTagTCIWrongLocality(d TestDPEInstance, c DPEClient, t *testing.T, handle *ContextHandle) { + var err error + + // Modify locality of DPE instance to test + d.SetLocality(DPE_SIMULATOR_OTHER_LOCALITY) + + // Restore locality of DPE instance after the test + defer d.SetLocality(DPE_SIMULATOR_AUTO_INIT_LOCALITY) + + _, err = c.TagTCI(handle, TCITag(1234)) + if err == nil { + t.Fatalf("[FATAL]: TagTCI command should return %q, but returned no error", StatusInvalidLocality) + } else if !errors.Is(err, StatusInvalidLocality) { + t.Fatalf("[FATAL]: Incorrect error type. TagTCI command should return %q, but returned %q", StatusInvalidLocality, err) + } +} + +// Checks whether the default handle remains unchanged when extended with TCI value. +func testTagTCIHandle(d TestDPEInstance, c DPEClient, t *testing.T, handle *ContextHandle, digestLen int, tag TCITag) { + tciValue := make([]byte, digestLen) + for i := range tciValue { + tciValue[i] = byte(i) + } + + newHandle, err := c.TagTCI(handle, tag) if err != nil { t.Fatalf("Could not tag TCI: %v", err) } + if *newHandle != *handle { + t.Errorf("New context handle from TagTCI was %x, expected %x", newHandle, handle) + } +} + +// Checks whether the ExtendTCI command updates the current TCI and cumulative TCI. +func testCurrentAndCumulativeTCI(d TestDPEInstance, c DPEClient, t *testing.T, handle *ContextHandle, digestLen int, tag TCITag) { + // Initialize TCI inputs + defaultTci := make([]byte, digestLen) + + tciValue := make([]byte, digestLen) + for i := range tciValue { + tciValue[i] = byte(i) + } + + // Initialize hasher + var hasher hash.Hash + if digestLen == 32 { + hasher = sha256.New() + } else if digestLen == 48 { + hasher = sha512.New384() + } else { + t.Error("[ERROR]: Unsupported hash algorithm used for TCI value generation") + } - if *handle != ctx { - t.Errorf("New context handle from TagTCI was %x, expected %x", handle, ctx) + // Set current TCI value + _, err := c.ExtendTCI(handle, tciValue) + if err != nil { + t.Fatalf("Could not tag TCI: %v", err) } - _, err = client.GetTaggedTCI(tag) + taggedTCI, err := c.GetTaggedTCI(tag) if err != nil { t.Fatalf("Could not get tagged TCI: %v", err) } - // TODO: For profiles which use auto-initialization, we don't know the expected - // TCIs. Uncomment this once the DeriveChild API is implemented so the test - // can control the TCI inputs. - /* - wantCumulativeTCI := make([]byte, profile.GetDigestSize()) - if !reflect.DeepEqual(taggedTCI.CumulativeTCI, wantCumulativeTCI) { - t.Errorf("GetTaggedTCI returned cumulative TCI %x, expected %x", taggedTCI.CumulativeTCI, wantCumulativeTCI) - } + // Check TCI_CURRENT + wantCurrentTCI := tciValue + if !bytes.Equal(taggedTCI.CurrentTCI, tciValue) { + t.Errorf("GetTaggedTCI returned current TCI %x, expected %x", taggedTCI.CurrentTCI, wantCurrentTCI) + } - wantCurrentTCI := make([]byte, profile.GetDigestSize()) - if !reflect.DeepEqual(taggedTCI.CurrentTCI, wantCurrentTCI) { - t.Errorf("GetTaggedTCI returned current TCI %x, expected %x", taggedTCI.CurrentTCI, wantCurrentTCI) - } - */ + // Cross-verify TCI_CUMULATIVE + hasher.Write(defaultTci) + hasher.Write(taggedTCI.CurrentTCI) + if wantCumulativeTCI := hasher.Sum(nil); !bytes.Equal(taggedTCI.CumulativeTCI, wantCumulativeTCI) { + t.Errorf("GetTaggedTCI returned cumulative TCI %x, expected %x", taggedTCI.CumulativeTCI, wantCumulativeTCI) + } +} - // Make sure some other tag is still not found. - if _, err := client.GetTaggedTCI(TCITag(98765)); !errors.Is(err, StatusBadTag) { - t.Fatalf("GetTaggedTCI returned %v, want %v", err, StatusBadTag) +// Checks whether the ExtendTCI command updates the current TCI. +func testForDerivedChildContexts(d TestDPEInstance, c DPEClient, t *testing.T, handle *ContextHandle, digestLen int, parentTag TCITag) { + var wantCumulativeTCI []byte + childTag := TCITag(23456) + + // Initialize TCI inputs + defaultTci := make([]byte, digestLen) + + 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) + } + + // Initialize hasher + var hasher hash.Hash + if digestLen == 32 { + hasher = sha256.New() + } else if digestLen == 48 { + hasher = sha512.New384() + } else { + t.Error("[ERROR]: Unsupported hash algorithm used for TCI value generation") } - // TODO: When DeriveChild is implemented, call it here to add more TCIs and call TagTCI again. + // Get parent context TCI values for cumulative value calculation + parentTci, err := c.GetTaggedTCI(parentTag) + if err != nil { + t.Fatalf("Could not get tagged TCI: %v", err) + } + + // Cross-verify parent's TCI_CUMULATIVE + hasher.Write(defaultTci) + hasher.Write(parentTci.CurrentTCI) + wantCumulativeTCI = hasher.Sum(nil) + if !bytes.Equal(parentTci.CumulativeTCI, wantCumulativeTCI) { + t.Errorf("Parent node's cumulative TCI %x, expected %x", parentTci.CumulativeTCI, wantCumulativeTCI) + } + + // Derive Child context with input data, tag it and check TCI_CUMULATIVE + child, err := c.DeriveChild(handle, tciValue, DeriveChildFlags(MakeDefault), 0, 0) + if err != nil { + t.Fatalf("[FATAL]: Error while creating default child handle in default context: %s", err) + } + + newHandle, err := c.TagTCI(&child.NewContextHandle, childTag) + if err != nil { + t.Fatalf("Could not tag TCI: %v", err) + } + + childTci, err := c.GetTaggedTCI(childTag) + if err != nil { + t.Fatalf("Could not get tagged TCI: %v", err) + } + + if !bytes.Equal(childTci.CurrentTCI, tciValue) { + t.Errorf("GetTaggedTCI returned current TCI %x, expected %x", childTci.CurrentTCI, tciValue) + } + + // Check TCI_CUMULATIVE after creating child context + hasher.Reset() + hasher.Write(defaultTci) + hasher.Write(childTci.CurrentTCI) + wantCumulativeTCI = hasher.Sum(nil) + if !bytes.Equal(childTci.CumulativeTCI, wantCumulativeTCI) { + t.Errorf("Child node's cumulative TCI %x, expected %x", childTci.CumulativeTCI, wantCumulativeTCI) + } + + // Extend TCI to child context and check TCI_CURRENT and TCI_CUMULATIVE + _, err = c.ExtendTCI(newHandle, extendTciValue) + if err != nil { + t.Fatalf("Could not tag TCI: %v", err) + } + + childExtendTci, err := c.GetTaggedTCI(childTag) + if err != nil { + t.Fatalf("Could not get tagged TCI: %v", err) + } + + if !bytes.Equal(childExtendTci.CurrentTCI, extendTciValue) { + t.Errorf("GetTaggedTCI returned current TCI %x, expected %x", childExtendTci.CurrentTCI, extendTciValue) + } + + // Check TCI_CUMULATIVE after extending input to child context + hasher.Reset() + hasher.Write(childTci.CumulativeTCI) + hasher.Write(childExtendTci.CurrentTCI) + wantCumulativeTCI = hasher.Sum(nil) + if !bytes.Equal(childExtendTci.CumulativeTCI, wantCumulativeTCI) { + t.Errorf("Child node's cumulative TCI %x, expected %x", childExtendTci.CumulativeTCI, wantCumulativeTCI) + } } diff --git a/verification/verification.go b/verification/verification.go index 4e2b0c06..4bac76c9 100644 --- a/verification/verification.go +++ b/verification/verification.go @@ -2,7 +2,9 @@ package verification -import "testing" +import ( + "testing" +) type DpeTestFunc func(d TestDPEInstance, c DPEClient, t *testing.T) @@ -34,7 +36,7 @@ var GetCertificateChainTestCase = TestCase{ "GetCertificateChain", TestGetCertificateChain, []string{"AutoInit", "X509"}, } var TagTCITestCase = TestCase{ - "TagTCI", TestTagTCI, []string{"AutoInit", "Tagging"}, + "TagTCI", TestTagTCI, []string{"AutoInit", "Tagging", "ExtendTci"}, } var GetProfileTestCase = TestCase{ "GetProfile", TestGetProfile, []string{}, @@ -42,12 +44,12 @@ var GetProfileTestCase = TestCase{ var AllTestCases = []TestCase{ CertifyKeyTestCase, - CertifyKeySimulationTestCase, - GetCertificateChainTestCase, TagTCITestCase, + GetCertificateChainTestCase, GetProfileTestCase, InitializeContextTestCase, InitializeContextSimulationTestCase, + CertifyKeySimulationTestCase, } func RunTargetTestCases(target TestTarget, t *testing.T) { From 3d0046249bb17f52668979a443bb8f7cbb758126 Mon Sep 17 00:00:00 2001 From: hpya93 Date: Wed, 8 Nov 2023 02:00:41 +0530 Subject: [PATCH 02/10] rebased code in accordance to PR 255 --- dpe/src/commands/sign.rs | 6 +- verification/abi.go | 299 +++++++++++++++--------------- verification/certifyKey.go | 17 +- verification/client.go | 6 +- verification/initializeContext.go | 9 +- verification/negativeCases.go | 259 ++++++++++++++++++++++++++ verification/simulator.go | 12 +- verification/tagTCI.go | 25 +-- verification/verification.go | 18 +- 9 files changed, 461 insertions(+), 190 deletions(-) create mode 100644 verification/negativeCases.go diff --git a/dpe/src/commands/sign.rs b/dpe/src/commands/sign.rs index 20811d87..8b955821 100644 --- a/dpe/src/commands/sign.rs +++ b/dpe/src/commands/sign.rs @@ -15,7 +15,7 @@ pub struct SignFlags(u32); bitflags! { impl SignFlags: u32 { - const IS_SYMMETRIC = 1u32 << 31; + const IS_SYMMETRIC = 1u32 << 30; } } @@ -83,7 +83,7 @@ impl CommandExecution for SignCmd { ) -> Result { // Make sure the operation is supported. if !dpe.support.is_symmetric() && self.uses_symmetric() { - return Err(DpeErrorCode::InvalidArgument); + return Err(DpeErrorCode::ArgumentNotSupported); } let idx = dpe.get_active_context_pos(&self.handle, locality)?; @@ -190,7 +190,7 @@ mod tests { // Bad argument assert_eq!( - Err(DpeErrorCode::InvalidArgument), + Err(DpeErrorCode::ArgumentNotSupported), SignCmd { handle: ContextHandle([0xff; ContextHandle::SIZE]), label: TEST_LABEL, diff --git a/verification/abi.go b/verification/abi.go index f6ee5cb0..22b23295 100755 --- a/verification/abi.go +++ b/verification/abi.go @@ -72,21 +72,6 @@ const ( type ContextHandle [16]byte -type RotateContextHandleFlags uint32 - -const ( - TargetIsDefault RotateContextHandleFlags = 1 << 31 -) - -type RotateContextHandleCmd struct { - Handle ContextHandle - Flags RotateContextHandleFlags -} - -type RotatedContextHandle struct { - NewContextHandle ContextHandle -} - type DestroyCtxFlags uint32 const ( @@ -120,31 +105,6 @@ type GetProfileResp struct { Flags uint32 } -type DeriveChildFlags uint32 - -const ( - InternalInputInfo DeriveChildFlags = 1 << 31 - InternalInputDice DeriveChildFlags = 1 << 30 - RetainParent DeriveChildFlags = 1 << 29 - MakeDefault DeriveChildFlags = 1 << 28 - ChangeLocality DeriveChildFlags = 1 << 27 - InputAllowCA DeriveChildFlags = 1 << 26 - InputAllowX509 DeriveChildFlags = 1 << 25 -) - -type DeriveChildReq[Digest DigestAlgorithm] struct { - ContextHandle ContextHandle - InputData Digest - Flags DeriveChildFlags - TciType uint32 - TargetLocality uint32 -} - -type DeriveChildResp struct { - NewContextHandle ContextHandle - ParentContextHandle ContextHandle -} - type CertifyKeyFlags uint32 const ( @@ -172,25 +132,6 @@ type CertifyKeyResp[CurveParameter Curve, Digest DigestAlgorithm] struct { Certificate []byte } -type SignFlags uint32 - -const ( - IsSymmetric SignFlags = 1 << 30 -) - -type SignReq[Digest DigestAlgorithm] struct { - ContextHandle ContextHandle - Label Digest - Flags SignFlags - ToBeSigned Digest -} - -type SignResp[Digest DigestAlgorithm] struct { - NewContextHandle ContextHandle - HmacOrSignatureR Digest - SignatureS Digest -} - type GetCertificateChainReq struct { Offset uint32 Size uint32 @@ -220,6 +161,65 @@ type GetTaggedTCIResp[Digest DigestAlgorithm] struct { CurrentTCI Digest } +type RotateContextHandleFlags uint32 + +const ( + TargetIsDefault RotateContextHandleFlags = 1 << 31 +) + +type RotateContextHandleCmd struct { + Handle ContextHandle + Flags RotateContextHandleFlags +} + +type RotatedContextHandle struct { + NewContextHandle ContextHandle +} + +type DeriveChildFlags uint32 + +const ( + InternalInputInfo DeriveChildFlags = 1 << 31 + InternalInputDice DeriveChildFlags = 1 << 30 + RetainParent DeriveChildFlags = 1 << 29 + MakeDefault DeriveChildFlags = 1 << 28 + ChangeLocality DeriveChildFlags = 1 << 27 + InputAllowCA DeriveChildFlags = 1 << 26 + InputAllowX509 DeriveChildFlags = 1 << 25 +) + +type DeriveChildReq[Digest DigestAlgorithm] struct { + ContextHandle ContextHandle + InputData Digest + Flags DeriveChildFlags + TciType uint32 + TargetLocality uint32 +} + +type DeriveChildResp struct { + NewContextHandle ContextHandle + ParentContextHandle ContextHandle +} + +type SignFlags uint32 + +const ( + IsSymmetric SignFlags = 1 << 30 +) + +type SignReq[Digest DigestAlgorithm] struct { + ContextHandle ContextHandle + Label Digest + Flags SignFlags + ToBeSigned Digest +} + +type SignResp[Digest DigestAlgorithm] struct { + NewContextHandle ContextHandle + HmacOrSignatureR Digest + SignatureS Digest +} + type ExtendTCIReq[Digest DigestAlgorithm] struct { ContextHandle ContextHandle InputData Digest @@ -404,42 +404,6 @@ func (c *dpeABI[CurveParameter, Digest]) CertifyKeyABI(cmd *CertifyKeyReq[Digest }, nil } -// DeriveChild calls DPE DeriveChild command. -func (c *dpeABI[_, Digest]) DeriveChildABI(cmd *DeriveChildReq[Digest]) (*DeriveChildResp, error) { - var respStruct DeriveChildResp - - _, err := execCommand(c.transport, CommandDeriveChild, c.Profile, cmd, &respStruct) - if err != nil { - return nil, err - } - - return &respStruct, err -} - -// RotateContext calls DPE RotateContextABI command. -func (c *dpeABI[_, Digest]) RotateContextABI(cmd *RotateContextHandleCmd) (*RotatedContextHandle, error) { - var respStruct RotatedContextHandle - - _, err := execCommand(c.transport, CommandRotateContextHandle, c.Profile, cmd, &respStruct) - if err != nil { - return nil, err - } - - return &respStruct, err -} - -// Sign calls the DPE Sign command. -func (c *dpeABI[_, Digest]) SignABI(cmd *SignReq[Digest]) (*SignResp[Digest], error) { - var respStruct SignResp[Digest] - - _, err := execCommand(c.transport, CommandSign, c.Profile, cmd, &respStruct) - if err != nil { - return nil, err - } - - return &respStruct, nil -} - // GetCertificateChain calls the DPE GetCertificateChain command. func (c *dpeABI[_, _]) GetCertificateChainABI() (*GetCertificateChainResp, error) { var certs GetCertificateChainResp @@ -503,6 +467,42 @@ func (c *dpeABI[_, Digest]) GetTaggedTCIABI(cmd *GetTaggedTCIReq) (*GetTaggedTCI return &respStruct, nil } +// DeriveChild calls DPE DeriveChild command. +func (c *dpeABI[_, Digest]) DeriveChildABI(cmd *DeriveChildReq[Digest]) (*DeriveChildResp, error) { + var respStruct DeriveChildResp + + _, err := execCommand(c.transport, CommandDeriveChild, c.Profile, cmd, &respStruct) + if err != nil { + return nil, err + } + + return &respStruct, err +} + +// RotateContextHandle calls DPE RotateContextHandle command. +func (c *dpeABI[_, Digest]) RotateContextABI(cmd *RotateContextHandleCmd) (*RotatedContextHandle, error) { + var respStruct RotatedContextHandle + + _, err := execCommand(c.transport, CommandRotateContextHandle, c.Profile, cmd, &respStruct) + if err != nil { + return nil, err + } + + return &respStruct, err +} + +// Sign calls the DPE Sign command. +func (c *dpeABI[_, Digest]) SignABI(cmd *SignReq[Digest]) (*SignResp[Digest], error) { + var respStruct SignResp[Digest] + + _, err := execCommand(c.transport, CommandSign, c.Profile, cmd, &respStruct) + if err != nil { + return nil, err + } + + return &respStruct, nil +} + // ExtendTCI calls the DPE ExtendTCI command. func (c *dpeABI[_, Digest]) ExtendTCIABI(cmd *ExtendTCIReq[Digest]) (*ExtendTCIResp, error) { var respStruct ExtendTCIResp @@ -531,7 +531,7 @@ func (c *dpeABI[_, _]) GetProfile() (*GetProfileResp, error) { func (c *dpeABI[_, Digest]) CertifyKey(handle *ContextHandle, label []byte, format CertifyKeyFormat, flags CertifyKeyFlags) (*CertifiedKey, error) { if len(label) != len(Digest(label)) { - return nil, fmt.Errorf("invalid digest length") + return nil, fmt.Errorf("invalid label length") } cmd := CertifyKeyReq[Digest]{ @@ -558,7 +558,59 @@ func (c *dpeABI[_, Digest]) CertifyKey(handle *ContextHandle, label []byte, form return key, nil } +func (c *dpeABI[_, _]) TagTCI(handle *ContextHandle, tag TCITag) (*ContextHandle, error) { + cmd := TagTCIReq{ + ContextHandle: *handle, + Tag: tag, + } + + resp, err := c.TagTCIABI(&cmd) + if err != nil { + return nil, err + } + + return &resp.NewContextHandle, nil +} + +func (c *dpeABI[_, _]) GetTaggedTCI(tag TCITag) (*DPETCI, error) { + cmd := GetTaggedTCIReq{ + Tag: tag, + } + + resp, err := c.GetTaggedTCIABI(&cmd) + if err != nil { + return nil, err + } + + return &DPETCI{ + CumulativeTCI: resp.CumulativeTCI.Bytes(), + CurrentTCI: resp.CurrentTCI.Bytes(), + }, nil +} + +func (c *dpeABI[_, _]) DestroyContext(handle *ContextHandle, flags DestroyCtxFlags) error { + cmd := DestroyCtxCmd{ + handle: *handle, + flags: flags, + } + + return c.DestroyContextABI(&cmd) +} + +func (c *dpeABI[_, _]) GetCertificateChain() ([]byte, error) { + resp, err := c.GetCertificateChainABI() + if err != nil { + return nil, err + } + + return resp.CertificateChain, nil +} + func (c *dpeABI[_, Digest]) DeriveChild(handle *ContextHandle, inputData []byte, flags DeriveChildFlags, tciType uint32, targetLocality uint32) (*DeriveChildResp, error) { + if len(inputData) != len(Digest(inputData)) { + return nil, fmt.Errorf("invalid digest length") + } + cmd := DeriveChildReq[Digest]{ ContextHandle: *handle, InputData: Digest(inputData), @@ -566,11 +618,6 @@ func (c *dpeABI[_, Digest]) DeriveChild(handle *ContextHandle, inputData []byte, TciType: tciType, TargetLocality: targetLocality, } - - if len(inputData) != len(cmd.InputData) { - return nil, fmt.Errorf("invalid digest length") - } - resp, err := c.DeriveChildABI(&cmd) if err != nil { return nil, err @@ -593,7 +640,7 @@ func (c *dpeABI[_, _]) RotateContextHandle(handle *ContextHandle, flags RotateCo func (c *dpeABI[_, Digest]) Sign(handle *ContextHandle, label []byte, flags SignFlags, toBeSigned []byte) (*DPESignedHash, error) { if len(label) != len(Digest(label)) { - return nil, fmt.Errorf("invalid digest length") + return nil, fmt.Errorf("invalid label length") } if len(toBeSigned) != len(Digest(toBeSigned)) { @@ -620,36 +667,6 @@ func (c *dpeABI[_, Digest]) Sign(handle *ContextHandle, label []byte, flags Sign return signedResp, nil } -func (c *dpeABI[_, _]) TagTCI(handle *ContextHandle, tag TCITag) (*ContextHandle, error) { - cmd := TagTCIReq{ - ContextHandle: *handle, - Tag: tag, - } - - resp, err := c.TagTCIABI(&cmd) - if err != nil { - return nil, err - } - - return &resp.NewContextHandle, nil -} - -func (c *dpeABI[_, _]) GetTaggedTCI(tag TCITag) (*DPETCI, error) { - cmd := GetTaggedTCIReq{ - Tag: tag, - } - - resp, err := c.GetTaggedTCIABI(&cmd) - if err != nil { - return nil, err - } - - return &DPETCI{ - CumulativeTCI: resp.CumulativeTCI.Bytes(), - CurrentTCI: resp.CurrentTCI.Bytes(), - }, nil -} - func (c *dpeABI[_, Digest]) ExtendTCI(handle *ContextHandle, inputData []byte) (*ContextHandle, error) { if len(inputData) != len(Digest(inputData)) { @@ -669,24 +686,6 @@ func (c *dpeABI[_, Digest]) ExtendTCI(handle *ContextHandle, inputData []byte) ( return &resp.NewContextHandle, nil } -func (c *dpeABI[_, _]) DestroyContext(handle *ContextHandle, flags DestroyCtxFlags) error { - cmd := DestroyCtxCmd{ - handle: *handle, - flags: flags, - } - - return c.DestroyContextABI(&cmd) -} - -func (c *dpeABI[_, _]) GetCertificateChain() ([]byte, error) { - resp, err := c.GetCertificateChainABI() - if err != nil { - return nil, err - } - - return resp.CertificateChain, nil -} - func (s *Support) ToFlags() uint32 { flags := uint32(0) if s.Simulation { diff --git a/verification/certifyKey.go b/verification/certifyKey.go index a77b9b68..d733bbb9 100755 --- a/verification/certifyKey.go +++ b/verification/certifyKey.go @@ -431,8 +431,11 @@ func checkCertificateStructure(t *testing.T, certBytes []byte) *x509.Certificate return x509Cert } -func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, use_simulation bool) { - ctx := getContextHandle(d, client, t, use_simulation) +func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, simulation bool) { + ctx := getInitialContextHandle(d, client, t, simulation) + if simulation { + defer client.DestroyContext(ctx, 0) + } type Params struct { Label []byte @@ -451,8 +454,8 @@ func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, use_simul } certifyKeyParams := []Params{ - Params{Label: make([]byte, digestLen), Flags: CertifyKeyFlags(0)}, - Params{Label: seqLabel, Flags: CertifyKeyFlags(0)}, + {Label: make([]byte, digestLen), Flags: CertifyKeyFlags(0)}, + {Label: seqLabel, Flags: CertifyKeyFlags(0)}, } for _, params := range certifyKeyParams { @@ -481,8 +484,12 @@ func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, use_simul // This also checks certificate lifetime, signatures as part of cert chain validation validateLeafCertChain(t, certChain, leafCert) - // TODO: When DeriveChild is implemented, call it here to add more TCIs and call CertifyKey again. + // Reassign handle for simulation mode. + // However, this does not impact in default mode because + // same default context handle is returned in default mode. ctx = &certifyKeyResp.Handle + + // TODO: When DeriveChild is implemented, call it here to add more TCIs and call CertifyKey again. } } diff --git a/verification/client.go b/verification/client.go index 1a5bbbee..23aaf42f 100755 --- a/verification/client.go +++ b/verification/client.go @@ -42,15 +42,15 @@ type DPESignedHash struct { type DPEClient interface { InitializeContext(flags InitCtxFlags) (*ContextHandle, error) GetProfile() (*GetProfileResp, error) - DeriveChild(handle *ContextHandle, inputData []byte, flags DeriveChildFlags, tciType uint32, targetLocality uint32) (*DeriveChildResp, error) CertifyKey(handle *ContextHandle, label []byte, format CertifyKeyFormat, flags CertifyKeyFlags) (*CertifiedKey, error) GetCertificateChain() ([]byte, error) TagTCI(handle *ContextHandle, tag TCITag) (*ContextHandle, error) GetTaggedTCI(tag TCITag) (*DPETCI, error) - ExtendTCI(handle *ContextHandle, inputData []byte) (*ContextHandle, error) DestroyContext(handle *ContextHandle, flags DestroyCtxFlags) error + DeriveChild(handle *ContextHandle, inputData []byte, flags DeriveChildFlags, tciType uint32, targetLocality uint32) (*DeriveChildResp, error) RotateContextHandle(handle *ContextHandle, flags RotateContextHandleFlags) (*ContextHandle, error) Sign(handle *ContextHandle, label []byte, flags SignFlags, toBeSigned []byte) (*DPESignedHash, error) + ExtendTCI(handle *ContextHandle, inputData []byte) (*ContextHandle, error) } func NewClient(t Transport, p Profile) (DPEClient, error) { @@ -60,6 +60,6 @@ func NewClient(t Transport, p Profile) (DPEClient, error) { case ProfileP384SHA384: return NewDPEABI384(t) default: - return nil, fmt.Errorf("Cannot create a DPE client for profile %d", p) + return nil, fmt.Errorf("cannot create a DPE client for profile %d", p) } } diff --git a/verification/initializeContext.go b/verification/initializeContext.go index 764cc5ed..e9bbf5ad 100644 --- a/verification/initializeContext.go +++ b/verification/initializeContext.go @@ -68,7 +68,10 @@ func testInitContext(d TestDPEInstance, client DPEClient, t *testing.T, simulati } } -func getContextHandle(d TestDPEInstance, c DPEClient, t *testing.T, simulation bool) *ContextHandle { +// When simulation is set to false, returns a default context handle. +// Else initializes a simulation context and returns its handle. To get simulation +// context handle, the DPE profile must support simulation context creation. +func getInitialContextHandle(d TestDPEInstance, c DPEClient, t *testing.T, simulation bool) *ContextHandle { var handle *ContextHandle var err error if simulation { @@ -77,7 +80,6 @@ func getContextHandle(d TestDPEInstance, c DPEClient, t *testing.T, simulation b if err != nil { t.Fatal("The instance should be able to create a simulation context.") } - // Could prove difficult to prove it is a cryptographically secure random. if *handle == ContextHandle([16]byte{0}) { t.Fatal("Incorrect simulation context handle.") } @@ -86,8 +88,7 @@ func getContextHandle(d TestDPEInstance, c DPEClient, t *testing.T, simulation b } } else { //default context - defaultContext := ContextHandle{0} - handle = &defaultContext + handle = &DefaultContextHandle } return handle diff --git a/verification/negativeCases.go b/verification/negativeCases.go new file mode 100644 index 00000000..9f6f9f1f --- /dev/null +++ b/verification/negativeCases.go @@ -0,0 +1,259 @@ +// Licensed under the Apache-2.0 license + +package verification + +import ( + "errors" + "testing" +) + +var InvalidHandle = ContextHandle{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} + +// Checks whether error is reported when non-existent handle is passed as input to DPE commands. +// Exceptions are - GetProfile, InitializeContext, GetCertificateChain, GetTaggedTCI commands +// which do not need context handle as input parameter. +func TestInvalidHandle(d TestDPEInstance, c DPEClient, t *testing.T) { + ctx := getInitialContextHandle(d, c, t, true) + defer c.DestroyContext(ctx, DestroyDescendants) + + profile, err := GetTransportProfile(d) + if err != nil { + t.Fatalf("Could not get profile: %v", err) + } + digestLen := profile.GetDigestSize() + + // Check DeriveChild with invalid handle + if _, err := c.DeriveChild(&InvalidHandle, make([]byte, digestLen), 0, 0, 0); err == nil { + t.Errorf("[ERROR]: DeriveChild should return %q, but returned no error", StatusInvalidHandle) + } else if !errors.Is(err, StatusInvalidHandle) { + t.Errorf("[ERROR]: Incorrect error type. DeriveChild should return %q, but returned %q", StatusInvalidHandle, err) + } + + // Check CertifyKey with invalid handle + if _, err := c.CertifyKey(&InvalidHandle, make([]byte, digestLen), 0, 0); err == nil { + t.Errorf("[ERROR]: CertifyKey should return %q, but returned no error", StatusInvalidHandle) + } else if !errors.Is(err, StatusInvalidHandle) { + t.Errorf("[ERROR]: Incorrect error type. CertifyKey should return %q, but returned %q", StatusInvalidHandle, err) + } + + // Check Sign with invalid handle + if _, err := c.Sign(&InvalidHandle, make([]byte, digestLen), 0, make([]byte, digestLen)); err == nil { + t.Errorf("[ERROR]: Sign should return %q, but returned no error", StatusInvalidHandle) + } else if !errors.Is(err, StatusInvalidHandle) { + t.Errorf("[ERROR]: Incorrect error type. Sign should return %q, but returned %q", StatusInvalidHandle, err) + } + + // Check RotateContextHandle with invalid handle + if _, err := c.RotateContextHandle(&InvalidHandle, RotateContextHandleFlags(TargetIsDefault)); err == nil { + t.Errorf("[ERROR]: RotateContextHandle should return %q, but returned no error", StatusInvalidHandle) + } else if !errors.Is(err, StatusInvalidHandle) { + t.Errorf("[ERROR]: Incorrect error type. RotateContextHandle should return %q, but returned %q", StatusInvalidHandle, err) + } + + // Check DestroyContext with invalid handle + if err := c.DestroyContext(&InvalidHandle, 0); err == nil { + t.Errorf("[ERROR]: DestroyContext should return %q, but returned no error", StatusInvalidHandle) + } else if !errors.Is(err, StatusInvalidHandle) { + t.Errorf("[ERROR]: Incorrect error type. DestroyContext should return %q, but returned %q", StatusInvalidHandle, err) + } + + // Check ExtendTCI with invalid handle + if _, err := c.ExtendTCI(&InvalidHandle, make([]byte, digestLen)); err == nil { + t.Errorf("[ERROR]: ExtendTCI should return %q, but returned no error", StatusInvalidHandle) + } else if !errors.Is(err, StatusInvalidHandle) { + t.Errorf("[ERROR]: Incorrect error type. ExtendTCI should return %q, but returned %q", StatusInvalidHandle, err) + } + + // Check TagTCI with invalid handle + if _, err := c.TagTCI(&InvalidHandle, 0); err == nil { + t.Errorf("[ERROR]: TagTCI should return %q, but returned no error", StatusInvalidHandle) + } else if !errors.Is(err, StatusInvalidHandle) { + t.Errorf("[ERROR]: Incorrect error type. TagTCI should return %q, but returned %q", StatusInvalidHandle, err) + } +} + +// Checks whether error is reported when caller from one locality issues DPE commands in another locality. +// Exceptions are - GetProfile, InitializeContext, GetCertificateChain, GetTaggedTCI commands +// which do not need context handle as input and hence locality is irrelevant. +func TestWrongLocality(d TestDPEInstance, c DPEClient, t *testing.T) { + // Modify and later restore the locality of DPE instance to test + d.SetLocality(DPE_SIMULATOR_OTHER_LOCALITY) + defer d.SetLocality(DPE_SIMULATOR_AUTO_INIT_LOCALITY) + + // Get default context handle + handle := &DefaultContextHandle + + // Get digest size + profile, err := GetTransportProfile(d) + if err != nil { + t.Fatalf("Could not get profile: %v", err) + } + + digestLen := profile.GetDigestSize() + + // Check DeriveChild from wrong context + if _, err := c.DeriveChild(handle, make([]byte, digestLen), 0, 0, 0); err == nil { + t.Errorf("[ERROR]: DeriveChild should return %q, but returned no error", StatusInvalidLocality) + } else if !errors.Is(err, StatusInvalidLocality) { + t.Errorf("[ERROR]: Incorrect error type. DeriveChild should return %q, but returned %q", StatusInvalidLocality, err) + } + + // Check CertifyKey from wrong locality + if _, err := c.CertifyKey(handle, make([]byte, digestLen), 0, 0); err == nil { + t.Errorf("[ERROR]: CertifyKey should return %q, but returned no error", StatusInvalidLocality) + } else if !errors.Is(err, StatusInvalidLocality) { + t.Errorf("[ERROR]: Incorrect error type. CertifyKey should return %q, but returned %q", StatusInvalidLocality, err) + } + + // Check Sign from wrong locality + if _, err := c.Sign(handle, make([]byte, digestLen), 0, make([]byte, digestLen)); err == nil { + t.Errorf("[ERROR]: Sign should return %q, but returned no error", StatusInvalidLocality) + } else if !errors.Is(err, StatusInvalidLocality) { + t.Errorf("[ERROR]: Incorrect error type. Sign should return %q, but returned %q", StatusInvalidLocality, err) + } + + // Check RotateContextHandle from wrong locality + if _, err := c.RotateContextHandle(handle, RotateContextHandleFlags(TargetIsDefault)); err == nil { + t.Errorf("[ERROR]: RotateContextHandle should return %q, but returned no error", StatusInvalidLocality) + } else if !errors.Is(err, StatusInvalidLocality) { + t.Errorf("[ERROR]: Incorrect error type. RotateContextHandle should return %q, but returned %q", StatusInvalidLocality, err) + } + + // Check DestroyContext from wrong locality + if err := c.DestroyContext(handle, 0); err == nil { + t.Errorf("[ERROR]: DestroyContext should return %q, but returned no error", StatusInvalidLocality) + } else if !errors.Is(err, StatusInvalidLocality) { + t.Errorf("[ERROR]: Incorrect error type. DestroyContext should return %q, but returned %q", StatusInvalidLocality, err) + } + + // Check ExtendTCI from wrong locality + if _, err := c.ExtendTCI(handle, make([]byte, digestLen)); err == nil { + t.Errorf("[ERROR]: ExtendTCI should return %q, but returned no error", StatusInvalidLocality) + } else if !errors.Is(err, StatusInvalidLocality) { + t.Errorf("[ERROR]: Incorrect error type. ExtendTCI should return %q, but returned %q", StatusInvalidLocality, err) + } + + // Check TagTCI from wrong locality + if _, err := c.TagTCI(handle, 0); err == nil { + t.Errorf("[ERROR]: TagTCI should return %q, but returned no error", StatusInvalidLocality) + } else if !errors.Is(err, StatusInvalidLocality) { + t.Errorf("[ERROR]: Incorrect error type. TagTCI should return %q, but returned %q", StatusInvalidLocality, err) + } +} + +// Checks whether error is reported while using commands that are turned off in DPE. +// DPE commands - TagTCI, RotateContextHandle, ExtendTCI, require support to be enabled in DPE profile +// before being called. +func TestUnsupportedCommand(d TestDPEInstance, c DPEClient, t *testing.T) { + ctx := &DefaultContextHandle + + profile, err := GetTransportProfile(d) + if err != nil { + t.Fatalf("Could not get profile: %v", err) + } + digestLen := profile.GetDigestSize() + + // Check whether RotateContextHandle is unsupported by DPE profile + if _, err := c.RotateContextHandle(ctx, RotateContextHandleFlags(TargetIsDefault)); err == nil { + t.Errorf("[ERROR]: RotateContextHandle is not supported by DPE, should return %q, but returned no error", StatusInvalidCommand) + } else if !errors.Is(err, StatusInvalidCommand) { + t.Errorf("[ERROR]: Incorrect error type. RotateContextHandle is not supported by DPE, should return %q, but returned %q", StatusInvalidCommand, err) + } + + // Check whether ExtendTCI is unsupported by DPE profile + if _, err := c.ExtendTCI(ctx, make([]byte, digestLen)); err == nil { + t.Errorf("[ERROR]: ExtendTCI is not supported by DPE, should return %q, but returned no error", StatusInvalidCommand) + } else if !errors.Is(err, StatusInvalidCommand) { + t.Errorf("[ERROR]: Incorrect error type. ExtendTCI is not supported by DPE, should return %q, but returned %q", StatusInvalidCommand, err) + } + + // Check whether TagTCI is unsupported by DPE profile + if _, err := c.TagTCI(ctx, 0); err == nil { + t.Errorf("[ERROR]: TagTCI is not supported by DPE, should return %q, but returned no error", StatusInvalidCommand) + } else if !errors.Is(err, StatusInvalidCommand) { + t.Errorf("[ERROR]: Incorrect error type. TagTCI is not supported by DPE, should return %q, but returned %q", StatusInvalidCommand, err) + } +} + +// Checks whether error is reported while enabling command flags that are turned off in DPE. +// The DPE command may be available but some of its flags may not be supported by DPE. +// DPE profile supports the below attributes. +// Simulation : Allows caller to request for context iniitialization in simulation mode +// IsCA : Allows caller to request the key cert of CA +// Csr : Allows caller to request the key cert in CSR format +// X509 : Allows caller to request the key cert in X509 format +// IsSymmetric : Allows caller to request for symmetric signing +// InternalInfo : Allows caller to derive child context with InternalInfo +// InternalDice : Allows caller to derive child context with InternalDice +func TestUnsupportedCommandFlag(d TestDPEInstance, c DPEClient, t *testing.T) { + handle := &DefaultContextHandle + + profile, err := GetTransportProfile(d) + if err != nil { + t.Fatalf("Could not get profile: %v", err) + } + digestLen := profile.GetDigestSize() + + // Check whether error is returned since simulation context initialization is unsupported by DPE profile + if _, err := c.InitializeContext(InitIsSimulation); err == nil { + t.Errorf("[ERROR]: Simulation is not supported by DPE, InitializeContext should return %q, but returned no error", StatusArgumentNotSupported) + } else if !errors.Is(err, StatusArgumentNotSupported) { + t.Errorf("[ERROR]: Incorrect error type. Simulation is not supported by DPE, InitializeContext supported by DPE, should return %q, but returned %q", StatusArgumentNotSupported, err) + } + + // Check whether error is returned since CA certificate request is unsupported by DPE profile + if _, err := c.CertifyKey(handle, make([]byte, digestLen), CertifyKeyX509, CertifyAddIsCA); err == nil { + t.Errorf("[ERROR]: IS_CA is not supported by DPE, CertifyKey should return %q, but returned no error", StatusArgumentNotSupported) + } else if !errors.Is(err, StatusArgumentNotSupported) { + t.Errorf("[ERROR]: Incorrect error type. IS_CA is not supported by DPE, CertifyKey should return %q, but returned %q", StatusArgumentNotSupported, err) + } + + // Check whether error is returned since CSR format is unsupported by DPE profile + if _, err := c.CertifyKey(handle, make([]byte, digestLen), CertifyKeyCsr, 0); err == nil { + t.Errorf("[ERROR]: CSR format is not supported by DPE, CertifyKey should return %q, but returned no error", StatusArgumentNotSupported) + } else if !errors.Is(err, StatusArgumentNotSupported) { + t.Errorf("[ERROR]: Incorrect error type. CSR format is not supported by DPE, CertifyKey should return %q, but returned %q", StatusArgumentNotSupported, err) + } + + // Check whether error is returned since X509 format is unsupported by DPE profile + if _, err := c.CertifyKey(handle, make([]byte, digestLen), CertifyKeyX509, 0); err == nil { + t.Errorf("[ERROR]: X509 format is not supported by DPE, CertifyKey should return %q, but returned no error", StatusArgumentNotSupported) + } else if !errors.Is(err, StatusArgumentNotSupported) { + t.Errorf("[ERROR]: Incorrect error type. X509 format is not supported by DPE, CertifyKey should return %q, but returned %q", StatusArgumentNotSupported, err) + } + + // Check whether error is returned since symmetric signing is unsupported by DPE profile + if _, err := c.Sign(handle, make([]byte, digestLen), SignFlags(IsSymmetric), make([]byte, digestLen)); err == nil { + t.Errorf("[ERROR]: Symmetric signing is not supported by DPE, Sign should return %q, but returned no error", StatusInvalidArgument) + } else if !errors.Is(err, StatusArgumentNotSupported) { + t.Errorf("[ERROR]: Incorrect error type. Symmetric signing is not supported by DPE, Sign should return %q, but returned %q", StatusInvalidArgument, err) + } + + // Check whether error is returned since InternalInfo usage is unsupported by DPE profile + if _, err := c.DeriveChild(handle, make([]byte, digestLen), DeriveChildFlags(InternalInputInfo), 0, 0); err == nil { + t.Errorf("[ERROR]:InternalInfo is not supported by DPE, DeriveChild should return %q, but returned no error", StatusArgumentNotSupported) + } else if !errors.Is(err, StatusArgumentNotSupported) { + t.Errorf("[ERROR]: Incorrect error type. InternalInfo is not supported by DPE, DeriveChild should return %q, but returned %q", StatusArgumentNotSupported, err) + } + + // Check whether error is returned since InternalDice usgae is unsupported by DPE profile + if _, err := c.DeriveChild(handle, make([]byte, digestLen), DeriveChildFlags(InternalInputDice), 0, 0); err == nil { + t.Errorf("[ERROR]:InternalDice is not supported by DPE, DeriveChild should return %q, but returned no error", StatusArgumentNotSupported) + } else if !errors.Is(err, StatusArgumentNotSupported) { + t.Errorf("[ERROR]: Incorrect error type. InternalDice is not supported by DPE, DeriveChild should return %q, but returned %q", StatusArgumentNotSupported, err) + } + + // Check whether error is returned since InternalInfo usage is unsupported by DPE profile + if _, err := c.DeriveChild(handle, make([]byte, digestLen), DeriveChildFlags(InputAllowCA), 0, 0); err == nil { + t.Errorf("[ERROR]:IS_CA is not supported by DPE, DeriveChild should return %q, but returned no error", StatusArgumentNotSupported) + } else if !errors.Is(err, StatusArgumentNotSupported) { + t.Errorf("[ERROR]: Incorrect error type. IS_CA is not supported by DPE, DeriveChild should return %q, but returned %q", StatusArgumentNotSupported, err) + } + + // Check whether error is returned since InternalDice usgae is unsupported by DPE profile + if _, err := c.DeriveChild(handle, make([]byte, digestLen), DeriveChildFlags(InputAllowX509), 0, 0); err == nil { + t.Errorf("[ERROR]:X509 is not supported by DPE, DeriveChild should return %q, but returned no error", StatusArgumentNotSupported) + } else if !errors.Is(err, StatusArgumentNotSupported) { + t.Errorf("[ERROR]: Incorrect error type. X509 is not supported by DPE, DeriveChild should return %q, but returned %q", StatusArgumentNotSupported, err) + } +} diff --git a/verification/simulator.go b/verification/simulator.go index 3c3d044b..e0b3e8ad 100644 --- a/verification/simulator.go +++ b/verification/simulator.go @@ -230,7 +230,7 @@ func GetSimulatorTargets() []TestTarget { }, { "DefaultSupport", - getTestTarget([]string{"AutoInit", "Simulation", "X509", "IsCA", "Tagging", "ExtendTci"}), + getTestTarget([]string{"AutoInit", "Simulation", "X509", "IsCA", "Tagging", "RotateContext", "ExtendTci"}), AllTestCases, }, { @@ -303,6 +303,16 @@ func GetSimulatorTargets() []TestTarget { getTestTarget([]string{"Simulation", "ExtendTci", "AutoInit", "Tagging", "RotateContext", "X509", "Csr", "IsSymmetric", "InternalInfo", "InternalDice", "IsCA"}), []TestCase{GetProfileTestCase}, }, + { + "NegativeCase_UnsupportedCommandByDPE", + getTestTarget([]string{"AutoInit"}), + []TestCase{UnsupportedCommand}, + }, + { + "NegativeCase_UnsupportedFeatureByDPE", + getTestTarget([]string{"AutoInit", "RotateContext", "ExtendTci", "Tagging"}), + []TestCase{UnsupportedCommandFlag}, + }, } } diff --git a/verification/tagTCI.go b/verification/tagTCI.go index 8c6849e2..ad2520fa 100644 --- a/verification/tagTCI.go +++ b/verification/tagTCI.go @@ -17,8 +17,10 @@ import ( func TestTagTCI(d TestDPEInstance, c DPEClient, t *testing.T) { var err error + useSimulation := false // To indicate that simulation context is not used + // Tag the default context - handle := getContextHandle(d, c, t, false) + handle := getInitialContextHandle(d, c, t, useSimulation) // Get digest size profile, err := GetTransportProfile(d) @@ -34,9 +36,6 @@ func TestTagTCI(d TestDPEInstance, c DPEClient, t *testing.T) { t.Fatalf("GetTaggedTCI returned %v, want %v", err, StatusBadTag) } - // Make sure using wrong locality reports error - testTagTCIWrongLocality(d, c, t, handle) - // Make sure default handle returns same handle when extended testTagTCIHandle(d, c, t, handle, digestLen, tag) @@ -53,24 +52,6 @@ func TestTagTCI(d TestDPEInstance, c DPEClient, t *testing.T) { testForDerivedChildContexts(d, c, t, handle, digestLen, tag) } -// Checks whether error is reported when the caller from one locality makes call to another locality. -func testTagTCIWrongLocality(d TestDPEInstance, c DPEClient, t *testing.T, handle *ContextHandle) { - var err error - - // Modify locality of DPE instance to test - d.SetLocality(DPE_SIMULATOR_OTHER_LOCALITY) - - // Restore locality of DPE instance after the test - defer d.SetLocality(DPE_SIMULATOR_AUTO_INIT_LOCALITY) - - _, err = c.TagTCI(handle, TCITag(1234)) - if err == nil { - t.Fatalf("[FATAL]: TagTCI command should return %q, but returned no error", StatusInvalidLocality) - } else if !errors.Is(err, StatusInvalidLocality) { - t.Fatalf("[FATAL]: Incorrect error type. TagTCI command should return %q, but returned %q", StatusInvalidLocality, err) - } -} - // Checks whether the default handle remains unchanged when extended with TCI value. func testTagTCIHandle(d TestDPEInstance, c DPEClient, t *testing.T, handle *ContextHandle, digestLen int, tag TCITag) { tciValue := make([]byte, digestLen) diff --git a/verification/verification.go b/verification/verification.go index 4bac76c9..8d0e34c3 100644 --- a/verification/verification.go +++ b/verification/verification.go @@ -36,20 +36,34 @@ var GetCertificateChainTestCase = TestCase{ "GetCertificateChain", TestGetCertificateChain, []string{"AutoInit", "X509"}, } var TagTCITestCase = TestCase{ - "TagTCI", TestTagTCI, []string{"AutoInit", "Tagging", "ExtendTci"}, + "TagTCI", TestTagTCI, []string{"AutoInit", "Tagging"}, } var GetProfileTestCase = TestCase{ "GetProfile", TestGetProfile, []string{}, } +var InvalidHandleTestCase = TestCase{ + "CheckInvalidHandle", TestInvalidHandle, []string{"Simulation", "RotateContext", "ExtendTci", "Tagging"}, +} +var WrongLocalityTestCase = TestCase{ + "CheckWrongLocality", TestWrongLocality, []string{"AutoInit", "RotateContext", "ExtendTci", "Tagging"}, +} +var UnsupportedCommand = TestCase{ + "CheckSupportForCommand", TestUnsupportedCommand, []string{"AutoInit"}, +} +var UnsupportedCommandFlag = TestCase{ + "CheckSupportForCommmandFlag", TestUnsupportedCommandFlag, []string{"AutoInit", "RotateContext", "ExtendTci", "Tagging"}, +} var AllTestCases = []TestCase{ CertifyKeyTestCase, TagTCITestCase, + CertifyKeySimulationTestCase, GetCertificateChainTestCase, GetProfileTestCase, InitializeContextTestCase, InitializeContextSimulationTestCase, - CertifyKeySimulationTestCase, + InvalidHandleTestCase, + WrongLocalityTestCase, } func RunTargetTestCases(target TestTarget, t *testing.T) { From 83a0d8cb0155959edd6cb793e224e953aa007956 Mon Sep 17 00:00:00 2001 From: hpya93 <94533459+hpya93@users.noreply.github.com> Date: Thu, 9 Nov 2023 23:58:53 +0530 Subject: [PATCH 03/10] Update tagTCI.go --- verification/tagTCI.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/verification/tagTCI.go b/verification/tagTCI.go index ad2520fa..0012f7b2 100644 --- a/verification/tagTCI.go +++ b/verification/tagTCI.go @@ -19,7 +19,7 @@ func TestTagTCI(d TestDPEInstance, c DPEClient, t *testing.T) { var err error useSimulation := false // To indicate that simulation context is not used - // Tag the default context + // Get the default context handle := getInitialContextHandle(d, c, t, useSimulation) // Get digest size @@ -30,6 +30,7 @@ func TestTagTCI(d TestDPEInstance, c DPEClient, t *testing.T) { digestLen := profile.GetDigestSize() + // Tag the default context tag := TCITag(12345) // Check to see our tag is not yet found. if _, err := c.GetTaggedTCI(tag); !errors.Is(err, StatusBadTag) { From d15f7d85482bc79b21b13cae7666fab30b8beac1 Mon Sep 17 00:00:00 2001 From: hpya93 Date: Fri, 10 Nov 2023 20:10:50 +0530 Subject: [PATCH 04/10] comments addressed --- verification/certifyKey.go | 10 ++-- verification/tagTCI.go | 109 +++++++++++++++++++---------------- verification/verification.go | 10 +++- 3 files changed, 74 insertions(+), 55 deletions(-) diff --git a/verification/certifyKey.go b/verification/certifyKey.go index d733bbb9..2a872655 100755 --- a/verification/certifyKey.go +++ b/verification/certifyKey.go @@ -433,9 +433,11 @@ func checkCertificateStructure(t *testing.T, certBytes []byte) *x509.Certificate func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, simulation bool) { ctx := getInitialContextHandle(d, client, t, simulation) - if simulation { - defer client.DestroyContext(ctx, 0) - } + defer func() { + if simulation { + client.DestroyContext(ctx, 0) + } + }() type Params struct { Label []byte @@ -449,7 +451,7 @@ func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, simulatio digestLen := profile.GetDigestSize() seqLabel := make([]byte, digestLen) - for i, _ := range seqLabel { + for i := range seqLabel { seqLabel[i] = byte(i) } diff --git a/verification/tagTCI.go b/verification/tagTCI.go index 0012f7b2..41fcfa8f 100644 --- a/verification/tagTCI.go +++ b/verification/tagTCI.go @@ -13,65 +13,62 @@ import ( "testing" ) -// This file is used to test the tagTCI command. +const defaultCtxTCITag = TCITag(12345) +const nonExistentTCITag = TCITag(98765) +const childCtxTCITag = TCITag(34567) +// Check tagTCI command with default context handle. func TestTagTCI(d TestDPEInstance, c DPEClient, t *testing.T) { var err error useSimulation := false // To indicate that simulation context is not used - // Get the default context + // Get default context handle handle := getInitialContextHandle(d, c, t, useSimulation) - // Get digest size - profile, err := GetTransportProfile(d) - if err != nil { - t.Fatalf("Could not get profile: %v", err) - } - - digestLen := profile.GetDigestSize() - - // Tag the default context - tag := TCITag(12345) - // Check to see our tag is not yet found. - if _, err := c.GetTaggedTCI(tag); !errors.Is(err, StatusBadTag) { + // Check to see our tag is not yet found and then tag default context + if _, err := c.GetTaggedTCI(defaultCtxTCITag); !errors.Is(err, StatusBadTag) { t.Fatalf("GetTaggedTCI returned %v, want %v", err, StatusBadTag) } - // Make sure default handle returns same handle when extended - testTagTCIHandle(d, c, t, handle, digestLen, tag) + // Tag default context handle and make sure default handle returns + // same handle when used for tagging TCI + newHandle, err := c.TagTCI(handle, defaultCtxTCITag) + if err != nil { + t.Fatalf("Could not tag TCI: %v", err) + } + if *newHandle != *handle { + t.Errorf("New context handle from TagTCI was %x, expected %x", newHandle, handle) + } - // Make sure the current TCI is updated - // For profiles which use auto-initialization, we don't know the expected TCIs so we can check only current TCI - testCurrentAndCumulativeTCI(d, c, t, handle, digestLen, tag) + // Retag a tagged TCI should report error + newTag := TCITag(11111) + if _, err := c.TagTCI(handle, newTag); !errors.Is(err, StatusBadTag) { + t.Fatalf("Re-tagging a tagged TCI returned %v, want %v", err, StatusBadTag) + } - // Make sure some other tag is still not found. - if _, err := c.GetTaggedTCI(TCITag(98765)); !errors.Is(err, StatusBadTag) { + // Fetching a non-existent tag should report error + if _, err := c.GetTaggedTCI(TCITag(nonExistentTCITag)); !errors.Is(err, StatusBadTag) { t.Fatalf("GetTaggedTCI returned %v, want %v", err, StatusBadTag) } - - // Pass TCI input to DerivedChild context and check cumulative TCI - testForDerivedChildContexts(d, c, t, handle, digestLen, tag) } -// Checks whether the default handle remains unchanged when extended with TCI value. -func testTagTCIHandle(d TestDPEInstance, c DPEClient, t *testing.T, handle *ContextHandle, digestLen int, tag TCITag) { - tciValue := make([]byte, digestLen) - for i := range tciValue { - tciValue[i] = byte(i) - } +// Check whether the ExtendTCI command updates the current TCI and cumulative TCI. +func TestExtendTCI(d TestDPEInstance, c 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) - newHandle, err := c.TagTCI(handle, tag) + // Get digest size + profile, err := GetTransportProfile(d) if err != nil { - t.Fatalf("Could not tag TCI: %v", err) - } - if *newHandle != *handle { - t.Errorf("New context handle from TagTCI was %x, expected %x", newHandle, handle) + t.Fatalf("Could not get profile: %v", err) } -} + digestLen := profile.GetDigestSize() -// Checks whether the ExtendTCI command updates the current TCI and cumulative TCI. -func testCurrentAndCumulativeTCI(d TestDPEInstance, c DPEClient, t *testing.T, handle *ContextHandle, digestLen int, tag TCITag) { - // Initialize TCI inputs + // Initialize TCI inputs with all zeroes + // since, TCI_DEFAULT for default context is all zeroes defaultTci := make([]byte, digestLen) tciValue := make([]byte, digestLen) @@ -86,16 +83,16 @@ func testCurrentAndCumulativeTCI(d TestDPEInstance, c DPEClient, t *testing.T, h } else if digestLen == 48 { hasher = sha512.New384() } else { - t.Error("[ERROR]: Unsupported hash algorithm used for TCI value generation") + t.Fatal("[FATAL]: Unsupported hash algorithm used for TCI value generation") } // Set current TCI value - _, err := c.ExtendTCI(handle, tciValue) + _, err = c.ExtendTCI(handle, tciValue) if err != nil { - t.Fatalf("Could not tag TCI: %v", err) + t.Fatalf("Could not extend TCI: %v", err) } - taggedTCI, err := c.GetTaggedTCI(tag) + taggedTCI, err := c.GetTaggedTCI(defaultCtxTCITag) if err != nil { t.Fatalf("Could not get tagged TCI: %v", err) } @@ -114,10 +111,22 @@ func testCurrentAndCumulativeTCI(d TestDPEInstance, c DPEClient, t *testing.T, h } } -// Checks whether the ExtendTCI command updates the current TCI. -func testForDerivedChildContexts(d TestDPEInstance, c DPEClient, t *testing.T, handle *ContextHandle, digestLen int, parentTag TCITag) { +// Check whether the ExtendTCI command with derived child context. +func TestExtendTciOnDerivedContexts(d TestDPEInstance, c DPEClient, t *testing.T) { + var err error var wantCumulativeTCI []byte - childTag := TCITag(23456) + + 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("Could not get profile: %v", err) + } + digestLen := profile.GetDigestSize() // Initialize TCI inputs defaultTci := make([]byte, digestLen) @@ -143,7 +152,7 @@ func testForDerivedChildContexts(d TestDPEInstance, c DPEClient, t *testing.T, h } // Get parent context TCI values for cumulative value calculation - parentTci, err := c.GetTaggedTCI(parentTag) + parentTci, err := c.GetTaggedTCI(defaultCtxTCITag) if err != nil { t.Fatalf("Could not get tagged TCI: %v", err) } @@ -162,12 +171,12 @@ func testForDerivedChildContexts(d TestDPEInstance, c DPEClient, t *testing.T, h t.Fatalf("[FATAL]: Error while creating default child handle in default context: %s", err) } - newHandle, err := c.TagTCI(&child.NewContextHandle, childTag) + newHandle, err := c.TagTCI(&child.NewContextHandle, childCtxTCITag) if err != nil { t.Fatalf("Could not tag TCI: %v", err) } - childTci, err := c.GetTaggedTCI(childTag) + childTci, err := c.GetTaggedTCI(childCtxTCITag) if err != nil { t.Fatalf("Could not get tagged TCI: %v", err) } @@ -191,7 +200,7 @@ func testForDerivedChildContexts(d TestDPEInstance, c DPEClient, t *testing.T, h t.Fatalf("Could not tag TCI: %v", err) } - childExtendTci, err := c.GetTaggedTCI(childTag) + childExtendTci, err := c.GetTaggedTCI(childCtxTCITag) if err != nil { t.Fatalf("Could not get tagged TCI: %v", err) } diff --git a/verification/verification.go b/verification/verification.go index 8d0e34c3..b3ee74a5 100644 --- a/verification/verification.go +++ b/verification/verification.go @@ -38,6 +38,12 @@ var GetCertificateChainTestCase = TestCase{ var TagTCITestCase = TestCase{ "TagTCI", TestTagTCI, []string{"AutoInit", "Tagging"}, } +var ExtendTCITestCase = TestCase{ + "ExtendTCITestCase", TestExtendTCI, []string{"AutoInit", "Tagging", "ExtendTci"}, +} +var ExtendDerivedTciTestCase = TestCase{ + "ExtendDerivedTciTestCase", TestExtendTciOnDerivedContexts, []string{"AutoInit", "Tagging", "ExtendTci"}, +} var GetProfileTestCase = TestCase{ "GetProfile", TestGetProfile, []string{}, } @@ -56,9 +62,11 @@ var UnsupportedCommandFlag = TestCase{ var AllTestCases = []TestCase{ CertifyKeyTestCase, - TagTCITestCase, CertifyKeySimulationTestCase, GetCertificateChainTestCase, + TagTCITestCase, + ExtendTCITestCase, + ExtendDerivedTciTestCase, GetProfileTestCase, InitializeContextTestCase, InitializeContextSimulationTestCase, From fb4c3eca8416ba3b88f7d9299f4f7db4b745528f Mon Sep 17 00:00:00 2001 From: hpya93 <94533459+hpya93@users.noreply.github.com> Date: Fri, 10 Nov 2023 20:45:50 +0530 Subject: [PATCH 05/10] Update initializeContext.go --- verification/initializeContext.go | 1 + 1 file changed, 1 insertion(+) diff --git a/verification/initializeContext.go b/verification/initializeContext.go index e9bbf5ad..728c3e47 100644 --- a/verification/initializeContext.go +++ b/verification/initializeContext.go @@ -71,6 +71,7 @@ func testInitContext(d TestDPEInstance, client DPEClient, t *testing.T, simulati // When simulation is set to false, returns a default context handle. // Else initializes a simulation context and returns its handle. To get simulation // context handle, the DPE profile must support simulation context creation. +// Caller must ensure to destroy the non-default handle through DestroyContext after usage. func getInitialContextHandle(d TestDPEInstance, c DPEClient, t *testing.T, simulation bool) *ContextHandle { var handle *ContextHandle var err error From e4a4387ae0ef09eca688c03c6dd0425659dd4080 Mon Sep 17 00:00:00 2001 From: hpya93 <94533459+hpya93@users.noreply.github.com> Date: Fri, 10 Nov 2023 21:24:48 +0530 Subject: [PATCH 06/10] Update tagTCI.go --- verification/tagTCI.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verification/tagTCI.go b/verification/tagTCI.go index 41fcfa8f..8a14216b 100644 --- a/verification/tagTCI.go +++ b/verification/tagTCI.go @@ -148,7 +148,7 @@ func TestExtendTciOnDerivedContexts(d TestDPEInstance, c DPEClient, t *testing.T } else if digestLen == 48 { hasher = sha512.New384() } else { - t.Error("[ERROR]: Unsupported hash algorithm used for TCI value generation") + t.Fatal("[FATAL]: Unsupported hash algorithm used for TCI value generation") } // Get parent context TCI values for cumulative value calculation From 29fd0f80578f80a5547b6b7ba149c73ae2f4f526 Mon Sep 17 00:00:00 2001 From: hpya93 Date: Sat, 11 Nov 2023 15:25:58 +0530 Subject: [PATCH 07/10] Clean up derived context and restore parent context for subsequent tests --- verification/certifyKey.go | 5 ----- verification/go.mod | 2 +- verification/tagTCI.go | 27 ++++++++++++++++++++++++--- verification/verification_test.go | 2 -- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/verification/certifyKey.go b/verification/certifyKey.go index 2a872655..44c3ee21 100755 --- a/verification/certifyKey.go +++ b/verification/certifyKey.go @@ -546,11 +546,6 @@ func buildVerifyOptions(t *testing.T, certChain []*x509.Certificate) x509.Verify return opts } -func extractFlagBit(pos int, flags uint32) bool { - var mask uint32 = (1 << pos) - return (flags & mask) > 0 -} - func getKeyUsageNames(keyUsage x509.KeyUsage) []string { keyUsageNames := []string{} diff --git a/verification/go.mod b/verification/go.mod index f88413a8..eb814063 100644 --- a/verification/go.mod +++ b/verification/go.mod @@ -11,7 +11,7 @@ require ( github.com/pelletier/go-toml v1.9.3 // indirect github.com/weppos/publicsuffix-go v0.30.1-0.20230422193905-8fecedd899db // indirect golang.org/x/crypto v0.7.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect + golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 golang.org/x/net v0.8.0 // indirect golang.org/x/text v0.8.0 // indirect ) diff --git a/verification/tagTCI.go b/verification/tagTCI.go index 8a14216b..6e4cc9f4 100644 --- a/verification/tagTCI.go +++ b/verification/tagTCI.go @@ -165,13 +165,20 @@ func TestExtendTciOnDerivedContexts(d TestDPEInstance, c DPEClient, t *testing.T t.Errorf("Parent node's cumulative TCI %x, expected %x", parentTci.CumulativeTCI, wantCumulativeTCI) } + // 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) + } + // Derive Child context with input data, tag it and check TCI_CUMULATIVE - child, err := c.DeriveChild(handle, tciValue, DeriveChildFlags(MakeDefault), 0, 0) + childCtx, err := c.DeriveChild(parentHandle, tciValue, DeriveChildFlags(RetainParent), 0, 0) if err != nil { t.Fatalf("[FATAL]: Error while creating default child handle in default context: %s", err) } - newHandle, err := c.TagTCI(&child.NewContextHandle, childCtxTCITag) + // Tag derived context + newHandle, err := c.TagTCI(&childCtx.NewContextHandle, childCtxTCITag) if err != nil { t.Fatalf("Could not tag TCI: %v", err) } @@ -195,7 +202,7 @@ func TestExtendTciOnDerivedContexts(d TestDPEInstance, c DPEClient, t *testing.T } // Extend TCI to child context and check TCI_CURRENT and TCI_CUMULATIVE - _, err = c.ExtendTCI(newHandle, extendTciValue) + newHandle, err = c.ExtendTCI(newHandle, extendTciValue) if err != nil { t.Fatalf("Could not tag TCI: %v", err) } @@ -217,4 +224,18 @@ func TestExtendTciOnDerivedContexts(d TestDPEInstance, c DPEClient, t *testing.T if !bytes.Equal(childExtendTci.CumulativeTCI, wantCumulativeTCI) { t.Errorf("Child node's cumulative TCI %x, expected %x", childExtendTci.CumulativeTCI, wantCumulativeTCI) } + + // Clean up derived context and restore default context handle for subsequnt tests + defer func() { + err := c.DestroyContext(newHandle, DestroyDescendants) + if err != nil { + t.Errorf("[ERROR]: Error while cleaning up derived context, this may cause failure in subsequent tests: %s", err) + } + + _, err = c.RotateContextHandle(&childCtx.ParentContextHandle, 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) + } + }() + } diff --git a/verification/verification_test.go b/verification/verification_test.go index 85fd24a7..b218621e 100755 --- a/verification/verification_test.go +++ b/verification/verification_test.go @@ -8,8 +8,6 @@ import ( "testing" ) -var testTargetType string - // This will be called before running tests, and it assigns the socket path based on command line flag. func TestMain(m *testing.M) { TargetExe = flag.String("sim", "../simulator/target/debug/simulator", "path to simulator executable") From bd55fe274d1bb8d3562c2e8c00679ae18ad02cd4 Mon Sep 17 00:00:00 2001 From: hpya93 Date: Tue, 14 Nov 2023 19:34:45 +0530 Subject: [PATCH 08/10] review comments --- verification/certifyKey.go | 2 +- verification/tagTCI.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/verification/certifyKey.go b/verification/certifyKey.go index 44c3ee21..73359678 100755 --- a/verification/certifyKey.go +++ b/verification/certifyKey.go @@ -435,7 +435,7 @@ func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, simulatio ctx := getInitialContextHandle(d, client, t, simulation) defer func() { if simulation { - client.DestroyContext(ctx, 0) + client.DestroyContext(ctx, DestroyDescendants) } }() diff --git a/verification/tagTCI.go b/verification/tagTCI.go index 6e4cc9f4..9660172b 100644 --- a/verification/tagTCI.go +++ b/verification/tagTCI.go @@ -225,7 +225,7 @@ func TestExtendTciOnDerivedContexts(d TestDPEInstance, c DPEClient, t *testing.T t.Errorf("Child node's cumulative TCI %x, expected %x", childExtendTci.CumulativeTCI, wantCumulativeTCI) } - // Clean up derived context and restore default context handle for subsequnt tests + // Clean up derived context and restore default context handle for subsequent tests defer func() { err := c.DestroyContext(newHandle, DestroyDescendants) if err != nil { From 6ed437f91a6e8437f6c5533accb08d9c54217f13 Mon Sep 17 00:00:00 2001 From: hpya93 Date: Thu, 16 Nov 2023 20:18:23 +0530 Subject: [PATCH 09/10] review comments --- verification/abi.go | 4 + verification/certifyKey.go | 47 +++++++- verification/extendTCI.go | 230 +++++++++++++++++++++++++++++++++++++ verification/tagTCI.go | 203 +------------------------------- 4 files changed, 284 insertions(+), 200 deletions(-) create mode 100644 verification/extendTCI.go diff --git a/verification/abi.go b/verification/abi.go index 22b23295..d4fdac6a 100755 --- a/verification/abi.go +++ b/verification/abi.go @@ -9,6 +9,10 @@ import ( var DefaultContextHandle = ContextHandle{0} +const defaultCtxTCITag = TCITag(12345) +const nonExistentTCITag = TCITag(98765) +const childCtxTCITag = TCITag(34567) + const ( CmdMagic uint32 = 0x44504543 RespMagic uint32 = 0x44504552 diff --git a/verification/certifyKey.go b/verification/certifyKey.go index 73359678..e7b59694 100755 --- a/verification/certifyKey.go +++ b/verification/certifyKey.go @@ -4,11 +4,14 @@ package verification import ( "bytes" + "crypto/sha256" + "crypto/sha512" "crypto/x509" "encoding/asn1" "encoding/binary" "encoding/pem" "fmt" + "hash" "reflect" "testing" "time" @@ -34,6 +37,8 @@ var ( OidExtensionTcgDiceKpAssertInit = asn1.ObjectIdentifier{2, 23, 133, 5, 4, 100, 10} OidExtensionTcgDiceKpAssertLoc = asn1.ObjectIdentifier{2, 23, 133, 5, 4, 100, 11} OidExtensionTcgDiceKpEca = asn1.ObjectIdentifier{2, 23, 133, 5, 4, 100, 12} + OidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1} + OidSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2} ) var TcgDiceCriticalExtensions = [...]string{ @@ -218,7 +223,7 @@ func checkCertifyKeyTcgUeidExtension(t *testing.T, c *x509.Certificate, label [] // A tcg-dice-MultiTcbInfo extension. // This extension SHOULD be marked as critical. -func checkCertifyKeyMultiTcbInfoExtension(t *testing.T, c *x509.Certificate) (TcgMultiTcbInfo, error) { +func checkCertifyKeyMultiTcbInfoExtensionStructure(t *testing.T, c *x509.Certificate) (TcgMultiTcbInfo, error) { t.Helper() var multiTcbInfo TcgMultiTcbInfo var err error @@ -241,6 +246,44 @@ func checkCertifyKeyMultiTcbInfoExtension(t *testing.T, c *x509.Certificate) (Tc return multiTcbInfo, err } +// Checks the FWID block's Digest. +// FWID at index 0 has the TCI_CURRENT as digest +// FWID at index 1 has the TCI_CUMULATIVE as digest +// The length of FWID array in each DICE TCB information block is 2. +func checkCurrentDiceTcbMeasurements(t *testing.T, multiTcbInfo []DiceTcbInfo, expectedCurrentValue []byte) { + currentTci := multiTcbInfo[0].Fwids[0].Digest + cumulativeTci := multiTcbInfo[0].Fwids[1].Digest + + if !bytes.Equal(currentTci, expectedCurrentValue) { + t.Errorf("[ERROR]: Unexpected TCI_CURRENT digest, want %v but got %v", expectedCurrentValue, currentTci) + } + + // Calculate expected cumulative value + var expectedCumulativeValue []byte + var defaultTci []byte + var hasher hash.Hash + if multiTcbInfo[0].Fwids[1].HashAlg.Equal(OidSHA384) { + hasher = sha512.New384() + defaultTci = make([]byte, 48) + hasher.Write(defaultTci) + } else if multiTcbInfo[0].Fwids[1].HashAlg.Equal(OidSHA256) { + hasher = sha256.New() + defaultTci = make([]byte, 32) + hasher.Write(defaultTci) + } + + // The DiceTcbInfo blocks are listed with current node at index0 followed by parent TCI nodes. + for i := len(multiTcbInfo) - 1; i >= 0; i-- { + hasher.Write(multiTcbInfo[i].Fwids[0].Digest) + } + expectedCumulativeValue = hasher.Sum(nil) + + // Verify the FWID index-1 which has TCI_CUMULATIVE value of current node + if !bytes.Equal(cumulativeTci, expectedCumulativeValue) { + t.Errorf("[ERROR]: Unexpected cumulative TCI value, want %v but got %v", expectedCumulativeValue, cumulativeTci) + } +} + // Check whether certificate extended key usage is as per spec // OID for ExtendedKeyUsage Extension: 2.5.29.37 // The ExtendedKeyUsage extension SHOULD be marked as critical @@ -354,7 +397,7 @@ func validateCertifyKeyCert(t *testing.T, c *x509.Certificate, flags uint32, lab checkCertifyKeyTcgUeidExtension(t, c, label) // Check MultiTcbInfo Extension structure - checkCertifyKeyMultiTcbInfoExtension(t, c) + checkCertifyKeyMultiTcbInfoExtensionStructure(t, c) } func checkCertificateStructure(t *testing.T, certBytes []byte) *x509.Certificate { diff --git a/verification/extendTCI.go b/verification/extendTCI.go new file mode 100644 index 00000000..68ea1845 --- /dev/null +++ b/verification/extendTCI.go @@ -0,0 +1,230 @@ +// Licensed under the Apache-2.0 license + +package verification + +import ( + "bytes" + "crypto/sha256" + "crypto/sha512" + "crypto/x509" + "hash" + + "testing" +) + +// Check whether the ExtendTCI command updates the current TCI and cumulative TCI. +func TestExtendTCI(d TestDPEInstance, c 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 := GetTransportProfile(d) + if err != nil { + t.Fatalf("[FATAL]: Could not get profile: %v", err) + } + digestLen := profile.GetDigestSize() + + // Initialize TCI inputs with all zeroes + // since, TCI_DEFAULT for default context is all zeroes + defaultTci := make([]byte, digestLen) + + // Initialize hasher + var hasher hash.Hash + if digestLen == 32 { + hasher = sha256.New() + } else if digestLen == 48 { + hasher = sha512.New384() + } + + tciValue := make([]byte, digestLen) + for i := range tciValue { + tciValue[i] = byte(i) + } + + // Set current TCI value + _, err = c.ExtendTCI(handle, tciValue) + if err != nil { + t.Fatalf("[FATAL]: Could not extend TCI: %v", err) + } + + // Cross-check current and cumulative measurement by GetTaggedTCI + verifyMeasurementsByGetTaggedTCI(c, t, defaultTci, tciValue, hasher) + + // Cross-check current and cumulative measurement by CertifyKey + verifyMeasurementsByCertifyKey(c, t, handle, defaultTci, tciValue, hasher) +} + +// Check whether the ExtendTCI command with derived child context. +func TestExtendTciOnDerivedContexts(d TestDPEInstance, c DPEClient, t *testing.T) { + var err error + var wantCumulativeTCI []byte + + 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 + defaultTci := make([]byte, digestLen) + + 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) + } + + // Initialize hasher + var hasher hash.Hash + if digestLen == 32 { + hasher = sha256.New() + } else if digestLen == 48 { + hasher = sha512.New384() + } + + // Get parent context TCI values for cumulative value calculation + parentTci, err := c.GetTaggedTCI(defaultCtxTCITag) + if err != nil { + t.Fatalf("[FATAL]: Could not get tagged TCI: %v", err) + } + + // Cross-verify parent's TCI_CUMULATIVE + hasher.Write(defaultTci) + hasher.Write(parentTci.CurrentTCI) + wantCumulativeTCI = hasher.Sum(nil) + if !bytes.Equal(parentTci.CumulativeTCI, wantCumulativeTCI) { + t.Errorf("[ERROR]: Parent node's cumulative TCI %x, expected %x", parentTci.CumulativeTCI, wantCumulativeTCI) + } + + // 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) + } + + // Derive Child context with input data, tag it and check TCI_CUMULATIVE + childCtx, err := c.DeriveChild(parentHandle, tciValue, DeriveChildFlags(RetainParent), 0, 0) + if err != nil { + t.Fatalf("[FATAL]: Error while creating default child handle in default context: %s", err) + } + + // Tag derived context + newHandle, err := c.TagTCI(&childCtx.NewContextHandle, childCtxTCITag) + if err != nil { + t.Fatalf("[FATAL]: Could not tag TCI: %v", err) + } + + childTci, err := c.GetTaggedTCI(childCtxTCITag) + if err != nil { + t.Fatalf("[FATAL]: Could not get tagged TCI: %v", err) + } + + if !bytes.Equal(childTci.CurrentTCI, tciValue) { + t.Errorf("[ERROR]: GetTaggedTCI returned current TCI %x, expected %x", childTci.CurrentTCI, tciValue) + } + + // Check TCI_CUMULATIVE after creating child context + hasher.Reset() + hasher.Write(defaultTci) + hasher.Write(childTci.CurrentTCI) + wantCumulativeTCI = hasher.Sum(nil) + if !bytes.Equal(childTci.CumulativeTCI, wantCumulativeTCI) { + t.Errorf("[ERROR]: Child node's cumulative TCI %x, expected %x", childTci.CumulativeTCI, wantCumulativeTCI) + } + + // Extend TCI to child context and check TCI_CURRENT and TCI_CUMULATIVE + newHandle, err = c.ExtendTCI(newHandle, extendTciValue) + if err != nil { + t.Fatalf("[FATAL]: Could not tag TCI: %v", err) + } + + childExtendTci, err := c.GetTaggedTCI(childCtxTCITag) + if err != nil { + t.Fatalf("[FATAL]: Could not get tagged TCI: %v", err) + } + + if !bytes.Equal(childExtendTci.CurrentTCI, extendTciValue) { + t.Errorf("[ERROR]: GetTaggedTCI returned current TCI %x, expected %x", childExtendTci.CurrentTCI, extendTciValue) + } + + // Check TCI_CUMULATIVE after extending input to child context + hasher.Reset() + hasher.Write(childTci.CumulativeTCI) + hasher.Write(childExtendTci.CurrentTCI) + wantCumulativeTCI = hasher.Sum(nil) + if !bytes.Equal(childExtendTci.CumulativeTCI, wantCumulativeTCI) { + t.Errorf("[ERROR]: Child node's cumulative TCI %x, expected %x", childExtendTci.CumulativeTCI, wantCumulativeTCI) + } + + // Clean up derived context and restore default context handle for subsequent tests + defer func() { + err := c.DestroyContext(newHandle, DestroyDescendants) + if err != nil { + t.Errorf("[ERROR]: Error while cleaning up derived context, this may cause failure in subsequent tests: %s", err) + } + + _, err = c.RotateContextHandle(&childCtx.ParentContextHandle, 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) + } + }() + +} + +func verifyMeasurementsByGetTaggedTCI(c DPEClient, t *testing.T, defaultTci []byte, tciValue []byte, hasher hash.Hash) { + taggedTCI, err := c.GetTaggedTCI(defaultCtxTCITag) + if err != nil { + t.Fatalf("[FATAL]: Could not get tagged TCI: %v", err) + } + + // Check TCI_CURRENT + wantCurrentTCI := tciValue + if !bytes.Equal(taggedTCI.CurrentTCI, tciValue) { + t.Errorf("[ERROR]: GetTaggedTCI returned current TCI %x, expected %x", taggedTCI.CurrentTCI, wantCurrentTCI) + } + + // Cross-verify TCI_CUMULATIVE + hasher.Write(defaultTci) + hasher.Write(taggedTCI.CurrentTCI) + if wantCumulativeTCI := hasher.Sum(nil); !bytes.Equal(taggedTCI.CumulativeTCI, wantCumulativeTCI) { + t.Errorf("[ERROR]: GetTaggedTCI returned cumulative TCI %x, expected %x", taggedTCI.CumulativeTCI, wantCumulativeTCI) + } +} + +func verifyMeasurementsByCertifyKey(c DPEClient, t *testing.T, handle *ContextHandle, label []byte, tciValue []byte, hasher hash.Hash) { + certifiedKey, err := c.CertifyKey(handle, label, CertifyKeyX509, 0) + if err != nil { + t.Fatalf("[FATAL]: Could not get Certified key: %v", err) + } + + leafCertBytes := certifiedKey.Certificate + + var leafCert *x509.Certificate + + // Check whether certificate is DER encoded. + if leafCert, err = x509.ParseCertificate(leafCertBytes); err != nil { + t.Fatalf("[FATAL]: Could not parse certificate using crypto/x509: %v", err) + } + + // Get DICE information from MultiTcbInfo Extension + multiTcbInfo, err := checkCertifyKeyMultiTcbInfoExtensionStructure(t, leafCert) + if err != nil { + t.Errorf("Error while unmarshalling MultiTCB information %v, skipping MultiTCB validation", err) + } else { + // Cross-verify cumulative value returned in MultiTcbInfo + checkCurrentDiceTcbMeasurements(t, multiTcbInfo, tciValue) + } +} diff --git a/verification/tagTCI.go b/verification/tagTCI.go index 9660172b..cff911ef 100644 --- a/verification/tagTCI.go +++ b/verification/tagTCI.go @@ -3,20 +3,10 @@ package verification import ( - "bytes" - "crypto/sha256" - "crypto/sha512" "errors" - "hash" - - //"reflect" "testing" ) -const defaultCtxTCITag = TCITag(12345) -const nonExistentTCITag = TCITag(98765) -const childCtxTCITag = TCITag(34567) - // Check tagTCI command with default context handle. func TestTagTCI(d TestDPEInstance, c DPEClient, t *testing.T) { var err error @@ -40,6 +30,11 @@ func TestTagTCI(d TestDPEInstance, c DPEClient, t *testing.T) { t.Errorf("New context handle from TagTCI was %x, expected %x", newHandle, handle) } + _, err = c.GetTaggedTCI(defaultCtxTCITag) + if err != nil { + t.Fatalf("Could not get tagged TCI: %v", err) + } + // Retag a tagged TCI should report error newTag := TCITag(11111) if _, err := c.TagTCI(handle, newTag); !errors.Is(err, StatusBadTag) { @@ -51,191 +46,3 @@ func TestTagTCI(d TestDPEInstance, c DPEClient, t *testing.T) { t.Fatalf("GetTaggedTCI returned %v, want %v", err, StatusBadTag) } } - -// Check whether the ExtendTCI command updates the current TCI and cumulative TCI. -func TestExtendTCI(d TestDPEInstance, c 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 := GetTransportProfile(d) - if err != nil { - t.Fatalf("Could not get profile: %v", err) - } - digestLen := profile.GetDigestSize() - - // Initialize TCI inputs with all zeroes - // since, TCI_DEFAULT for default context is all zeroes - defaultTci := make([]byte, digestLen) - - tciValue := make([]byte, digestLen) - for i := range tciValue { - tciValue[i] = byte(i) - } - - // Initialize hasher - var hasher hash.Hash - if digestLen == 32 { - hasher = sha256.New() - } else if digestLen == 48 { - hasher = sha512.New384() - } else { - t.Fatal("[FATAL]: Unsupported hash algorithm used for TCI value generation") - } - - // Set current TCI value - _, err = c.ExtendTCI(handle, tciValue) - if err != nil { - t.Fatalf("Could not extend TCI: %v", err) - } - - taggedTCI, err := c.GetTaggedTCI(defaultCtxTCITag) - if err != nil { - t.Fatalf("Could not get tagged TCI: %v", err) - } - - // Check TCI_CURRENT - wantCurrentTCI := tciValue - if !bytes.Equal(taggedTCI.CurrentTCI, tciValue) { - t.Errorf("GetTaggedTCI returned current TCI %x, expected %x", taggedTCI.CurrentTCI, wantCurrentTCI) - } - - // Cross-verify TCI_CUMULATIVE - hasher.Write(defaultTci) - hasher.Write(taggedTCI.CurrentTCI) - if wantCumulativeTCI := hasher.Sum(nil); !bytes.Equal(taggedTCI.CumulativeTCI, wantCumulativeTCI) { - t.Errorf("GetTaggedTCI returned cumulative TCI %x, expected %x", taggedTCI.CumulativeTCI, wantCumulativeTCI) - } -} - -// Check whether the ExtendTCI command with derived child context. -func TestExtendTciOnDerivedContexts(d TestDPEInstance, c DPEClient, t *testing.T) { - var err error - var wantCumulativeTCI []byte - - 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("Could not get profile: %v", err) - } - digestLen := profile.GetDigestSize() - - // Initialize TCI inputs - defaultTci := make([]byte, digestLen) - - 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) - } - - // Initialize hasher - var hasher hash.Hash - if digestLen == 32 { - hasher = sha256.New() - } else if digestLen == 48 { - hasher = sha512.New384() - } else { - t.Fatal("[FATAL]: Unsupported hash algorithm used for TCI value generation") - } - - // Get parent context TCI values for cumulative value calculation - parentTci, err := c.GetTaggedTCI(defaultCtxTCITag) - if err != nil { - t.Fatalf("Could not get tagged TCI: %v", err) - } - - // Cross-verify parent's TCI_CUMULATIVE - hasher.Write(defaultTci) - hasher.Write(parentTci.CurrentTCI) - wantCumulativeTCI = hasher.Sum(nil) - if !bytes.Equal(parentTci.CumulativeTCI, wantCumulativeTCI) { - t.Errorf("Parent node's cumulative TCI %x, expected %x", parentTci.CumulativeTCI, wantCumulativeTCI) - } - - // 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) - } - - // Derive Child context with input data, tag it and check TCI_CUMULATIVE - childCtx, err := c.DeriveChild(parentHandle, tciValue, DeriveChildFlags(RetainParent), 0, 0) - if err != nil { - t.Fatalf("[FATAL]: Error while creating default child handle in default context: %s", err) - } - - // Tag derived context - newHandle, err := c.TagTCI(&childCtx.NewContextHandle, childCtxTCITag) - if err != nil { - t.Fatalf("Could not tag TCI: %v", err) - } - - childTci, err := c.GetTaggedTCI(childCtxTCITag) - if err != nil { - t.Fatalf("Could not get tagged TCI: %v", err) - } - - if !bytes.Equal(childTci.CurrentTCI, tciValue) { - t.Errorf("GetTaggedTCI returned current TCI %x, expected %x", childTci.CurrentTCI, tciValue) - } - - // Check TCI_CUMULATIVE after creating child context - hasher.Reset() - hasher.Write(defaultTci) - hasher.Write(childTci.CurrentTCI) - wantCumulativeTCI = hasher.Sum(nil) - if !bytes.Equal(childTci.CumulativeTCI, wantCumulativeTCI) { - t.Errorf("Child node's cumulative TCI %x, expected %x", childTci.CumulativeTCI, wantCumulativeTCI) - } - - // Extend TCI to child context and check TCI_CURRENT and TCI_CUMULATIVE - newHandle, err = c.ExtendTCI(newHandle, extendTciValue) - if err != nil { - t.Fatalf("Could not tag TCI: %v", err) - } - - childExtendTci, err := c.GetTaggedTCI(childCtxTCITag) - if err != nil { - t.Fatalf("Could not get tagged TCI: %v", err) - } - - if !bytes.Equal(childExtendTci.CurrentTCI, extendTciValue) { - t.Errorf("GetTaggedTCI returned current TCI %x, expected %x", childExtendTci.CurrentTCI, extendTciValue) - } - - // Check TCI_CUMULATIVE after extending input to child context - hasher.Reset() - hasher.Write(childTci.CumulativeTCI) - hasher.Write(childExtendTci.CurrentTCI) - wantCumulativeTCI = hasher.Sum(nil) - if !bytes.Equal(childExtendTci.CumulativeTCI, wantCumulativeTCI) { - t.Errorf("Child node's cumulative TCI %x, expected %x", childExtendTci.CumulativeTCI, wantCumulativeTCI) - } - - // Clean up derived context and restore default context handle for subsequent tests - defer func() { - err := c.DestroyContext(newHandle, DestroyDescendants) - if err != nil { - t.Errorf("[ERROR]: Error while cleaning up derived context, this may cause failure in subsequent tests: %s", err) - } - - _, err = c.RotateContextHandle(&childCtx.ParentContextHandle, 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) - } - }() - -} From 440bbdd1efdd06174fe9ff7c181fd269674a32d3 Mon Sep 17 00:00:00 2001 From: hpya93 <94533459+hpya93@users.noreply.github.com> Date: Thu, 16 Nov 2023 20:28:52 +0530 Subject: [PATCH 10/10] Update README.md