hpke_rs_rust_crypto/
aead.rs

1use 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);