1use ring::aead::{
2 AES_256_GCM, Aad, BoundKey, NONCE_LEN, Nonce, NonceSequence, OpeningKey, SealingKey, Tag,
3 UnboundKey,
4};
5
6#[derive(Clone, Copy)]
7struct Counter(u64, u64);
8
9impl Default for Counter {
10 fn default() -> Self {
11 Self(0, u64::from(u32::MAX))
12 }
13}
14
15impl Counter {
16 fn advance(&mut self) -> RingResult<()> {
17 if self.0 >= self.1 {
18 return Err(ring::error::Unspecified);
19 }
20 self.0 += 1;
21 Ok(())
22 }
23
24 const fn size() -> usize {
25 8
26 }
27
28 fn to_bytes(self) -> [u8; 8] {
29 self.0.to_be_bytes()
30 }
31}
32
33#[derive(Clone, Copy, Default)]
34struct CounterNonceSequence(Counter, [u8; NONCE_LEN]);
35
36type RingResult<T> = Result<T, ring::error::Unspecified>;
37
38impl NonceSequence for CounterNonceSequence {
39 fn advance(&mut self) -> RingResult<Nonce> {
41 let nonce_bytes = &mut self.1;
42
43 let bytes = self.0.to_bytes();
44 nonce_bytes[NONCE_LEN - Counter::size()..].copy_from_slice(&bytes);
45
46 self.0.advance()?;
47 Ok(Nonce::assume_unique_for_key(*nonce_bytes))
48 }
49}
50
51pub struct Aes256GcmCodec {
52 seal: Aes256GcmEnCodec,
53 open: Aes256GcmDeCodec,
54}
55
56impl Aes256GcmCodec {
57 pub fn try_new(key: &[u8]) -> RingResult<Self> {
58 Ok(Self {
59 seal: Aes256GcmEnCodec::try_new(key)?,
60 open: Aes256GcmDeCodec::try_new(key)?,
61 })
62 }
63
64 pub fn encrypt(&mut self, data: &mut [u8]) -> RingResult<Tag> {
65 self.seal.encrypt(data)
66 }
67
68 pub fn decrypt_with_tag(
69 &mut self,
70 decrypeted_data: &[u8],
71 tag: Tag,
72 ) -> RingResult<(Vec<u8>, usize)> {
73 self.open.decrypt_with_tag(decrypeted_data, tag)
74 }
75
76 pub fn decrypt<'a>(&mut self, data: &'a mut [u8]) -> RingResult<&'a mut [u8]> {
77 self.open.decrypt(data)
78 }
79}
80
81#[derive(Debug)]
82pub struct Aes256GcmEnCodec {
83 seal: SealingKey<CounterNonceSequence>,
84}
85
86impl Aes256GcmEnCodec {
87 pub fn try_new_data_v2(key: &[u8], prefix: [u8; 4]) -> RingResult<Self> {
91 let mut nonce = [0; NONCE_LEN];
92 nonce[..4].copy_from_slice(&prefix);
93 Ok(Self {
94 seal: SealingKey::new(
95 UnboundKey::new(&AES_256_GCM, key)?,
96 CounterNonceSequence(Counter(0, u64::MAX), nonce),
97 ),
98 })
99 }
100
101 pub fn try_new(key: &[u8]) -> RingResult<Self> {
102 let counter = CounterNonceSequence::default();
103 Ok(Self {
104 seal: SealingKey::new(UnboundKey::new(&AES_256_GCM, key)?, counter),
105 })
106 }
107
108 pub fn new(key: UnboundKey) -> Self {
109 let counter = CounterNonceSequence::default();
110 Self {
111 seal: SealingKey::new(key, counter),
112 }
113 }
114}
115
116impl Encryptor for Aes256GcmEnCodec {
117 fn encrypt(&mut self, data: &mut [u8]) -> RingResult<Tag> {
118 self.seal.seal_in_place_separate_tag(Aad::empty(), data)
119 }
120}
121
122#[derive(Debug)]
123pub struct Aes256GcmDeCodec {
124 open: OpeningKey<CounterNonceSequence>,
125}
126
127impl Aes256GcmDeCodec {
128 pub fn try_new_data_v2(key: &[u8], prefix: [u8; 4]) -> RingResult<Self> {
130 let mut nonce = [0; NONCE_LEN];
131 nonce[..4].copy_from_slice(&prefix);
132 Ok(Self {
133 open: OpeningKey::new(
134 UnboundKey::new(&AES_256_GCM, key)?,
135 CounterNonceSequence(Counter(0, u64::MAX), nonce),
136 ),
137 })
138 }
139
140 pub fn try_new(key: &[u8]) -> RingResult<Self> {
141 let counter = CounterNonceSequence::default();
142 Ok(Self {
143 open: OpeningKey::new(UnboundKey::new(&AES_256_GCM, key)?, counter),
144 })
145 }
146
147 pub fn new(key: UnboundKey) -> Self {
148 let counter = CounterNonceSequence::default();
149 Self {
150 open: OpeningKey::new(key, counter),
151 }
152 }
153}
154
155impl Decryptor for Aes256GcmDeCodec {
156 fn decrypt_with_tag(
157 &mut self,
158 decrypeted_data: &[u8],
159 tag: Tag,
160 ) -> RingResult<(Vec<u8>, usize)> {
161 let mut new_data = [decrypeted_data, tag.as_ref()].concat();
162 let new_data_len = self.decrypt(&mut new_data)?.len();
163 Ok((new_data, new_data_len))
164 }
165
166 fn decrypt<'a>(&mut self, data: &'a mut [u8]) -> RingResult<&'a mut [u8]> {
167 self.open.open_in_place(Aad::empty(), data)
168 }
169}
170
171pub trait Encryptor: 'static {
172 fn encrypt(&mut self, data: &mut [u8]) -> RingResult<Tag>;
173}
174
175pub trait Decryptor {
176 fn decrypt_with_tag(
177 &mut self,
178 decrypeted_data: &[u8],
179 tag: Tag,
180 ) -> RingResult<(Vec<u8>, usize)>;
181 fn decrypt<'a>(&mut self, data: &'a mut [u8]) -> RingResult<&'a mut [u8]>;
182}
183
184#[cfg(test)]
185mod tests {
186 use super::{Counter, CounterNonceSequence};
187 use ring::aead::NonceSequence;
188 use std::slice::from_raw_parts_mut;
189 use std::time::Instant;
190
191 use crate::codec::Aes256GcmCodec;
192
193 #[test]
194 fn legacy_nonces_keep_their_bytes_and_both_counter_widths_fail_closed() {
195 for limit in [u64::from(u32::MAX), u64::MAX] {
196 let mut seq = CounterNonceSequence(Counter(limit - 1, limit), [0; 12]);
197 let nonce = seq.advance().unwrap();
198 assert_eq!(&nonce.as_ref()[..4], &[0; 4]);
199 assert_eq!(&nonce.as_ref()[4..], &(limit - 1).to_be_bytes());
200 assert!(seq.advance().is_err());
201 assert!(seq.advance().is_err());
202 }
203 let mut seq = CounterNonceSequence::default();
204 assert_eq!(seq.advance().unwrap().as_ref(), &[0; 12]);
205 assert_eq!(
206 seq.advance().unwrap().as_ref(),
207 &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
208 );
209 }
210
211 struct Timer {
212 ins: Instant,
213 hint: String,
214 }
215
216 impl Timer {
217 fn new_with_hint(hint: String) -> Self {
218 Self {
219 ins: Instant::now(),
220 hint,
221 }
222 }
223 }
224
225 impl Drop for Timer {
226 fn drop(&mut self) {
227 println!("{} consume time:{:?}", self.hint, self.ins.elapsed());
228 }
229 }
230
231 fn write_slice(slice: &[u8]) {
232 let ptr = slice.as_ptr() as *mut u8;
233 let mut_slice = unsafe { from_raw_parts_mut(ptr, slice.len()) };
234 mut_slice[1] = b'a';
235 println!("{mut_slice:?}")
236 }
237
238 #[test]
239 fn test_write_mut_slice() {
240 let vec: Vec<u8> = "bbc".into();
241 write_slice(&vec);
242 assert_eq!(vec[1], b'a');
243 }
244
245 #[test]
246 fn test_codec() {
247 const TEST_KEY: [u8; 32] = [0x42; 32];
248 let data = String::from(
249 "fdafas反对fdasfasfasfsdafdasfsdfasd范德萨发顺🤣❤️😁😍👍👍丰十大大师傅士大夫大撒发射点发士大夫大师傅大师傅士大夫士大夫阿斯蒂芬大师傅阿斯顿法大师傅看叫阿三的发就可是大家发开始打客服开始大幅喀什的开发点卡收费就开始打客服就是的咖啡肯定撒法开始打客服就是的咖啡就开始大幅扣税的急啊看发叫阿三的发生的开发就是大家可是大家发看大数据开发大数据开发大家ask发就是的咖啡的萨芬就卡死的房价开始打家开发商的JFK上的飞机卡上的纠纷开始打飞机宽带技术开发就开始大家开发建设的卡JFK大数据风控静安寺的看法角度看萨芬卡上的纠纷看静安寺的看法角度思考积分可是大家发卡是大家看法就大肆砍伐尽快打算减肥肯定是积分开始大幅技术大咖积分开始打飞机扣税的急啊看发的技术开发就是JFK十大福克斯大家开发大撒发射点幅度萨芬撒旦发发收范德萨发顺丰士大夫十大阿斯蒂芬大师傅阿斯顿附件是的客服对接撒巨大石块积分的课时费阿斯蒂芬法大师傅大师傅十大法大师傅阿斯蒂芬阿斯顿法大师傅阿斯蒂芬大师傅阿斯顿法大师傅大师傅阿斯蒂芬阿斯蒂芬士大夫阿斯蒂芬大师傅的萨芬打算减肥上岛咖啡加快速度大数据开发就是打客服看大数据开发就开始减肥卡萨丁JFK是大家看法加快速度JFK技术大咖积分喀什的开发独守空房技术大咖积分空手道解放扣税的开发商的开发接口是大家看法角度看是否扣税的急啊看发生的开发的快速减肥开始大幅就是打客服卡上的纠纷啊撒旦解放扣税的急啊看发加快速度点卡JFK啥的但是法大师傅技术大咖积分卡萨丁就反馈是大家看法啊是大家看法卡上的纠纷可是大家发喀什的开发大卡司喀什的开发就是打客服法大师傅士大夫的式咖啡机上岛咖啡就是的咖啡艰苦大师傅看上雕刻技法喀什的开发上岛咖啡就喀什的开发就是打客服卡上的纠纷技术的咖啡机肯定撒开发啊十大科技开发速度加啊反馈就是的咖啡开始大幅大师傅似的十大放假啊上岛咖啡就可是大家发空间的是否撒旦士大夫的撒娇开发是大家看法大肆砍伐就喀什的开发氨基酸的考虑非军事对抗疗法金克拉撒旦发艰苦拉萨的飞机喀什打开发就可是大家发可是大家看附件卡上的纠纷卡刷点卡技术的咖啡机可是大家发卡是大家看法静安寺的看法就可是大家发卡萨丁就开发商的急啊看飞机迪斯科发技术的咖啡机可是大家发看电视剧开发商大开始打到发大水发大水",
250 );
251 let mut cryption = Aes256GcmCodec::try_new(&TEST_KEY).unwrap();
252 let mut out_buf = data.as_bytes().to_vec();
253 let tag = {
254 let _timer = Timer::new_with_hint("Encrypt".into());
255 cryption.encrypt(&mut out_buf).unwrap()
256 };
257 println!("tag:{:?}", tag.as_ref());
258 let (decrypeted_data, len) = {
259 let _timer = Timer::new_with_hint("Decrypt".into());
260 cryption.decrypt_with_tag(&out_buf, tag).unwrap()
261 };
262 assert_eq!(
263 data,
264 String::from_utf8(decrypeted_data[..len].to_vec()).unwrap()
265 );
266 }
267}