use alloc::vec::Vec;
use crate::CryptoError;
pub trait Aead: Send + Sync + crate::traits::MaybeDebug {
#[must_use]
fn name(&self) -> &'static str;
#[must_use]
fn key_len(&self) -> usize;
#[must_use]
fn nonce_len(&self) -> usize;
#[must_use]
fn tag_len(&self) -> usize;
#[must_use = "result must be checked"]
fn seal(
&self,
key: &[u8],
nonce: &[u8],
aad: &[u8],
pt: &[u8],
ct_out: &mut [u8],
) -> Result<usize, CryptoError>;
#[must_use = "result must be checked"]
fn open(
&self,
key: &[u8],
nonce: &[u8],
aad: &[u8],
ct: &[u8],
pt_out: &mut [u8],
) -> Result<usize, CryptoError>;
#[must_use = "result must be checked"]
fn seal_to_vec(
&self,
key: &[u8],
nonce: &[u8],
aad: &[u8],
plaintext: &[u8],
) -> Result<Vec<u8>, CryptoError> {
let mut out = alloc::vec![0u8; plaintext.len() + self.tag_len()];
self.seal(key, nonce, aad, plaintext, &mut out)?;
Ok(out)
}
#[must_use = "result must be checked"]
fn open_to_vec(
&self,
key: &[u8],
nonce: &[u8],
aad: &[u8],
ciphertext: &[u8],
) -> Result<Vec<u8>, CryptoError> {
let tag_len = self.tag_len();
if ciphertext.len() < tag_len {
return Err(CryptoError::BufferTooSmall);
}
let mut out = alloc::vec![0u8; ciphertext.len() - tag_len];
self.open(key, nonce, aad, ciphertext, &mut out)?;
Ok(out)
}
#[must_use = "result must be checked"]
fn seal_detached(
&self,
key: &[u8],
nonce: &[u8],
aad: &[u8],
pt: &[u8],
ct_out: &mut [u8],
) -> Result<alloc::vec::Vec<u8>, CryptoError> {
if ct_out.len() != pt.len() {
return Err(CryptoError::BadInput);
}
let combined_len = pt
.len()
.checked_add(self.tag_len())
.ok_or(CryptoError::BadInput)?;
let mut combined = alloc::vec![0u8; combined_len];
self.seal(key, nonce, aad, pt, &mut combined)?;
ct_out.copy_from_slice(&combined[..pt.len()]);
Ok(combined[pt.len()..].to_vec())
}
#[must_use = "result must be checked"]
fn open_detached(
&self,
key: &[u8],
nonce: &[u8],
aad: &[u8],
ct: &[u8],
tag: &[u8],
pt_out: &mut [u8],
) -> Result<(), CryptoError> {
let combined_len = ct
.len()
.checked_add(tag.len())
.ok_or(CryptoError::BadInput)?;
let mut combined = alloc::vec![0u8; combined_len];
combined[..ct.len()].copy_from_slice(ct);
combined[ct.len()..].copy_from_slice(tag);
let n = self.open(key, nonce, aad, &combined, pt_out)?;
let _ = n;
Ok(())
}
fn max_plaintext_len(&self) -> u64 {
u64::MAX
}
#[must_use = "result must be checked"]
fn seal_in_place(
&self,
key: &[u8],
nonce: &[u8],
aad: &[u8],
buf: &mut alloc::vec::Vec<u8>,
) -> Result<(), CryptoError> {
let pt_len = buf.len();
let ct_len = pt_len
.checked_add(self.tag_len())
.ok_or(CryptoError::BadInput)?;
let pt = buf[..pt_len].to_vec();
buf.resize(ct_len, 0u8);
self.seal(key, nonce, aad, &pt, buf)?;
Ok(())
}
}
pub trait StreamingAead: Sized + Send {
#[must_use = "result must be checked"]
fn init(key: &[u8], nonce: &[u8], aad: &[u8]) -> Result<Self, CryptoError>;
#[must_use = "result must be checked"]
fn encrypt_update(&mut self, chunk: &[u8], out: &mut [u8]) -> Result<usize, CryptoError>;
#[must_use = "result must be checked"]
fn encrypt_finalize(self, out: &mut [u8]) -> Result<[u8; 16], CryptoError>;
#[must_use = "result must be checked"]
fn decrypt_update(&mut self, chunk: &[u8], out: &mut [u8]) -> Result<usize, CryptoError>;
#[must_use = "result must be checked"]
fn decrypt_finalize(self, expected_tag: &[u8]) -> Result<(), CryptoError>;
fn reset(&mut self);
}