hpke_rs_rust_crypto/
aead.rs1use alloc::{format, vec::Vec};
2
3use aes_gcm::{Aes128Gcm as RC_Aes128Gcm, Aes256Gcm as RC_Aes256Gcm};
4use chacha20poly1305::{
5 aead::{Aead, KeyInit, Payload},
6 ChaCha20Poly1305 as RC_ChaCha20Poly1305,
7};
8use hpke_rs_crypto::{error::Error, types::AeadAlgorithm, HpkeCrypto};
9
10use super::HpkeRustCrypto;
11
12macro_rules! implement_aead {
13 ($name_seal: ident, $name_open: ident, $name:ident, $algorithm:ident) => {
14 pub(crate) fn $name_seal(
15 key: &[u8],
16 nonce: &[u8],
17 aad: &[u8],
18 msg: &[u8],
19 ) -> Result<Vec<u8>, Error> {
20 if nonce.len() != 12 {
21 return Err(Error::AeadInvalidNonce);
22 }
23
24 let cipher = $algorithm::new_from_slice(key)
25 .map_err(|e| Error::CryptoLibraryError(format!("AEAD error: {:?}", e)))?;
26 cipher
27 .encrypt(nonce.into(), Payload { msg, aad })
28 .map_err(|e| Error::CryptoLibraryError(format!("AEAD error: {:?}", e)))
29 }
30 pub(crate) fn $name_open(
31 alg: AeadAlgorithm,
32 key: &[u8],
33 nonce: &[u8],
34 aad: &[u8],
35 msg: &[u8],
36 ) -> Result<Vec<u8>, Error> {
37 let nonce_length = HpkeRustCrypto::aead_nonce_length(alg);
38 if nonce.len() != nonce_length {
39 return Err(Error::AeadInvalidNonce);
40 }
41 let tag_length = HpkeRustCrypto::aead_tag_length(alg);
42 if msg.len() <= tag_length {
43 return Err(Error::AeadInvalidCiphertext);
44 }
45
46 let cipher = $algorithm::new_from_slice(key)
47 .map_err(|e| Error::CryptoLibraryError(format!("AEAD error: {:?}", e)))?;
48
49 cipher
50 .decrypt(nonce.into(), Payload { msg, aad })
51 .map_err(|_| Error::AeadOpenError)
52 }
53 };
54}
55
56implement_aead!(aes128_seal, aes128_open, AesGcm128, RC_Aes128Gcm);
57implement_aead!(aes256_seal, aes256_open, AesGcm256, RC_Aes256Gcm);
58implement_aead!(
59 chacha_seal,
60 chacha_open,
61 ChaCha20Poly1305,
62 RC_ChaCha20Poly1305
63);