use std::sync::OnceLock;
pub trait AeadGcm: Send + Sync {
fn seal(&self, nonce: &[u8; 12], aad: &[u8], buf: &mut [u8]) -> [u8; 16];
fn open_compute_tag(&self, nonce: &[u8; 12], aad: &[u8], buf: &mut [u8]) -> [u8; 16];
fn clone_box(&self) -> Box<dyn AeadGcm>;
}
pub trait AeadOps: Send + Sync {
fn name(&self) -> &'static str;
fn aes128_gcm(&self, key: &[u8; 16]) -> Box<dyn AeadGcm>;
fn aes256_gcm(&self, key: &[u8; 32]) -> Box<dyn AeadGcm>;
}
pub type Sha256Compress = fn(h: &mut [u32; 8], block: &[u8; 64]);
pub trait HashOps: Send + Sync {
fn name(&self) -> &'static str;
fn sha256_compress(&self) -> Sha256Compress;
}
static AEAD_BACKEND: OnceLock<&'static dyn AeadOps> = OnceLock::new();
static HASH_BACKEND: OnceLock<&'static dyn HashOps> = OnceLock::new();
pub fn install(backend: &'static dyn AeadOps) -> Result<(), crate::Error> {
if crate::policy::fips_mode_enabled() {
return Err(crate::Error::Unsupported);
}
AEAD_BACKEND
.set(backend)
.map_err(|_| crate::Error::Unsupported)
}
pub fn installed_aead() -> Option<&'static dyn AeadOps> {
AEAD_BACKEND.get().copied()
}
pub fn install_hash(backend: &'static dyn HashOps) -> Result<(), crate::Error> {
if crate::policy::fips_mode_enabled() {
return Err(crate::Error::Unsupported);
}
HASH_BACKEND
.set(backend)
.map_err(|_| crate::Error::Unsupported)
}
pub fn installed_hash() -> Option<&'static dyn HashOps> {
HASH_BACKEND.get().copied()
}
pub(crate) fn current_sha256_compress() -> Sha256Compress {
match HASH_BACKEND.get() {
Some(backend) => backend.sha256_compress(),
None => crate::sha2::compress256,
}
}