From 24ffe748fbb63719cac7b7d5dddd96765e69ddcd Mon Sep 17 00:00:00 2001 From: hpya93 Date: Sat, 4 Nov 2023 02:58:44 +0530 Subject: [PATCH 01/12] Common client code and few bug fixes --- dpe/src/commands/sign.rs | 6 +- verification/abi.go | 217 ++++++++++++++++++++++- verification/certifyKey.go | 35 ++-- verification/client.go | 12 +- verification/initializeContext.go | 24 +++ verification/negativeCases.go | 275 ++++++++++++++++++++++++++++++ verification/simulator.go | 22 ++- verification/tagTCI.go | 22 +-- verification/verification.go | 16 +- 9 files changed, 579 insertions(+), 50 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 57c0d880..22b23295 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 ) @@ -156,6 +161,74 @@ 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 +} + +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 @@ -365,7 +438,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 +467,54 @@ 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 + + _, 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 label 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 @@ -485,6 +606,86 @@ func (c *dpeABI[_, _]) GetCertificateChain() ([]byte, error) { 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), + Flags: flags, + TciType: tciType, + TargetLocality: targetLocality, + } + 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 label 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[_, 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 (s *Support) ToFlags() uint32 { flags := uint32(0) if s.Simulation { diff --git a/verification/certifyKey.go b/verification/certifyKey.go index 3e83e05d..c80d3f26 100755 --- a/verification/certifyKey.go +++ b/verification/certifyKey.go @@ -431,26 +431,10 @@ func checkCertificateStructure(t *testing.T, certBytes []byte) *x509.Certificate return x509Cert } -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} +func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, simulation bool) { + ctx := getContextHandle(d, client, t, simulation) + if simulation { + defer client.DestroyContext(ctx, 0) } type Params struct { @@ -470,13 +454,13 @@ 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 { // 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) } @@ -500,6 +484,11 @@ 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) + // 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 96cde995..23aaf42f 100755 --- a/verification/client.go +++ b/verification/client.go @@ -33,6 +33,12 @@ 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) @@ -41,6 +47,10 @@ type DPEClient interface { TagTCI(handle *ContextHandle, tag TCITag) (*ContextHandle, error) GetTaggedTCI(tag TCITag) (*DPETCI, 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) { @@ -50,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 68edbda4..a9d331d9 100644 --- a/verification/initializeContext.go +++ b/verification/initializeContext.go @@ -67,3 +67,27 @@ 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 + handle = &DefaultContextHandle + } + + return handle +} diff --git a/verification/negativeCases.go b/verification/negativeCases.go new file mode 100644 index 00000000..d4645c56 --- /dev/null +++ b/verification/negativeCases.go @@ -0,0 +1,275 @@ +// 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} + +func TestInvalidHandle(d TestDPEInstance, c DPEClient, t *testing.T) { + testInvalidHandle(d, c, t) +} + +// 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 := getContextHandle(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) + } +} + +func TestWrongLocality(d TestDPEInstance, c DPEClient, t *testing.T) { + testWrongLocality(d, c, t) +} + +// 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) + } +} + +func TestUnsupportedCommand(d TestDPEInstance, c DPEClient, t *testing.T) { + testUnsupportedCommand(d, c, t) +} + +// 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) + } +} + +func TestUnsupportedCommandFlag(d TestDPEInstance, c DPEClient, t *testing.T) { + testUnsupportedCommandFlag(d, c, t) +} + +// 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 97ac04c5..e8210ab8 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", "RotateContext", "ExtendTci"}), AllTestCases, }, { @@ -303,6 +303,26 @@ func GetSimulatorTargets() []TestTarget { getTestTarget([]string{"Simulation", "ExtendTci", "AutoInit", "Tagging", "RotateContext", "X509", "Csr", "IsSymmetric", "InternalInfo", "InternalDice", "IsCA"}), []TestCase{GetProfileTestCase}, }, + { + "NegativeCase_InvalidHandle", + getTestTarget([]string{"Simulation", "RotateContext", "ExtendTci", "Tagging"}), + []TestCase{InvalidHandleTestCase}, + }, + { + "NegativeCase_WrongLocality", + getTestTarget([]string{"AutoInit", "RotateContext", "ExtendTci", "Tagging"}), + []TestCase{WrongLocalityTestCase}, + }, + { + "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 367a77d2..03ee0e04 100644 --- a/verification/tagTCI.go +++ b/verification/tagTCI.go @@ -8,16 +8,14 @@ import ( "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) + testTagTCI(d, client, t, false) +} + +func testTagTCI(d TestDPEInstance, client DPEClient, t *testing.T, simulation bool) { + ctx := getContextHandle(d, client, t, simulation) + if simulation { + defer client.DestroyContext(ctx, DestroyDescendants) } tag := TCITag(12345) @@ -27,14 +25,12 @@ func TestTagTCI(d TestDPEInstance, client DPEClient, t *testing.T) { } // Tag the default context - var ctx ContextHandle - - handle, err := client.TagTCI(&ctx, tag) + handle, err := client.TagTCI(ctx, tag) if err != nil { t.Fatalf("Could not tag TCI: %v", err) } - if *handle != ctx { + if *handle != *ctx { t.Errorf("New context handle from TagTCI was %x, expected %x", handle, ctx) } diff --git a/verification/verification.go b/verification/verification.go index 4e2b0c06..b1ae6acc 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) @@ -39,6 +41,18 @@ var TagTCITestCase = TestCase{ 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, From 8e3623d05727e48a8511275843f7092902fe8ad0 Mon Sep 17 00:00:00 2001 From: hpya93 Date: Wed, 8 Nov 2023 01:01:08 +0530 Subject: [PATCH 02/12] Common client code with review comments addressed --- verification/certifyKey.go | 2 +- verification/initializeContext.go | 6 ++++-- verification/negativeCases.go | 26 +++++--------------------- verification/simulator.go | 10 ---------- verification/tagTCI.go | 10 ++-------- verification/verification.go | 2 ++ 6 files changed, 14 insertions(+), 42 deletions(-) diff --git a/verification/certifyKey.go b/verification/certifyKey.go index c80d3f26..d733bbb9 100755 --- a/verification/certifyKey.go +++ b/verification/certifyKey.go @@ -432,7 +432,7 @@ func checkCertificateStructure(t *testing.T, certBytes []byte) *x509.Certificate } func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, simulation bool) { - ctx := getContextHandle(d, client, t, simulation) + ctx := getInitialContextHandle(d, client, t, simulation) if simulation { defer client.DestroyContext(ctx, 0) } diff --git a/verification/initializeContext.go b/verification/initializeContext.go index a9d331d9..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.") } diff --git a/verification/negativeCases.go b/verification/negativeCases.go index d4645c56..9f6f9f1f 100644 --- a/verification/negativeCases.go +++ b/verification/negativeCases.go @@ -9,15 +9,11 @@ import ( var InvalidHandle = ContextHandle{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} -func TestInvalidHandle(d TestDPEInstance, c DPEClient, t *testing.T) { - testInvalidHandle(d, c, t) -} - // 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 := getContextHandle(d, c, t, true) +func TestInvalidHandle(d TestDPEInstance, c DPEClient, t *testing.T) { + ctx := getInitialContextHandle(d, c, t, true) defer c.DestroyContext(ctx, DestroyDescendants) profile, err := GetTransportProfile(d) @@ -76,14 +72,10 @@ func testInvalidHandle(d TestDPEInstance, c DPEClient, t *testing.T) { } } -func TestWrongLocality(d TestDPEInstance, c DPEClient, t *testing.T) { - testWrongLocality(d, c, t) -} - // 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) { +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) @@ -149,14 +141,10 @@ func testWrongLocality(d TestDPEInstance, c DPEClient, t *testing.T) { } } -func TestUnsupportedCommand(d TestDPEInstance, c DPEClient, t *testing.T) { - testUnsupportedCommand(d, c, t) -} - // 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) { +func TestUnsupportedCommand(d TestDPEInstance, c DPEClient, t *testing.T) { ctx := &DefaultContextHandle profile, err := GetTransportProfile(d) @@ -187,10 +175,6 @@ func testUnsupportedCommand(d TestDPEInstance, c DPEClient, t *testing.T) { } } -func TestUnsupportedCommandFlag(d TestDPEInstance, c DPEClient, t *testing.T) { - testUnsupportedCommandFlag(d, c, t) -} - // 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. @@ -201,7 +185,7 @@ func TestUnsupportedCommandFlag(d TestDPEInstance, c DPEClient, t *testing.T) { // 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) { +func TestUnsupportedCommandFlag(d TestDPEInstance, c DPEClient, t *testing.T) { handle := &DefaultContextHandle profile, err := GetTransportProfile(d) diff --git a/verification/simulator.go b/verification/simulator.go index e8210ab8..e0b3e8ad 100644 --- a/verification/simulator.go +++ b/verification/simulator.go @@ -303,16 +303,6 @@ func GetSimulatorTargets() []TestTarget { getTestTarget([]string{"Simulation", "ExtendTci", "AutoInit", "Tagging", "RotateContext", "X509", "Csr", "IsSymmetric", "InternalInfo", "InternalDice", "IsCA"}), []TestCase{GetProfileTestCase}, }, - { - "NegativeCase_InvalidHandle", - getTestTarget([]string{"Simulation", "RotateContext", "ExtendTci", "Tagging"}), - []TestCase{InvalidHandleTestCase}, - }, - { - "NegativeCase_WrongLocality", - getTestTarget([]string{"AutoInit", "RotateContext", "ExtendTci", "Tagging"}), - []TestCase{WrongLocalityTestCase}, - }, { "NegativeCase_UnsupportedCommandByDPE", getTestTarget([]string{"AutoInit"}), diff --git a/verification/tagTCI.go b/verification/tagTCI.go index 03ee0e04..b02a1c3a 100644 --- a/verification/tagTCI.go +++ b/verification/tagTCI.go @@ -9,14 +9,8 @@ import ( ) func TestTagTCI(d TestDPEInstance, client DPEClient, t *testing.T) { - testTagTCI(d, client, t, false) -} - -func testTagTCI(d TestDPEInstance, client DPEClient, t *testing.T, simulation bool) { - ctx := getContextHandle(d, client, t, simulation) - if simulation { - defer client.DestroyContext(ctx, DestroyDescendants) - } + useSimulation := false + ctx := getInitialContextHandle(d, client, t, useSimulation) tag := TCITag(12345) // Check to see our tag is not yet found. diff --git a/verification/verification.go b/verification/verification.go index b1ae6acc..2da85fc9 100644 --- a/verification/verification.go +++ b/verification/verification.go @@ -62,6 +62,8 @@ var AllTestCases = []TestCase{ GetProfileTestCase, InitializeContextTestCase, InitializeContextSimulationTestCase, + InvalidHandleTestCase, + WrongLocalityTestCase, } func RunTargetTestCases(target TestTarget, t *testing.T) { From 2ab3aeb8a32258593e794d0e4ae74710bf2388d1 Mon Sep 17 00:00:00 2001 From: Jordan Hand Date: Thu, 16 Nov 2023 17:31:33 -0800 Subject: [PATCH 03/12] Add all DPE crates to a workspace * Make a common workspace to make it easier to format/build all code at once. * Set the rust version to a common version to ensure the same compiler is being used locally and in CI. --- Cargo.lock | 1224 +++++++++++++++++++++++++++++ Cargo.toml | 11 + crypto/src/openssl.rs | 8 +- rust-toolchain.toml | 5 + verification/verification_test.go | 2 +- 5 files changed, 1248 insertions(+), 2 deletions(-) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 rust-toolchain.toml diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..8623feae --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1224 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "asn1" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2affba5e62ee09eeba078f01a00c4aed45ac4287e091298eccbb0d4802efbdc5" +dependencies = [ + "asn1_derive", + "chrono", +] + +[[package]] +name = "asn1-rs" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "asn1_derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfab79c195875e5aef2bd20b4c8ed8d43ef9610bcffefbbcf66f88f555cc78af" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "num-traits", +] + +[[package]] +name = "clap" +version = "4.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "cms" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b1b34bce0eaafd63b374fa6b58178d72c0b6670e92db786bdd3cde9e37a1f1" +dependencies = [ + "const-oid", + "der", + "spki", + "x509-cert", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto" +version = "0.1.0" +dependencies = [ + "arrayvec", + "hkdf", + "openssl", + "rand", + "sha2", + "strum", + "strum_macros", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctrlc" +version = "3.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf" +dependencies = [ + "nix", + "windows-sys", +] + +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "der_derive", + "flagset", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der-parser" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "der_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "dpe" +version = "0.1.0" +dependencies = [ + "asn1", + "bitflags", + "cms", + "constant_time_eq", + "crypto", + "der", + "openssl", + "platform", + "spki", + "ufmt", + "x509-parser", + "zerocopy", + "zeroize", +] + +[[package]] +name = "env_logger" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "errno" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "flagset" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a7e408202050813e6f1d9addadcaafef3dca7530c7ddfb005d4081cce6779" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "linux-raw-sys" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "openssl" +version = "0.10.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "openssl-sys" +version = "0.9.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "pem" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b13fe415cdf3c8e44518e18a7c95a13431d9bdf6d15367d82b23c377fdd441a" +dependencies = [ + "base64", + "serde", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "platform" +version = "0.1.0" +dependencies = [ + "openssl", + "ufmt", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + +[[package]] +name = "rustix" +version = "0.38.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ad981d6c340a49cdc40a1028d9c6084ec7e9fa33fcb839cab656a267071e234" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "serde" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "simulator" +version = "0.1.0" +dependencies = [ + "clap", + "crypto", + "ctrlc", + "dpe", + "env_logger", + "log", + "openssl", + "platform", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "termcolor" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tools" +version = "0.1.0" +dependencies = [ + "crypto", + "dpe", + "pem", + "platform", + "zerocopy", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ufmt" +version = "0.2.0" +source = "git+https://github.com/korran/ufmt.git?rev=1d0743c1ffffc68bc05ca8eeb81c166192863f33#1d0743c1ffffc68bc05ca8eeb81c166192863f33" +dependencies = [ + "ufmt-macros", + "ufmt-write", +] + +[[package]] +name = "ufmt-macros" +version = "0.3.0" +source = "git+https://github.com/korran/ufmt.git?rev=1d0743c1ffffc68bc05ca8eeb81c166192863f33#1d0743c1ffffc68bc05ca8eeb81c166192863f33" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ufmt-write" +version = "0.1.0" +source = "git+https://github.com/korran/ufmt.git?rev=1d0743c1ffffc68bc05ca8eeb81c166192863f33#1d0743c1ffffc68bc05ca8eeb81c166192863f33" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "x509-cert" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25eefca1d99701da3a57feb07e5079fc62abba059fc139e98c13bbb250f3ef29" +dependencies = [ + "const-oid", + "der", + "spki", +] + +[[package]] +name = "x509-parser" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "zerocopy" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96f8f25c15a0edc9b07eb66e7e6e97d124c0505435c382fde1ab7ceb188aa956" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "855e0f6af9cd72b87d8a6c586f3cb583f5cdcc62c2c80869d8cd7e96fdf7ee20" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..4b2428fe --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +# Licensed under the Apache-2.0 license + +[workspace] + +members = [ + "dpe", + "crypto", + "platform", + "simulator", + "tools", +] diff --git a/crypto/src/openssl.rs b/crypto/src/openssl.rs index a0327fa6..1556c5e1 100644 --- a/crypto/src/openssl.rs +++ b/crypto/src/openssl.rs @@ -20,7 +20,7 @@ impl From for CryptoError { fn from(e: ErrorStack) -> Self { // Just return the top error on the stack let s = e.errors(); - let e_code = if s.len() > 0 { + let e_code = if !s.is_empty() { s[0].code().try_into().unwrap_or(0u32) } else { 0u32 @@ -99,6 +99,12 @@ impl OpensslCrypto { } } +impl Default for OpensslCrypto { + fn default() -> Self { + Self::new() + } +} + type OpensslCdi = Vec; type OpensslPrivKey = CryptoBuf; diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..9c9cb70b --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,5 @@ +# Licensed under the Apache-2.0 license + +[toolchain] +channel = "1.70" +components = ["rustfmt", "clippy"] diff --git a/verification/verification_test.go b/verification/verification_test.go index 85fd24a7..6ec0bcb9 100755 --- a/verification/verification_test.go +++ b/verification/verification_test.go @@ -12,7 +12,7 @@ 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") + TargetExe = flag.String("sim", "../target/debug/simulator", "path to simulator executable") exitVal := m.Run() os.Exit(exitVal) From a1d2ecf303fecafca381bf21bfcfdf1c45d7a9c2 Mon Sep 17 00:00:00 2001 From: hpya93 <94533459+hpya93@users.noreply.github.com> Date: Mon, 20 Nov 2023 21:34:11 +0530 Subject: [PATCH 04/12] Add tests for ExtendTCI Add ExtendTCI tests to the DPE verification test suite --- verification/abi.go | 4 + verification/certifyKey.go | 62 ++++++-- verification/extendTCI.go | 230 ++++++++++++++++++++++++++++++ verification/go.mod | 2 +- verification/initializeContext.go | 1 + verification/tagTCI.go | 55 +++---- verification/verification.go | 8 ++ verification/verification_test.go | 2 - 8 files changed, 318 insertions(+), 46 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 d733bbb9..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 { @@ -433,9 +476,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, DestroyDescendants) + } + }() type Params struct { Label []byte @@ -449,7 +494,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) } @@ -544,11 +589,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/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/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/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 diff --git a/verification/tagTCI.go b/verification/tagTCI.go index b02a1c3a..cff911ef 100644 --- a/verification/tagTCI.go +++ b/verification/tagTCI.go @@ -4,54 +4,45 @@ package verification import ( "errors" - //"reflect" "testing" ) -func TestTagTCI(d TestDPEInstance, client DPEClient, t *testing.T) { - useSimulation := false - ctx := getInitialContextHandle(d, client, t, useSimulation) +// 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 - tag := TCITag(12345) - // Check to see our tag is not yet found. - if _, err := client.GetTaggedTCI(tag); !errors.Is(err, StatusBadTag) { + // Get default context handle + handle := getInitialContextHandle(d, c, t, useSimulation) + + // 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) } - // Tag the default context - handle, err := client.TagTCI(ctx, 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 *handle != *ctx { - t.Errorf("New context handle from TagTCI was %x, expected %x", handle, ctx) + if *newHandle != *handle { + t.Errorf("New context handle from TagTCI was %x, expected %x", newHandle, handle) } - _, err = client.GetTaggedTCI(tag) + _, err = c.GetTaggedTCI(defaultCtxTCITag) 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) - } - - wantCurrentTCI := make([]byte, profile.GetDigestSize()) - if !reflect.DeepEqual(taggedTCI.CurrentTCI, wantCurrentTCI) { - t.Errorf("GetTaggedTCI returned current TCI %x, expected %x", taggedTCI.CurrentTCI, wantCurrentTCI) - } - */ - - // 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) + // 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) } - // TODO: When DeriveChild is implemented, call it here to add more TCIs and call TagTCI again. + // 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) + } } diff --git a/verification/verification.go b/verification/verification.go index 2da85fc9..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{}, } @@ -59,6 +65,8 @@ var AllTestCases = []TestCase{ CertifyKeySimulationTestCase, GetCertificateChainTestCase, TagTCITestCase, + ExtendTCITestCase, + ExtendDerivedTciTestCase, GetProfileTestCase, InitializeContextTestCase, InitializeContextSimulationTestCase, diff --git a/verification/verification_test.go b/verification/verification_test.go index 6ec0bcb9..3da20773 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", "../target/debug/simulator", "path to simulator executable") From b62fe7090f9f01bd1a3710ff8ce86f6426c66907 Mon Sep 17 00:00:00 2001 From: Sree Revoori Date: Fri, 17 Nov 2023 15:14:13 +0000 Subject: [PATCH 05/12] Remove tagging from DPE This will be added to caliptra-sw runtime in a separate PR. --- dpe/fuzz/src/fuzz_target_1.rs | 2 - dpe/src/commands/get_tagged_tci.rs | 41 ------ dpe/src/commands/mod.rs | 12 -- dpe/src/commands/tag_tci.rs | 197 ----------------------------- dpe/src/context.rs | 27 ++-- dpe/src/dpe_instance.rs | 4 +- dpe/src/lib.rs | 2 +- dpe/src/response.rs | 18 +-- dpe/src/support.rs | 39 ++---- simulator/src/main.rs | 7 - verification/abi.go | 90 +------------ verification/client.go | 2 - verification/errors.go | 2 - verification/extendTCI.go | 151 ---------------------- verification/negativeCases.go | 27 +--- verification/simulator.go | 16 +-- verification/tagTCI.go | 48 ------- verification/verification.go | 16 +-- 18 files changed, 40 insertions(+), 661 deletions(-) delete mode 100644 dpe/src/commands/get_tagged_tci.rs delete mode 100644 dpe/src/commands/tag_tci.rs delete mode 100644 verification/tagTCI.go diff --git a/dpe/fuzz/src/fuzz_target_1.rs b/dpe/fuzz/src/fuzz_target_1.rs index 7aeb4998..36184dbe 100644 --- a/dpe/fuzz/src/fuzz_target_1.rs +++ b/dpe/fuzz/src/fuzz_target_1.rs @@ -82,8 +82,6 @@ fn harness(data: &[u8]) { Response::Sign(ref res) => res.resp_hdr.status, Response::DestroyCtx(ref resp_hdr) => resp_hdr.status, Response::ExtendTci(ref res) => res.resp_hdr.status, - Response::TagTci(ref res) => res.resp_hdr.status, - Response::GetTaggedTci(ref res) => res.resp_hdr.status, Response::GetCertificateChain(ref res) => res.resp_hdr.status, Response::Error(ref resp_hdr) => resp_hdr.status, }; diff --git a/dpe/src/commands/get_tagged_tci.rs b/dpe/src/commands/get_tagged_tci.rs deleted file mode 100644 index 989293a3..00000000 --- a/dpe/src/commands/get_tagged_tci.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed under the Apache-2.0 license. -use super::CommandExecution; -use crate::{ - dpe_instance::{DpeEnv, DpeInstance, DpeTypes}, - response::{DpeErrorCode, GetTaggedTciResp, Response, ResponseHdr}, -}; - -#[repr(C)] -#[derive(Debug, PartialEq, Eq, zerocopy::FromBytes)] -#[cfg_attr(test, derive(zerocopy::AsBytes))] -pub struct GetTaggedTciCmd { - tag: u32, -} - -impl CommandExecution for GetTaggedTciCmd { - fn execute( - &self, - dpe: &mut DpeInstance, - _env: &mut DpeEnv, - _: u32, - ) -> Result { - // Make sure this command is supported. - if !dpe.support.tagging() { - return Err(DpeErrorCode::InvalidCommand); - } - - // Tags are unique across all contexts, so we just need to return the first context - // we find with the requested tag. - let ctx = dpe - .contexts - .iter() - .find(|c| c.has_tag() && c.tag == self.tag) - .ok_or(DpeErrorCode::BadTag)?; - - Ok(Response::GetTaggedTci(GetTaggedTciResp { - tci_cumulative: ctx.tci.tci_cumulative, - tci_current: ctx.tci.tci_current, - resp_hdr: ResponseHdr::new(DpeErrorCode::NoError), - })) - } -} diff --git a/dpe/src/commands/mod.rs b/dpe/src/commands/mod.rs index f60cbfd7..637d79b7 100644 --- a/dpe/src/commands/mod.rs +++ b/dpe/src/commands/mod.rs @@ -12,10 +12,8 @@ pub use self::initialize_context::InitCtxCmd; pub use self::certify_key::{CertifyKeyCmd, CertifyKeyFlags}; use self::extend_tci::ExtendTciCmd; -use self::get_tagged_tci::GetTaggedTciCmd; pub use self::rotate_context::{RotateCtxCmd, RotateCtxFlags}; pub use self::sign::{SignCmd, SignFlags}; -use self::tag_tci::TagTciCmd; use crate::{ dpe_instance::{DpeEnv, DpeInstance, DpeTypes}, @@ -30,11 +28,9 @@ mod derive_child; mod destroy_context; mod extend_tci; mod get_certificate_chain; -mod get_tagged_tci; mod initialize_context; mod rotate_context; mod sign; -mod tag_tci; #[derive(Debug, PartialEq, Eq)] pub enum Command { @@ -46,8 +42,6 @@ pub enum Command { RotateCtx(RotateCtxCmd), DestroyCtx(DestroyCtxCmd), ExtendTci(ExtendTciCmd), - TagTci(TagTciCmd), - GetTaggedTci(GetTaggedTciCmd), GetCertificateChain(GetCertificateChainCmd), } @@ -61,8 +55,6 @@ impl Command { pub const DESTROY_CONTEXT: u32 = 0x0f; pub const GET_CERTIFICATE_CHAIN: u32 = 0x80; pub const EXTEND_TCI: u32 = 0x81; - pub const TAG_TCI: u32 = 0x82; - pub const GET_TAGGED_TCI: u32 = 0x83; /// Returns the command with its parameters given a slice of bytes. /// @@ -85,8 +77,6 @@ impl Command { Self::parse_command(Command::GetCertificateChain, bytes) } Command::EXTEND_TCI => Self::parse_command(Command::ExtendTci, bytes), - Command::TAG_TCI => Self::parse_command(Command::TagTci, bytes), - Command::GET_TAGGED_TCI => Self::parse_command(Command::GetTaggedTci, bytes), _ => Err(DpeErrorCode::InvalidCommand), } } @@ -112,8 +102,6 @@ impl From for u32 { Command::RotateCtx(_) => Command::ROTATE_CONTEXT_HANDLE, Command::DestroyCtx(_) => Command::DESTROY_CONTEXT, Command::ExtendTci(_) => Command::EXTEND_TCI, - Command::TagTci(_) => Command::TAG_TCI, - Command::GetTaggedTci(_) => Command::GET_TAGGED_TCI, Command::GetCertificateChain(_) => Command::GET_CERTIFICATE_CHAIN, } } diff --git a/dpe/src/commands/tag_tci.rs b/dpe/src/commands/tag_tci.rs deleted file mode 100644 index a2d90cd3..00000000 --- a/dpe/src/commands/tag_tci.rs +++ /dev/null @@ -1,197 +0,0 @@ -// Licensed under the Apache-2.0 license. -use super::CommandExecution; -use crate::{ - context::ContextHandle, - dpe_instance::{DpeEnv, DpeInstance, DpeTypes}, - response::{DpeErrorCode, NewHandleResp, Response, ResponseHdr}, -}; - -#[repr(C)] -#[derive(Debug, PartialEq, Eq, zerocopy::FromBytes)] -#[cfg_attr(test, derive(zerocopy::AsBytes))] -pub struct TagTciCmd { - handle: ContextHandle, - tag: u32, -} - -impl CommandExecution for TagTciCmd { - fn execute( - &self, - dpe: &mut DpeInstance, - env: &mut DpeEnv, - locality: u32, - ) -> Result { - // Make sure this command is supported. - if !dpe.support.tagging() { - return Err(DpeErrorCode::InvalidCommand); - } - // Make sure the tag isn't used by any other contexts. - if dpe - .contexts - .iter() - .any(|c| c.has_tag() && c.tag == self.tag) - { - return Err(DpeErrorCode::BadTag); - } - - let idx = dpe.get_active_context_pos(&self.handle, locality)?; - - if dpe.contexts[idx].has_tag() { - return Err(DpeErrorCode::BadTag); - } - - // Because handles are one-time use, let's rotate the handle, if it isn't the default. - dpe.roll_onetime_use_handle(env, idx)?; - let context = &mut dpe.contexts[idx]; - context.has_tag = true.into(); - context.tag = self.tag; - - Ok(Response::TagTci(NewHandleResp { - handle: context.handle, - resp_hdr: ResponseHdr::new(DpeErrorCode::NoError), - })) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - commands::{Command, CommandHdr, InitCtxCmd}, - dpe_instance::tests::{ - TestTypes, RANDOM_HANDLE, SIMULATION_HANDLE, TEST_HANDLE, TEST_LOCALITIES, - }, - support::Support, - }; - use crypto::OpensslCrypto; - use platform::default::DefaultPlatform; - use zerocopy::AsBytes; - - const TEST_TAG_TCI_CMD: TagTciCmd = TagTciCmd { - handle: SIMULATION_HANDLE, - tag: 0x1234_5678, - }; - - #[test] - fn test_deserialize_tag_tci() { - let mut command = CommandHdr::new_for_test(Command::TAG_TCI) - .as_bytes() - .to_vec(); - command.extend(TEST_TAG_TCI_CMD.as_bytes()); - assert_eq!( - Ok(Command::TagTci(TEST_TAG_TCI_CMD)), - Command::deserialize(&command) - ); - } - - #[test] - fn test_tag_tci() { - let mut env = DpeEnv:: { - crypto: OpensslCrypto::new(), - platform: DefaultPlatform, - }; - let mut dpe = DpeInstance::new(&mut env, Support::default()).unwrap(); - // Make sure it returns an error if the command is marked unsupported. - assert_eq!( - Err(DpeErrorCode::InvalidCommand), - TagTciCmd { - handle: ContextHandle::default(), - tag: 0, - } - .execute(&mut dpe, &mut env, TEST_LOCALITIES[0]) - ); - - // Make a new instance that supports tagging. - let mut dpe = DpeInstance::new(&mut env, Support::TAGGING | Support::SIMULATION).unwrap(); - InitCtxCmd::new_use_default() - .execute(&mut dpe, &mut env, TEST_LOCALITIES[0]) - .unwrap(); - - // Wrong locality. - assert_eq!( - Err(DpeErrorCode::InvalidLocality), - TagTciCmd { - handle: ContextHandle::default(), - tag: 0, - } - .execute(&mut dpe, &mut env, TEST_LOCALITIES[1]) - ); - - let sim_local = TEST_LOCALITIES[1]; - // Make a simulation context to test against. - InitCtxCmd::new_simulation() - .execute(&mut dpe, &mut env, sim_local) - .unwrap(); - - // Invalid handle. - assert_eq!( - Err(DpeErrorCode::InvalidHandle), - TagTciCmd { - handle: TEST_HANDLE, - tag: 0, - } - .execute(&mut dpe, &mut env, TEST_LOCALITIES[0]) - ); - - // Tag default handle. - assert_eq!( - Ok(Response::TagTci(NewHandleResp { - handle: ContextHandle::default(), - resp_hdr: ResponseHdr::new(DpeErrorCode::NoError), - })), - TagTciCmd { - handle: ContextHandle::default(), - tag: 0, - } - .execute(&mut dpe, &mut env, TEST_LOCALITIES[0]) - ); - - // Try to re-tag the default context. - assert_eq!( - Err(DpeErrorCode::BadTag), - TagTciCmd { - handle: ContextHandle::default(), - tag: 1, - } - .execute(&mut dpe, &mut env, TEST_LOCALITIES[0]) - ); - - // Try same tag on simulation. - assert_eq!( - Err(DpeErrorCode::BadTag), - TagTciCmd { - handle: SIMULATION_HANDLE, - tag: 0, - } - .execute(&mut dpe, &mut env, TEST_LOCALITIES[1]) - ); - - // Give the simulation context another handle so we can prove the handle rotates when it - // gets tagged. - let simulation_ctx = &mut dpe.contexts[dpe - .get_active_context_pos(&RANDOM_HANDLE, sim_local) - .unwrap()]; - let sim_tmp_handle = ContextHandle([0xff; ContextHandle::SIZE]); - simulation_ctx.handle = sim_tmp_handle; - assert!(dpe - .get_active_context_pos(&RANDOM_HANDLE, sim_local) - .is_err()); - - // Tag simulation. - match (TagTciCmd { - handle: sim_tmp_handle, - tag: 1, - } - .execute(&mut dpe, &mut env, TEST_LOCALITIES[1])) - { - Ok(Response::TagTci(NewHandleResp { handle, .. })) => { - // Make sure it rotated back to the deterministic simulation handle. - assert!(dpe - .get_active_context_pos(&sim_tmp_handle, sim_local) - .is_err()); - assert!(dpe.get_active_context_pos(&handle, sim_local).is_ok()); - } - _ => panic!("Tag simulation failed"), - } - } -} diff --git a/dpe/src/context.rs b/dpe/src/context.rs index 8d891942..d4b7aab3 100644 --- a/dpe/src/context.rs +++ b/dpe/src/context.rs @@ -14,11 +14,6 @@ pub struct Context { /// Which hardware locality owns the context. pub locality: u32, - /// Optional tag assigned to the context. - pub tag: u32, - - /// Whether a tag has been assigned to the context. - pub has_tag: U8Bool, /// Index in DPE instance of the parent context. 0xFF if this node is the root pub parent_idx: u8, @@ -36,6 +31,7 @@ pub struct Context { pub allow_ca: U8Bool, /// Whether this context can emit certificates in X.509 format pub allow_x509: U8Bool, + pub reserved: [u8; 1], } impl Context { @@ -50,18 +46,14 @@ impl Context { context_type: ContextType::Normal, state: ContextState::Inactive, locality: 0, - has_tag: U8Bool::new(false), - tag: 0, uses_internal_input_info: U8Bool::new(false), uses_internal_input_dice: U8Bool::new(false), allow_ca: U8Bool::new(false), allow_x509: U8Bool::new(false), + reserved: [0; 1], } } - pub fn has_tag(&self) -> bool { - self.has_tag.get() - } pub fn uses_internal_input_info(&self) -> bool { self.uses_internal_input_info.get() } @@ -101,8 +93,6 @@ impl Context { /// context cannot be re-initialized. pub fn destroy(&mut self) { self.tci = TciNodeData::new(); - self.has_tag = false.into(); - self.tag = 0; self.state = ContextState::Inactive; self.uses_internal_input_info = false.into(); self.uses_internal_input_dice = false.into(); @@ -274,16 +264,16 @@ mod tests { let root_index = CHAIN_INDICES[0]; assert_eq!(MAX_HANDLES, CHAIN_INDICES.len()); - // Lets put the context's index in the tag to make it easy to find later. - contexts[root_index].tag = root_index as u32; + // Put the context's index in the handle to make it easy to find later. + contexts[root_index].handle = ContextHandle([root_index as u8; ContextHandle::SIZE]); contexts[root_index].state = ContextState::Retired; - // Assign all of the children's parents and put their index in the tag. + // Assign all of the children's parents and put their index in the handle. for (parent_chain_idx, child_idx) in CHAIN_INDICES.iter().skip(1).enumerate() { let parent_idx = CHAIN_INDICES[parent_chain_idx]; let context = &mut contexts[*child_idx]; context.parent_idx = parent_idx as u8; - context.tag = *child_idx as u32; + context.handle = ContextHandle([*child_idx as u8; ContextHandle::SIZE]); context.state = ContextState::Active; } @@ -295,7 +285,10 @@ mod tests { .rev() .zip(ChildToRootIter::new(leaf_index, &contexts)) { - assert_eq!(*answer, status.unwrap().tag as usize); + assert_eq!( + [*answer as u8; ContextHandle::SIZE], + status.unwrap().handle.0 + ); count += 1; } diff --git a/dpe/src/dpe_instance.rs b/dpe/src/dpe_instance.rs index 54a9f492..6b65aae1 100644 --- a/dpe/src/dpe_instance.rs +++ b/dpe/src/dpe_instance.rs @@ -114,8 +114,6 @@ impl DpeInstance { Command::RotateCtx(cmd) => cmd.execute(self, env, locality), Command::DestroyCtx(cmd) => cmd.execute(self, env, locality), Command::ExtendTci(cmd) => cmd.execute(self, env, locality), - Command::TagTci(cmd) => cmd.execute(self, env, locality), - Command::GetTaggedTci(cmd) => cmd.execute(self, env, locality), Command::GetCertificateChain(cmd) => cmd.execute(self, env, locality), }; @@ -128,7 +126,7 @@ impl DpeInstance { // Inlined so the callsite optimizer knows that idx < self.contexts.len() // and won't insert possible call to panic. #[inline(always)] - pub(crate) fn get_active_context_pos( + pub fn get_active_context_pos( &self, handle: &ContextHandle, locality: u32, diff --git a/dpe/src/lib.rs b/dpe/src/lib.rs index f2bcb41f..75f0a210 100644 --- a/dpe/src/lib.rs +++ b/dpe/src/lib.rs @@ -23,7 +23,7 @@ pub mod x509; use zerocopy::{AsBytes, FromBytes}; const MAX_CERT_SIZE: usize = 2048; -const MAX_HANDLES: usize = 24; +pub const MAX_HANDLES: usize = 24; const CURRENT_PROFILE_MAJOR_VERSION: u16 = 0; const CURRENT_PROFILE_MINOR_VERSION: u16 = 8; diff --git a/dpe/src/response.rs b/dpe/src/response.rs index b5ffda48..78ae42d9 100644 --- a/dpe/src/response.rs +++ b/dpe/src/response.rs @@ -5,8 +5,8 @@ Abstract: DPE reponses and serialization. --*/ use crate::{ - context::ContextHandle, tci::TciMeasurement, CURRENT_PROFILE_MAJOR_VERSION, - CURRENT_PROFILE_MINOR_VERSION, DPE_PROFILE, MAX_CERT_SIZE, MAX_HANDLES, + context::ContextHandle, CURRENT_PROFILE_MAJOR_VERSION, CURRENT_PROFILE_MINOR_VERSION, + DPE_PROFILE, MAX_CERT_SIZE, MAX_HANDLES, }; use crypto::CryptoError; use platform::PlatformError; @@ -23,8 +23,6 @@ pub enum Response { Sign(SignResp), DestroyCtx(ResponseHdr), ExtendTci(NewHandleResp), - TagTci(NewHandleResp), - GetTaggedTci(GetTaggedTciResp), GetCertificateChain(GetCertificateChainResp), Error(ResponseHdr), } @@ -40,8 +38,6 @@ impl Response { Response::Sign(res) => res.as_bytes(), Response::DestroyCtx(res) => res.as_bytes(), Response::ExtendTci(res) => res.as_bytes(), - Response::TagTci(res) => res.as_bytes(), - Response::GetTaggedTci(res) => res.as_bytes(), Response::GetCertificateChain(res) => res.as_bytes(), Response::Error(res) => res.as_bytes(), } @@ -135,15 +131,6 @@ pub struct SignResp { pub sig_s: [u8; DPE_PROFILE.get_ecc_int_size()], } -#[repr(C)] -#[derive(Debug, zerocopy::AsBytes)] -#[cfg_attr(test, derive(PartialEq, Eq))] -pub struct GetTaggedTciResp { - pub resp_hdr: ResponseHdr, - pub tci_cumulative: TciMeasurement, - pub tci_current: TciMeasurement, -} - #[repr(C)] #[derive(Debug, PartialEq, Eq, zerocopy::AsBytes, zerocopy::FromBytes)] pub struct GetCertificateChainResp { @@ -162,7 +149,6 @@ pub enum DpeErrorCode { ArgumentNotSupported = 4, InvalidHandle = 0x1000, InvalidLocality = 0x1001, - BadTag = 0x1002, MaxTcis = 0x1003, Platform(PlatformError) = 0x01000000, Crypto(CryptoError) = 0x02000000, diff --git a/dpe/src/support.rs b/dpe/src/support.rs index 170c142c..5f38ac85 100644 --- a/dpe/src/support.rs +++ b/dpe/src/support.rs @@ -12,14 +12,13 @@ bitflags! { const SIMULATION = 1u32 << 31; const EXTEND_TCI = 1u32 << 30; const AUTO_INIT = 1u32 << 29; - const TAGGING = 1u32 << 28; const ROTATE_CONTEXT = 1u32 << 27; const X509 = 1u32 << 26; const CSR = 1u32 << 25; const IS_SYMMETRIC = 1u32 << 24; - const INTERNAL_INFO = 1u32 << 23; - const INTERNAL_DICE = 1u32 << 22; - const IS_CA = 1u32 << 21; + const INTERNAL_INFO = 1u32 << 22; + const INTERNAL_DICE = 1u32 << 21; + const IS_CA = 1u32 << 20; } } @@ -33,9 +32,6 @@ impl Support { pub fn auto_init(&self) -> bool { self.contains(Support::AUTO_INIT) } - pub fn tagging(&self) -> bool { - self.contains(Support::TAGGING) - } pub fn rotate_context(&self) -> bool { self.contains(Support::ROTATE_CONTEXT) } @@ -67,7 +63,6 @@ pub mod test { pub const SUPPORT: Support = bitflags_join!( Support::SIMULATION, Support::AUTO_INIT, - Support::TAGGING, Support::ROTATE_CONTEXT, Support::X509 ); @@ -83,9 +78,6 @@ pub mod test { // Supports auto-init. let flags = Support::AUTO_INIT.bits(); assert_eq!(flags, 1 << 29); - // Supports tagging. - let flags = Support::TAGGING.bits(); - assert_eq!(flags, 1 << 28); // Supports rotate context. let flags = Support::ROTATE_CONTEXT.bits(); assert_eq!(flags, 1 << 27); @@ -100,13 +92,13 @@ pub mod test { assert_eq!(flags, 1 << 24); // Supports internal info. let flags = Support::INTERNAL_INFO.bits(); - assert_eq!(flags, 1 << 23); + assert_eq!(flags, 1 << 22); // Supports internal DICE. let flags = Support::INTERNAL_DICE.bits(); - assert_eq!(flags, 1 << 22); + assert_eq!(flags, 1 << 21); // Supports is ca. let flags = Support::IS_CA.bits(); - assert_eq!(flags, 1 << 21); + assert_eq!(flags, 1 << 20); // Supports a couple combos. let flags = (Support::SIMULATION | Support::AUTO_INIT @@ -116,18 +108,12 @@ pub mod test { .bits(); assert_eq!( flags, - (1 << 31) | (1 << 29) | (1 << 27) | (1 << 25) | (1 << 22) - ); - let flags = (Support::EXTEND_TCI - | Support::TAGGING - | Support::X509 - | Support::IS_SYMMETRIC - | Support::INTERNAL_INFO) - .bits(); - assert_eq!( - flags, - (1 << 30) | (1 << 28) | (1 << 26) | (1 << 24) | (1 << 23) + (1 << 31) | (1 << 29) | (1 << 27) | (1 << 25) | (1 << 21) ); + let flags = + (Support::EXTEND_TCI | Support::X509 | Support::IS_SYMMETRIC | Support::INTERNAL_INFO) + .bits(); + assert_eq!(flags, (1 << 30) | (1 << 26) | (1 << 24) | (1 << 22)); // Supports everything. let flags = Support::all().bits(); assert_eq!( @@ -135,14 +121,13 @@ pub mod test { (1 << 31) | (1 << 30) | (1 << 29) - | (1 << 28) | (1 << 27) | (1 << 26) | (1 << 25) | (1 << 24) - | (1 << 23) | (1 << 22) | (1 << 21) + | (1 << 20) ); } } diff --git a/simulator/src/main.rs b/simulator/src/main.rs index d788366c..76941501 100644 --- a/simulator/src/main.rs +++ b/simulator/src/main.rs @@ -49,8 +49,6 @@ fn handle_request(dpe: &mut DpeInstance, env: &mut DpeEnv, stream Response::Sign(ref res) => res.resp_hdr.status, Response::DestroyCtx(ref resp_hdr) => resp_hdr.status, Response::ExtendTci(ref res) => res.resp_hdr.status, - Response::TagTci(ref res) => res.resp_hdr.status, - Response::GetTaggedTci(ref res) => res.resp_hdr.status, Response::GetCertificateChain(ref res) => res.resp_hdr.status, Response::Error(ref resp_hdr) => resp_hdr.status, }; @@ -83,10 +81,6 @@ struct Args { #[arg(long)] supports_auto_init: bool, - /// Supports the TagTci and GetTaggedTci commands. - #[arg(long)] - supports_tagging: bool, - /// Supports the RotateContextHandle command. #[arg(long)] supports_rotate_context: bool, @@ -152,7 +146,6 @@ fn main() -> std::io::Result<()> { support.set(Support::INTERNAL_INFO, args.supports_internal_info); support.set(Support::IS_CA, args.supports_is_ca); support.set(Support::IS_SYMMETRIC, args.supports_is_symmetric); - support.set(Support::TAGGING, args.supports_tagging); let mut env = DpeEnv:: { crypto: OpensslCrypto::new(), diff --git a/verification/abi.go b/verification/abi.go index d4fdac6a..63f76607 100755 --- a/verification/abi.go +++ b/verification/abi.go @@ -9,10 +9,6 @@ import ( var DefaultContextHandle = ContextHandle{0} -const defaultCtxTCITag = TCITag(12345) -const nonExistentTCITag = TCITag(98765) -const childCtxTCITag = TCITag(34567) - const ( CmdMagic uint32 = 0x44504543 RespMagic uint32 = 0x44504552 @@ -27,7 +23,6 @@ type Support struct { Simulation bool ExtendTci bool AutoInit bool - Tagging bool RotateContext bool X509 bool Csr bool @@ -47,8 +42,6 @@ const ( CommandDestroyContext CommandCode = 0xf CommandGetCertificateChain CommandCode = 0x80 CommandExtendTCI CommandCode = 0x81 - CommandTagTCI CommandCode = 0x82 - CommandGetTaggedTCI CommandCode = 0x83 ) type CommandHdr struct { @@ -145,26 +138,6 @@ type GetCertificateChainResp struct { CertificateChain []byte } -type TCITag uint32 - -type TagTCIReq struct { - ContextHandle ContextHandle - Tag TCITag -} - -type TagTCIResp struct { - NewContextHandle ContextHandle -} - -type GetTaggedTCIReq struct { - Tag TCITag -} - -type GetTaggedTCIResp[Digest DigestAlgorithm] struct { - CumulativeTCI Digest - CurrentTCI Digest -} - type RotateContextHandleFlags uint32 const ( @@ -447,30 +420,6 @@ func (c *dpeABI[_, _]) GetCertificateChainABI() (*GetCertificateChainResp, error return &certs, nil } -// TagTCI calls the DPE TagTCI command. -func (c *dpeABI[_, _]) TagTCIABI(cmd *TagTCIReq) (*TagTCIResp, error) { - var respStruct TagTCIResp - - _, err := execCommand(c.transport, CommandTagTCI, c.Profile, cmd, &respStruct) - if err != nil { - return nil, err - } - - return &respStruct, nil -} - -// GetTaggedTCI calls the DPE GetTaggedTCI command. -func (c *dpeABI[_, Digest]) GetTaggedTCIABI(cmd *GetTaggedTCIReq) (*GetTaggedTCIResp[Digest], error) { - var respStruct GetTaggedTCIResp[Digest] - - _, err := execCommand(c.transport, CommandGetTaggedTCI, c.Profile, cmd, &respStruct) - if err != nil { - return nil, err - } - - return &respStruct, nil -} - // DeriveChild calls DPE DeriveChild command. func (c *dpeABI[_, Digest]) DeriveChildABI(cmd *DeriveChildReq[Digest]) (*DeriveChildResp, error) { var respStruct DeriveChildResp @@ -562,36 +511,6 @@ 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, @@ -701,9 +620,6 @@ func (s *Support) ToFlags() uint32 { if s.AutoInit { flags |= (1 << 29) } - if s.Tagging { - flags |= (1 << 28) - } if s.RotateContext { flags |= (1 << 27) } @@ -717,13 +633,13 @@ func (s *Support) ToFlags() uint32 { flags |= (1 << 24) } if s.InternalInfo { - flags |= (1 << 23) + flags |= (1 << 22) } if s.InternalDice { - flags |= (1 << 22) + flags |= (1 << 21) } if s.IsCA { - flags |= (1 << 21) + flags |= (1 << 20) } return flags } diff --git a/verification/client.go b/verification/client.go index 23aaf42f..6f6109a1 100755 --- a/verification/client.go +++ b/verification/client.go @@ -44,8 +44,6 @@ type DPEClient interface { GetProfile() (*GetProfileResp, 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) 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) diff --git a/verification/errors.go b/verification/errors.go index 4236f790..c94a138a 100644 --- a/verification/errors.go +++ b/verification/errors.go @@ -35,8 +35,6 @@ func (s Status) Error() string { return "contextHandle does not exist" case StatusInvalidLocality: return "Hardware Locality does not exist" - case StatusBadTag: - return "TCI Tag is either in use (TagTci) or not found (GetTaggedTci)" case StatusMaxTCIs: return "maximum number of TCIs have been created" case StatusPlatformError: diff --git a/verification/extendTCI.go b/verification/extendTCI.go index 68ea1845..3d2bcdbd 100644 --- a/verification/extendTCI.go +++ b/verification/extendTCI.go @@ -3,7 +3,6 @@ package verification import ( - "bytes" "crypto/sha256" "crypto/sha512" "crypto/x509" @@ -50,160 +49,10 @@ func TestExtendTCI(d TestDPEInstance, c DPEClient, t *testing.T) { 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 { diff --git a/verification/negativeCases.go b/verification/negativeCases.go index 9f6f9f1f..ac39092c 100644 --- a/verification/negativeCases.go +++ b/verification/negativeCases.go @@ -10,7 +10,7 @@ import ( 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 +// Exceptions are - GetProfile, InitializeContext, GetCertificateChain, 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) @@ -63,17 +63,10 @@ func TestInvalidHandle(d TestDPEInstance, c DPEClient, t *testing.T) { } 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 +// Exceptions are - GetProfile, InitializeContext, GetCertificateChain, 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 @@ -132,17 +125,10 @@ func TestWrongLocality(d TestDPEInstance, c DPEClient, t *testing.T) { } 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 +// DPE commands - RotateContextHandle, ExtendTCI, require support to be enabled in DPE profile // before being called. func TestUnsupportedCommand(d TestDPEInstance, c DPEClient, t *testing.T) { ctx := &DefaultContextHandle @@ -166,13 +152,6 @@ func TestUnsupportedCommand(d TestDPEInstance, c DPEClient, t *testing.T) { } 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. diff --git a/verification/simulator.go b/verification/simulator.go index e0b3e8ad..dd7b4adf 100644 --- a/verification/simulator.go +++ b/verification/simulator.go @@ -55,9 +55,6 @@ func (s *DpeSimulator) PowerOn() error { if s.supports.AutoInit { args = append(args, "--supports-auto-init") } - if s.supports.Tagging { - args = append(args, "--supports-tagging") - } if s.supports.RotateContext { args = append(args, "--supports-rotate-context") } @@ -230,7 +227,7 @@ func GetSimulatorTargets() []TestTarget { }, { "DefaultSupport", - getTestTarget([]string{"AutoInit", "Simulation", "X509", "IsCA", "Tagging", "RotateContext", "ExtendTci"}), + getTestTarget([]string{"AutoInit", "Simulation", "X509", "IsCA", "RotateContext", "ExtendTci"}), AllTestCases, }, { @@ -248,11 +245,6 @@ func GetSimulatorTargets() []TestTarget { getTestTarget([]string{"AutoInit"}), []TestCase{GetProfileTestCase}, }, - { - "GetProfile_Tagging", - getTestTarget([]string{"Tagging"}), - []TestCase{GetProfileTestCase}, - }, { "GetProfile_RotateContext", getTestTarget([]string{"RotateContext"}), @@ -295,12 +287,12 @@ func GetSimulatorTargets() []TestTarget { }, { "GetProfile_Combo02", - getTestTarget([]string{"ExtendTci", "Tagging", "X509", "InternalInfo"}), + getTestTarget([]string{"ExtendTci", "X509", "InternalInfo"}), []TestCase{GetProfileTestCase}, }, { "GetProfile_All", - getTestTarget([]string{"Simulation", "ExtendTci", "AutoInit", "Tagging", "RotateContext", "X509", "Csr", "IsSymmetric", "InternalInfo", "InternalDice", "IsCA"}), + getTestTarget([]string{"Simulation", "ExtendTci", "AutoInit", "RotateContext", "X509", "Csr", "IsSymmetric", "InternalInfo", "InternalDice", "IsCA"}), []TestCase{GetProfileTestCase}, }, { @@ -310,7 +302,7 @@ func GetSimulatorTargets() []TestTarget { }, { "NegativeCase_UnsupportedFeatureByDPE", - getTestTarget([]string{"AutoInit", "RotateContext", "ExtendTci", "Tagging"}), + getTestTarget([]string{"AutoInit", "RotateContext", "ExtendTci"}), []TestCase{UnsupportedCommandFlag}, }, } diff --git a/verification/tagTCI.go b/verification/tagTCI.go deleted file mode 100644 index cff911ef..00000000 --- a/verification/tagTCI.go +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed under the Apache-2.0 license - -package verification - -import ( - "errors" - "testing" -) - -// 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 default context handle - handle := getInitialContextHandle(d, c, t, useSimulation) - - // 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) - } - - // 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) - } - - _, 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) { - t.Fatalf("Re-tagging a tagged TCI returned %v, want %v", 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) - } -} diff --git a/verification/verification.go b/verification/verification.go index b3ee74a5..a955dc61 100644 --- a/verification/verification.go +++ b/verification/verification.go @@ -35,38 +35,30 @@ var CertifyKeySimulationTestCase = TestCase{ var GetCertificateChainTestCase = TestCase{ "GetCertificateChain", TestGetCertificateChain, []string{"AutoInit", "X509"}, } -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"}, + "ExtendTCITestCase", TestExtendTCI, []string{"AutoInit", "ExtendTci"}, } var GetProfileTestCase = TestCase{ "GetProfile", TestGetProfile, []string{}, } var InvalidHandleTestCase = TestCase{ - "CheckInvalidHandle", TestInvalidHandle, []string{"Simulation", "RotateContext", "ExtendTci", "Tagging"}, + "CheckInvalidHandle", TestInvalidHandle, []string{"Simulation", "RotateContext", "ExtendTci"}, } var WrongLocalityTestCase = TestCase{ - "CheckWrongLocality", TestWrongLocality, []string{"AutoInit", "RotateContext", "ExtendTci", "Tagging"}, + "CheckWrongLocality", TestWrongLocality, []string{"AutoInit", "RotateContext", "ExtendTci"}, } var UnsupportedCommand = TestCase{ "CheckSupportForCommand", TestUnsupportedCommand, []string{"AutoInit"}, } var UnsupportedCommandFlag = TestCase{ - "CheckSupportForCommmandFlag", TestUnsupportedCommandFlag, []string{"AutoInit", "RotateContext", "ExtendTci", "Tagging"}, + "CheckSupportForCommmandFlag", TestUnsupportedCommandFlag, []string{"AutoInit", "RotateContext", "ExtendTci"}, } var AllTestCases = []TestCase{ CertifyKeyTestCase, CertifyKeySimulationTestCase, GetCertificateChainTestCase, - TagTCITestCase, ExtendTCITestCase, - ExtendDerivedTciTestCase, GetProfileTestCase, InitializeContextTestCase, InitializeContextSimulationTestCase, From fb105d95e274846a1e0dcc626d2fd64be16798d6 Mon Sep 17 00:00:00 2001 From: Jordan Hand Date: Mon, 20 Nov 2023 16:43:42 -0800 Subject: [PATCH 06/12] Fix verification tests to pass against Caliptra emulator 1. Refactor ExtendTCI to calculate the cumulative measurement properly 2. Refactor some helpers for better readability 3. Skip bad locality test for targets that don't have locality control --- verification/certifyKey.go | 71 ++--------------------------------- verification/certs.go | 69 ++++++++++++++++++++++++++++++++++ verification/extendTCI.go | 60 ++++++++++++++--------------- verification/negativeCases.go | 9 ++++- verification/simulator.go | 4 ++ verification/transport.go | 2 + 6 files changed, 115 insertions(+), 100 deletions(-) create mode 100644 verification/certs.go diff --git a/verification/certifyKey.go b/verification/certifyKey.go index e7b59694..126478a3 100755 --- a/verification/certifyKey.go +++ b/verification/certifyKey.go @@ -4,14 +4,11 @@ package verification import ( "bytes" - "crypto/sha256" - "crypto/sha512" "crypto/x509" "encoding/asn1" "encoding/binary" "encoding/pem" "fmt" - "hash" "reflect" "testing" "time" @@ -221,69 +218,6 @@ func checkCertifyKeyTcgUeidExtension(t *testing.T, c *x509.Certificate, label [] } } -// A tcg-dice-MultiTcbInfo extension. -// This extension SHOULD be marked as critical. -func checkCertifyKeyMultiTcbInfoExtensionStructure(t *testing.T, c *x509.Certificate) (TcgMultiTcbInfo, error) { - t.Helper() - var multiTcbInfo TcgMultiTcbInfo - var err error - - // Check MultiTcbInfo Extension - //tcg-dice-MultiTcbInfo extension - for _, ext := range c.Extensions { - if ext.Id.Equal(OidExtensionTcgDiceMultiTcbInfo) { // OID for Tcg Dice MultiTcbInfo - if !ext.Critical { - t.Errorf("[ERROR]: TCG DICE MultiTcbInfo extension is not marked as CRITICAL") - } - _, err = asn1.Unmarshal(ext.Value, &multiTcbInfo) - if err != nil { - // multiTcb info is not provided in leaf - t.Errorf("[ERROR]: Failed to unmarshal MultiTcbInfo field: %v", err) - } - break - } - } - 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 @@ -397,7 +331,10 @@ func validateCertifyKeyCert(t *testing.T, c *x509.Certificate, flags uint32, lab checkCertifyKeyTcgUeidExtension(t, c, label) // Check MultiTcbInfo Extension structure - checkCertifyKeyMultiTcbInfoExtensionStructure(t, c) + _, err := getMultiTcbInfo(c) + if err != nil { + t.Error(err) + } } func checkCertificateStructure(t *testing.T, certBytes []byte) *x509.Certificate { diff --git a/verification/certs.go b/verification/certs.go new file mode 100644 index 00000000..7307c044 --- /dev/null +++ b/verification/certs.go @@ -0,0 +1,69 @@ +// Licensed under the Apache-2.0 license + +package verification + +import ( + "crypto/x509" + "encoding/asn1" + "fmt" +) + +// A tcg-dice-MultiTcbInfo extension. +// This extension SHOULD be marked as critical. +func getMultiTcbInfo(c *x509.Certificate) (TcgMultiTcbInfo, error) { + var multiTcbInfo TcgMultiTcbInfo + + // Check MultiTcbInfo Extension + //tcg-dice-MultiTcbInfo extension + for _, ext := range c.Extensions { + if ext.Id.Equal(OidExtensionTcgDiceMultiTcbInfo) { // OID for Tcg Dice MultiTcbInfo + if !ext.Critical { + return multiTcbInfo, fmt.Errorf("[ERROR]: TCG DICE MultiTcbInfo extension is not marked as CRITICAL") + } + _, err := asn1.Unmarshal(ext.Value, &multiTcbInfo) + if err != nil { + // multiTcb info is not provided in leaf + return multiTcbInfo, fmt.Errorf("[ERROR]: Failed to unmarshal MultiTcbInfo field: %v", err) + } + break + } + } + return multiTcbInfo, nil +} + +func getTcbInfoForHandle(c DPEClient, handle *ContextHandle) (DiceTcbInfo, error) { + // Get digest size + profile, err := c.GetProfile() + if err != nil { + return DiceTcbInfo{}, err + } + + digestLen := profile.Profile.GetDigestSize() + label := make([]byte, digestLen) + + certifiedKey, err := c.CertifyKey(handle, label, CertifyKeyX509, 0) + if err != nil { + return DiceTcbInfo{}, err + } + + leafCertBytes := certifiedKey.Certificate + + var leafCert *x509.Certificate + + // Check whether certificate is DER encoded. + if leafCert, err = x509.ParseCertificate(leafCertBytes); err != nil { + return DiceTcbInfo{}, err + } + + // Get DICE information from MultiTcbInfo Extension + multiTcbInfo, err := getMultiTcbInfo(leafCert) + if err != nil { + return DiceTcbInfo{}, err + } + + if len(multiTcbInfo) == 0 { + return DiceTcbInfo{}, fmt.Errorf("Certificate MutliTcbInfo is empty") + } + + return multiTcbInfo[0], nil +} diff --git a/verification/extendTCI.go b/verification/extendTCI.go index 3d2bcdbd..3397ca3b 100644 --- a/verification/extendTCI.go +++ b/verification/extendTCI.go @@ -3,9 +3,9 @@ package verification import ( + "bytes" "crypto/sha256" "crypto/sha512" - "crypto/x509" "hash" "testing" @@ -26,54 +26,52 @@ func TestExtendTCI(d TestDPEInstance, c DPEClient, t *testing.T) { } 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) } + tcbInfo, err := getTcbInfoForHandle(c, handle) + if err != nil { + t.Fatal(err) + } + lastCumulative := tcbInfo.Fwids[1].Digest + // Set current TCI value _, err = c.ExtendTCI(handle, tciValue) if err != nil { t.Fatalf("[FATAL]: Could not extend TCI: %v", err) } + // Compute expected cumulative + var hasher hash.Hash + if digestLen == 32 { + hasher = sha256.New() + } else if digestLen == 48 { + hasher = sha512.New384() + } + hasher.Write(lastCumulative) + hasher.Write(tciValue) + expectedCumulative := hasher.Sum(nil) + // Cross-check current and cumulative measurement by CertifyKey - verifyMeasurementsByCertifyKey(c, t, handle, defaultTci, tciValue, hasher) + verifyMeasurements(c, t, handle, tciValue, expectedCumulative) } -func verifyMeasurementsByCertifyKey(c DPEClient, t *testing.T, handle *ContextHandle, label []byte, tciValue []byte, hasher hash.Hash) { - certifiedKey, err := c.CertifyKey(handle, label, CertifyKeyX509, 0) +func verifyMeasurements(c DPEClient, t *testing.T, handle *ContextHandle, expectedCurrent []byte, expectedCumulative []byte) { + tcbInfo, err := getTcbInfoForHandle(c, handle) if err != nil { - t.Fatalf("[FATAL]: Could not get Certified key: %v", err) + t.Fatal(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) + // Check that the last TcbInfo current/cumulative are as expected + current := tcbInfo.Fwids[0].Digest + cumulative := tcbInfo.Fwids[1].Digest + if !bytes.Equal(current, expectedCurrent) { + t.Errorf("[ERROR]: Unexpected TCI_CURRENT digest, want %v but got %v", expectedCurrent, current) } - // 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) + if !bytes.Equal(cumulative, expectedCumulative) { + t.Errorf("[ERROR]: Unexpected cumulative TCI value, want %v but got %v", expectedCumulative, cumulative) } } diff --git a/verification/negativeCases.go b/verification/negativeCases.go index ac39092c..24042403 100644 --- a/verification/negativeCases.go +++ b/verification/negativeCases.go @@ -69,9 +69,14 @@ func TestInvalidHandle(d TestDPEInstance, c DPEClient, t *testing.T) { // Exceptions are - GetProfile, InitializeContext, GetCertificateChain, commands // which do not need context handle as input and hence locality is irrelevant. func TestWrongLocality(d TestDPEInstance, c DPEClient, t *testing.T) { + if !d.HasLocalityControl() { + t.Skipf("Target does not have locality control") + } + // 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) + currentLocality := d.GetLocality() + d.SetLocality(currentLocality + 1) + defer d.SetLocality(currentLocality) // Get default context handle handle := &DefaultContextHandle diff --git a/verification/simulator.go b/verification/simulator.go index dd7b4adf..f86d6747 100644 --- a/verification/simulator.go +++ b/verification/simulator.go @@ -171,6 +171,10 @@ func (s *DpeSimulator) GetSupportedLocalities() []uint32 { return []uint32{DPE_SIMULATOR_AUTO_INIT_LOCALITY, DPE_SIMULATOR_OTHER_LOCALITY} } +func (s *DpeSimulator) HasLocalityControl() bool { + return true +} + func (s *DpeSimulator) SetLocality(locality uint32) { s.currentLocality = locality } diff --git a/verification/transport.go b/verification/transport.go index 5d89371d..6feded7d 100644 --- a/verification/transport.go +++ b/verification/transport.go @@ -41,6 +41,8 @@ type TestDPEInstance interface { SetIsInitialized(bool) // Returns a slice of all the localities the instance supports. GetSupportedLocalities() []uint32 + // Whether the target can artificially control the locality of the caller + HasLocalityControl() bool // Sets the current locality. SetLocality(locality uint32) // Gets the current locality. From aa151de3aa64ea980c0f2cfe94c2d9cc5f4afe35 Mon Sep 17 00:00:00 2001 From: Sree Revoori Date: Tue, 21 Nov 2023 04:47:41 +0000 Subject: [PATCH 07/12] Make roll_onetime_use_handle public for use in Caliptra --- dpe/src/dpe_instance.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dpe/src/dpe_instance.rs b/dpe/src/dpe_instance.rs index 6b65aae1..f58abd56 100644 --- a/dpe/src/dpe_instance.rs +++ b/dpe/src/dpe_instance.rs @@ -221,7 +221,7 @@ impl DpeInstance { /// # Arguments /// /// * `idx` - the index of the context - pub(crate) fn roll_onetime_use_handle( + pub fn roll_onetime_use_handle( &mut self, env: &mut DpeEnv, idx: usize, From cdad64f7133048f8717eafb97cfcf37f0ab03112 Mon Sep 17 00:00:00 2001 From: Sree Revoori Date: Tue, 21 Nov 2023 18:19:30 +0000 Subject: [PATCH 08/12] Make DestroyContextCmd public for use in Caliptra --- dpe/src/commands/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dpe/src/commands/mod.rs b/dpe/src/commands/mod.rs index 637d79b7..b7732067 100644 --- a/dpe/src/commands/mod.rs +++ b/dpe/src/commands/mod.rs @@ -5,7 +5,7 @@ Abstract: DPE Commands and deserialization. --*/ pub use self::derive_child::{DeriveChildCmd, DeriveChildFlags}; -pub(crate) use self::destroy_context::DestroyCtxCmd; +pub use self::destroy_context::DestroyCtxCmd; pub use self::get_certificate_chain::GetCertificateChainCmd; pub use self::initialize_context::InitCtxCmd; From e364da726eedb0e7e59fa86640af027708250c94 Mon Sep 17 00:00:00 2001 From: Jordan Hand Date: Mon, 20 Nov 2023 17:18:59 -0800 Subject: [PATCH 09/12] Restore ExtendTCI Test Restore the ExtendTCI test removed in #251. Since TagTCI was removed, this tests needed to be refactored a bit. --- verification/certs.go | 19 +++--- verification/extendTCI.go | 108 +++++++++++++++++++++++++++++++++-- verification/verification.go | 4 ++ 3 files changed, 117 insertions(+), 14 deletions(-) diff --git a/verification/certs.go b/verification/certs.go index 7307c044..1dc83a8b 100644 --- a/verification/certs.go +++ b/verification/certs.go @@ -31,39 +31,42 @@ func getMultiTcbInfo(c *x509.Certificate) (TcgMultiTcbInfo, error) { return multiTcbInfo, nil } -func getTcbInfoForHandle(c DPEClient, handle *ContextHandle) (DiceTcbInfo, error) { +func getTcbInfoForHandle(c DPEClient, handle *ContextHandle) (*ContextHandle, DiceTcbInfo, error) { + outHandle := handle + // Get digest size profile, err := c.GetProfile() if err != nil { - return DiceTcbInfo{}, err + return outHandle, DiceTcbInfo{}, fmt.Errorf("Cannot get profile: %s", err) } digestLen := profile.Profile.GetDigestSize() label := make([]byte, digestLen) - certifiedKey, err := c.CertifyKey(handle, label, CertifyKeyX509, 0) + certifiedKey, err := c.CertifyKey(outHandle, label, CertifyKeyX509, 0) if err != nil { - return DiceTcbInfo{}, err + return outHandle, DiceTcbInfo{}, fmt.Errorf("Could not certify key: %s", err) } + outHandle = &certifiedKey.Handle leafCertBytes := certifiedKey.Certificate var leafCert *x509.Certificate // Check whether certificate is DER encoded. if leafCert, err = x509.ParseCertificate(leafCertBytes); err != nil { - return DiceTcbInfo{}, err + return outHandle, DiceTcbInfo{}, err } // Get DICE information from MultiTcbInfo Extension multiTcbInfo, err := getMultiTcbInfo(leafCert) if err != nil { - return DiceTcbInfo{}, err + return outHandle, DiceTcbInfo{}, err } if len(multiTcbInfo) == 0 { - return DiceTcbInfo{}, fmt.Errorf("Certificate MutliTcbInfo is empty") + return outHandle, DiceTcbInfo{}, fmt.Errorf("Certificate MutliTcbInfo is empty") } - return multiTcbInfo[0], nil + return outHandle, multiTcbInfo[0], nil } diff --git a/verification/extendTCI.go b/verification/extendTCI.go index 3397ca3b..e46d1cdb 100644 --- a/verification/extendTCI.go +++ b/verification/extendTCI.go @@ -31,7 +31,7 @@ func TestExtendTCI(d TestDPEInstance, c DPEClient, t *testing.T) { tciValue[i] = byte(i) } - tcbInfo, err := getTcbInfoForHandle(c, handle) + handle, tcbInfo, err := getTcbInfoForHandle(c, handle) if err != nil { t.Fatal(err) } @@ -43,8 +43,14 @@ func TestExtendTCI(d TestDPEInstance, c DPEClient, t *testing.T) { t.Fatalf("[FATAL]: Could not extend TCI: %v", err) } - // Compute expected cumulative + // Check current and cumulative measurement by CertifyKey + expectedCumulative := computeExpectedCumulative(lastCumulative, tciValue) + verifyMeasurements(c, t, handle, tciValue, expectedCumulative) +} + +func computeExpectedCumulative(lastCumulative []byte, tciValue []byte) []byte { var hasher hash.Hash + digestLen := len(lastCumulative) if digestLen == 32 { hasher = sha256.New() } else if digestLen == 48 { @@ -52,14 +58,104 @@ func TestExtendTCI(d TestDPEInstance, c DPEClient, t *testing.T) { } hasher.Write(lastCumulative) hasher.Write(tciValue) - expectedCumulative := hasher.Sum(nil) + return hasher.Sum(nil) +} - // Cross-check current and cumulative measurement by CertifyKey - verifyMeasurements(c, t, handle, tciValue, expectedCumulative) +// Check whether the ExtendTCI command with derived child context. +func TestExtendTciOnDerivedContexts(d TestDPEInstance, c DPEClient, t *testing.T) { + useSimulation := false // To indicate that simulation context is not used + + // Get default context handle + handle := getInitialContextHandle(d, c, t, useSimulation) + + // Get digest size + profile, err := GetTransportProfile(d) + if err != nil { + t.Fatalf("[FATAL]: Could not get profile: %v", err) + } + digestLen := profile.GetDigestSize() + + // Initialize TCI inputs + tciValue := make([]byte, digestLen) + for i := range tciValue { + tciValue[i] = byte(i + 1) + } + + extendTciValue := make([]byte, digestLen) + for i := range extendTciValue { + extendTciValue[i] = byte(i + 2) + } + + // Preserve parent context to restore for subsequent tests. + parentHandle, err := c.RotateContextHandle(handle, RotateContextHandleFlags(0)) + if err != nil { + t.Errorf("[ERROR]: Error while rotating parent context handle, this may cause failure in subsequent tests: %s", err) + } + + // Change parent back to default context + defer func() { + _, err = c.RotateContextHandle(parentHandle, RotateContextHandleFlags(TargetIsDefault)) + if err != nil { + t.Errorf("[ERROR]: Error while restoring parent context handle as default context handle, this may cause failure in subsequent tests: %s", err) + } + }() + + // Derive Child context with input data, tag it and check TCI_CUMULATIVE + childCtx, err := c.DeriveChild(parentHandle, tciValue, DeriveChildFlags(RetainParent|InputAllowX509), 0, 0) + if err != nil { + t.Fatalf("[FATAL]: Error while creating default child handle in default context: %s", err) + } + + childHandle := &childCtx.NewContextHandle + parentHandle = &childCtx.ParentContextHandle + + // Clean up contexts + defer func() { + err := c.DestroyContext(childHandle, DestroyDescendants) + if err != nil { + t.Errorf("[ERROR]: Error while cleaning up derived context, this may cause failure in subsequent tests: %s", err) + } + }() + + childHandle, childTcbInfo, err := getTcbInfoForHandle(c, childHandle) + if err != nil { + t.Fatalf("[FATAL]: Could not get TcbInfo: %v", err) + } + + if !bytes.Equal(childTcbInfo.Fwids[0].Digest, tciValue) { + t.Errorf("[ERROR]: Got current TCI %x, expected %x", childTcbInfo.Fwids[0].Digest, tciValue) + } + + // Check TCI_CUMULATIVE after creating child context + wantCumulativeTCI := computeExpectedCumulative(make([]byte, digestLen), childTcbInfo.Fwids[0].Digest) + if !bytes.Equal(childTcbInfo.Fwids[1].Digest, wantCumulativeTCI) { + t.Errorf("[ERROR]: Child node's cumulative TCI %x, expected %x", childTcbInfo.Fwids[1].Digest, wantCumulativeTCI) + } + + // Set current TCI value + lastCumulative := childTcbInfo.Fwids[1].Digest + childHandle, err = c.ExtendTCI(childHandle, extendTciValue) + if err != nil { + t.Fatalf("[FATAL]: Could not extend TCI: %v", err) + } + + childHandle, childTcbInfo, err = getTcbInfoForHandle(c, childHandle) + if err != nil { + t.Fatalf("[FATAL]: Could not get TcbInfo: %v", err) + } + + if !bytes.Equal(childTcbInfo.Fwids[0].Digest, extendTciValue) { + t.Errorf("[ERROR]: Got current TCI %x, expected %x", childTcbInfo.Fwids[0].Digest, extendTciValue) + } + + wantCumulativeTCI = computeExpectedCumulative(lastCumulative, extendTciValue) + if !bytes.Equal(childTcbInfo.Fwids[1].Digest, wantCumulativeTCI) { + t.Errorf("[ERROR]: Child node's cumulative TCI %x, expected %x", childTcbInfo.Fwids[1].Digest, wantCumulativeTCI) + } } func verifyMeasurements(c DPEClient, t *testing.T, handle *ContextHandle, expectedCurrent []byte, expectedCumulative []byte) { - tcbInfo, err := getTcbInfoForHandle(c, handle) + handle, tcbInfo, err := getTcbInfoForHandle(c, handle) if err != nil { t.Fatal(err) } diff --git a/verification/verification.go b/verification/verification.go index a955dc61..7b83fb46 100644 --- a/verification/verification.go +++ b/verification/verification.go @@ -38,6 +38,9 @@ var GetCertificateChainTestCase = TestCase{ var ExtendTCITestCase = TestCase{ "ExtendTCITestCase", TestExtendTCI, []string{"AutoInit", "ExtendTci"}, } +var ExtendDerivedTciTestCase = TestCase{ + "ExtendDerivedTciTestCase", TestExtendTciOnDerivedContexts, []string{"AutoInit", "ExtendTci"}, +} var GetProfileTestCase = TestCase{ "GetProfile", TestGetProfile, []string{}, } @@ -59,6 +62,7 @@ var AllTestCases = []TestCase{ CertifyKeySimulationTestCase, GetCertificateChainTestCase, ExtendTCITestCase, + ExtendDerivedTciTestCase, GetProfileTestCase, InitializeContextTestCase, InitializeContextSimulationTestCase, From 1b68c8ac86e7f518ed9874a3a9930795ac6a9015 Mon Sep 17 00:00:00 2001 From: Sree Revoori Date: Tue, 21 Nov 2023 22:00:29 +0000 Subject: [PATCH 10/12] Derive AsBytes unconditionally for DestroyContextCmd --- dpe/src/commands/destroy_context.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dpe/src/commands/destroy_context.rs b/dpe/src/commands/destroy_context.rs index a40222f5..4e67b7d9 100644 --- a/dpe/src/commands/destroy_context.rs +++ b/dpe/src/commands/destroy_context.rs @@ -7,8 +7,7 @@ use crate::{ }; #[repr(C)] -#[derive(Debug, PartialEq, Eq, zerocopy::FromBytes)] -#[cfg_attr(test, derive(zerocopy::AsBytes))] +#[derive(Debug, PartialEq, Eq, zerocopy::FromBytes, zerocopy::AsBytes)] pub struct DestroyCtxCmd { pub handle: ContextHandle, } From d0c06e87229bbee62d2181d232fce8bf9b7cb82d Mon Sep 17 00:00:00 2001 From: hpya93 <94533459+hpya93@users.noreply.github.com> Date: Wed, 22 Nov 2023 03:38:10 +0530 Subject: [PATCH 11/12] Sign support (#251) Add verification tests for the Sign command --- verification/certifyKey.go | 130 +++++++++++++++++++++------ verification/sign.go | 170 +++++++++++++++++++++++++++++++++++ verification/simulator.go | 2 +- verification/verification.go | 14 ++- 4 files changed, 289 insertions(+), 27 deletions(-) create mode 100644 verification/sign.go diff --git a/verification/certifyKey.go b/verification/certifyKey.go index 126478a3..15e07b3c 100755 --- a/verification/certifyKey.go +++ b/verification/certifyKey.go @@ -4,11 +4,14 @@ package verification import ( "bytes" + "crypto/ecdsa" + "crypto/elliptic" "crypto/x509" "encoding/asn1" "encoding/binary" "encoding/pem" "fmt" + "math/big" "reflect" "testing" "time" @@ -117,18 +120,23 @@ const ( type TcgMultiTcbInfo = []DiceTcbInfo +type CertifyKeyParams struct { + Label []byte + Flags CertifyKeyFlags +} + func TestCertifyKey(d TestDPEInstance, c DPEClient, t *testing.T) { testCertifyKey(d, c, t, false) } -func TestCertifyKey_SimulationMode(d TestDPEInstance, c DPEClient, t *testing.T) { +func TestCertifyKeySimulation(d TestDPEInstance, c DPEClient, t *testing.T) { testCertifyKey(d, c, t, true) } // Ignores critical extensions that are unknown to x509 package // but atleast defined in DPE certificate profile specification. // UnhandledCriticalExtensions may have only custom extensions mentioned in spec -// unknownExtnMap collects extensions unknown to both x59 and the DICE certificate profiles spec. +// unknownExtnMap collects extensions unknown to both x509 and the DICE certificate profiles spec. // positive case expects the unknownExtnMap to be empty. func removeTcgDiceCriticalExtensions(t *testing.T, certs []*x509.Certificate) { t.Helper() @@ -158,6 +166,11 @@ func removeTcgDiceCriticalExtensions(t *testing.T, certs []*x509.Certificate) { } } +// Ignores extended key usages that are unknown to x509 package +// but atleast defined in DPE certificate profile specification. +// UnhandledExtendedKeyUsages may have only custom key usages mentioned in spec +// unknownKeyUsagesMap collects keyusages unknown to both x509 and the DICE certificate profiles spec. +// positive case expects the unknownKeyUsagesMap to be empty. func removeTcgDiceExtendedKeyUsages(t *testing.T, certs []*x509.Certificate) { t.Helper() unknownKeyUsagesMap := map[string][]string{} @@ -218,7 +231,7 @@ func checkCertifyKeyTcgUeidExtension(t *testing.T, c *x509.Certificate, label [] } } -// Check whether certificate extended key usage is as per spec +// Checks 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 // If IsCA = true, the extension SHOULD contain tcg-dice-kp-eca @@ -274,7 +287,7 @@ func checkCertifyKeyExtendedKeyUsages(t *testing.T, c *x509.Certificate) (*TcgMu return multiTcbInfo, err } -// Check for KeyUsage Extension as per spec +// Checks for KeyUsage Extension as per spec // If IsCA = true, KeyUsage extension MUST contain DigitalSignature and KeyCertSign // If IsCA = false, KeyUsage extension MUST contain only DigitalSignature func checkCertifyKeyExtensions(t *testing.T, c *x509.Certificate) { @@ -296,25 +309,25 @@ func checkCertifyKeyExtensions(t *testing.T, c *x509.Certificate) { } -// Validate basic constraints in certificate returned by CertifyKey command +// Validates basic constraints in certificate returned by CertifyKey command // against the flag set for input parameter. // The BasicConstraints extension MUST be included // If CertifyKey AddIsCA is set, IsCA MUST be set to true. // If CertifyKey AddIsCA is NOT set, IsCA MUST be set to false -func checkCertifyKeyBasicConstraints(t *testing.T, c *x509.Certificate, flags uint32) { +func checkCertifyKeyBasicConstraints(t *testing.T, c *x509.Certificate, flags CertifyKeyFlags) { t.Helper() flagsBuf := &bytes.Buffer{} binary.Write(flagsBuf, binary.LittleEndian, flags) - flagIsCA := uint32(CertifyAddIsCA)&flags != 0 + flagIsCA := CertifyAddIsCA&flags != 0 if flagIsCA != c.IsCA { t.Errorf("[ERROR]: ADD_IS_CA is set to %v but the basic constraint IsCA is set to %v", flagIsCA, c.IsCA) } } -// Validate X509 fields in certificate returned by CertifyKey command. -func validateCertifyKeyCert(t *testing.T, c *x509.Certificate, flags uint32, label []byte) { +// Validates X509 fields in certificate returned by CertifyKey command. +func validateCertifyKeyCert(t *testing.T, c *x509.Certificate, flags CertifyKeyFlags, label []byte) { t.Helper() // Check for basic constraints extension @@ -337,6 +350,7 @@ func validateCertifyKeyCert(t *testing.T, c *x509.Certificate, flags uint32, lab } } +// Parses X509 certificate func checkCertificateStructure(t *testing.T, certBytes []byte) *x509.Certificate { t.Helper() failed := false @@ -411,44 +425,48 @@ func checkCertificateStructure(t *testing.T, certBytes []byte) *x509.Certificate return x509Cert } -func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, simulation bool) { - ctx := getInitialContextHandle(d, client, t, simulation) +func testCertifyKey(d TestDPEInstance, c DPEClient, t *testing.T, simulation bool) { + handle := getInitialContextHandle(d, c, t, simulation) defer func() { if simulation { - client.DestroyContext(ctx, DestroyDescendants) + c.DestroyContext(handle, DestroyDescendants) } }() - type Params struct { - Label []byte - Flags CertifyKeyFlags - } - profile, err := GetTransportProfile(d) if err != nil { t.Fatalf("Could not get profile: %v", err) } digestLen := profile.GetDigestSize() + var hashAlg asn1.ObjectIdentifier + if digestLen == 32 { + hashAlg = OidSHA256 + } else if digestLen == 48 { + hashAlg = OidSHA384 + } else { + t.Fatal("Unknown Hash Algorithm") + } + seqLabel := make([]byte, digestLen) for i := range seqLabel { seqLabel[i] = byte(i) } - certifyKeyParams := []Params{ + certifyKeyParams := []CertifyKeyParams{ {Label: make([]byte, digestLen), Flags: CertifyKeyFlags(0)}, {Label: seqLabel, Flags: CertifyKeyFlags(0)}, } for _, params := range certifyKeyParams { // Get DPE leaf certificate from CertifyKey - certifyKeyResp, err := client.CertifyKey(ctx, params.Label, CertifyKeyX509, params.Flags) + certifyKeyResp, err := c.CertifyKey(handle, params.Label, CertifyKeyX509, params.Flags) if err != nil { t.Fatalf("[FATAL]: Could not certify key: %v", err) } // Get root and intermediate certificates to validate certificate chain of leaf cert - certChainBytes, err := client.GetCertificateChain() + certChainBytes, err := c.GetCertificateChain() if err != nil { t.Fatalf("[FATAL]: Could not get Certificate Chain: %v", err) } @@ -459,8 +477,14 @@ func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, simulatio leafCert := checkCertificateStructure(t, leafCertBytes) certChain := checkCertificateChain(t, certChainBytes) + // Check default context handle is unchanged + checkCertifyKeyRespHandle(*certifyKeyResp, t, handle) + + // Check key returned in command response against certificate + checkCertifyKeyResponse(t, leafCert, *certifyKeyResp, hashAlg) + // Validate that all X.509 fields conform with the format defined in the DPE iRoT profile - validateCertifyKeyCert(t, leafCert, uint32(params.Flags), params.Label) + validateCertifyKeyCert(t, leafCert, params.Flags, params.Label) // Ensure full certificate chain has valid signatures // This also checks certificate lifetime, signatures as part of cert chain validation @@ -469,13 +493,12 @@ func testCertifyKey(d TestDPEInstance, client DPEClient, t *testing.T, simulatio // 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. + handle = &certifyKeyResp.Handle } + // TODO: When DeriveChild is implemented, call it here to add more TCIs and call CertifyKey again. } -// Build certificate chain and calls to validateSignature on each chain. +// Builds and verifies certificate chain. func validateLeafCertChain(t *testing.T, certChain []*x509.Certificate, leafCert *x509.Certificate) { t.Helper() certsToProcess := []*x509.Certificate{leafCert} @@ -502,6 +525,7 @@ func validateLeafCertChain(t *testing.T, certChain []*x509.Certificate, leafCert } } +// Builds Certificate chain verifier parameters. func buildVerifyOptions(t *testing.T, certChain []*x509.Certificate) x509.VerifyOptions { roots := x509.NewCertPool() intermediates := x509.NewCertPool() @@ -526,6 +550,7 @@ func buildVerifyOptions(t *testing.T, certChain []*x509.Certificate) x509.Verify return opts } +// Gets KeyUsage bitmap and returns as list of KeyUsage name strings. func getKeyUsageNames(keyUsage x509.KeyUsage) []string { keyUsageNames := []string{} @@ -567,3 +592,58 @@ func getKeyUsageNames(keyUsage x509.KeyUsage) []string { return keyUsageNames } + +// Checks CertifyKey command response against public key extracted from certificate returned in response +func checkCertifyKeyResponse(t *testing.T, x509Cert *x509.Certificate, response CertifiedKey, hashAlg asn1.ObjectIdentifier) { + var err error + + publicKeyDer, err := x509.MarshalPKIXPublicKey(x509Cert.PublicKey) + if err != nil { + t.Fatalf("[FATAL]: Could not marshal pub key: %v", err) + } + + // Parse the DER-encoded public key + pubKeyInCert, err := x509.ParsePKIXPublicKey(publicKeyDer) + if err != nil { + t.Fatalf("[FATAL]: Failed to parse DER-encoded public key: %v", err) + } + + if _, ok := pubKeyInCert.(*ecdsa.PublicKey); !ok { + t.Fatal("[FATAL]: Public key is not a ecdsa key") + } + + var pubKeyInResponse ecdsa.PublicKey + + if hashAlg.Equal(OidSHA384) { + pubKeyInResponse = ecdsa.PublicKey{ + Curve: elliptic.P384(), + X: new(big.Int).SetBytes(response.Pub.X), + Y: new(big.Int).SetBytes(response.Pub.Y), + } + } else if hashAlg.Equal(OidSHA256) { + pubKeyInResponse = ecdsa.PublicKey{ + Curve: elliptic.P256(), + X: new(big.Int).SetBytes(response.Pub.X), + Y: new(big.Int).SetBytes(response.Pub.Y), + } + } else { + t.Errorf("[ERROR]: Unsupported hash algorithm.") + return + } + + if !(pubKeyInResponse.Equal(pubKeyInCert)) { + t.Errorf("[ERROR]: Public key returned in response must match the Public Key Info in the certificate.") + } +} + +// Checks whether the context handle is unchanged after certifyKey command when default context handle is used. +func checkCertifyKeyRespHandle(res CertifiedKey, t *testing.T, handle *ContextHandle) { + if *handle != DefaultContextHandle { + t.Logf("[LOG]: Handle is not default context, skipping check...") + return + } + + if res.Handle != *handle { + t.Errorf("[ERROR]: Handle must be unchanged by CertifyKey, want original handle %v but got %v", handle, res.Handle) + } +} diff --git a/verification/sign.go b/verification/sign.go new file mode 100644 index 00000000..eb127ee4 --- /dev/null +++ b/verification/sign.go @@ -0,0 +1,170 @@ +// Licensed under the Apache-2.0 license + +package verification + +import ( + "bytes" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/x509" + "errors" + "math/big" + "testing" +) + +// Obtain and validate signature of asymmetric signing. +// Check whether the digital signature returned by Sign command can be verified +// using public key in signing key certificate returned by CertifyKey command. +// Inspite of the DPE profile supporting symmetric key, for symmetric signing it must be enabled +// explicitly in Sign command flags. Else asymmetric signing is used as default. +func TestAsymmetricSigning(d TestDPEInstance, c DPEClient, t *testing.T) { + useSimulation := false + 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() + + // Validate asymmetric signature generated + flags := SignFlags(0) + + seqLabel := make([]byte, digestLen) + for i := range seqLabel { + seqLabel[i] = byte(i) + } + + tbs := make([]byte, digestLen) + for i := range tbs { + tbs[i] = byte(i) + } + + signResp, err := c.Sign(handle, seqLabel, flags, tbs) + if err != nil { + t.Fatalf("[FATAL]: Error while signing %v", err) + } + + // Get signing key certificate using CertifyKey command + certifiedKey, err := c.CertifyKey(handle, seqLabel, CertifyKeyX509, CertifyKeyFlags(0)) + if err != nil { + t.Fatalf("[FATAL]: Could not CertifyKey: %v", err) + } + + // Check certificate structure + if _, err := x509.ParseCertificate(certifiedKey.Certificate); err != nil { + t.Fatalf("[FATAL]: Could not parse certificate using crypto/x509: %v", err) + } + + // Read public key + var ec elliptic.Curve + x := new(big.Int).SetBytes(certifiedKey.Pub.X) + y := new(big.Int).SetBytes(certifiedKey.Pub.Y) + + if digestLen == 32 { + ec = elliptic.P256() + } else if digestLen == 48 { + ec = elliptic.P384() + } + + publicKey := ecdsa.PublicKey{Curve: ec, X: x, Y: y} + + // Build Signature from bytes + r := new(big.Int).SetBytes(signResp.HmacOrSignatureR) + s := new(big.Int).SetBytes(signResp.SignatureS) + + // Verify Signature + valid := ecdsa.Verify(&publicKey, tbs, r, s) + if !valid { + t.Error("Signature Verification failed") + } +} + +// Check command fails in simulated context because this context does not allow signing. +// This is because simulation context does not allow using context's private key. +func TestSignSimulation(d TestDPEInstance, c DPEClient, t *testing.T) { + useSimulation := true + handle := getInitialContextHandle(d, c, t, useSimulation) + defer func() { + c.DestroyContext(handle, DestroyDescendants) + }() + + // Get digest size + profile, err := GetTransportProfile(d) + if err != nil { + t.Fatalf("Could not get profile: %v", err) + } + + digestLen := profile.GetDigestSize() + + if _, err := c.Sign(handle, make([]byte, digestLen), SignFlags(IsSymmetric), make([]byte, digestLen)); err == nil { + t.Fatalf("[FATAL]: Should return %q, but returned no error", StatusInvalidArgument) + } else if !errors.Is(err, StatusInvalidArgument) { + t.Fatalf("[FATAL]: Incorrect error type. Should return %q, but returned %q", StatusInvalidArgument, err) + } + + if _, err := c.Sign(handle, make([]byte, digestLen), SignFlags(0), make([]byte, digestLen)); err == nil { + t.Fatalf("[FATAL]: Should return %q, but returned no error", StatusInvalidArgument) + } else if !errors.Is(err, StatusInvalidArgument) { + t.Fatalf("[FATAL]: Incorrect error type. Should return %q, but returned %q", StatusInvalidArgument, err) + } +} + +// Obtain HMAC (symmetric signature) generated and compare for varying label inputs. +// Signature created is deterministic and depends on label passed to command. +// This is because label is used by DPE in symmetric key derivation. +// Invoking Sign command multiple times with same label and same content (TBS) should return same signature +// but it should return different signatures for different labels despite having the same content (To Be Signed content). +func TestSymmetricSigning(d TestDPEInstance, c DPEClient, t *testing.T) { + useSimulation := false + 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() + label := make([]byte, digestLen) + for i := range label { + label[i] = byte(i) + } + + tbs := make([]byte, digestLen) + for i := range tbs { + tbs[i] = byte(i) + } + + signedData, err := c.Sign(handle, label, SignFlags(IsSymmetric), tbs) + if err != nil { + t.Fatalf("[FATAL]: Error while signing %v", err) + } + + // Rerun with same label and compare signature emitted. + signedDataWithSameLabel, err := c.Sign(handle, label, SignFlags(IsSymmetric), tbs) + if err != nil { + t.Fatalf("[FATAL]: Error while signing %v", err) + } + + // Symmetric sign only populates HmacOrSignatureR. SignatureS is all zeroes. + if !bytes.Equal(signedDataWithSameLabel.HmacOrSignatureR, signedData.HmacOrSignatureR) { + t.Errorf("[ERROR]: Signature varies for same label, want %v but got %v", signedData.HmacOrSignatureR, signedDataWithSameLabel.HmacOrSignatureR) + } + + // Rerun with different label, signature must change this time + newLabel := make([]byte, digestLen) + for i := range newLabel { + newLabel[i] = byte(0) + } + + signedDataWithDiffLabel, err := c.Sign(handle, newLabel, SignFlags(IsSymmetric), tbs) + if err != nil { + t.Fatalf("[FATAL]: Error while signing %v", err) + } + + if bytes.Equal(signedDataWithDiffLabel.HmacOrSignatureR, signedData.HmacOrSignatureR) { + t.Errorf("[ERROR]: Signature must vary for different label despite having same toBeSigned content, want new signature but got old %v", signedData.HmacOrSignatureR) + } +} diff --git a/verification/simulator.go b/verification/simulator.go index f86d6747..becb62ce 100644 --- a/verification/simulator.go +++ b/verification/simulator.go @@ -231,7 +231,7 @@ func GetSimulatorTargets() []TestTarget { }, { "DefaultSupport", - getTestTarget([]string{"AutoInit", "Simulation", "X509", "IsCA", "RotateContext", "ExtendTci"}), + getTestTarget([]string{"AutoInit", "Simulation", "X509", "IsCA", "RotateContext", "ExtendTci", "IsSymmetric"}), AllTestCases, }, { diff --git a/verification/verification.go b/verification/verification.go index 7b83fb46..5be5da0f 100644 --- a/verification/verification.go +++ b/verification/verification.go @@ -30,7 +30,7 @@ var CertifyKeyTestCase = TestCase{ "CertifyKey", TestCertifyKey, []string{"AutoInit", "X509", "IsCA"}, } var CertifyKeySimulationTestCase = TestCase{ - "CertifyKeySimulation", TestCertifyKey_SimulationMode, []string{"AutoInit", "Simulation", "X509", "IsCA"}, + "CertifyKeySimulation", TestCertifyKeySimulation, []string{"AutoInit", "Simulation", "X509", "IsCA"}, } var GetCertificateChainTestCase = TestCase{ "GetCertificateChain", TestGetCertificateChain, []string{"AutoInit", "X509"}, @@ -56,6 +56,15 @@ var UnsupportedCommand = TestCase{ var UnsupportedCommandFlag = TestCase{ "CheckSupportForCommmandFlag", TestUnsupportedCommandFlag, []string{"AutoInit", "RotateContext", "ExtendTci"}, } +var SignAsymmetricTestCase = TestCase{ + "Sign", TestAsymmetricSigning, []string{"AutoInit", "X509"}, +} +var SignSymmetricTestCase = TestCase{ + "SignSymmetric", TestSymmetricSigning, []string{"AutoInit", "IsSymmetric"}, +} +var SignSimulationTestCase = TestCase{ + "SignSimulation", TestSignSimulation, []string{"Simulation"}, +} var AllTestCases = []TestCase{ CertifyKeyTestCase, @@ -63,6 +72,9 @@ var AllTestCases = []TestCase{ GetCertificateChainTestCase, ExtendTCITestCase, ExtendDerivedTciTestCase, + SignAsymmetricTestCase, + SignSymmetricTestCase, + SignSimulationTestCase, GetProfileTestCase, InitializeContextTestCase, InitializeContextSimulationTestCase, From ac339f6e9145c0865a93d27726051756821e765d Mon Sep 17 00:00:00 2001 From: hpya93 <94533459+hpya93@users.noreply.github.com> Date: Tue, 28 Nov 2023 07:14:05 +0530 Subject: [PATCH 12/12] RotateContext handle command tests (#252) Added tests for RotateContextHandle command * Added a test to check and report invalid handle with a test handle (moved to negativeCases.go, taken care in PR 255, as a common negative case test) The following are part of this PR: * RotateHandle in default context * RotateHandle in non-default context * RotateHandle in with TARGET_DEFAULT flag --- verification/rotateContextHandle.go | 67 +++++++++++++++++++++++++++++ verification/verification.go | 8 ++++ 2 files changed, 75 insertions(+) create mode 100644 verification/rotateContextHandle.go diff --git a/verification/rotateContextHandle.go b/verification/rotateContextHandle.go new file mode 100644 index 00000000..951fcf89 --- /dev/null +++ b/verification/rotateContextHandle.go @@ -0,0 +1,67 @@ +// Licensed under the Apache-2.0 license + +package verification + +import ( + "errors" + "testing" +) + +func TestRotateContextHandle(d TestDPEInstance, c DPEClient, t *testing.T) { + simulation := false + handle := getInitialContextHandle(d, c, t, simulation) + + // Check whether the rotated context handle is a random context handle + handle, err := c.RotateContextHandle(handle, RotateContextHandleFlags(0)) + if err != nil { + t.Fatalf("[FATAL]: Could not rotate context handle: %v", err) + } + if *handle == DefaultContextHandle { + t.Errorf("[ERROR]: Expected random context handle but have got default context %v", handle) + } + + // Rotate back the handle to default handle for subsequent tests + // This works only when there is no default handle available + handle, err = c.RotateContextHandle(handle, TargetIsDefault) + if err != nil { + t.Fatalf("[FATAL]: Could not rotate context handle: %v", err) + } + if *handle != DefaultContextHandle { + t.Errorf("[ERROR]: TARGET_IS_DEFAULT is set, have got %v but want %v", handle, DefaultContextHandle) + } + + // Check for error when a default context handle exists already and handle is rotated to default handle + // Since, there cannot be more than one default context handle + _, err = c.RotateContextHandle(handle, TargetIsDefault) + if err == nil { + t.Fatalf("[FATAL]: Should return %q for default context, but returned no error", StatusInvalidArgument) + } else if !errors.Is(err, StatusInvalidArgument) { + t.Fatalf("[FATAL]: Incorrect error type. Should return %q, but returned %q", StatusInvalidArgument, err) + } +} + +func TestRotateContextHandleSimulation(d TestDPEInstance, c DPEClient, t *testing.T) { + simulation := true + handle := getInitialContextHandle(d, c, t, simulation) + defer func() { + c.DestroyContext(handle, DestroyDescendants) + }() + + // Check whether the rotated context handle is a random context handle + handle, err := c.RotateContextHandle(handle, RotateContextHandleFlags(0)) + if err != nil { + t.Fatalf("[FATAL]: Could not rotate context handle: %v", err) + } + if *handle == DefaultContextHandle { + t.Errorf("[ERROR]: Expected random context handle but have got default context %v", handle) + } + + // In simulated context, the handle cannot be rotated to default handle + // Since, it is not allowed to have a both of default and non-default context handles together + _, err = c.RotateContextHandle(handle, TargetIsDefault) + if err == nil { + t.Fatalf("[FATAL]: Should return %q for simulation context, but returned no error", StatusInvalidArgument) + } else if !errors.Is(err, StatusInvalidArgument) { + t.Fatalf("[FATAL]: Incorrect error type. Should return %q, but returned %q", StatusInvalidArgument, err) + } +} diff --git a/verification/verification.go b/verification/verification.go index 5be5da0f..7133d8f1 100644 --- a/verification/verification.go +++ b/verification/verification.go @@ -56,6 +56,12 @@ var UnsupportedCommand = TestCase{ var UnsupportedCommandFlag = TestCase{ "CheckSupportForCommmandFlag", TestUnsupportedCommandFlag, []string{"AutoInit", "RotateContext", "ExtendTci"}, } +var RotateContextTestCase = TestCase{ + "RotateContextHandle", TestRotateContextHandle, []string{"AutoInit", "RotateContext"}, +} +var RotateContextSimulationTestCase = TestCase{ + "RotateContextHandleSimulation", TestRotateContextHandleSimulation, []string{"Simulation", "RotateContext"}, +} var SignAsymmetricTestCase = TestCase{ "Sign", TestAsymmetricSigning, []string{"AutoInit", "X509"}, } @@ -72,6 +78,8 @@ var AllTestCases = []TestCase{ GetCertificateChainTestCase, ExtendTCITestCase, ExtendDerivedTciTestCase, + RotateContextTestCase, + RotateContextSimulationTestCase, SignAsymmetricTestCase, SignSymmetricTestCase, SignSimulationTestCase,