Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Common client code and few bug fixes #255

Merged
merged 2 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions dpe/src/commands/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct SignFlags(u32);

bitflags! {
impl SignFlags: u32 {
const IS_SYMMETRIC = 1u32 << 31;
const IS_SYMMETRIC = 1u32 << 30;
jhand2 marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -83,7 +83,7 @@ impl CommandExecution for SignCmd {
) -> Result<Response, DpeErrorCode> {
// Make sure the operation is supported.
if !dpe.support.is_symmetric() && self.uses_symmetric() {
return Err(DpeErrorCode::InvalidArgument);
return Err(DpeErrorCode::ArgumentNotSupported);
jhand2 marked this conversation as resolved.
Show resolved Hide resolved
}

let idx = dpe.get_active_context_pos(&self.handle, locality)?;
Expand Down Expand Up @@ -190,7 +190,7 @@ mod tests {

// Bad argument
assert_eq!(
Err(DpeErrorCode::InvalidArgument),
Err(DpeErrorCode::ArgumentNotSupported),
jhand2 marked this conversation as resolved.
Show resolved Hide resolved
SignCmd {
handle: ContextHandle([0xff; ContextHandle::SIZE]),
label: TEST_LABEL,
Expand Down
217 changes: 209 additions & 8 deletions verification/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
package verification

import (
"errors"
"fmt"
"reflect"
)

var DefaultContextHandle = ContextHandle{0}

jhand2 marked this conversation as resolved.
Show resolved Hide resolved
const (
CmdMagic uint32 = 0x44504543
RespMagic uint32 = 0x44504552
Expand Down Expand Up @@ -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
)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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)
Expand All @@ -409,17 +530,17 @@ 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,
Label: Digest(label),
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
Expand Down Expand Up @@ -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 {
Expand Down
35 changes: 12 additions & 23 deletions verification/certifyKey.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 := getInitialContextHandle(d, client, t, simulation)
if simulation {
defer client.DestroyContext(ctx, 0)
jhand2 marked this conversation as resolved.
Show resolved Hide resolved
}

type Params struct {
Expand All @@ -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)
}
Expand All @@ -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

jhand2 marked this conversation as resolved.
Show resolved Hide resolved
// TODO: When DeriveChild is implemented, call it here to add more TCIs and call CertifyKey again.
}
}
Expand Down
Loading