Skip to content

Commit

Permalink
Add CFI to DPE
Browse files Browse the repository at this point in the history
  • Loading branch information
sree-revoori1 committed Feb 12, 2024
1 parent 01128ac commit a9020ee
Show file tree
Hide file tree
Showing 20 changed files with 545 additions and 52 deletions.
27 changes: 27 additions & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ members = [
"simulator",
"tools",
]

[workspace.dependencies]
caliptra-cfi-lib-git = { git = "https://github.com/chipsalliance/caliptra-cfi.git", package = "caliptra-cfi-lib-git", default-features = false, features = ["cfi", "cfi-counter" ] }
caliptra-cfi-derive-git = { git = "https://github.com/chipsalliance/caliptra-cfi.git", package = "caliptra-cfi-derive-git" }
10 changes: 5 additions & 5 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function test_rust_targets() {

cargo test --manifest-path platform/Cargo.toml --features=$profile --no-default-features
cargo test --manifest-path crypto/Cargo.toml --no-default-features
cargo test --manifest-path dpe/Cargo.toml --features=$profile --no-default-features
cargo test --manifest-path dpe/Cargo.toml --features=$profile --no-default-features -- --test-threads=1
cargo test --manifest-path simulator/Cargo.toml --features=$profile,openssl --no-default-features
}

Expand Down Expand Up @@ -80,13 +80,13 @@ run_verification_tests dpe_profile_p384_sha384 rustcrypto

# Build fuzz target
( cd dpe/fuzz
rustup toolchain install nightly-2023-04-15
cargo +nightly-2023-04-15 install cargo-fuzz cargo-afl
rustup toolchain install nightly-2023-11-16
cargo +nightly-2023-11-16 install cargo-fuzz cargo-afl
cargo fmt --check
cargo clippy --features libfuzzer-sys
cargo clippy --features afl
cargo +nightly-2023-04-15 fuzz build --features libfuzzer-sys
cargo +nightly-2023-04-15 afl build --features afl
cargo +nightly-2023-11-16 fuzz build --features libfuzzer-sys
cargo +nightly-2023-11-16 afl build --features afl
)

# Fix license headers
Expand Down
3 changes: 3 additions & 0 deletions crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ edition = "2021"
openssl = ["dep:openssl", "dep:hkdf", "dep:sha2"]
rustcrypto = ["dep:hkdf", "dep:hmac", "dep:p256", "dep:p384", "dep:rand", "dep:sha2", "dep:base64ct", "dep:ecdsa", "dep:sec1"]
deterministic_rand = ["dep:rand"]
no-cfi = []

[dependencies]
arrayvec = { version = "0.7.4", default-features = false, features = ["zeroize"] }
caliptra-cfi-lib-git.workspace = true
caliptra-cfi-derive-git.workspace = true
ecdsa = { version = "0.16.9", optional = true, features = ["pem"]}
hkdf = { version = "0.12.3", optional = true }
hmac = {version="0.12.1", optional = true}
Expand Down
25 changes: 25 additions & 0 deletions crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,18 @@ pub trait Crypto {
info: &[u8],
) -> Result<Self::Cdi, CryptoError>;

/// CFI wrapper around derive_cdi
///
/// To implement this function, you need to add the
/// cfi_impl_fn proc_macro to derive_cdi.
#[cfg(not(feature = "no-cfi"))]
fn __cfi_derive_cdi(
&mut self,
algs: AlgLen,
measurement: &Digest,
info: &[u8],
) -> Result<Self::Cdi, CryptoError>;

/// Derives a key pair using a cryptographically secure KDF
///
/// # Arguments
Expand All @@ -187,6 +199,19 @@ pub trait Crypto {
info: &[u8],
) -> Result<(Self::PrivKey, EcdsaPub), CryptoError>;

/// CFI wrapper around derive_key_pair
///
/// To implement this function, you need to add the
/// cfi_impl_fn proc_macro to derive_key_pair.
#[cfg(not(feature = "no-cfi"))]
fn __cfi_derive_key_pair(
&mut self,
algs: AlgLen,
cdi: &Self::Cdi,
label: &[u8],
info: &[u8],
) -> Result<(Self::PrivKey, EcdsaPub), CryptoError>;

/// Sign `digest` with the platform Alias Key
///
/// # Arguments
Expand Down
4 changes: 4 additions & 0 deletions crypto/src/openssl.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Licensed under the Apache-2.0 license

