use oxicrypto::Aead as CryptoAead;
use oxicrypto_adapter_aws_lc::aead::AwsLcAead;
use crate::aead::Aead as StoreAead;
use crate::EncryptError;
#[derive(Debug, Clone, Copy)]
pub struct AwsLcOxistoreAead {
inner: AwsLcAead,
}
impl AwsLcOxistoreAead {
pub fn aes256_gcm_siv() -> Self {
Self {
inner: AwsLcAead::aes256_gcm_siv(),
}
}
pub fn aes256_gcm() -> Self {
Self {
inner: AwsLcAead::aes256_gcm(),
}
}
pub fn chacha20_poly1305() -> Self {
Self {
inner: AwsLcAead::chacha20_poly1305(),
}
}
}
impl StoreAead for AwsLcOxistoreAead {
fn nonce_len(&self) -> usize {
CryptoAead::nonce_len(&self.inner)
}
fn tag_len(&self) -> usize {
CryptoAead::tag_len(&self.inner)
}
fn seal(
&self,
key: &[u8; 32],
nonce: &[u8],
aad: &[u8],
pt: &[u8],
) -> Result<Vec<u8>, EncryptError> {
let tag_len = CryptoAead::tag_len(&self.inner);
let out_len = pt
.len()
.checked_add(tag_len)
.ok_or(EncryptError::RngFailed)?;
let mut out = vec![0u8; out_len];
CryptoAead::seal(&self.inner, key.as_slice(), nonce, aad, pt, &mut out)
.map_err(|e| EncryptError::EncryptionFailed(e.to_string()))?;
Ok(out)
}
fn open(
&self,
key: &[u8; 32],
nonce: &[u8],
aad: &[u8],
ct: &[u8],
) -> Result<Vec<u8>, EncryptError> {
let tag_len = CryptoAead::tag_len(&self.inner);
if ct.len() < tag_len {
return Err(EncryptError::CiphertextTooShort {
min_expected: tag_len,
got: ct.len(),
});
}
let pt_len = ct.len() - tag_len;
let mut pt = vec![0u8; pt_len];
CryptoAead::open(&self.inner, key.as_slice(), nonce, aad, ct, &mut pt)
.map_err(|_| EncryptError::AuthenticationFailed)?;
Ok(pt)
}
}