diff --git a/ci.sh b/ci.sh index 288256de..636be056 100755 --- a/ci.sh +++ b/ci.sh @@ -83,7 +83,7 @@ run_verification_tests dpe_profile_p384_sha384 rustcrypto # Build fuzz target ( cd dpe/fuzz rustup toolchain install nightly-2023-11-16 - cargo +nightly-2023-11-16 install cargo-fuzz cargo-afl + cargo +nightly-2023-11-16 install cargo-fuzz cargo-afl --locked cargo fmt --check cargo clippy --features libfuzzer-sys cargo clippy --features afl diff --git a/dpe/fuzz/Cargo.lock b/dpe/fuzz/Cargo.lock index 99f8c64e..a360d113 100644 --- a/dpe/fuzz/Cargo.lock +++ b/dpe/fuzz/Cargo.lock @@ -943,18 +943,18 @@ checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" [[package]] name = "zerocopy" -version = "0.8.6" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a65238aacd5fb83fb03fcaf94823e71643e937000ec03c46e7da94234b10c870" +checksum = "e031087b26520ba76806365896f191416ce84873ed6c6910a9ab5fe0f98f8ed3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.6" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ca22c4ad176b37bd81a565f66635bde3d654fe6832730c3e52e1018ae1655ee" +checksum = "568244125ba0fc91ae949b97f2852f82cb1a65c3327bd68e6edadd29e67cca26" dependencies = [ "proc-macro2", "quote", diff --git a/dpe/src/lib.rs b/dpe/src/lib.rs index f5d5e36d..9f56ea04 100644 --- a/dpe/src/lib.rs +++ b/dpe/src/lib.rs @@ -25,14 +25,15 @@ pub mod x509; use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout}; -const MAX_CERT_SIZE: usize = 2048; +// Max cert size returned by CertifyKey +const MAX_CERT_SIZE: usize = 6144; #[cfg(not(feature = "arbitrary_max_handles"))] pub const MAX_HANDLES: usize = 24; #[cfg(feature = "arbitrary_max_handles")] include!(concat!(env!("OUT_DIR"), "/arbitrary_max_handles.rs")); const CURRENT_PROFILE_MAJOR_VERSION: u16 = 0; -const CURRENT_PROFILE_MINOR_VERSION: u16 = 10; +const CURRENT_PROFILE_MINOR_VERSION: u16 = 11; #[cfg(not(feature = "disable_internal_info"))] const INTERNAL_INPUT_INFO_SIZE: usize = size_of::() + size_of::(); @@ -65,8 +66,9 @@ impl From for U8Bool { } pub enum DpeProfile { - P256Sha256 = 1, - P384Sha384 = 2, + // Note: Min profiles (1 & 2) are not supported by this implementation + P256Sha256 = 3, + P384Sha384 = 4, } impl DpeProfile { diff --git a/dpe/src/response.rs b/dpe/src/response.rs index 384d4f0e..22d042ed 100644 --- a/dpe/src/response.rs +++ b/dpe/src/response.rs @@ -9,7 +9,7 @@ use crate::{ CURRENT_PROFILE_MINOR_VERSION, DPE_PROFILE, MAX_CERT_SIZE, MAX_HANDLES, }; use crypto::CryptoError; -use platform::PlatformError; +use platform::{PlatformError, MAX_CHUNK_SIZE}; use zerocopy::IntoBytes; #[cfg_attr(test, derive(PartialEq, Debug, Eq))] @@ -190,7 +190,7 @@ pub struct SignResp { pub struct GetCertificateChainResp { pub resp_hdr: ResponseHdr, pub certificate_size: u32, - pub certificate_chain: [u8; MAX_CERT_SIZE], + pub certificate_chain: [u8; MAX_CHUNK_SIZE], } #[derive(Debug, PartialEq, Eq, Clone, Copy)] diff --git a/platform/src/lib.rs b/platform/src/lib.rs index d62551fd..37452458 100644 --- a/platform/src/lib.rs +++ b/platform/src/lib.rs @@ -15,6 +15,7 @@ pub mod default; pub mod printer; +// Max cert chunk returned by GetCertificateChain pub const MAX_CHUNK_SIZE: usize = 2048; pub const MAX_ISSUER_NAME_SIZE: usize = 128; pub const MAX_SN_SIZE: usize = 20; diff --git a/verification/client/abi.go b/verification/client/abi.go index 9c424c32..2707734e 100644 --- a/verification/client/abi.go +++ b/verification/client/abi.go @@ -16,7 +16,7 @@ const ( RespMagic uint32 = 0x44504552 CurrentProfileMajorVersion uint16 = 0 - CurrentProfileMinorVersion uint16 = 10 + CurrentProfileMinorVersion uint16 = 11 ) // CommandCode is a DPE command code @@ -264,7 +264,7 @@ type SignResp[Digest DigestAlgorithm] struct { } // DPEABI is a connection to a DPE instance, parameterized by hash algorithm and ECC curve. -type DPEABI[CurveParameter Curve, Digest DigestAlgorithm] struct { +type DPEABI[CurveParameter Curve, Digest DigestAlgorithm, Cert DPECertificate] struct { transport Transport constants profileInfo Profile Profile @@ -277,30 +277,42 @@ type DPEABI[CurveParameter Curve, Digest DigestAlgorithm] struct { } // DPEABI256 is a client that implements DPE_PROFILE_IROT_P256_SHA256 -type DPEABI256 = DPEABI[NISTP256Parameter, SHA256Digest] +type DPEABI256Min = DPEABI[NISTP256Parameter, SHA256Digest, DPEMinCertificate] // DPEABI384 is a client that implements DPE_PROFILE_IROT_P384_SHA384 -type DPEABI384 = DPEABI[NISTP384Parameter, SHA384Digest] +type DPEABI384Min = DPEABI[NISTP384Parameter, SHA384Digest, DPEMinCertificate] + +// DPEABI256 is a client that implements DPE_PROFILE_IROT_P256_SHA256 +type DPEABI256 = DPEABI[NISTP256Parameter, SHA256Digest, DPEFullCertificate] + +// DPEABI384 is a client that implements DPE_PROFILE_IROT_P384_SHA384 +type DPEABI384 = DPEABI[NISTP384Parameter, SHA384Digest, DPEFullCertificate] // dpeProfileImplementsTypeConstraints checks that the requested DPEABI type constraints are compatible with the DPE profile. -func dpeProfileImplementsTypeConstraints[C Curve, D DigestAlgorithm](profile Profile) error { +func dpeProfileImplementsTypeConstraints[C Curve, D DigestAlgorithm, Cert DPECertificate](profile Profile) error { // Test that the expected value types produced by each DPE profile can be assigned to variables of type C and D var c C var d D + var cert Cert var targetProfile Profile _, isP256 := any(c).(NISTP256Parameter) _, isSHA256 := any(d).(SHA256Digest) _, isP384 := any(c).(NISTP384Parameter) _, isSHA384 := any(d).(SHA384Digest) + _, isMin := any(cert).(DPEMinCertificate) - if isP256 && isSHA256 { + if isP256 && isSHA256 && isMin { + targetProfile = ProfileMinP256SHA256 + } else if isP384 && isSHA384 && isMin { + targetProfile = ProfileMinP384SHA384 + } else if isP256 && isSHA256 && !isMin { targetProfile = ProfileP256SHA256 - } else if isP384 && isSHA384 { + } else if isP384 && isSHA384 && !isMin { targetProfile = ProfileP384SHA384 } else { - return fmt.Errorf("client requested (Curve = %v, Digest = %v), this is an invalid DPE profile", - reflect.TypeOf(c), reflect.TypeOf(d)) + return fmt.Errorf("client requested (Curve = %v, Digest = %v, Certificate = %v), this is an invalid DPE profile", + reflect.TypeOf(c), reflect.TypeOf(d), reflect.TypeOf(cert)) } if profile != targetProfile { @@ -311,13 +323,13 @@ func dpeProfileImplementsTypeConstraints[C Curve, D DigestAlgorithm](profile Pro } // newDPEABI initializes a new DPE client. -func newDPEABI[C Curve, D DigestAlgorithm](t Transport) (*DPEABI[C, D], error) { +func newDPEABI[C Curve, D DigestAlgorithm, Cert DPECertificate](t Transport) (*DPEABI[C, D, Cert], error) { rsp, err := getProfile(t) if err != nil { return nil, fmt.Errorf("could not query DPE for profile: %w", err) } - if err := dpeProfileImplementsTypeConstraints[C, D](rsp.Profile); err != nil { + if err := dpeProfileImplementsTypeConstraints[C, D, Cert](rsp.Profile); err != nil { return nil, err } @@ -331,7 +343,7 @@ func newDPEABI[C Curve, D DigestAlgorithm](t Transport) (*DPEABI[C, D], error) { return nil, fmt.Errorf("unknown DPE profile version %d.%d", rsp.MajorVersion, rsp.MinorVersion) } - return &DPEABI[C, D]{ + return &DPEABI[C, D, Cert]{ transport: t, constants: constants, Profile: rsp.Profile, @@ -343,18 +355,28 @@ func newDPEABI[C Curve, D DigestAlgorithm](t Transport) (*DPEABI[C, D], error) { }, nil } -// NewDPEABI256 is a convenience wrapper for NewDPEABI[NISTP256Parameter, SHA256Digest]. -func NewDPEABI256(t Transport) (*DPEABI[NISTP256Parameter, SHA256Digest], error) { - return newDPEABI[NISTP256Parameter, SHA256Digest](t) +// NewDPEABI256 is a convenience wrapper for NewDPEABI[NISTP256Parameter, SHA256Digest, DPEFullCertificate]. +func NewDPEABI256(t Transport) (*DPEABI[NISTP256Parameter, SHA256Digest, DPEFullCertificate], error) { + return newDPEABI[NISTP256Parameter, SHA256Digest, DPEFullCertificate](t) +} + +// NewDPEABI384 is a convenience wrapper for NewDPEABI[NISTP384Parameter, SHA384Digest, DPEFullCertificate]. +func NewDPEABI384(t Transport) (*DPEABI[NISTP384Parameter, SHA384Digest, DPEFullCertificate], error) { + return newDPEABI[NISTP384Parameter, SHA384Digest, DPEFullCertificate](t) +} + +// NewDPEABI256Min is a convenience wrapper for NewDPEABI[NISTP256Parameter, SHA256Digest, DPEMinCertificate]. +func NewDPEABI256Min(t Transport) (*DPEABI[NISTP256Parameter, SHA256Digest, DPEMinCertificate], error) { + return newDPEABI[NISTP256Parameter, SHA256Digest, DPEMinCertificate](t) } -// NewDPEABI384 is a convenience wrapper for NewDPEABI[NISTP384Parameter, SHA384Digest]. -func NewDPEABI384(t Transport) (*DPEABI[NISTP384Parameter, SHA384Digest], error) { - return newDPEABI[NISTP384Parameter, SHA384Digest](t) +// NewDPEABI384Min is a convenience wrapper for NewDPEABI[NISTP384Parameter, SHA384Digest, DPEMinCertificate]. +func NewDPEABI384Min(t Transport) (*DPEABI[NISTP384Parameter, SHA384Digest, DPEMinCertificate], error) { + return newDPEABI[NISTP384Parameter, SHA384Digest, DPEMinCertificate](t) } // InitializeContextABI calls InitializeContext -func (c *DPEABI[_, _]) InitializeContextABI(cmd *InitCtxCmd) (*InitCtxResp, error) { +func (c *DPEABI[_, _, _]) InitializeContextABI(cmd *InitCtxCmd) (*InitCtxResp, error) { var respStruct InitCtxResp if _, err := execCommand(c.transport, c.constants.Codes.InitializeContext, c.Profile, cmd, &respStruct); err != nil { @@ -410,12 +432,12 @@ func getProfile(t Transport) (*GetProfileResp, error) { } // GetProfileABI calls the DPE GetProfile for this ABI -func (c *DPEABI[_, _]) GetProfileABI() (*GetProfileResp, error) { +func (c *DPEABI[_, _, _]) GetProfileABI() (*GetProfileResp, error) { return getProfile(c.transport) } // DestroyContextABI calls the DPE DestroyContext for this ABI -func (c *DPEABI[_, _]) DestroyContextABI(cmd *DestroyCtxCmd) error { +func (c *DPEABI[_, _, _]) DestroyContextABI(cmd *DestroyCtxCmd) error { // DestroyContext does not return any parameters. respStruct := struct{}{} @@ -427,14 +449,14 @@ func (c *DPEABI[_, _]) DestroyContextABI(cmd *DestroyCtxCmd) error { } // CertifyKeyABI calls the DPE CertifyKey command. -func (c *DPEABI[CurveParameter, Digest]) CertifyKeyABI(cmd *CertifyKeyReq[Digest]) (*CertifyKeyResp[CurveParameter, Digest], error) { +func (c *DPEABI[CurveParameter, Digest, DPECertificate]) CertifyKeyABI(cmd *CertifyKeyReq[Digest]) (*CertifyKeyResp[CurveParameter, Digest], error) { // Define an anonymous struct for the response, because we have to accept the variable-sized certificate. respStruct := struct { NewContextHandle [16]byte DerivedPublicKeyX CurveParameter DerivedPublicKeyY CurveParameter CertificateSize uint32 - Certificate [2048]byte + Certificate DPECertificate }{} _, err := execCommand(c.transport, c.constants.Codes.CertifyKey, c.Profile, cmd, &respStruct) @@ -443,7 +465,7 @@ func (c *DPEABI[CurveParameter, Digest]) CertifyKeyABI(cmd *CertifyKeyReq[Digest } // Check that the reported cert size makes sense. - if respStruct.CertificateSize > 2048 { + if respStruct.CertificateSize > uint32(CertLen[DPECertificate]()) { return nil, fmt.Errorf("DPE reported a %d-byte cert, which was larger than 2048", respStruct.CertificateSize) } @@ -451,12 +473,12 @@ func (c *DPEABI[CurveParameter, Digest]) CertifyKeyABI(cmd *CertifyKeyReq[Digest NewContextHandle: respStruct.NewContextHandle, DerivedPublicKeyX: respStruct.DerivedPublicKeyX, DerivedPublicKeyY: respStruct.DerivedPublicKeyY, - Certificate: respStruct.Certificate[:respStruct.CertificateSize], + Certificate: respStruct.Certificate.Bytes()[:respStruct.CertificateSize], }, nil } // GetCertificateChainABI calls the DPE GetCertificateChain command. -func (c *DPEABI[_, _]) GetCertificateChainABI() (*GetCertificateChainResp, error) { +func (c *DPEABI[_, _, _]) GetCertificateChainABI() (*GetCertificateChainResp, error) { var certs GetCertificateChainResp // Initialize request input parameters @@ -495,7 +517,7 @@ func (c *DPEABI[_, _]) GetCertificateChainABI() (*GetCertificateChainResp, error } // DeriveContextABI calls DPE DeriveContext command. -func (c *DPEABI[_, Digest]) DeriveContextABI(cmd *DeriveContextReq[Digest]) (*DeriveContextResp, error) { +func (c *DPEABI[_, Digest, _]) DeriveContextABI(cmd *DeriveContextReq[Digest]) (*DeriveContextResp, error) { var respStruct DeriveContextResp _, err := execCommand(c.transport, c.constants.Codes.DeriveContext, c.Profile, cmd, &respStruct) @@ -507,7 +529,7 @@ func (c *DPEABI[_, Digest]) DeriveContextABI(cmd *DeriveContextReq[Digest]) (*De } // RotateContextHandleABI calls DPE RotateContextHandle command. -func (c *DPEABI[_, Digest]) RotateContextABI(cmd *RotateContextHandleCmd) (*RotatedContextHandle, error) { +func (c *DPEABI[_, Digest, _]) RotateContextABI(cmd *RotateContextHandleCmd) (*RotatedContextHandle, error) { var respStruct RotatedContextHandle _, err := execCommand(c.transport, c.constants.Codes.RotateContextHandle, c.Profile, cmd, &respStruct) @@ -519,7 +541,7 @@ func (c *DPEABI[_, Digest]) RotateContextABI(cmd *RotateContextHandleCmd) (*Rota } // SignABI calls the DPE Sign command. -func (c *DPEABI[_, Digest]) SignABI(cmd *SignReq[Digest]) (*SignResp[Digest], error) { +func (c *DPEABI[_, Digest, _]) SignABI(cmd *SignReq[Digest]) (*SignResp[Digest], error) { var respStruct SignResp[Digest] _, err := execCommand(c.transport, c.constants.Codes.Sign, c.Profile, cmd, &respStruct) @@ -531,7 +553,7 @@ func (c *DPEABI[_, Digest]) SignABI(cmd *SignReq[Digest]) (*SignResp[Digest], er } // InitializeContext calls the DPE InitializeContext command -func (c *DPEABI[_, _]) InitializeContext(flags InitCtxFlags) (*ContextHandle, error) { +func (c *DPEABI[_, _, _]) InitializeContext(flags InitCtxFlags) (*ContextHandle, error) { cmd := InitCtxCmd{flags: flags} resp, err := c.InitializeContextABI(&cmd) if err != nil { @@ -542,12 +564,12 @@ func (c *DPEABI[_, _]) InitializeContext(flags InitCtxFlags) (*ContextHandle, er } // GetProfile calls the DPE GetProfile command -func (c *DPEABI[_, _]) GetProfile() (*GetProfileResp, error) { +func (c *DPEABI[_, _, _]) GetProfile() (*GetProfileResp, error) { return c.GetProfileABI() } // CertifyKey calls the DPE CertifyKey command -func (c *DPEABI[_, Digest]) CertifyKey(handle *ContextHandle, label []byte, format CertifyKeyFormat, flags CertifyKeyFlags) (*CertifiedKey, error) { +func (c *DPEABI[_, Digest, _]) CertifyKey(handle *ContextHandle, label []byte, format CertifyKeyFormat, flags CertifyKeyFlags) (*CertifiedKey, error) { if len(label) != DigestLen[Digest]() { return nil, fmt.Errorf("invalid label length") } @@ -582,7 +604,7 @@ func (c *DPEABI[_, Digest]) CertifyKey(handle *ContextHandle, label []byte, form } // DestroyContext calls DPE DestroyContext command -func (c *DPEABI[_, _]) DestroyContext(handle *ContextHandle) error { +func (c *DPEABI[_, _, _]) DestroyContext(handle *ContextHandle) error { cmd := DestroyCtxCmd{ handle: *handle, } @@ -591,7 +613,7 @@ func (c *DPEABI[_, _]) DestroyContext(handle *ContextHandle) error { } // GetCertificateChain calls DPE GetCertificateChain command -func (c *DPEABI[_, _]) GetCertificateChain() ([]byte, error) { +func (c *DPEABI[_, _, _]) GetCertificateChain() ([]byte, error) { resp, err := c.GetCertificateChainABI() if err != nil { return nil, err @@ -601,7 +623,7 @@ func (c *DPEABI[_, _]) GetCertificateChain() ([]byte, error) { } // DeriveContext calls DPE DeriveContext command -func (c *DPEABI[_, Digest]) DeriveContext(handle *ContextHandle, inputData []byte, flags DeriveContextFlags, tciType uint32, targetLocality uint32) (*DeriveContextResp, error) { +func (c *DPEABI[_, Digest, _]) DeriveContext(handle *ContextHandle, inputData []byte, flags DeriveContextFlags, tciType uint32, targetLocality uint32) (*DeriveContextResp, error) { if len(inputData) != DigestLen[Digest]() { return nil, fmt.Errorf("invalid digest length") } @@ -627,7 +649,7 @@ func (c *DPEABI[_, Digest]) DeriveContext(handle *ContextHandle, inputData []byt } // RotateContextHandle calls DPE RotateContextHandle command -func (c *DPEABI[_, _]) RotateContextHandle(handle *ContextHandle, flags RotateContextHandleFlags) (*ContextHandle, error) { +func (c *DPEABI[_, _, _]) RotateContextHandle(handle *ContextHandle, flags RotateContextHandleFlags) (*ContextHandle, error) { cmd := RotateContextHandleCmd{ Handle: *handle, Flags: flags, @@ -640,7 +662,7 @@ func (c *DPEABI[_, _]) RotateContextHandle(handle *ContextHandle, flags RotateCo } // Sign calls DPE Sign command -func (c *DPEABI[_, Digest]) Sign(handle *ContextHandle, label []byte, flags SignFlags, toBeSigned []byte) (*DPESignedHash, error) { +func (c *DPEABI[_, Digest, _]) Sign(handle *ContextHandle, label []byte, flags SignFlags, toBeSigned []byte) (*DPESignedHash, error) { dLen := DigestLen[Digest]() if len(label) != dLen { return nil, fmt.Errorf("invalid label length") diff --git a/verification/client/client.go b/verification/client/client.go index 5010e430..260b1fa6 100644 --- a/verification/client/client.go +++ b/verification/client/client.go @@ -61,6 +61,10 @@ type DPEClient interface { // NewClient returns a new DPE client func NewClient(t Transport, p Profile) (DPEClient, error) { switch p { + case ProfileMinP256SHA256: + return NewDPEABI256Min(t) + case ProfileMinP384SHA384: + return NewDPEABI384Min(t) case ProfileP256SHA256: return NewDPEABI256(t) case ProfileP384SHA384: diff --git a/verification/client/profile.go b/verification/client/profile.go index cf57f274..f03bfdde 100644 --- a/verification/client/profile.go +++ b/verification/client/profile.go @@ -11,17 +11,25 @@ import ( type Profile uint32 const ( - // ProfileP256SHA256 is NIST P-256, SHA-256 - ProfileP256SHA256 Profile = 1 - // ProfileP384SHA384 is NIST P-384, SHA-384 - ProfileP384SHA384 Profile = 2 + // ProfileIrotMinP256SHA256 is NIST P-256, SHA-256 "minimal profile" + ProfileMinP256SHA256 Profile = 1 + // ProfileIrotMinP384SHA384 is NIST P-384, SHA-384 "minimal" profile + ProfileMinP384SHA384 Profile = 2 + // ProfileIrotMinP256SHA256 is NIST P-256, SHA-256 "minimal profile" + ProfileP256SHA256 Profile = 3 + // ProfileIrotP384SHA384 is NIST P-384, SHA-384 "minimal" profile + ProfileP384SHA384 Profile = 4 ) // GetDigestSize gets the digest size of the profile's supported hash algorithm func (p Profile) GetDigestSize() int { switch p { + case ProfileMinP256SHA256: + fallthrough case ProfileP256SHA256: return 32 + case ProfileMinP384SHA384: + fallthrough case ProfileP384SHA384: return 48 } @@ -31,8 +39,12 @@ func (p Profile) GetDigestSize() int { // GetECCIntSize gets the ECC int size of the profile's supported ECC curve func (p Profile) GetECCIntSize() int { switch p { + case ProfileMinP256SHA256: + fallthrough case ProfileP256SHA256: return 32 + case ProfileMinP384SHA384: + fallthrough case ProfileP384SHA384: return 48 } @@ -41,8 +53,12 @@ func (p Profile) GetECCIntSize() int { func (p Profile) String() string { switch p { + case ProfileMinP256SHA256: + return "DPE_PROFILE_IROT_MIN_P256_SHA256" case ProfileP256SHA256: return "DPE_PROFILE_IROT_P256_SHA256" + case ProfileMinP384SHA384: + return "DPE_PROFILE_IROT_MIN_P384_SHA384" case ProfileP384SHA384: return "DPE_PROFILE_IROT_P384_SHA384" } @@ -83,6 +99,32 @@ type DigestAlgorithm interface { Bytes() []byte } +// DPEMinCertificate represents a certificate for the DPE minimal iRoT profiles +type DPEMinCertificate [2046]byte + +// DPEFullCertificate represents a certificate for the DPE full iRoT profiles +type DPEFullCertificate [6144]byte + +type DPECertificate interface { + DPEMinCertificate | DPEFullCertificate + + Bytes() []byte +} + +func CertLen[C DPECertificate]() int { + return reflect.TypeOf((*C)(nil)).Elem().Len() +} + +// Bytes returns a byte slice of the DPE min certificate +func (c DPEMinCertificate) Bytes() []byte { + return c[:] +} + +// Bytes returns a byte slice of the DPE full certificate +func (c DPEFullCertificate) Bytes() []byte { + return c[:] +} + func NewDigest[D DigestAlgorithm](b []byte) (D, error) { var d D switch tmp := any(&d).(type) { diff --git a/verification/testing/certifyKey.go b/verification/testing/certifyKey.go index c264edd7..7d0a3208 100644 --- a/verification/testing/certifyKey.go +++ b/verification/testing/certifyKey.go @@ -690,12 +690,16 @@ func getKeyUsageNames(keyUsage x509.KeyUsage) []string { func checkPubKey(t *testing.T, p client.Profile, pubkey any, response client.CertifiedKey) { var pubKeyInResponse ecdsa.PublicKey switch p { + case client.ProfileMinP256SHA256: + fallthrough case client.ProfileP256SHA256: pubKeyInResponse = ecdsa.PublicKey{ Curve: elliptic.P256(), X: new(big.Int).SetBytes(response.Pub.X), Y: new(big.Int).SetBytes(response.Pub.Y), } + case client.ProfileMinP384SHA384: + fallthrough case client.ProfileP384SHA384: pubKeyInResponse = ecdsa.PublicKey{ Curve: elliptic.P384(), diff --git a/verification/testing/deriveContext.go b/verification/testing/deriveContext.go index e3e8df40..0623d4e8 100644 --- a/verification/testing/deriveContext.go +++ b/verification/testing/deriveContext.go @@ -6,6 +6,7 @@ import ( "bytes" "crypto/sha256" "crypto/sha512" + "crypto/x509" "errors" "hash" "testing" @@ -217,13 +218,30 @@ func TestMaxTCIs(d client.TestDPEInstance, c client.DPEClient, t *testing.T) { maxTciCount := int(d.GetMaxTciNodes()) allowedTciCount := maxTciCount - 1 // since, a TCI node is already auto-initialized for i := 0; i < allowedTciCount; i++ { - resp, err = c.DeriveContext(handle, make([]byte, digestSize), 0, 0, 0) + resp, err = c.DeriveContext(handle, make([]byte, digestSize), client.InputAllowX509, 0, 0) if err != nil { t.Fatalf("[FATAL]: Error encountered in executing derive child: %v", err) } handle = &resp.NewContextHandle } + // Make sure cert fits in CertifyKeyResponse + // Similarly, when commands like CertifyKey try to make use of features/flags that are unsupported + // by child context, it will fail. + digestLen := profile.GetDigestSize() + cert, err := c.CertifyKey(handle, make([]byte, digestLen), client.CertifyKeyX509, 0) + if err != nil { + t.Fatalf("[FATAL]; CertifyKey failed with error %v", err) + } + + handle = &cert.Handle + + t.Logf("Cert size = %d\n", len(cert.Certificate)) + + if _, err = x509.ParseCertificate(cert.Certificate); err != nil { + t.Fatalf("[FATAL]: Could not parse certificate: %v", err) + } + // Exceed the Max TCI node count limit _, err = c.DeriveContext(handle, make([]byte, digestSize), 0, 0, 0) if err == nil { diff --git a/verification/testing/simulator.go b/verification/testing/simulator.go index 04b721e7..6282bf92 100644 --- a/verification/testing/simulator.go +++ b/verification/testing/simulator.go @@ -147,7 +147,7 @@ func GetSimulatorTargets() []TestTarget { }, { "DeriveContext_MaxTCIs", - getTestTarget([]string{"AutoInit", "Simulation"}), + getTestTarget([]string{"AutoInit", "Recursive", "X509"}), []TestCase{DeriveContextMaxTCIsTestCase}, }, { diff --git a/verification/testing/verification.go b/verification/testing/verification.go index b509635e..1893baee 100644 --- a/verification/testing/verification.go +++ b/verification/testing/verification.go @@ -124,7 +124,7 @@ var DeriveContextSimulationTestCase = TestCase{ // DeriveContextMaxTCIsTestCase checks whether the number of derived contexts is limited by MAX_TCI_NODES attribute of the profile var DeriveContextMaxTCIsTestCase = TestCase{ - "DeriveContext_MaxTCIs", TestMaxTCIs, []string{"AutoInit"}, + "DeriveContext_MaxTCIs", TestMaxTCIs, []string{"AutoInit", "X509"}, } // DeriveContextLocalityTestCase tests DerivedContext with the ChangeLocality flag.