use crate::{hkdf::*, AlgLen, Crypto, CryptoBuf, CryptoError, Digest, EcdsaPub, Hasher, HmacSig};
#[cfg(not(feature = "no-cfi"))]
use caliptra_cfi_derive_git::cfi_impl_fn;
use openssl::{
bn::{BigNum, BigNumContext},
ec::{EcGroup, EcKey, EcPoint},
Expand Down Expand Up @@ -122,6 +124,7 @@ impl Crypto for OpensslCrypto {
Ok(OpensslHasher(openssl::hash::Hasher::new(md)?))
}

#[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)]
fn derive_cdi(
&mut self,
algs: AlgLen,
Expand All @@ -131,6 +134,7 @@ impl Crypto for OpensslCrypto {
hkdf_derive_cdi(algs, measurement, info)
}

#[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)]
fn derive_key_pair(
&mut self,
algs: AlgLen,
Expand Down
7 changes: 6 additions & 1 deletion dpe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ version = "0.1.0"
edition = "2021"

[features]
default = ["dpe_profile_p256_sha256"]
default = ["dpe_profile_p256_sha256", "no-cfi"]
dpe_profile_p256_sha256 = ["platform/dpe_profile_p256_sha256"]
dpe_profile_p384_sha384 = ["platform/dpe_profile_p384_sha384"]
# Run ARBITRARY_MAX_HANDLES=n cargo build --features arbitrary_max_handles to use this feature
Expand All @@ -22,18 +22,23 @@ disable_internal_info = []
disable_internal_dice = []
disable_is_ca = []
disable_retain_parent_context = []
no-cfi = ["crypto/no-cfi"]

[dependencies]
bitflags = "2.4.0"
caliptra-cfi-lib-git.workspace = true
caliptra-cfi-derive-git.workspace = true
constant_time_eq = "0.3.0"
crypto = {path = "../crypto", default-features = false}
platform = {path = "../platform", default-features = false}
ufmt = { git = "https://github.com/korran/ufmt.git", rev = "1d0743c1ffffc68bc05ca8eeb81c166192863f33", features = ["inline"] }
zerocopy = "0.6.1"
zeroize = { version = "1.6.0", default-features = false, features = ["zeroize_derive"] }
cfg-if = "1.0.0"

[dev-dependencies]
asn1 = "0.13.0"
caliptra-cfi-lib-git = { workspace = true, features = ["cfi-test"] }
openssl = "0.10.57"
x509-parser = "0.15.1"
crypto = {path = "../crypto", features = ["deterministic_rand", "openssl"]}
Expand Down
27 changes: 27 additions & 0 deletions dpe/fuzz/Cargo.lock

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

48 changes: 38 additions & 10 deletions dpe/src/commands/certify_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ use crate::{
DPE_PROFILE, MAX_CERT_SIZE, MAX_HANDLES,
};
use bitflags::bitflags;
#[cfg(not(feature = "no-cfi"))]
use caliptra_cfi_derive_git::cfi_impl_fn;
use caliptra_cfi_lib_git::cfi_launder;
#[cfg(not(feature = "no-cfi"))]
use caliptra_cfi_lib_git::{cfi_assert, cfi_assert_eq};
use cfg_if::cfg_if;
use crypto::Crypto;
use platform::{Platform, MAX_ISSUER_NAME_SIZE};

Expand Down Expand Up @@ -41,6 +47,7 @@ impl CertifyKeyCmd {
}

impl CommandExecution for CertifyKeyCmd {
#[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)]
fn execute(
&self,
dpe: &mut DpeInstance,
Expand All @@ -64,21 +71,40 @@ impl CommandExecution for CertifyKeyCmd {
if !context.allow_x509() {
return Err(DpeErrorCode::InvalidArgument);
}
} else if self.format == Self::FORMAT_CSR && !dpe.support.csr() {
return Err(DpeErrorCode::ArgumentNotSupported);
}

// Make sure the command is coming from the right locality.
if context.locality != locality {
return Err(DpeErrorCode::InvalidLocality);
}

cfg_if! {
if #[cfg(not(feature = "no-cfi"))] {
cfi_assert!(!self.uses_is_ca() || dpe.support.is_ca());
cfi_assert!(!self.uses_is_ca() || context.allow_ca());
cfi_assert!(self.format != Self::FORMAT_X509 || dpe.support.x509());
cfi_assert!(self.format != Self::FORMAT_X509 || context.allow_x509());
cfi_assert!(self.format != Self::FORMAT_CSR || dpe.support.csr());
cfi_assert_eq(context.locality, locality);
}
}

let algs = DPE_PROFILE.alg_len();
let digest = dpe.compute_measurement_hash(env, idx)?;
let cdi = env
.crypto
.derive_cdi(DPE_PROFILE.alg_len(), &digest, b"DPE")?;
let (priv_key, pub_key) = env
.crypto
.derive_key_pair(algs, &cdi, &self.label, b"ECC")?;
let key_pair = env.crypto.derive_key_pair(algs, &cdi, &self.label, b"ECC");
if cfi_launder(key_pair.is_ok()) {
#[cfg(not(feature = "no-cfi"))]
cfi_assert!(key_pair.is_ok());
} else {
#[cfg(not(feature = "no-cfi"))]
cfi_assert!(key_pair.is_err());
}
let (priv_key, pub_key) = key_pair?;

let mut subj_serial = [0u8; DPE_PROFILE.get_hash_size() * 2];
env.crypto
Expand Down Expand Up @@ -109,6 +135,8 @@ impl CommandExecution for CertifyKeyCmd {
let mut cert = [0u8; MAX_CERT_SIZE];
let cert_size = match self.format {
Self::FORMAT_X509 => {
#[cfg(not(feature = "no-cfi"))]
cfi_assert_eq(self.format, Self::FORMAT_X509);
let mut tbs_buffer = [0u8; MAX_CERT_SIZE];
let mut tbs_writer = CertWriter::new(&mut tbs_buffer, true);
if issuer_len > MAX_ISSUER_NAME_SIZE {
Expand Down Expand Up @@ -141,15 +169,10 @@ impl CommandExecution for CertifyKeyCmd {
u32::try_from(bytes_written).map_err(|_| DpeErrorCode::InternalError)?
}
Self::FORMAT_CSR => {
if !dpe.support.csr() {
return Err(DpeErrorCode::ArgumentNotSupported);
}

#[cfg(not(feature = "no-cfi"))]
cfi_assert_eq(self.format, Self::FORMAT_CSR);
let mut cert_req_info_buffer = [0u8; MAX_CERT_SIZE];
let mut cert_req_info_writer = CertWriter::new(&mut cert_req_info_buffer, true);
if issuer_len > MAX_ISSUER_NAME_SIZE {
return Err(DpeErrorCode::InternalError);
}
let mut bytes_written = cert_req_info_writer.encode_certification_request_info(
&pub_key,
&subject_name,
Expand Down Expand Up @@ -230,6 +253,7 @@ mod tests {
dpe_instance::tests::{TestTypes, SIMULATION_HANDLE, TEST_LOCALITIES},
support::Support,
};
use caliptra_cfi_lib_git::CfiCounter;
use cms::{
content_info::{CmsVersion, ContentInfo},
signed_data::{SignedData, SignerIdentifier},
Expand Down Expand Up @@ -262,6 +286,7 @@ mod tests {

#[test]
fn test_deserialize_certify_key() {
CfiCounter::reset_for_test();
let mut command = CommandHdr::new_for_test(Command::CERTIFY_KEY)
.as_bytes()
.to_vec();
Expand All @@ -274,6 +299,7 @@ mod tests {

#[test]
fn test_certify_key_x509() {
CfiCounter::reset_for_test();
let mut env = DpeEnv::<TestTypes> {
crypto: OpensslCrypto::new(),
platform: DefaultPlatform,
Expand Down Expand Up @@ -314,6 +340,7 @@ mod tests {

#[test]
fn test_is_ca() {
CfiCounter::reset_for_test();
let mut env = DpeEnv::<TestTypes> {
crypto: OpensslCrypto::new(),
platform: DefaultPlatform,
Expand Down Expand Up @@ -385,6 +412,7 @@ mod tests {

#[test]
fn test_certify_key_csr() {
CfiCounter::reset_for_test();
let mut env = DpeEnv::<TestTypes> {
crypto: OpensslCrypto::new(),
platform: DefaultPlatform,
Expand Down
Loading

0 comments on commit a9020ee

Please sign in to comment.