use zeroize::Zeroizing;
use crate::error::{HsmError, HsmResult};
use crate::store::key_material::RawKeyMaterial;
fn generate_random_bytes(out: &mut [u8]) -> HsmResult<()> {
let mut drbg = crate::crypto::drbg::HmacDrbg::new()?;
drbg.generate(out)
}
use crate::crypto::drbg::DrbgRng;
pub fn generate_aes_key(key_len_bytes: usize, fips_mode: bool) -> HsmResult<RawKeyMaterial> {
match key_len_bytes {
16 | 24 | 32 => {}
_ => return Err(HsmError::KeySizeRange),
}
if fips_mode && key_len_bytes == 16 {
return Err(HsmError::MechanismParamInvalid);
}
let mut key = Zeroizing::new(vec![0u8; key_len_bytes]);
generate_random_bytes(&mut key)?;
Ok(RawKeyMaterial::new(key.to_vec()))
}
pub fn generate_rsa_key_pair(
modulus_bits: u32,
fips_mode: bool,
) -> HsmResult<(RawKeyMaterial, Vec<u8>, Vec<u8>)> {
use rsa::traits::PublicKeyParts;
use rsa::{pkcs8::EncodePrivateKey, RsaPrivateKey};
match modulus_bits {
2048 | 3072 | 4096 => {}
_ => return Err(HsmError::KeySizeRange),
}
if fips_mode && modulus_bits < 3072 {
return Err(HsmError::MechanismParamInvalid);
}
let mut rng = DrbgRng::new()?;
let private_key =
RsaPrivateKey::new(&mut rng, modulus_bits as usize).map_err(|_| HsmError::GeneralError)?;
let modulus = private_key.n().to_bytes_be();
let pub_exp = private_key.e().to_bytes_be();
let der = private_key
.to_pkcs8_der()
.map_err(|_| HsmError::GeneralError)?;
let result = RawKeyMaterial::new(der.as_bytes().to_vec());
Ok((result, modulus, pub_exp))
}
pub fn generate_ec_p256_key_pair() -> HsmResult<(RawKeyMaterial, Vec<u8>)> {
use elliptic_curve::sec1::ToEncodedPoint;
use p256::SecretKey;
let mut rng = DrbgRng::new()?;
let secret_key = SecretKey::random(&mut rng);
let public_key = secret_key.public_key();
let pub_point = public_key.to_encoded_point(false);
Ok((
RawKeyMaterial::new(secret_key.to_bytes().to_vec()),
pub_point.as_bytes().to_vec(),
))
}
pub fn generate_ec_p384_key_pair() -> HsmResult<(RawKeyMaterial, Vec<u8>)> {
use elliptic_curve::sec1::ToEncodedPoint;
use p384::SecretKey;
let mut rng = DrbgRng::new()?;
let secret_key = SecretKey::random(&mut rng);
let public_key = secret_key.public_key();
let pub_point = public_key.to_encoded_point(false);
Ok((
RawKeyMaterial::new(secret_key.to_bytes().to_vec()),
pub_point.as_bytes().to_vec(),
))
}
pub fn generate_ed25519_key_pair() -> HsmResult<(RawKeyMaterial, Vec<u8>)> {
use ed25519_dalek::SigningKey;
let mut rng = DrbgRng::new()?;
let signing_key = SigningKey::generate(&mut rng);
let verifying_key = signing_key.verifying_key();
Ok((
RawKeyMaterial::new(signing_key.to_bytes().to_vec()),
verifying_key.to_bytes().to_vec(),
))
}