1 // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 // Copyright by contributors to this project. 3 // SPDX-License-Identifier: (Apache-2.0 OR MIT) 4 5 #[cfg(feature = "mock")] 6 use mockall::automock; 7 8 use alloc::vec::Vec; 9 use mls_rs_core::{crypto::CipherSuite, error::IntoAnyError}; 10 11 pub const AEAD_ID_EXPORT_ONLY: u16 = 0xFFFF; 12 pub const AES_TAG_LEN: usize = 16; 13 14 /// A trait that provides the required AEAD functions 15 #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] 16 #[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))] 17 #[cfg_attr( 18 all(not(target_arch = "wasm32"), mls_build_async), 19 maybe_async::must_be_async 20 )] 21 #[cfg_attr(feature = "mock", automock(type Error = crate::mock::TestError;))] 22 pub trait AeadType: Send + Sync { 23 type Error: IntoAnyError; 24 aead_id(&self) -> u1625 fn aead_id(&self) -> u16; 26 27 #[allow(clippy::needless_lifetimes)] seal<'a>( &self, key: &[u8], data: &[u8], aad: Option<&'a [u8]>, nonce: &[u8], ) -> Result<Vec<u8>, Self::Error>28 async fn seal<'a>( 29 &self, 30 key: &[u8], 31 data: &[u8], 32 aad: Option<&'a [u8]>, 33 nonce: &[u8], 34 ) -> Result<Vec<u8>, Self::Error>; 35 36 #[allow(clippy::needless_lifetimes)] open<'a>( &self, key: &[u8], ciphertext: &[u8], aad: Option<&'a [u8]>, nonce: &[u8], ) -> Result<Vec<u8>, Self::Error>37 async fn open<'a>( 38 &self, 39 key: &[u8], 40 ciphertext: &[u8], 41 aad: Option<&'a [u8]>, 42 nonce: &[u8], 43 ) -> Result<Vec<u8>, Self::Error>; 44 key_size(&self) -> usize45 fn key_size(&self) -> usize; nonce_size(&self) -> usize46 fn nonce_size(&self) -> usize; 47 } 48 49 /// AEAD Id, as specified in RFC 9180, Section 5.1 and Table 5. 50 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 51 #[repr(u16)] 52 #[non_exhaustive] 53 pub enum AeadId { 54 /// AES-128-GCM: 16 byte key, 12 byte nonce, 16 byte tag 55 Aes128Gcm = 0x0001, 56 /// AES-256-GCM: 32 byte key, 12 byte nonce, 16 byte tag 57 Aes256Gcm = 0x0002, 58 /// ChaCha20-Poly1305: 32 byte key, 12 byte nonce, 16 byte tag 59 Chacha20Poly1305 = 0x0003, 60 } 61 62 impl AeadId { new(cipher_suite: CipherSuite) -> Option<Self>63 pub fn new(cipher_suite: CipherSuite) -> Option<Self> { 64 match cipher_suite { 65 CipherSuite::P256_AES128 | CipherSuite::CURVE25519_AES128 => Some(AeadId::Aes128Gcm), 66 CipherSuite::CURVE448_AES256 | CipherSuite::P384_AES256 | CipherSuite::P521_AES256 => { 67 Some(AeadId::Aes256Gcm) 68 } 69 CipherSuite::CURVE25519_CHACHA | CipherSuite::CURVE448_CHACHA => { 70 Some(AeadId::Chacha20Poly1305) 71 } 72 _ => None, 73 } 74 } 75 key_size(&self) -> usize76 pub fn key_size(&self) -> usize { 77 match self { 78 AeadId::Aes128Gcm => 16, 79 AeadId::Aes256Gcm => 32, 80 AeadId::Chacha20Poly1305 => 32, 81 } 82 } 83 nonce_size(&self) -> usize84 pub fn nonce_size(&self) -> usize { 85 12 86 } 87 } 88