1use aes_gcm::aead::{Aead, KeyInit, Payload};
8use aes_gcm::{Aes256Gcm, Key, Nonce};
9
10use crate::Error;
11
12pub fn seal(
14 key: &[u8; 32],
15 nonce: &[u8; 12],
16 aad: &[u8],
17 plaintext: &[u8],
18) -> Result<Vec<u8>, Error> {
19 let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(key));
20 cipher
21 .encrypt(
22 Nonce::from_slice(nonce),
23 Payload {
24 msg: plaintext,
25 aad,
26 },
27 )
28 .map_err(|_| Error::Aead)
29}
30
31pub fn open(
33 key: &[u8; 32],
34 nonce: &[u8; 12],
35 aad: &[u8],
36 ciphertext: &[u8],
37) -> Result<Vec<u8>, Error> {
38 let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(key));
39 cipher
40 .decrypt(
41 Nonce::from_slice(nonce),
42 Payload {
43 msg: ciphertext,
44 aad,
45 },
46 )
47 .map_err(|_| Error::Aead)
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 fn key() -> [u8; 32] {
55 [9u8; 32]
56 }
57 fn nonce() -> [u8; 12] {
58 [3u8; 12]
59 }
60
61 #[test]
62 fn roundtrip() {
63 let k = key();
64 let n = nonce();
65 let ct = seal(&k, &n, b"context", b"plaintext").unwrap();
66 let pt = open(&k, &n, b"context", &ct).unwrap();
67 assert_eq!(pt, b"plaintext");
68 }
69
70 #[test]
71 fn empty_plaintext_roundtrips() {
72 let k = key();
73 let n = nonce();
74 let ct = seal(&k, &n, b"", b"").unwrap();
75 let pt = open(&k, &n, b"", &ct).unwrap();
76 assert!(pt.is_empty());
77 }
78
79 #[test]
80 fn tampered_ciphertext_rejected() {
81 let k = key();
82 let n = nonce();
83 let mut ct = seal(&k, &n, b"", b"plaintext").unwrap();
84 ct[0] ^= 0x01;
85 assert!(matches!(open(&k, &n, b"", &ct).unwrap_err(), Error::Aead));
86 }
87
88 #[test]
89 fn wrong_aad_rejected() {
90 let k = key();
91 let n = nonce();
92 let ct = seal(&k, &n, b"context-a", b"plaintext").unwrap();
93 assert!(matches!(
94 open(&k, &n, b"context-b", &ct).unwrap_err(),
95 Error::Aead
96 ));
97 }
98
99 #[test]
100 fn wrong_key_rejected() {
101 let n = nonce();
102 let ct = seal(&[1u8; 32], &n, b"", b"plaintext").unwrap();
103 assert!(matches!(
104 open(&[2u8; 32], &n, b"", &ct).unwrap_err(),
105 Error::Aead
106 ));
107 }
108}