Skip to content

Commit

Permalink
Use an "exported" variant of derive_cdi and export_key_pair to distin…
Browse files Browse the repository at this point in the history
…guish the exported CDI from the DPE CDI. Use this new API to create the exported CDIs keypair
  • Loading branch information
clundin25 committed Jan 3, 2025
1 parent c81cc70 commit 392b65f
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 47 deletions.
69 changes: 50 additions & 19 deletions crypto/src/openssl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,35 @@ impl OpensslCrypto {

EcKey::from_private_components(&group, priv_key_bn, &pub_point)
}

fn derive_key_pair_inner(
&mut self,
algs: AlgLen,
cdi: &<OpensslCrypto as Crypto>::Cdi,
label: &[u8],
info: &[u8],
) -> Result<(<OpensslCrypto as Crypto>::PrivKey, EcdsaPub), CryptoError> {
let priv_key = hkdf_get_priv_key(algs, cdi, label, info)?;

let ec_priv_key = OpensslCrypto::ec_key_from_priv_key(algs, &priv_key)?;
let nid = OpensslCrypto::get_curve(algs);

let group = EcGroup::from_curve_name(nid).unwrap();
let mut bn_ctx = BigNumContext::new().unwrap();

let mut x = BigNum::new().unwrap();
let mut y = BigNum::new().unwrap();

ec_priv_key
.public_key()
.affine_coordinates(&group, &mut x, &mut y, &mut bn_ctx)
.unwrap();

let x = CryptoBuf::new(&x.to_vec_padded(algs.size() as i32).unwrap()).unwrap();
let y = CryptoBuf::new(&y.to_vec_padded(algs.size() as i32).unwrap()).unwrap();

Ok((priv_key, EcdsaPub { x, y }))
}
}

