Skip to content

Commit

Permalink
Add CA certificate generation to DeriveContextCmd
Browse files Browse the repository at this point in the history
  • Loading branch information
clundin25 committed Jan 10, 2025
1 parent 661f64d commit 1b38a44
Show file tree
Hide file tree
Showing 15 changed files with 1,079 additions and 203 deletions.
66 changes: 66 additions & 0 deletions crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,20 @@ pub trait Crypto {
info: &[u8],
) -> Result<Self::Cdi, CryptoError>;

/// Derive a CDI for an exported private key based on the current base CDI and measurements
///
/// # Arguments
///
/// * `algs` - Which length of algorithms to use.
/// * `measurement` - A digest of the measurements which should be used for CDI derivation
/// * `info` - Caller-supplied info string to use in CDI derivation
fn derive_exported_cdi(
&mut self,
algs: AlgLen,
measurement: &Digest,
info: &[u8],
) -> Result<Self::Cdi, CryptoError>;

/// CFI wrapper around derive_cdi
///
/// To implement this function, you need to add the
Expand All @@ -182,6 +196,28 @@ pub trait Crypto {
info: &[u8],
) -> Result<Self::Cdi, CryptoError>;

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

/// Retrieves the CDI for an exported private key.
fn get_exported_cdi(&mut self) -> Result<Self::Cdi, CryptoError>;

/// CFI wrapper around get_exported_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_get_exported_cdi(&mut self) -> Result<Self::Cdi, CryptoError>;

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

/// Derives an exported key pair using a cryptographically secure KDF
///
/// # Arguments
///
/// * `algs` - Which length of algorithms to use.
/// * `cdi` - Caller-supplied private key to use in public key derivation
/// * `label` - Caller-supplied label to use in asymmetric key derivation
/// * `info` - Caller-supplied info string to use in asymmetric key derivation
///
fn derive_key_pair_exported(
&mut self,
algs: AlgLen,
cdi: &Self::Cdi,
label: &[u8],
info: &[u8],
) -> Result<(Self::PrivKey, EcdsaPub), CryptoError>;

/// CFI wrapper around derive_key_pair
///
/// To implement this function, you need to add the
Expand All @@ -212,6 +265,19 @@ pub trait Crypto {
info: &[u8],
) -> Result<(Self::PrivKey, EcdsaPub), CryptoError>;

/// CFI wrapper around derive_key_pair_exported
///
/// 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_exported(
&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
101 changes: 76 additions & 25 deletions crypto/src/openssl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,31 @@ impl Hasher for OpensslHasher {
}

#[cfg(feature = "deterministic_rand")]
pub struct OpensslCrypto(StdRng);
pub struct OpensslCrypto {
rng: StdRng,
// Cached CDI for exported CDI operations.
exported_cdi: Option<Vec<u8>>,
}

#[cfg(not(feature = "deterministic_rand"))]
pub struct OpensslCrypto;
pub struct OpensslCrypto {
exported_cdi: Option<Vec<u8>>,
}

impl OpensslCrypto {
#[cfg(feature = "deterministic_rand")]
pub fn new() -> Self {
const SEED: [u8; 32] = [1; 32];
let seeded_rng = StdRng::from_seed(SEED);
OpensslCrypto(seeded_rng)
OpensslCrypto {
rng: seeded_rng,
exported_cdi: None,
}
}

#[cfg(not(feature = "deterministic_rand"))]
pub fn new() -> Self {
Self {}
Self { exported_cdi: None }
}

fn get_digest(algs: AlgLen) -> MessageDigest {
Expand Down Expand Up @@ -90,6 +99,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 All @@ -112,7 +150,7 @@ impl Crypto for OpensslCrypto {

#[cfg(feature = "deterministic_rand")]
fn rand_bytes(&mut self, dst: &mut [u8]) -> Result<(), CryptoError> {
StdRng::fill_bytes(&mut self.0, dst);
StdRng::fill_bytes(&mut self.rng, dst);
Ok(())
}

Expand All @@ -133,7 +171,28 @@ impl Crypto for OpensslCrypto {
measurement: &Digest,
info: &[u8],
) -> Result<Self::Cdi, CryptoError> {
hkdf_derive_cdi(algs, measurement, info)
let cdi = hkdf_derive_cdi(algs, measurement, info)?;
self.exported_cdi = Some(cdi.clone());
Ok(cdi)
}

#[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)]
fn derive_exported_cdi(
&mut self,
algs: AlgLen,
measurement: &Digest,
info: &[u8],
) -> Result<Self::Cdi, CryptoError> {
let cdi = hkdf_derive_cdi(algs, measurement, info)?;
self.exported_cdi = Some(cdi.clone());
Ok(cdi)
}

#[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)]
fn get_exported_cdi(&mut self) -> Result<Self::Cdi, CryptoError> {
self.exported_cdi
.clone()
.ok_or(CryptoError::CryptoLibError(0))
}

#[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)]
Expand All @@ -144,26 +203,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
Loading

0 comments on commit 1b38a44

Please sign in to comment.