shadowsocks_crypto/
kind.rs

1//! Cipher Kind
2
3#[cfg(feature = "v1-aead-extra")]
4use crate::v1::aeadcipher::{Aes128Ccm, Aes128GcmSiv, Aes256Ccm, Aes256GcmSiv, Sm4Ccm, Sm4Gcm, XChaCha20Poly1305};
5#[cfg(feature = "v1-aead")]
6use crate::v1::aeadcipher::{Aes128Gcm, Aes256Gcm, ChaCha20Poly1305};
7
8#[cfg(feature = "v1-stream")]
9use crate::v1::streamcipher::{
10    Aes128Cfb1,
11    Aes128Cfb128,
12    Aes128Cfb8,
13    Aes128Ctr,
14    Aes128Ofb,
15    Aes192Cfb1,
16    Aes192Cfb128,
17    Aes192Cfb8,
18    Aes192Ctr,
19    Aes192Ofb,
20    Aes256Cfb1,
21    Aes256Cfb128,
22
23    Aes256Cfb8,
24    Aes256Ctr,
25    Aes256Ofb,
26    Camellia128Cfb1,
27    Camellia128Cfb128,
28    Camellia128Cfb8,
29    Camellia128Ctr,
30    Camellia128Ofb,
31    Camellia192Cfb1,
32    Camellia192Cfb128,
33    Camellia192Cfb8,
34    Camellia192Ctr,
35    Camellia192Ofb,
36    Camellia256Cfb1,
37    Camellia256Cfb128,
38
39    Camellia256Cfb8,
40    Camellia256Ctr,
41    Camellia256Ofb,
42
43    Chacha20,
44    Rc4,
45    Rc4Md5,
46};
47
48#[cfg(feature = "v2-extra")]
49use crate::v2::crypto::ChaCha8Poly1305 as Aead2022ChaCha8Poly1305;
50#[cfg(feature = "v2")]
51use crate::v2::crypto::{
52    Aes128Gcm as Aead2022Aes128Gcm,
53    Aes256Gcm as Aead2022Aes256Gcm,
54    ChaCha20Poly1305 as Aead2022ChaCha20Poly1305,
55};
56
57/// Category of ciphers
58#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash)]
59pub enum CipherCategory {
60    /// No encryption
61    None,
62    /// Stream ciphers is used for OLD ShadowSocks protocol, which uses stream ciphers to encrypt data payloads
63    #[cfg(feature = "v1-stream")]
64    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
65    Stream,
66    /// AEAD ciphers is used in modern ShadowSocks protocol, which sends data in separate packets
67    #[cfg(feature = "v1-aead")]
68    #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead")))]
69    Aead,
70    /// AEAD ciphers 2022 with enhanced security
71    #[cfg(feature = "v2")]
72    #[cfg_attr(docsrs, doc(cfg(feature = "v2")))]
73    Aead2022,
74}
75
76/// ShadowSocks cipher type
77#[allow(non_camel_case_types)]
78#[allow(clippy::upper_case_acronyms)]
79#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash)]
80pub enum CipherKind {
81    NONE,
82
83    #[cfg(feature = "v1-stream")]
84    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
85    SS_TABLE,
86    #[cfg(feature = "v1-stream")]
87    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
88    SS_RC4_MD5,
89
90    #[cfg(feature = "v1-stream")]
91    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
92    AES_128_CTR,
93    #[cfg(feature = "v1-stream")]
94    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
95    AES_192_CTR,
96    #[cfg(feature = "v1-stream")]
97    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
98    AES_256_CTR,
99
100    #[cfg(feature = "v1-stream")]
101    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
102    AES_128_CFB1,
103    #[cfg(feature = "v1-stream")]
104    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
105    AES_128_CFB8,
106    #[cfg(feature = "v1-stream")]
107    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
108    AES_128_CFB128,
109    #[cfg(feature = "v1-stream")]
110    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
111    AES_192_CFB1,
112    #[cfg(feature = "v1-stream")]
113    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
114    AES_192_CFB8,
115    #[cfg(feature = "v1-stream")]
116    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
117    AES_192_CFB128,
118    #[cfg(feature = "v1-stream")]
119    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
120    AES_256_CFB1,
121    #[cfg(feature = "v1-stream")]
122    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
123    AES_256_CFB8,
124    #[cfg(feature = "v1-stream")]
125    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
126    AES_256_CFB128,
127
128    #[cfg(feature = "v1-stream")]
129    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
130    AES_128_OFB,
131    #[cfg(feature = "v1-stream")]
132    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
133    AES_192_OFB,
134    #[cfg(feature = "v1-stream")]
135    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
136    AES_256_OFB,
137
138    #[cfg(feature = "v1-stream")]
139    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
140    CAMELLIA_128_CTR,
141    #[cfg(feature = "v1-stream")]
142    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
143    CAMELLIA_192_CTR,
144    #[cfg(feature = "v1-stream")]
145    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
146    CAMELLIA_256_CTR,
147
148    #[cfg(feature = "v1-stream")]
149    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
150    CAMELLIA_128_CFB1,
151    #[cfg(feature = "v1-stream")]
152    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
153    CAMELLIA_128_CFB8,
154    #[cfg(feature = "v1-stream")]
155    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
156    CAMELLIA_128_CFB128,
157    #[cfg(feature = "v1-stream")]
158    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
159    CAMELLIA_192_CFB1,
160    #[cfg(feature = "v1-stream")]
161    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
162    CAMELLIA_192_CFB8,
163    #[cfg(feature = "v1-stream")]
164    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
165    CAMELLIA_192_CFB128,
166    #[cfg(feature = "v1-stream")]
167    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
168    CAMELLIA_256_CFB1,
169    #[cfg(feature = "v1-stream")]
170    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
171    CAMELLIA_256_CFB8,
172    #[cfg(feature = "v1-stream")]
173    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
174    CAMELLIA_256_CFB128,
175
176    #[cfg(feature = "v1-stream")]
177    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
178    CAMELLIA_128_OFB,
179    #[cfg(feature = "v1-stream")]
180    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
181    CAMELLIA_192_OFB,
182    #[cfg(feature = "v1-stream")]
183    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
184    CAMELLIA_256_OFB,
185
186    #[cfg(feature = "v1-stream")]
187    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
188    RC4,
189    // NOTE: IETF 版本
190    #[cfg(feature = "v1-stream")]
191    #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))]
192    CHACHA20,
193
194    // AEAD Cipher
195    #[cfg(feature = "v1-aead")]
196    #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead")))]
197    /// AEAD_AES_128_GCM
198    AES_128_GCM,
199    #[cfg(feature = "v1-aead")]
200    #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead")))]
201    /// AEAD_AES_256_GCM
202    AES_256_GCM,
203
204    #[cfg(feature = "v1-aead-extra")]
205    #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
206    /// AEAD_AES_128_CCM
207    AES_128_CCM,
208    #[cfg(feature = "v1-aead-extra")]
209    #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
210    /// AEAD_AES_256_CCM
211    AES_256_CCM,
212
213    #[cfg(feature = "v1-aead-extra")]
214    #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
215    /// AEAD_AES_128_GCM_SIV
216    AES_128_GCM_SIV,
217    #[cfg(feature = "v1-aead-extra")]
218    #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
219    /// AEAD_AES_256_GCM_SIV
220    AES_256_GCM_SIV,
221
222    // NOTE: IETF 版本
223    #[cfg(feature = "v1-aead")]
224    #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead")))]
225    /// AEAD_CHACHA20_POLY1305
226    CHACHA20_POLY1305,
227
228    #[cfg(feature = "v1-aead-extra")]
229    #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
230    /// AEAD_XCHACHA20_POLY1305
231    XCHACHA20_POLY1305,
232
233    #[cfg(feature = "v1-aead-extra")]
234    #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
235    /// SM4_GCM
236    SM4_GCM,
237    #[cfg(feature = "v1-aead-extra")]
238    #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))]
239    /// SM4_GCM
240    SM4_CCM,
241
242    #[cfg(feature = "v2")]
243    #[cfg_attr(docsrs, doc(cfg(feature = "v2")))]
244    /// 2022-blake3-aes-128-gcm
245    AEAD2022_BLAKE3_AES_128_GCM,
246
247    #[cfg(feature = "v2")]
248    #[cfg_attr(docsrs, doc(cfg(feature = "v2")))]
249    /// 2022-blake3-aes-128-gcm
250    AEAD2022_BLAKE3_AES_256_GCM,
251
252    #[cfg(feature = "v2")]
253    #[cfg_attr(docsrs, doc(cfg(feature = "v2")))]
254    /// 2022-blake3-chacha20-poly1305
255    AEAD2022_BLAKE3_CHACHA20_POLY1305,
256    #[cfg(feature = "v2-extra")]
257    #[cfg_attr(docsrs, doc(cfg(feature = "v2-extra")))]
258    /// 2022-blake3-chacha8-poly1305
259    AEAD2022_BLAKE3_CHACHA8_POLY1305,
260}
261
262impl CipherKind {
263    /// The category of the cipher
264    pub fn category(&self) -> CipherCategory {
265        #[cfg(feature = "v1-stream")]
266        if self.is_stream() {
267            return CipherCategory::Stream;
268        }
269
270        #[cfg(feature = "v1-aead")]
271        if self.is_aead() {
272            return CipherCategory::Aead;
273        }
274
275        #[cfg(feature = "v2")]
276        if self.is_aead_2022() {
277            return CipherCategory::Aead2022;
278        }
279
280        CipherCategory::None
281    }
282
283    /// Check if the current cipher is `NONE`
284    pub fn is_none(&self) -> bool {
285        matches!(*self, CipherKind::NONE)
286    }
287
288    /// Check if the current cipher is a stream cipher
289    #[cfg(feature = "v1-stream")]
290    #[allow(clippy::match_like_matches_macro)]
291    pub fn is_stream(&self) -> bool {
292        use self::CipherKind::*;
293
294        match *self {
295            SS_TABLE | SS_RC4_MD5 | AES_128_CTR | AES_192_CTR | AES_256_CTR | AES_128_CFB1 | AES_128_CFB8
296            | AES_128_CFB128 | AES_192_CFB1 | AES_192_CFB8 | AES_192_CFB128 | AES_256_CFB1 | AES_256_CFB8
297            | AES_256_CFB128 | AES_128_OFB | AES_192_OFB | AES_256_OFB | CAMELLIA_128_CTR | CAMELLIA_192_CTR
298            | CAMELLIA_256_CTR | CAMELLIA_128_CFB1 | CAMELLIA_128_CFB8 | CAMELLIA_128_CFB128 | CAMELLIA_192_CFB1
299            | CAMELLIA_192_CFB8 | CAMELLIA_192_CFB128 | CAMELLIA_256_CFB1 | CAMELLIA_256_CFB8 | CAMELLIA_256_CFB128
300            | CAMELLIA_128_OFB | CAMELLIA_192_OFB | CAMELLIA_256_OFB | RC4 | CHACHA20 => true,
301            _ => false,
302        }
303    }
304
305    /// Check if the current cipher is an AEAD cipher
306    #[cfg(feature = "v1-aead")]
307    pub fn is_aead(&self) -> bool {
308        use self::CipherKind::*;
309
310        match *self {
311            AES_128_GCM | AES_256_GCM | CHACHA20_POLY1305 => true,
312
313            #[cfg(feature = "v1-aead-extra")]
314            AES_128_CCM | AES_256_CCM | AES_128_GCM_SIV | AES_256_GCM_SIV | XCHACHA20_POLY1305 | SM4_GCM | SM4_CCM => {
315                true
316            }
317
318            _ => false,
319        }
320    }
321
322    #[cfg(feature = "v2")]
323    pub fn is_aead_2022(&self) -> bool {
324        use self::CipherKind::*;
325
326        match *self {
327            AEAD2022_BLAKE3_AES_128_GCM | AEAD2022_BLAKE3_AES_256_GCM | AEAD2022_BLAKE3_CHACHA20_POLY1305 => true,
328            #[cfg(feature = "v2-extra")]
329            AEAD2022_BLAKE3_CHACHA8_POLY1305 => true,
330            _ => false,
331        }
332    }
333
334    /// Key length of the cipher
335    pub fn key_len(&self) -> usize {
336        use self::CipherKind::*;
337
338        match *self {
339            NONE => 0,
340
341            #[cfg(feature = "v1-stream")]
342            SS_TABLE => 0,
343            #[cfg(feature = "v1-stream")]
344            SS_RC4_MD5 => Rc4Md5::key_size(),
345
346            #[cfg(feature = "v1-stream")]
347            AES_128_CTR => Aes128Ctr::KEY_LEN,
348            #[cfg(feature = "v1-stream")]
349            AES_192_CTR => Aes192Ctr::KEY_LEN,
350            #[cfg(feature = "v1-stream")]
351            AES_256_CTR => Aes256Ctr::KEY_LEN,
352
353            #[cfg(feature = "v1-stream")]
354            AES_128_CFB1 => Aes128Cfb1::KEY_LEN,
355            #[cfg(feature = "v1-stream")]
356            AES_128_CFB8 => Aes128Cfb8::KEY_LEN,
357            #[cfg(feature = "v1-stream")]
358            AES_128_CFB128 => Aes128Cfb128::KEY_LEN,
359            #[cfg(feature = "v1-stream")]
360            AES_192_CFB1 => Aes192Cfb1::KEY_LEN,
361            #[cfg(feature = "v1-stream")]
362            AES_192_CFB8 => Aes192Cfb8::KEY_LEN,
363            #[cfg(feature = "v1-stream")]
364            AES_192_CFB128 => Aes192Cfb128::KEY_LEN,
365            #[cfg(feature = "v1-stream")]
366            AES_256_CFB1 => Aes256Cfb1::KEY_LEN,
367            #[cfg(feature = "v1-stream")]
368            AES_256_CFB8 => Aes256Cfb8::KEY_LEN,
369            #[cfg(feature = "v1-stream")]
370            AES_256_CFB128 => Aes256Cfb128::KEY_LEN,
371
372            #[cfg(feature = "v1-stream")]
373            AES_128_OFB => Aes128Ofb::KEY_LEN,
374            #[cfg(feature = "v1-stream")]
375            AES_192_OFB => Aes192Ofb::KEY_LEN,
376            #[cfg(feature = "v1-stream")]
377            AES_256_OFB => Aes256Ofb::KEY_LEN,
378
379            #[cfg(feature = "v1-stream")]
380            CAMELLIA_128_CTR => Camellia128Ctr::KEY_LEN,
381            #[cfg(feature = "v1-stream")]
382            CAMELLIA_192_CTR => Camellia192Ctr::KEY_LEN,
383            #[cfg(feature = "v1-stream")]
384            CAMELLIA_256_CTR => Camellia256Ctr::KEY_LEN,
385            #[cfg(feature = "v1-stream")]
386            CAMELLIA_128_CFB1 => Camellia128Cfb1::KEY_LEN,
387            #[cfg(feature = "v1-stream")]
388            CAMELLIA_128_CFB8 => Camellia128Cfb8::KEY_LEN,
389            #[cfg(feature = "v1-stream")]
390            CAMELLIA_128_CFB128 => Camellia128Cfb128::KEY_LEN,
391            #[cfg(feature = "v1-stream")]
392            CAMELLIA_192_CFB1 => Camellia192Cfb1::KEY_LEN,
393            #[cfg(feature = "v1-stream")]
394            CAMELLIA_192_CFB8 => Camellia192Cfb8::KEY_LEN,
395            #[cfg(feature = "v1-stream")]
396            CAMELLIA_192_CFB128 => Camellia192Cfb128::KEY_LEN,
397            #[cfg(feature = "v1-stream")]
398            CAMELLIA_256_CFB1 => Camellia256Cfb1::KEY_LEN,
399            #[cfg(feature = "v1-stream")]
400            CAMELLIA_256_CFB8 => Camellia256Cfb8::KEY_LEN,
401            #[cfg(feature = "v1-stream")]
402            CAMELLIA_256_CFB128 => Camellia256Cfb128::KEY_LEN,
403
404            #[cfg(feature = "v1-stream")]
405            CAMELLIA_128_OFB => Camellia128Ofb::KEY_LEN,
406            #[cfg(feature = "v1-stream")]
407            CAMELLIA_192_OFB => Camellia192Ofb::KEY_LEN,
408            #[cfg(feature = "v1-stream")]
409            CAMELLIA_256_OFB => Camellia256Ofb::KEY_LEN,
410
411            // NOTE: RC4 密码本身支持 1..256 长度的 Key,
412            //       但是 SS 这里把 Key 的长度限制在 16.
413            #[cfg(feature = "v1-stream")]
414            RC4 => Rc4::key_size(),
415            #[cfg(feature = "v1-stream")]
416            CHACHA20 => Chacha20::key_size(),
417
418            // AEAD
419            #[cfg(feature = "v1-aead")]
420            AES_128_GCM => Aes128Gcm::key_size(),
421            #[cfg(feature = "v1-aead")]
422            AES_256_GCM => Aes256Gcm::key_size(),
423
424            #[cfg(feature = "v1-aead-extra")]
425            AES_128_CCM => Aes128Ccm::key_size(),
426            #[cfg(feature = "v1-aead-extra")]
427            AES_256_CCM => Aes256Ccm::key_size(),
428
429            #[cfg(feature = "v1-aead-extra")]
430            AES_128_GCM_SIV => Aes128GcmSiv::key_size(),
431            #[cfg(feature = "v1-aead-extra")]
432            AES_256_GCM_SIV => Aes256GcmSiv::key_size(),
433
434            #[cfg(feature = "v1-aead")]
435            CHACHA20_POLY1305 => ChaCha20Poly1305::key_size(),
436
437            #[cfg(feature = "v1-aead-extra")]
438            XCHACHA20_POLY1305 => XChaCha20Poly1305::key_size(),
439
440            #[cfg(feature = "v1-aead-extra")]
441            SM4_GCM => Sm4Gcm::key_size(),
442            #[cfg(feature = "v1-aead-extra")]
443            SM4_CCM => Sm4Ccm::key_size(),
444
445            #[cfg(feature = "v2")]
446            AEAD2022_BLAKE3_AES_128_GCM => Aead2022Aes128Gcm::key_size(),
447            #[cfg(feature = "v2")]
448            AEAD2022_BLAKE3_AES_256_GCM => Aead2022Aes256Gcm::key_size(),
449            #[cfg(feature = "v2")]
450            AEAD2022_BLAKE3_CHACHA20_POLY1305 => Aead2022ChaCha20Poly1305::key_size(),
451            #[cfg(feature = "v2-extra")]
452            AEAD2022_BLAKE3_CHACHA8_POLY1305 => Aead2022ChaCha8Poly1305::key_size(),
453        }
454    }
455
456    /// Stream Cipher's initializer vector length
457    #[cfg(feature = "v1-stream")]
458    pub fn iv_len(&self) -> usize {
459        use self::CipherKind::*;
460
461        match *self {
462            NONE => 0,
463            SS_TABLE => 0,
464
465            SS_RC4_MD5 => Rc4Md5::nonce_size(),
466
467            AES_128_CTR => Aes128Ctr::IV_LEN,
468            AES_192_CTR => Aes192Ctr::IV_LEN,
469            AES_256_CTR => Aes256Ctr::IV_LEN,
470
471            AES_128_CFB1 => Aes128Cfb1::IV_LEN,
472            AES_128_CFB8 => Aes128Cfb8::IV_LEN,
473            AES_128_CFB128 => Aes128Cfb128::IV_LEN,
474            AES_192_CFB1 => Aes192Cfb1::IV_LEN,
475            AES_192_CFB8 => Aes192Cfb8::IV_LEN,
476            AES_192_CFB128 => Aes192Cfb128::IV_LEN,
477            AES_256_CFB1 => Aes256Cfb1::IV_LEN,
478            AES_256_CFB8 => Aes256Cfb8::IV_LEN,
479            AES_256_CFB128 => Aes256Cfb128::IV_LEN,
480
481            AES_128_OFB => Aes128Ofb::IV_LEN,
482            AES_192_OFB => Aes192Ofb::IV_LEN,
483            AES_256_OFB => Aes256Ofb::IV_LEN,
484
485            CAMELLIA_128_CTR => Camellia128Ctr::IV_LEN,
486            CAMELLIA_192_CTR => Camellia192Ctr::IV_LEN,
487            CAMELLIA_256_CTR => Camellia256Ctr::IV_LEN,
488
489            CAMELLIA_128_CFB1 => Camellia128Cfb1::IV_LEN,
490            CAMELLIA_128_CFB8 => Camellia128Cfb8::IV_LEN,
491            CAMELLIA_128_CFB128 => Camellia128Cfb128::IV_LEN,
492            CAMELLIA_192_CFB1 => Camellia192Cfb1::IV_LEN,
493            CAMELLIA_192_CFB8 => Camellia192Cfb8::IV_LEN,
494            CAMELLIA_192_CFB128 => Camellia192Cfb128::IV_LEN,
495            CAMELLIA_256_CFB1 => Camellia256Cfb1::IV_LEN,
496            CAMELLIA_256_CFB8 => Camellia256Cfb8::IV_LEN,
497            CAMELLIA_256_CFB128 => Camellia256Cfb128::IV_LEN,
498
499            CAMELLIA_128_OFB => Camellia128Ofb::IV_LEN,
500            CAMELLIA_192_OFB => Camellia192Ofb::IV_LEN,
501            CAMELLIA_256_OFB => Camellia256Ofb::IV_LEN,
502
503            RC4 => Rc4::nonce_size(),
504            CHACHA20 => Chacha20::nonce_size(),
505
506            #[allow(unreachable_patterns)]
507            _ => panic!("only support Stream ciphers"),
508        }
509    }
510
511    /// AEAD Cipher's TAG length
512    #[cfg(any(feature = "v1-aead", feature = "v2"))]
513    pub fn tag_len(&self) -> usize {
514        use self::CipherKind::*;
515
516        match *self {
517            #[cfg(feature = "v1-aead")]
518            AES_128_GCM => Aes128Gcm::tag_size(),
519            #[cfg(feature = "v1-aead")]
520            AES_256_GCM => Aes256Gcm::tag_size(),
521
522            #[cfg(feature = "v1-aead-extra")]
523            AES_128_GCM_SIV => Aes128GcmSiv::tag_size(),
524            #[cfg(feature = "v1-aead-extra")]
525            AES_256_GCM_SIV => Aes256GcmSiv::tag_size(),
526
527            #[cfg(feature = "v1-aead-extra")]
528            AES_128_CCM => Aes128Ccm::tag_size(),
529            #[cfg(feature = "v1-aead-extra")]
530            AES_256_CCM => Aes256Ccm::tag_size(),
531
532            #[cfg(feature = "v1-aead")]
533            CHACHA20_POLY1305 => ChaCha20Poly1305::tag_size(),
534
535            #[cfg(feature = "v1-aead-extra")]
536            XCHACHA20_POLY1305 => XChaCha20Poly1305::tag_size(),
537
538            #[cfg(feature = "v1-aead-extra")]
539            SM4_GCM => Sm4Gcm::tag_size(),
540            #[cfg(feature = "v1-aead-extra")]
541            SM4_CCM => Sm4Ccm::tag_size(),
542
543            #[cfg(feature = "v2")]
544            AEAD2022_BLAKE3_AES_128_GCM => Aead2022Aes128Gcm::tag_size(),
545            #[cfg(feature = "v2")]
546            AEAD2022_BLAKE3_AES_256_GCM => Aead2022Aes256Gcm::tag_size(),
547            #[cfg(feature = "v2")]
548            AEAD2022_BLAKE3_CHACHA20_POLY1305 => Aead2022ChaCha20Poly1305::tag_size(),
549            #[cfg(feature = "v2-extra")]
550            AEAD2022_BLAKE3_CHACHA8_POLY1305 => Aead2022ChaCha8Poly1305::tag_size(),
551
552            _ => panic!("only support AEAD ciphers"),
553        }
554    }
555
556    /// AEAD Cipher's SALT length
557    #[cfg(any(feature = "v1-aead", feature = "v2"))]
558    pub fn salt_len(&self) -> usize {
559        #[cfg(feature = "v1-aead")]
560        if self.is_aead() {
561            return self.key_len();
562        }
563
564        #[cfg(feature = "v2")]
565        if self.is_aead_2022() {
566            return self.key_len();
567        }
568
569        panic!("only support AEAD ciphers");
570    }
571
572    /// AEAD Cipher's nonce length
573    #[cfg(feature = "v2")]
574    pub fn nonce_len(&self) -> usize {
575        #[cfg(feature = "v2-extra")]
576        use crate::v2::udp::ChaCha8Poly1305Cipher;
577        use crate::v2::udp::{AesGcmCipher, ChaCha20Poly1305Cipher};
578
579        match *self {
580            CipherKind::AEAD2022_BLAKE3_AES_128_GCM | CipherKind::AEAD2022_BLAKE3_AES_256_GCM => {
581                AesGcmCipher::nonce_size()
582            }
583            CipherKind::AEAD2022_BLAKE3_CHACHA20_POLY1305 => ChaCha20Poly1305Cipher::nonce_size(),
584            #[cfg(feature = "v2-extra")]
585            CipherKind::AEAD2022_BLAKE3_CHACHA8_POLY1305 => ChaCha8Poly1305Cipher::nonce_size(),
586            _ => panic!("only support AEAD 2022 ciphers"),
587        }
588    }
589}
590
591impl core::fmt::Display for CipherKind {
592    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
593        f.write_str(match *self {
594            CipherKind::NONE => "none",
595
596            #[cfg(feature = "v1-stream")]
597            CipherKind::SS_TABLE => "table",
598            #[cfg(feature = "v1-stream")]
599            CipherKind::SS_RC4_MD5 => "rc4-md5",
600
601            #[cfg(feature = "v1-stream")]
602            CipherKind::AES_128_CTR => "aes-128-ctr",
603            #[cfg(feature = "v1-stream")]
604            CipherKind::AES_192_CTR => "aes-192-ctr",
605            #[cfg(feature = "v1-stream")]
606            CipherKind::AES_256_CTR => "aes-256-ctr",
607
608            #[cfg(feature = "v1-stream")]
609            CipherKind::AES_128_CFB128 => "aes-128-cfb",
610            #[cfg(feature = "v1-stream")]
611            CipherKind::AES_128_CFB1 => "aes-128-cfb1",
612            #[cfg(feature = "v1-stream")]
613            CipherKind::AES_128_CFB8 => "aes-128-cfb8",
614
615            #[cfg(feature = "v1-stream")]
616            CipherKind::AES_192_CFB128 => "aes-192-cfb",
617            #[cfg(feature = "v1-stream")]
618            CipherKind::AES_192_CFB1 => "aes-192-cfb1",
619            #[cfg(feature = "v1-stream")]
620            CipherKind::AES_192_CFB8 => "aes-192-cfb8",
621
622            #[cfg(feature = "v1-stream")]
623            CipherKind::AES_256_CFB128 => "aes-256-cfb",
624            #[cfg(feature = "v1-stream")]
625            CipherKind::AES_256_CFB1 => "aes-256-cfb1",
626            #[cfg(feature = "v1-stream")]
627            CipherKind::AES_256_CFB8 => "aes-256-cfb8",
628
629            #[cfg(feature = "v1-stream")]
630            CipherKind::AES_128_OFB => "aes-128-ofb",
631            #[cfg(feature = "v1-stream")]
632            CipherKind::AES_192_OFB => "aes-192-ofb",
633            #[cfg(feature = "v1-stream")]
634            CipherKind::AES_256_OFB => "aes-256-ofb",
635
636            #[cfg(feature = "v1-stream")]
637            CipherKind::CAMELLIA_128_CTR => "camellia-128-ctr",
638            #[cfg(feature = "v1-stream")]
639            CipherKind::CAMELLIA_192_CTR => "camellia-192-ctr",
640            #[cfg(feature = "v1-stream")]
641            CipherKind::CAMELLIA_256_CTR => "camellia-256-ctr",
642
643            #[cfg(feature = "v1-stream")]
644            CipherKind::CAMELLIA_128_CFB128 => "camellia-128-cfb",
645            #[cfg(feature = "v1-stream")]
646            CipherKind::CAMELLIA_128_CFB1 => "camellia-128-cfb1",
647            #[cfg(feature = "v1-stream")]
648            CipherKind::CAMELLIA_128_CFB8 => "camellia-128-cfb8",
649
650            #[cfg(feature = "v1-stream")]
651            CipherKind::CAMELLIA_192_CFB128 => "camellia-192-cfb",
652            #[cfg(feature = "v1-stream")]
653            CipherKind::CAMELLIA_192_CFB1 => "camellia-192-cfb1",
654            #[cfg(feature = "v1-stream")]
655            CipherKind::CAMELLIA_192_CFB8 => "camellia-192-cfb8",
656
657            #[cfg(feature = "v1-stream")]
658            CipherKind::CAMELLIA_256_CFB128 => "camellia-256-cfb",
659            #[cfg(feature = "v1-stream")]
660            CipherKind::CAMELLIA_256_CFB1 => "camellia-256-cfb1",
661            #[cfg(feature = "v1-stream")]
662            CipherKind::CAMELLIA_256_CFB8 => "camellia-256-cfb8",
663
664            #[cfg(feature = "v1-stream")]
665            CipherKind::CAMELLIA_128_OFB => "camellia-128-ofb",
666            #[cfg(feature = "v1-stream")]
667            CipherKind::CAMELLIA_192_OFB => "camellia-192-ofb",
668            #[cfg(feature = "v1-stream")]
669            CipherKind::CAMELLIA_256_OFB => "camellia-256-ofb",
670
671            #[cfg(feature = "v1-stream")]
672            CipherKind::RC4 => "rc4",
673            #[cfg(feature = "v1-stream")]
674            CipherKind::CHACHA20 => "chacha20-ietf",
675
676            #[cfg(feature = "v1-aead")]
677            CipherKind::AES_128_GCM => "aes-128-gcm",
678            #[cfg(feature = "v1-aead")]
679            CipherKind::AES_256_GCM => "aes-256-gcm",
680
681            #[cfg(feature = "v1-aead-extra")]
682            CipherKind::AES_128_CCM => "aes-128-ccm",
683            #[cfg(feature = "v1-aead-extra")]
684            CipherKind::AES_256_CCM => "aes-256-ccm",
685
686            #[cfg(feature = "v1-aead-extra")]
687            CipherKind::AES_128_GCM_SIV => "aes-128-gcm-siv",
688            #[cfg(feature = "v1-aead-extra")]
689            CipherKind::AES_256_GCM_SIV => "aes-256-gcm-siv",
690
691            #[cfg(feature = "v1-aead")]
692            CipherKind::CHACHA20_POLY1305 => "chacha20-ietf-poly1305",
693
694            #[cfg(feature = "v1-aead-extra")]
695            CipherKind::XCHACHA20_POLY1305 => "xchacha20-ietf-poly1305",
696
697            #[cfg(feature = "v1-aead-extra")]
698            CipherKind::SM4_GCM => "sm4-gcm",
699            #[cfg(feature = "v1-aead-extra")]
700            CipherKind::SM4_CCM => "sm4-ccm",
701
702            #[cfg(feature = "v2")]
703            CipherKind::AEAD2022_BLAKE3_AES_128_GCM => "2022-blake3-aes-128-gcm",
704            #[cfg(feature = "v2")]
705            CipherKind::AEAD2022_BLAKE3_AES_256_GCM => "2022-blake3-aes-256-gcm",
706            #[cfg(feature = "v2")]
707            CipherKind::AEAD2022_BLAKE3_CHACHA20_POLY1305 => "2022-blake3-chacha20-poly1305",
708            #[cfg(feature = "v2-extra")]
709            CipherKind::AEAD2022_BLAKE3_CHACHA8_POLY1305 => "2022-blake3-chacha8-poly1305",
710        })
711    }
712}
713
714/// Error while parsing `CipherKind` from string
715#[derive(Debug, Clone)]
716pub struct ParseCipherKindError;
717
718impl core::fmt::Display for ParseCipherKindError {
719    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
720        f.write_str("invalid CipherKind")
721    }
722}
723
724impl core::str::FromStr for CipherKind {
725    type Err = ParseCipherKindError;
726
727    fn from_str(s: &str) -> Result<Self, ParseCipherKindError> {
728        use self::CipherKind::*;
729
730        match s.to_lowercase().as_str() {
731            "plain" | "none" => Ok(NONE),
732
733            #[cfg(feature = "v1-stream")]
734            "table" | "" => Ok(SS_TABLE),
735            #[cfg(feature = "v1-stream")]
736            "rc4-md5" => Ok(SS_RC4_MD5),
737
738            #[cfg(feature = "v1-stream")]
739            "aes-128-ctr" => Ok(AES_128_CTR),
740            #[cfg(feature = "v1-stream")]
741            "aes-192-ctr" => Ok(AES_192_CTR),
742            #[cfg(feature = "v1-stream")]
743            "aes-256-ctr" => Ok(AES_256_CTR),
744
745            #[cfg(feature = "v1-stream")]
746            "aes-128-cfb" => Ok(AES_128_CFB128),
747            #[cfg(feature = "v1-stream")]
748            "aes-128-cfb1" => Ok(AES_128_CFB1),
749            #[cfg(feature = "v1-stream")]
750            "aes-128-cfb8" => Ok(AES_128_CFB8),
751            #[cfg(feature = "v1-stream")]
752            "aes-128-cfb128" => Ok(AES_128_CFB128),
753
754            #[cfg(feature = "v1-stream")]
755            "aes-192-cfb" => Ok(AES_192_CFB128),
756            #[cfg(feature = "v1-stream")]
757            "aes-192-cfb1" => Ok(AES_192_CFB1),
758            #[cfg(feature = "v1-stream")]
759            "aes-192-cfb8" => Ok(AES_192_CFB8),
760            #[cfg(feature = "v1-stream")]
761            "aes-192-cfb128" => Ok(AES_192_CFB128),
762
763            #[cfg(feature = "v1-stream")]
764            "aes-256-cfb" => Ok(AES_256_CFB128),
765            #[cfg(feature = "v1-stream")]
766            "aes-256-cfb1" => Ok(AES_256_CFB1),
767            #[cfg(feature = "v1-stream")]
768            "aes-256-cfb8" => Ok(AES_256_CFB8),
769            #[cfg(feature = "v1-stream")]
770            "aes-256-cfb128" => Ok(AES_256_CFB128),
771
772            #[cfg(feature = "v1-stream")]
773            "aes-128-ofb" => Ok(AES_128_OFB),
774            #[cfg(feature = "v1-stream")]
775            "aes-192-ofb" => Ok(AES_192_OFB),
776            #[cfg(feature = "v1-stream")]
777            "aes-256-ofb" => Ok(AES_256_OFB),
778
779            #[cfg(feature = "v1-stream")]
780            "camellia-128-ctr" => Ok(CAMELLIA_128_CTR),
781            #[cfg(feature = "v1-stream")]
782            "camellia-192-ctr" => Ok(CAMELLIA_192_CTR),
783            #[cfg(feature = "v1-stream")]
784            "camellia-256-ctr" => Ok(CAMELLIA_256_CTR),
785
786            #[cfg(feature = "v1-stream")]
787            "camellia-128-cfb" => Ok(CAMELLIA_128_CFB128),
788            #[cfg(feature = "v1-stream")]
789            "camellia-128-cfb1" => Ok(CAMELLIA_128_CFB1),
790            #[cfg(feature = "v1-stream")]
791            "camellia-128-cfb8" => Ok(CAMELLIA_128_CFB8),
792            #[cfg(feature = "v1-stream")]
793            "camellia-128-cfb128" => Ok(CAMELLIA_128_CFB128),
794
795            #[cfg(feature = "v1-stream")]
796            "camellia-192-cfb" => Ok(CAMELLIA_192_CFB128),
797            #[cfg(feature = "v1-stream")]
798            "camellia-192-cfb1" => Ok(CAMELLIA_192_CFB1),
799            #[cfg(feature = "v1-stream")]
800            "camellia-192-cfb8" => Ok(CAMELLIA_192_CFB8),
801            #[cfg(feature = "v1-stream")]
802            "camellia-192-cfb128" => Ok(CAMELLIA_192_CFB128),
803
804            #[cfg(feature = "v1-stream")]
805            "camellia-256-cfb" => Ok(CAMELLIA_256_CFB128),
806            #[cfg(feature = "v1-stream")]
807            "camellia-256-cfb1" => Ok(CAMELLIA_256_CFB1),
808            #[cfg(feature = "v1-stream")]
809            "camellia-256-cfb8" => Ok(CAMELLIA_256_CFB8),
810            #[cfg(feature = "v1-stream")]
811            "camellia-256-cfb128" => Ok(CAMELLIA_256_CFB128),
812
813            #[cfg(feature = "v1-stream")]
814            "camellia-128-ofb" => Ok(CAMELLIA_128_OFB),
815            #[cfg(feature = "v1-stream")]
816            "camellia-192-ofb" => Ok(CAMELLIA_192_OFB),
817            #[cfg(feature = "v1-stream")]
818            "camellia-256-ofb" => Ok(CAMELLIA_256_OFB),
819
820            #[cfg(feature = "v1-stream")]
821            "rc4" => Ok(RC4),
822            #[cfg(feature = "v1-stream")]
823            "chacha20-ietf" => Ok(CHACHA20),
824
825            // AEAD Ciphers
826            #[cfg(feature = "v1-aead")]
827            "aes-128-gcm" => Ok(AES_128_GCM),
828            #[cfg(feature = "v1-aead")]
829            "aes-256-gcm" => Ok(AES_256_GCM),
830
831            #[cfg(feature = "v1-aead-extra")]
832            "aes-128-ccm" => Ok(AES_128_CCM),
833            #[cfg(feature = "v1-aead-extra")]
834            "aes-256-ccm" => Ok(AES_256_CCM),
835
836            #[cfg(feature = "v1-aead-extra")]
837            "aes-128-gcm-siv" => Ok(AES_128_GCM_SIV),
838            #[cfg(feature = "v1-aead-extra")]
839            "aes-256-gcm-siv" => Ok(AES_256_GCM_SIV),
840
841            #[cfg(feature = "v1-aead")]
842            "chacha20-ietf-poly1305" => Ok(CHACHA20_POLY1305),
843
844            #[cfg(feature = "v1-aead-extra")]
845            "xchacha20-ietf-poly1305" => Ok(XCHACHA20_POLY1305),
846
847            #[cfg(feature = "v1-aead-extra")]
848            "sm4-gcm" => Ok(SM4_GCM),
849            #[cfg(feature = "v1-aead-extra")]
850            "sm4-ccm" => Ok(SM4_CCM),
851
852            #[cfg(feature = "v2")]
853            "2022-blake3-aes-128-gcm" => Ok(AEAD2022_BLAKE3_AES_128_GCM),
854            #[cfg(feature = "v2")]
855            "2022-blake3-aes-256-gcm" => Ok(AEAD2022_BLAKE3_AES_256_GCM),
856            #[cfg(feature = "v2")]
857            "2022-blake3-chacha20-poly1305" => Ok(AEAD2022_BLAKE3_CHACHA20_POLY1305),
858            #[cfg(feature = "v2-extra")]
859            "2022-blake3-chacha8-poly1305" => Ok(AEAD2022_BLAKE3_CHACHA8_POLY1305),
860
861            _ => Err(ParseCipherKindError),
862        }
863    }
864}