Skip to content

Commit

Permalink
Refactor X.509 encoding library to use the der crate
Browse files Browse the repository at this point in the history
The der crate-based implementation is significantly less code and follows a
more consistent pattern. Since this allows defining types with encoding
rules, this will make it much simpler to add structures for ML-DSA
structures for Caliptra 2.0.

The der crate is part of RustCrypto and is intended to be
embedded/no_std friendly.
  • Loading branch information
jhand2 committed Sep 12, 2024
1 parent 2e02db5 commit 1ad2a64
Show file tree
Hide file tree
Showing 7 changed files with 1,046 additions and 1,849 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

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

16 changes: 16 additions & 0 deletions crypto/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ pub struct EcdsaSig {
pub s: CryptoBuf,
}

pub const MAX_ENCODED_ECDSA_PUB: usize = 1 + (2 * CryptoBuf::MAX_SIZE);

#[derive(ZeroizeOnDrop)]
pub struct EncodedEcdsaPub(pub ArrayVec<u8, MAX_ENCODED_ECDSA_PUB>);

impl From<&EcdsaPub> for EncodedEcdsaPub {
fn from(value: &EcdsaPub) -> Self {
// PANIC FREE: Size of data is same is 1 + x_max + y_max
let mut encoded = EncodedEcdsaPub(ArrayVec::<u8, MAX_ENCODED_ECDSA_PUB>::new());
encoded.0.push(0x4);
encoded.0.try_extend_from_slice(value.x.bytes()).unwrap();
encoded.0.try_extend_from_slice(value.y.bytes()).unwrap();
encoded
}
}

/// An ECDSA public key
#[derive(ZeroizeOnDrop)]
pub struct EcdsaPub {
Expand Down
3 changes: 2 additions & 1 deletion dpe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ caliptra-cfi-lib-git = { workspace = true, default-features = false, features =
caliptra-cfi-derive-git.workspace = true
constant_time_eq = "0.3.0"
crypto = {path = "../crypto", default-features = false}
der = { version = "0.7.9", default-features = false, features = ["oid", "derive"] }
platform = {path = "../platform", default-features = false}
ufmt = { git = "https://github.com/korran/ufmt.git", rev = "1d0743c1ffffc68bc05ca8eeb81c166192863f33", features = ["inline"] }
zerocopy.workspace = true
zeroize = { version = "1.6.0", default-features = false, features = ["zeroize_derive"] }
cfg-if = "1.0.0"

[dev-dependencies]
asn1 = "0.13.0"
asn1 = { version = "0.13.0", default-features = false}
caliptra-cfi-lib-git = { workspace = true, features = ["cfi-test"] }
openssl.workspace = true
x509-parser = "0.15.1"
Expand Down
5 changes: 3 additions & 2 deletions dpe/fuzz/Cargo.lock

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

16 changes: 8 additions & 8 deletions dpe/src/commands/certify_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
dpe_instance::{DpeEnv, DpeInstance, DpeTypes},
response::{CertifyKeyResp, DpeErrorCode, Response, ResponseHdr},
tci::TciNodeData,
x509::{CertWriter, DirectoryString, MeasurementData, Name},
x509::{CertWriter, MeasurementData, Name},
DPE_PROFILE, MAX_CERT_SIZE, MAX_HANDLES,
};
use bitflags::bitflags;
Expand Down Expand Up @@ -116,8 +116,8 @@ impl CommandExecution for CertifyKeyCmd {
let truncated_subj_serial = &subj_serial[..64];

let subject_name = Name {
cn: DirectoryString::PrintableString(b"DPE Leaf"),
serial: DirectoryString::PrintableString(truncated_subj_serial),
cn: b"DPE Leaf",
serial: truncated_subj_serial,
};

// Get TCI Nodes
Expand Down Expand Up @@ -178,7 +178,7 @@ impl CommandExecution for CertifyKeyCmd {
let cert_validity = env.platform.get_cert_validity()?;
let mut bytes_written = tbs_writer.encode_ecdsa_tbs(
/*serial=*/
&subject_name.serial.bytes()[..20], // Serial number must be truncated to 20 bytes
&subject_name.serial[..20], // Serial number must be truncated to 20 bytes
&issuer_name[..issuer_len],
&subject_name,
&pub_key,
Expand Down Expand Up @@ -671,13 +671,13 @@ mod tests {
.unwrap();
let truncated_subj_serial = &subj_serial[..64];
let subject_name = Name {
cn: DirectoryString::PrintableString(b"DPE Leaf"),
serial: DirectoryString::PrintableString(truncated_subj_serial),
cn: b"DPE Leaf",
serial: truncated_subj_serial,
};
let expected_subject_name = format!(
"CN={}, serialNumber={}",
str::from_utf8(subject_name.cn.bytes()).unwrap(),
str::from_utf8(&subject_name.serial.bytes()).unwrap()
str::from_utf8(subject_name.cn).unwrap(),
str::from_utf8(&subject_name.serial).unwrap()
);
let actual_subject_name = cri.subject.to_string_with_registry(oid_registry()).unwrap();
assert_eq!(expected_subject_name, actual_subject_name);
Expand Down
14 changes: 12 additions & 2 deletions dpe/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ Abstract:
DPE reponses and serialization.
--*/
use crate::{
context::ContextHandle, validation::ValidationError, CURRENT_PROFILE_MAJOR_VERSION,
CURRENT_PROFILE_MINOR_VERSION, DPE_PROFILE, MAX_CERT_SIZE, MAX_HANDLES,
context::ContextHandle, validation::ValidationError, x509::X509Error,
CURRENT_PROFILE_MAJOR_VERSION, CURRENT_PROFILE_MINOR_VERSION, DPE_PROFILE, MAX_CERT_SIZE,
MAX_HANDLES,
};
use crypto::CryptoError;
use platform::PlatformError;
Expand Down Expand Up @@ -151,6 +152,7 @@ pub enum DpeErrorCode {
Platform(PlatformError) = 0x01000000,
Crypto(CryptoError) = 0x02000000,
Validation(ValidationError) = 0x03000000,
X509(X509Error) = 0x04000000,
}

impl From<PlatformError> for DpeErrorCode {
Expand All @@ -165,6 +167,12 @@ impl From<CryptoError> for DpeErrorCode {
}
}

impl From<X509Error> for DpeErrorCode {
fn from(e: X509Error) -> Self {
DpeErrorCode::X509(e)
}
}

impl DpeErrorCode {
/// Get the spec-defined numeric error code. This does not include the
/// extended error information returned from the Platform and Crypto
Expand All @@ -181,6 +189,7 @@ impl DpeErrorCode {
DpeErrorCode::Platform(e) => self.discriminant() | e.discriminant() as u32,
DpeErrorCode::Crypto(e) => self.discriminant() | e.discriminant() as u32,
DpeErrorCode::Validation(e) => self.discriminant() | e.discriminant() as u32,
DpeErrorCode::X509(e) => self.discriminant() | e.discriminant() as u32,
_ => self.discriminant(),
}
}
Expand All @@ -194,6 +203,7 @@ impl DpeErrorCode {
match self {
DpeErrorCode::Platform(e) => e.get_error_detail(),
DpeErrorCode::Crypto(e) => e.get_error_detail(),
DpeErrorCode::X509(e) => e.get_error_detail(),
_ => None,
}
}
Expand Down
Loading

0 comments on commit 1ad2a64

Please sign in to comment.