impl Default for OpensslCrypto {
Expand Down Expand Up @@ -133,6 +162,16 @@ impl Crypto for OpensslCrypto {
hkdf_derive_cdi(algs, measurement, info)
}

#[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)]
fn derive_cdi_exported(
&mut self,
algs: AlgLen,
measurement: &Digest,
info: &[u8],
) -> Result<Self::Cdi, CryptoError> {
hkdf_derive_cdi(algs, measurement, info)
}

#[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)]
fn derive_key_pair(
&mut self,
Expand All @@ -141,26 +180,18 @@ impl Crypto for OpensslCrypto {
label: &[u8],
info: &[u8],
) -> Result<(Self::PrivKey, EcdsaPub), CryptoError> {
let priv_key = hkdf_get_priv_key(algs, cdi, label, info)?;

let ec_priv_key = OpensslCrypto::ec_key_from_priv_key(algs, &priv_key)?;
let nid = OpensslCrypto::get_curve(algs);

let group = EcGroup::from_curve_name(nid).unwrap();
let mut bn_ctx = BigNumContext::new().unwrap();

let mut x = BigNum::new().unwrap();
let mut y = BigNum::new().unwrap();

ec_priv_key
.public_key()
.affine_coordinates(&group, &mut x, &mut y, &mut bn_ctx)
.unwrap();

let x = CryptoBuf::new(&x.to_vec_padded(algs.size() as i32).unwrap()).unwrap();
let y = CryptoBuf::new(&y.to_vec_padded(algs.size() as i32).unwrap()).unwrap();
self.derive_key_pair_inner(algs, cdi, label, info)
}

Ok((priv_key, EcdsaPub { x, y }))
#[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)]
fn derive_key_pair_exported(
&mut self,
algs: AlgLen,
cdi: &Self::Cdi,
label: &[u8],
info: &[u8],
) -> Result<(Self::PrivKey, EcdsaPub), CryptoError> {
self.derive_key_pair_inner(algs, cdi, label, info)
}

fn ecdsa_sign_with_alias(
Expand Down
67 changes: 48 additions & 19 deletions crypto/src/rustcrypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,34 @@ impl RustCryptoImpl {
let seeded_rng = StdRng::from_seed(SEED);
RustCryptoImpl(seeded_rng)
}

fn derive_key_pair_inner(
&mut self,
algs: AlgLen,
cdi: &<RustCryptoImpl as Crypto>::Cdi,
label: &[u8],
info: &[u8],
) -> Result<(<RustCryptoImpl as Crypto>::PrivKey, EcdsaPub), CryptoError> {
let secret = hkdf_get_priv_key(algs, cdi, label, info)?;
match algs {
AlgLen::Bit256 => {
let signing = p256::ecdsa::SigningKey::from_slice(&secret.bytes())?;
let verifying = p256::ecdsa::VerifyingKey::from(&signing);
let point = verifying.to_encoded_point(false);
let x = CryptoBuf::new(point.x().ok_or(RUSTCRYPTO_ECDSA_ERROR)?.as_slice())?;
let y = CryptoBuf::new(point.y().ok_or(RUSTCRYPTO_ECDSA_ERROR)?.as_slice())?;
Ok((secret, EcdsaPub { x, y }))
}
AlgLen::Bit384 => {
let signing = p384::ecdsa::SigningKey::from_slice(&secret.bytes())?;
let verifying = p384::ecdsa::VerifyingKey::from(&signing);
let point = verifying.to_encoded_point(false);
let x = CryptoBuf::new(point.x().ok_or(RUSTCRYPTO_ECDSA_ERROR)?.as_slice())?;
let y = CryptoBuf::new(point.y().ok_or(RUSTCRYPTO_ECDSA_ERROR)?.as_slice())?;
Ok((secret, EcdsaPub { x, y }))
}
}
}
}

impl Crypto for RustCryptoImpl {
Expand Down Expand Up @@ -96,32 +124,33 @@ impl Crypto for RustCryptoImpl {
hkdf_derive_cdi(algs, measurement, info)
}

fn derive_cdi_exported(
&mut self,
algs: AlgLen,
measurement: &Digest,
info: &[u8],
) -> Result<Self::Cdi, CryptoError> {
hkdf_derive_cdi(algs, measurement, info)
}

fn derive_key_pair(
&mut self,
algs: AlgLen,
cdi: &Self::Cdi,
label: &[u8],
info: &[u8],
) -> Result<(Self::PrivKey, EcdsaPub), CryptoError> {
let secret = hkdf_get_priv_key(algs, cdi, label, info)?;
match algs {
AlgLen::Bit256 => {
let signing = p256::ecdsa::SigningKey::from_slice(&secret.bytes())?;
let verifying = p256::ecdsa::VerifyingKey::from(&signing);
let point = verifying.to_encoded_point(false);
let x = CryptoBuf::new(point.x().ok_or(RUSTCRYPTO_ECDSA_ERROR)?.as_slice())?;
let y = CryptoBuf::new(point.y().ok_or(RUSTCRYPTO_ECDSA_ERROR)?.as_slice())?;
Ok((secret, EcdsaPub { x, y }))
}
AlgLen::Bit384 => {
let signing = p384::ecdsa::SigningKey::from_slice(&secret.bytes())?;
let verifying = p384::ecdsa::VerifyingKey::from(&signing);
let point = verifying.to_encoded_point(false);
let x = CryptoBuf::new(point.x().ok_or(RUSTCRYPTO_ECDSA_ERROR)?.as_slice())?;
let y = CryptoBuf::new(point.y().ok_or(RUSTCRYPTO_ECDSA_ERROR)?.as_slice())?;
Ok((secret, EcdsaPub { x, y }))
}
}
self.derive_key_pair_inner(algs, cdi, label, info)
}

fn derive_key_pair_exported(
&mut self,
algs: AlgLen,
cdi: &Self::Cdi,
label: &[u8],
info: &[u8],
) -> Result<(Self::PrivKey, EcdsaPub), CryptoError> {
self.derive_key_pair_inner(algs, cdi, label, info)
}

fn ecdsa_sign_with_alias(
Expand Down
27 changes: 18 additions & 9 deletions dpe/src/commands/derive_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,12 +300,19 @@ impl CommandExecution for DeriveContextCmd {
let digest = dpe.compute_measurement_hash(env, parent_idx)?;
let cdi = env
.crypto
.derive_cdi(DPE_PROFILE.alg_len(), &digest, b"DPE")?;
.derive_cdi(DPE_PROFILE.alg_len(), &digest, b"Exported CDI")?;

let mut exported_cdi_handle = [0; MAX_EXPORTED_CDI_SIZE];
env.crypto
.rand_bytes(&mut exported_cdi_handle)
.map_err(DpeErrorCode::Crypto)?;

let key_label = b"Exported ECC"; // TODO(clundin): Is this an appropriate
// label?
let key_pair =
env.crypto
.derive_key_pair(algs, &cdi, &[0xA; DPE_PROFILE.get_hash_size()], b"ECC");
let (_, pub_key) = key_pair?;
.derive_key_pair_exported(algs, &cdi, key_label, &exported_cdi_handle);
let (priv_key, pub_key) = key_pair?;

let mut subj_serial = [0u8; DPE_PROFILE.get_hash_size() * 2];
env.crypto
Expand Down Expand Up @@ -352,7 +359,7 @@ impl CommandExecution for DeriveContextCmd {
};

let measurements = MeasurementData {
label: &[0xA; DPE_PROFILE.get_hash_size()], //TODO(clundin): Determine correct label
label: key_label, //TODO(clundin): Determine correct label
tci_nodes: &nodes[..tcb_count],
is_ca: true,
supports_recursive: false,
Expand Down Expand Up @@ -387,9 +394,12 @@ impl CommandExecution for DeriveContextCmd {
let tbs_digest = env
.crypto
.hash(DPE_PROFILE.alg_len(), &tbs_buffer[..bytes_written])?;
let sig = env
.crypto
.ecdsa_sign_with_alias(DPE_PROFILE.alg_len(), &tbs_digest)?;
let sig = env.crypto.ecdsa_sign_with_derived(
DPE_PROFILE.alg_len(),
&tbs_digest,
&priv_key,
&pub_key,
)?;

let mut cert_writer = CertWriter::new(&mut cert, true);
bytes_written =
Expand All @@ -400,8 +410,7 @@ impl CommandExecution for DeriveContextCmd {
handle: ContextHandle::new_invalid(),
parent_handle: dpe.contexts[parent_idx].handle,
resp_hdr: ResponseHdr::new(DpeErrorCode::NoError),
exported_cdi: [0; MAX_EXPORTED_CDI_SIZE], // TODO(clundin): Implement CDI storage
// behind a Platform trait.
exported_cdi: exported_cdi_handle,
certificate_size: cert_size,
new_certificate: cert,
}))
Expand Down

0 comments on commit 392b65f

Please sign in to comment.