Skip to content

Commit

Permalink
Add verification tests for the "export-cdi" DeriveContext feature
Browse files Browse the repository at this point in the history
  • Loading branch information
clundin25 committed Jan 22, 2025
1 parent 27b8300 commit d67fb24
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 12 deletions.
5 changes: 5 additions & 0 deletions simulator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ struct Args {
/// Supports the RETAIN_PARENT_CONTEXT extension to DeriveContext
#[arg(long)]
supports_retain_parent_context: bool,

/// Supports the CDI_EXPORT extension to DeriveContext
#[arg(long)]
supports_cdi_export: bool,
}

struct SimTypes {}
Expand Down Expand Up @@ -156,6 +160,7 @@ fn main() -> std::io::Result<()> {
Support::RETAIN_PARENT_CONTEXT,
args.supports_retain_parent_context,
);
support.set(Support::CDI_EXPORT, args.supports_cdi_export);

let mut env = DpeEnv::<SimTypes> {
crypto: <SimTypes as DpeTypes>::Crypto::new(),
Expand Down
59 changes: 47 additions & 12 deletions verification/client/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type Support struct {
InternalDice bool
IsCA bool
RetainParentContext bool
CdiExport bool
}

// profileCommandCodes holds command codes for a specific revision of the
Expand Down Expand Up @@ -125,6 +126,9 @@ const (
// ContextHandle is a DPE context handle
type ContextHandle [16]byte

// ExportedCdi is a handle to an exported CDI
type ExportedCdi [32]byte

// DestroyCtxCmd is input parameters to DestroyContext
type DestroyCtxCmd struct {
handle ContextHandle
Expand Down Expand Up @@ -223,6 +227,8 @@ const (
InputAllowCA DeriveContextFlags = 1 << 26
InputAllowX509 DeriveContextFlags = 1 << 25
Recursive DeriveContextFlags = 1 << 24
CdiExport DeriveContextFlags = 1 << 23
CreateCertificate DeriveContextFlags = 1 << 22
)

// DeriveContextReq is the input request to DeriveContext
Expand All @@ -238,16 +244,14 @@ type DeriveContextReq[Digest DigestAlgorithm] struct {
type DeriveContextResp struct {
NewContextHandle ContextHandle
ParentContextHandle ContextHandle
ExportedCdi ExportedCdi
CertificateSize uint32
NewCertificate []byte
}

// SignFlags is the input flags to Sign
type SignFlags uint32

// Supported Sign flags
const (
IsSymmetric SignFlags = 1 << 30
)

// SignReq is the input request to Sign
type SignReq[Digest DigestAlgorithm] struct {
ContextHandle ContextHandle
Expand Down Expand Up @@ -517,15 +521,43 @@ func (c *DPEABI[_, _, _]) GetCertificateChainABI() (*GetCertificateChainResp, er
}

// DeriveContextABI calls DPE DeriveContext command.
func (c *DPEABI[_, Digest, _]) DeriveContextABI(cmd *DeriveContextReq[Digest]) (*DeriveContextResp, error) {
var respStruct DeriveContextResp
func (c *DPEABI[_, Digest, DPECertificate]) DeriveContextABI(cmd *DeriveContextReq[Digest]) (*DeriveContextResp, error) {
// Define an anonymous struct for the response, because the shape changes if exportCdi is set.
if cmd.Flags&CdiExport == CdiExport {
respStruct := struct {
NewContextHandle [16]byte
ParentContextHandle [16]byte
ExportedCdi [32]byte
CertificateSize uint32
Certificate DPECertificate
}{}
_, err := execCommand(c.transport, c.constants.Codes.DeriveContext, c.Profile, cmd, &respStruct)
if err != nil {
return nil, err
}

_, err := execCommand(c.transport, c.constants.Codes.DeriveContext, c.Profile, cmd, &respStruct)
if err != nil {
return nil, err
}
return &DeriveContextResp{
NewContextHandle: respStruct.NewContextHandle,
ParentContextHandle: respStruct.ParentContextHandle,
ExportedCdi: respStruct.ExportedCdi,
CertificateSize: respStruct.CertificateSize,
NewCertificate: respStruct.Certificate.Bytes()[:respStruct.CertificateSize],
}, nil
} else {
respStruct := struct {
NewContextHandle [16]byte
ParentContextHandle [16]byte
}{}
_, err := execCommand(c.transport, c.constants.Codes.DeriveContext, c.Profile, cmd, &respStruct)
if err != nil {
return nil, err
}

return &respStruct, err
return &DeriveContextResp{
NewContextHandle: respStruct.NewContextHandle,
ParentContextHandle: respStruct.ParentContextHandle,
}, nil
}
}

// RotateContextHandleABI calls DPE RotateContextHandle command.
Expand Down Expand Up @@ -738,5 +770,8 @@ func (s *Support) ToFlags() uint32 {
if s.RetainParentContext {
flags |= (1 << 19)
}
if s.CdiExport {
flags |= (1 << 18)
}
return flags
}
3 changes: 3 additions & 0 deletions verification/sim/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ func (s *DpeSimulator) PowerOn() error {
if s.supports.RetainParentContext {
args = append(args, "--supports-retain-parent-context")
}
if s.supports.CdiExport {
args = append(args, "--supports-cdi-export")
}

s.cmd = exec.Command(s.exePath, args...)
s.cmd.Stdout = os.Stdout
Expand Down
39 changes: 39 additions & 0 deletions verification/testing/deriveContext.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,45 @@ func TestDeriveContext(d client.TestDPEInstance, c client.DPEClient, t *testing.
handle = &resp.NewContextHandle
}

func TestDeriveContextCdiExport(d client.TestDPEInstance, c client.DPEClient, t *testing.T) {
var resp *client.DeriveContextResp

simulation := false
handle := getInitialContextHandle(d, c, t, simulation)
defer func() {
c.DestroyContext(handle)
}()

profile, err := client.GetTransportProfile(d)
if err != nil {
t.Fatalf("Could not get profile: %v", err)
}
digestLen := profile.GetDigestSize()

resp, err = c.DeriveContext(handle, make([]byte, digestLen), client.CdiExport|client.CreateCertificate, 0, 0)
if err != nil {
t.Fatalf("[ERROR]: Error while exporting CdiExport: %s", err)
}

if resp.ExportedCdi == client.ExportedCdi(bytes.Repeat([]byte{0x0}, 32)) {
t.Fatalf("[FATAL]: Expected ExportedCdi field to be set but was %v", resp.ExportedCdi)
}
if resp.NewContextHandle != client.ContextHandle(bytes.Repeat([]byte{0xFF}, 16)) {
t.Fatalf("[FATAL]: Expected invalid NewContextHandle field but it was set to %v", resp.NewContextHandle)
}
if resp.ParentContextHandle != client.ContextHandle(bytes.Repeat([]byte{0xFF}, 16)) {
t.Fatalf("[FATAL]: Expected invalid ParentContextHandle field but it was set to %v", resp.ParentContextHandle)
}
if resp.CertificateSize == 0 {
t.Fatalf("[FATAL]: Expected CertificateSize to be set but was set to %v", resp.CertificateSize)
}

// Check whether certificate is correctly encoded.
if _, err := x509.ParseCertificate(resp.NewCertificate); err != nil {
t.Fatalf("[FATAL]: Could not parse certificate using crypto/x509: %v", err)
}
}

// Validates DerivedChild command with ChangeLocality flag.
func TestChangeLocality(d client.TestDPEInstance, c client.DPEClient, t *testing.T) {
if !d.HasLocalityControl() {
Expand Down
5 changes: 5 additions & 0 deletions verification/testing/simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ func GetSimulatorTargets() []TestTarget {
getTestTarget([]string{"AutoInit", "X509", "RetainParentContext"}),
[]TestCase{DeriveContextTestCase},
},
{
"TestDeriveContextCdiExport",
getTestTarget([]string{"AutoInit", "CdiExport"}),
[]TestCase{TestDeriveContextCdiExportTestCase},
},
{
"DeriveContext_Simulation",
getTestTarget([]string{"AutoInit", "Simulation", "X509", "RetainParentContext"}),
Expand Down
5 changes: 5 additions & 0 deletions verification/testing/verification.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ var DeriveContextTestCase = TestCase{
"DeriveContext", TestDeriveContext, []string{"AutoInit", "RetainParentContext"},
}

// TestDeriveContextCdiExport tests DeriveContext
var TestDeriveContextCdiExportTestCase = TestCase{
"DeriveContextCdiExport", TestDeriveContextCdiExport, []string{"CdiExport"},
}

// DeriveContextSimulationTestCase tests DeriveContext with Simulation contexts
var DeriveContextSimulationTestCase = TestCase{
"DeriveContextSimulation", TestDeriveContextSimulation, []string{"AutoInit", "Simulation", "X509", "InternalDice", "InternalInfo", "RetainParentContext"},
Expand Down

0 comments on commit d67fb24

Please sign in to comment.