bitwarden_crypto/hazmat/symmetric_encryption/mod.rs
1//! # Symmetric key encryption
2//!
3//! Low-level ("hazmat") authenticated symmetric ciphers, exposed behind two traits:
4//! - [`Aead`]: authenticated encryption *with* associated data. Implemented by AES-256-GCM
5//! ([`Aes256Gcm`]), XAES-256-GCM ([`XAes256Gcm`]), and XChaCha20-Poly1305
6//! ([`XChaCha20Poly1305`]).
7//!
8//! These are dangerous primitives that operate directly on raw key material. In most cases you
9//! should use the higher-level [`safe`](crate::safe) module (e.g. the password-protected key
10//! envelope or data envelope) instead.
11
12use crate::CryptoError;
13pub(crate) mod aes_gcm;
14pub(crate) mod xaes_256_gcm;
15pub(crate) mod xchacha20;
16
17#[allow(unused_imports)]
18pub(crate) use aes_gcm::Aes256Gcm;
19#[allow(unused_imports)]
20pub(crate) use xaes_256_gcm::XAes256Gcm;
21#[allow(unused_imports)]
22pub(crate) use xchacha20::XChaCha20Poly1305;
23
24/// Authenticated encryption **with** associated data (AEAD).
25///
26/// In addition to encrypting and authenticating the plaintext, a cipher implementing this trait
27/// authenticates (but does not encrypt) caller-supplied associated data. The exact same associated
28/// data must be supplied to [`decrypt`](Aead::decrypt) for authentication to succeed.
29#[allow(dead_code)]
30pub(crate) trait Aead {
31 /// Key material used by the cipher.
32 type Key;
33 /// Authenticated ciphertext (the encrypted bytes). The nonce is tracked separately, by the
34 /// caller.
35 type Ciphertext;
36 /// The per-message nonce. A fresh nonce must be supplied for every encryption under a given
37 /// key.
38 type Nonce;
39
40 /// Encrypts `plaintext` under `key` with `nonce`, authenticating `associated_data` along with
41 /// the ciphertext.
42 ///
43 /// The same `nonce` must be supplied to [`decrypt`](Aead::decrypt). A fresh nonce must be used
44 /// for every message encrypted under a given key.
45 fn encrypt(
46 key: &Self::Key,
47 nonce: &Self::Nonce,
48 plaintext: &[u8],
49 associated_data: &[u8],
50 ) -> Self::Ciphertext;
51
52 /// Authenticates and decrypts `ciphertext` under `key` with `nonce`, verifying
53 /// `associated_data`.
54 ///
55 /// Returns [`CryptoError::KeyDecrypt`] if authentication fails (including a mismatch of
56 /// `associated_data` or `nonce`) or the ciphertext is malformed.
57 fn decrypt(
58 key: &Self::Key,
59 nonce: &Self::Nonce,
60 ciphertext: &Self::Ciphertext,
61 associated_data: &[u8],
62 ) -> Result<Vec<u8>, CryptoError>;
63}