pub trait AeadProvider {
type Algorithm: AeadAlgorithm;
type Key: Sized;
type Tag: Sized + AsRef<[u8]>;
fn load_from_keydata(&mut self, alg: Self::Algorithm, key: &[u8]) -> Self::Key;
fn encrypt_in_place(
&mut self,
key: &Self::Key,
nonce: &[u8],
message: &mut [u8],
aad: impl AadGenerator,
) -> Self::Tag;
#[must_use = "message must not be accessed after a failed decryption"]
fn decrypt_in_place(
&mut self,
key: &Self::Key,
nonce: &[u8],
message: &mut [u8],
tag: &[u8],
aad: impl AadGenerator,
) -> Result<(), DecryptionFailed>;
}
#[derive(Debug)]
pub struct DecryptionFailed;
impl core::fmt::Display for DecryptionFailed {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("decryption failed")
}
}
impl core::error::Error for DecryptionFailed {}
pub trait AeadAlgorithm: Sized + PartialEq + Eq + core::fmt::Debug + Clone {
fn key_length(&self) -> usize;
fn tag_length(&self) -> usize;
fn nonce_length(&self) -> usize;
#[inline]
#[allow(
unused_variables,
reason = "Argument names are part of the documentation"
)]
fn from_cose_number(number: impl Into<i128>) -> Option<Self> {
None
}
}
pub trait AadGenerator {
fn items(&self) -> impl Iterator<Item = &[u8]>;
}
impl AadGenerator for &[u8] {
fn items(&self) -> impl Iterator<Item = &[u8]> {
[*self].into_iter()
}
}
impl AadGenerator for &[&[u8]] {
fn items(&self) -> impl Iterator<Item = &[u8]> {
self.iter().copied()
}
}
pub fn test_aead_algorithm_aesccm_16_64_128<AP: AeadProvider>() {
let cose_10 = AP::Algorithm::from_cose_number(10i8).expect(
"test for type claiming AES-CCM-16-64-128 compatibility did not recognize COSE number 10",
);
assert_eq!(cose_10.tag_length(), 8)
}