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

Increase max cert size to 6KiB #365

Merged
merged 1 commit into from
Dec 6, 2024
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
2 changes: 1 addition & 1 deletion ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions dpe/fuzz/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions dpe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<GetProfileResp>() + size_of::<u32>();
Expand Down Expand Up @@ -65,8 +66,9 @@ impl From<bool> 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 {
Expand Down
4 changes: 2 additions & 2 deletions dpe/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))]
Expand Down Expand Up @@ -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)]
Expand Down
1 change: 1 addition & 0 deletions platform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
96 changes: 59 additions & 37 deletions verification/client/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const (
RespMagic uint32 = 0x44504552

CurrentProfileMajorVersion uint16 = 0
CurrentProfileMinorVersion uint16 = 10
CurrentProfileMinorVersion uint16 = 11
)

// CommandCode is a DPE command code
Expand Down Expand Up @@ -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
Expand All @@ -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 {
Expand All @@ -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
}

Expand All @@ -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,
Expand All @@ -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 {
Expand Down Expand Up @@ -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{}{}

Expand All @@ -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)
Expand All @@ -443,20 +465,20 @@ 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)
}

return &CertifyKeyResp[CurveParameter, 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
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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 {
Expand All @@ -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")
}
Expand Down Expand Up @@ -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,
}
Expand All @@ -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
Expand All @@ -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")
}
Expand All @@ -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,
Expand All @@ -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")
Expand Down
4 changes: 4 additions & 0 deletions verification/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading
Loading