usesuper::SymKey; usecrate::{err::Res, hpke::Aead as AeadId}; use aead::{AeadMut, Key, NewAead, Nonce, Payload}; use aes_gcm::{Aes128Gcm, Aes256Gcm}; use chacha20poly1305::ChaCha20Poly1305; use std::convert::TryFrom;
/// All the nonces are the same length. Exploit that. pubconst NONCE_LEN: usize = 12; const COUNTER_LEN: usize = 8; const TAG_LEN: usize = 16;
// Dispatch functions; this just shows how janky that this sort of abstraction can be. // If this grows too much, this is fairly clearly responsive to using a macro. impl AeadEngine { fn encrypt(&mutself, nonce: &[u8], pt: Payload) -> Res<Vec<u8>> { let tag = matchself { Self::Aes128Gcm(e) => e.encrypt(Nonce::<Aes128Gcm>::from_slice(nonce), pt)?, Self::Aes256Gcm(e) => e.encrypt(Nonce::<Aes256Gcm>::from_slice(nonce), pt)?, Self::ChaCha20Poly1305(e) => {
e.encrypt(Nonce::<ChaCha20Poly1305>::from_slice(nonce), pt)?
}
};
Ok(tag)
} fn decrypt(&mutself, nonce: &[u8], pt: Payload) -> Res<Vec<u8>> { let tag = matchself { Self::Aes128Gcm(e) => e.decrypt(Nonce::<Aes128Gcm>::from_slice(nonce), pt)?, Self::Aes256Gcm(e) => e.decrypt(Nonce::<Aes256Gcm>::from_slice(nonce), pt)?, Self::ChaCha20Poly1305(e) => {
e.decrypt(Nonce::<ChaCha20Poly1305>::from_slice(nonce), pt)?
}
};
Ok(tag)
}
}
/// A switch-hitting AEAD that uses a selected primitive. pubstruct Aead {
mode: Mode,
engine: AeadEngine,
nonce_base: [u8; NONCE_LEN],
seq: SequenceNumber,
}
pubfn seal(&mutself, aad: &[u8], pt: &[u8]) -> Res<Vec<u8>> {
assert_eq!(self.mode, Mode::Encrypt); // A copy for the nonce generator to write into. But we don't use the value. let nonce = self.nonce(self.seq); self.seq += 1; let ct = self.engine.encrypt(&nonce, Payload { msg: pt, aad })?;
Ok(ct)
}
#[cfg(test)] mod test { usesuper::{ super::super::{hpke::Aead as AeadId, init},
Aead, Mode, SequenceNumber, NONCE_LEN,
};
/// Check that the first invocation of encryption matches expected values. /// Also check decryption of the same. fn check0(
algorithm: AeadId,
key: &[u8],
nonce: &[u8; NONCE_LEN],
aad: &[u8],
pt: &[u8],
ct: &[u8],
) {
init(); let k = Aead::import_key(algorithm, key).unwrap();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.