// 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, #[allow(dead_code, reason = "Used by stream feature")]
algorithm: AeadId,
engine: AeadEngine,
nonce_base: [u8; NONCE_LEN],
seq: SequenceNumber,
}
impl Decrypt for Aead { fn open(&mutself, aad: &[u8], ct: &[u8]) -> Res<Vec<u8>> { let res = self.open_seq(aad, self.seq, ct); self.seq += 1;
res
}
fn alg(&self) -> AeadId { self.algorithm
}
}
impl Encrypt for Aead { fn 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)
}
fn alg(&self) -> AeadId { self.algorithm
}
}
#[cfg(test)] mod test { usesuper::SequenceNumber; usecrate::{
crypto::{Decrypt, Encrypt},
hpke::Aead as AeadId,
init, Aead, Mode, 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.