variant_ssl/
cipher.rs

1//! Symmetric ciphers.
2
3#[cfg(ossl300)]
4use crate::cvt_p;
5#[cfg(ossl300)]
6use crate::error::ErrorStack;
7#[cfg(ossl300)]
8use crate::lib_ctx::LibCtxRef;
9use crate::nid::Nid;
10use cfg_if::cfg_if;
11use foreign_types::{ForeignTypeRef, Opaque};
12use openssl_macros::corresponds;
13#[cfg(ossl300)]
14use std::ffi::CString;
15use std::ops::{Deref, DerefMut};
16#[cfg(ossl300)]
17use std::ptr;
18
19use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
20
21cfg_if! {
22    if #[cfg(ossl300)] {
23        use foreign_types::ForeignType;
24
25        type Inner = *mut ffi::EVP_CIPHER;
26
27        impl Drop for Cipher {
28            #[inline]
29            fn drop(&mut self) {
30                unsafe {
31                    ffi::EVP_CIPHER_free(self.as_ptr());
32                }
33            }
34        }
35
36        impl ForeignType for Cipher {
37            type CType = ffi::EVP_CIPHER;
38            type Ref = CipherRef;
39
40            #[inline]
41            unsafe fn from_ptr(ptr: *mut Self::CType) -> Self {
42                Cipher(ptr)
43            }
44
45            #[inline]
46            fn as_ptr(&self) -> *mut Self::CType {
47                self.0
48            }
49        }
50
51        impl Deref for Cipher {
52            type Target = CipherRef;
53
54            #[inline]
55            fn deref(&self) -> &Self::Target {
56                unsafe {
57                    CipherRef::from_ptr(self.as_ptr())
58                }
59            }
60        }
61
62        impl DerefMut for Cipher {
63            #[inline]
64            fn deref_mut(&mut self) -> &mut Self::Target {
65                unsafe {
66                    CipherRef::from_ptr_mut(self.as_ptr())
67                }
68            }
69        }
70    } else {
71        enum Inner {}
72
73        impl Deref for Cipher {
74            type Target = CipherRef;
75
76            #[inline]
77            fn deref(&self) -> &Self::Target {
78                match self.0 {}
79            }
80        }
81
82        impl DerefMut for Cipher {
83            #[inline]
84            fn deref_mut(&mut self) -> &mut Self::Target {
85                match self.0 {}
86            }
87        }
88    }
89}
90
91/// A symmetric cipher.
92pub struct Cipher(Inner);
93
94unsafe impl Sync for Cipher {}
95unsafe impl Send for Cipher {}
96
97impl Cipher {
98    /// Looks up the cipher for a certain nid.
99    #[corresponds(EVP_get_cipherbynid)]
100    pub fn from_nid(nid: Nid) -> Option<&'static CipherRef> {
101        unsafe {
102            let ptr = ffi::EVP_get_cipherbyname(ffi::OBJ_nid2sn(nid.as_raw()));
103            if ptr.is_null() {
104                None
105            } else {
106                Some(CipherRef::from_ptr(ptr as *mut _))
107            }
108        }
109    }
110
111    /// Fetches a cipher object corresponding to the specified algorithm name and properties.
112    ///
113    /// Requires OpenSSL 3.0.0 or newer.
114    #[corresponds(EVP_CIPHER_fetch)]
115    #[cfg(ossl300)]
116    pub fn fetch(
117        ctx: Option<&LibCtxRef>,
118        algorithm: &str,
119        properties: Option<&str>,
120    ) -> Result<Self, ErrorStack> {
121        let algorithm = CString::new(algorithm).unwrap();
122        let properties = properties.map(|s| CString::new(s).unwrap());
123
124        unsafe {
125            let ptr = cvt_p(ffi::EVP_CIPHER_fetch(
126                ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr),
127                algorithm.as_ptr(),
128                properties.as_ref().map_or(ptr::null_mut(), |s| s.as_ptr()),
129            ))?;
130
131            Ok(Cipher::from_ptr(ptr))
132        }
133    }
134
135    pub fn aes_128_ecb() -> &'static CipherRef {
136        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ecb() as *mut _) }
137    }
138
139    pub fn aes_128_cbc() -> &'static CipherRef {
140        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cbc() as *mut _) }
141    }
142
143    #[cfg(not(any(boringssl, awslc)))]
144    pub fn aes_128_xts() -> &'static CipherRef {
145        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_xts() as *mut _) }
146    }
147
148    #[cfg(not(boringssl))]
149    pub fn aes_256_xts() -> &'static CipherRef {
150        unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_xts() as *mut _) }
151    }
152
153    pub fn aes_128_ctr() -> &'static CipherRef {
154        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ctr() as *mut _) }
155    }
156
157    #[cfg(not(boringssl))]
158    pub fn aes_128_cfb1() -> &'static CipherRef {
159        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb1() as *mut _) }
160    }
161
162    #[cfg(not(boringssl))]
163    pub fn aes_128_cfb128() -> &'static CipherRef {
164        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb128() as *mut _) }
165    }
166
167    #[cfg(not(boringssl))]
168    pub fn aes_128_cfb8() -> &'static CipherRef {
169        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb8() as *mut _) }
170    }
171
172    pub fn aes_128_gcm() -> &'static CipherRef {
173        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_gcm() as *mut _) }
174    }
175
176    #[cfg(not(boringssl))]
177    pub fn aes_128_ccm() -> &'static CipherRef {
178        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ccm() as *mut _) }
179    }
180
181    pub fn aes_128_ofb() -> &'static CipherRef {
182        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ofb() as *mut _) }
183    }
184
185    /// Requires OpenSSL 1.1.0 or newer.
186    #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
187    pub fn aes_128_ocb() -> &'static CipherRef {
188        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ocb() as *mut _) }
189    }
190
191    /// Requires OpenSSL 1.1.0 or newer.
192    #[cfg(ossl110)]
193    pub fn aes_128_wrap() -> &'static CipherRef {
194        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_wrap() as *mut _) }
195    }
196
197    /// Requires OpenSSL 1.1.0 or newer.
198    #[cfg(ossl110)]
199    pub fn aes_128_wrap_pad() -> &'static CipherRef {
200        unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_wrap_pad() as *mut _) }
201    }
202
203    pub fn aes_192_ecb() -> &'static CipherRef {
204        unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ecb() as *mut _) }
205    }
206
207    pub fn aes_192_cbc() -> &'static CipherRef {
208        unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cbc() as *mut _) }
209    }
210
211    pub fn aes_192_ctr() -> &'static CipherRef {
212        unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ctr() as *mut _) }
213    }
214
215    #[cfg(not(boringssl))]
216    pub fn aes_192_cfb1() -> &'static CipherRef {
217        unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb1() as *mut _) }
218    }
219
220    #[cfg(not(boringssl))]
221    pub fn aes_192_cfb128() -> &'static CipherRef {
222        unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb128() as *mut _) }
223    }
224
225    #[cfg(not(boringssl))]
226    pub fn aes_192_cfb8() -> &'static CipherRef {
227        unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb8() as *mut _) }
228    }
229
230    pub fn aes_192_gcm() -> &'static CipherRef {
231        unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_gcm() as *mut _) }
232    }
233
234    #[cfg(not(boringssl))]
235    pub fn aes_192_ccm() -> &'static CipherRef {
236        unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ccm() as *mut _) }
237    }
238
239    pub fn aes_192_ofb() -> &'static CipherRef {
240        unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ofb() as *mut _) }
241    }
242
243    /// Requires OpenSSL 1.1.0 or newer.
244    #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
245    pub fn aes_192_ocb() -> &'static CipherRef {
246        unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ocb() as *mut _) }
247    }
248
249    /// Requires OpenSSL 1.1.0 or newer.
250    #[cfg(ossl110)]
251    pub fn aes_192_wrap() -> &'static CipherRef {
252        unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap() as *mut _) }
253    }
254
255    /// Requires OpenSSL 1.1.0 or newer.
256    #[cfg(ossl110)]
257    pub fn aes_192_wrap_pad() -> &'static CipherRef {
258        unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap_pad() as *mut _) }
259    }
260
261    pub fn aes_256_ecb() -> &'static CipherRef {
262        unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ecb() as *mut _) }
263    }
264
265    pub fn aes_256_cbc() -> &'static CipherRef {
266        unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cbc() as *mut _) }
267    }
268
269    pub fn aes_256_ctr() -> &'static CipherRef {
270        unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ctr() as *mut _) }
271    }
272
273    #[cfg(not(boringssl))]
274    pub fn aes_256_cfb1() -> &'static CipherRef {
275        unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb1() as *mut _) }
276    }
277
278    #[cfg(not(boringssl))]
279    pub fn aes_256_cfb128() -> &'static CipherRef {
280        unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb128() as *mut _) }
281    }
282
283    #[cfg(not(boringssl))]
284    pub fn aes_256_cfb8() -> &'static CipherRef {
285        unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb8() as *mut _) }
286    }
287
288    pub fn aes_256_gcm() -> &'static CipherRef {
289        unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_gcm() as *mut _) }
290    }
291
292    #[cfg(not(boringssl))]
293    pub fn aes_256_ccm() -> &'static CipherRef {
294        unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ccm() as *mut _) }
295    }
296
297    pub fn aes_256_ofb() -> &'static CipherRef {
298        unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ofb() as *mut _) }
299    }
300
301    /// Requires OpenSSL 1.1.0 or newer.
302    #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
303    pub fn aes_256_ocb() -> &'static CipherRef {
304        unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ocb() as *mut _) }
305    }
306
307    /// Requires OpenSSL 1.1.0 or newer.
308    #[cfg(ossl110)]
309    pub fn aes_256_wrap() -> &'static CipherRef {
310        unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap() as *mut _) }
311    }
312
313    /// Requires OpenSSL 1.1.0 or newer.
314    #[cfg(ossl110)]
315    pub fn aes_256_wrap_pad() -> &'static CipherRef {
316        unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap_pad() as *mut _) }
317    }
318
319    #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
320    pub fn bf_cbc() -> &'static CipherRef {
321        unsafe { CipherRef::from_ptr(ffi::EVP_bf_cbc() as *mut _) }
322    }
323
324    #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
325    pub fn bf_ecb() -> &'static CipherRef {
326        unsafe { CipherRef::from_ptr(ffi::EVP_bf_ecb() as *mut _) }
327    }
328
329    #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
330    pub fn bf_cfb64() -> &'static CipherRef {
331        unsafe { CipherRef::from_ptr(ffi::EVP_bf_cfb64() as *mut _) }
332    }
333
334    #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
335    pub fn bf_ofb() -> &'static CipherRef {
336        unsafe { CipherRef::from_ptr(ffi::EVP_bf_ofb() as *mut _) }
337    }
338
339    pub fn des_cbc() -> &'static CipherRef {
340        unsafe { CipherRef::from_ptr(ffi::EVP_des_cbc() as *mut _) }
341    }
342
343    pub fn des_ecb() -> &'static CipherRef {
344        unsafe { CipherRef::from_ptr(ffi::EVP_des_ecb() as *mut _) }
345    }
346
347    pub fn des_ede3() -> &'static CipherRef {
348        unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3() as *mut _) }
349    }
350
351    pub fn des_ede3_ecb() -> &'static CipherRef {
352        unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_ecb() as *mut _) }
353    }
354
355    pub fn des_ede3_cbc() -> &'static CipherRef {
356        unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cbc() as *mut _) }
357    }
358
359    #[cfg(not(any(boringssl, awslc)))]
360    pub fn des_ede3_cfb8() -> &'static CipherRef {
361        unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb8() as *mut _) }
362    }
363
364    #[cfg(not(any(boringssl, awslc)))]
365    pub fn des_ede3_cfb64() -> &'static CipherRef {
366        unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb64() as *mut _) }
367    }
368
369    #[cfg(not(any(boringssl, awslc)))]
370    pub fn des_ede3_ofb() -> &'static CipherRef {
371        unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_ofb() as *mut _) }
372    }
373
374    #[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
375    pub fn rc4() -> &'static CipherRef {
376        unsafe { CipherRef::from_ptr(ffi::EVP_rc4() as *mut _) }
377    }
378
379    #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
380    pub fn camellia128_cfb128() -> &'static CipherRef {
381        unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cfb128() as *mut _) }
382    }
383
384    #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
385    pub fn camellia128_ecb() -> &'static CipherRef {
386        unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ecb() as *mut _) }
387    }
388
389    #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
390    pub fn camellia128_cbc() -> &'static CipherRef {
391        unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cbc() as *mut _) }
392    }
393
394    #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
395    pub fn camellia128_ofb() -> &'static CipherRef {
396        unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ofb() as *mut _) }
397    }
398
399    #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
400    pub fn camellia192_cfb128() -> &'static CipherRef {
401        unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cfb128() as *mut _) }
402    }
403
404    #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
405    pub fn camellia192_ecb() -> &'static CipherRef {
406        unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ecb() as *mut _) }
407    }
408
409    #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
410    pub fn camellia192_cbc() -> &'static CipherRef {
411        unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cbc() as *mut _) }
412    }
413
414    #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
415    pub fn camellia192_ofb() -> &'static CipherRef {
416        unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ofb() as *mut _) }
417    }
418
419    #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
420    pub fn camellia256_cfb128() -> &'static CipherRef {
421        unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cfb128() as *mut _) }
422    }
423
424    #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
425    pub fn camellia256_ecb() -> &'static CipherRef {
426        unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ecb() as *mut _) }
427    }
428
429    #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
430    pub fn camellia256_cbc() -> &'static CipherRef {
431        unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cbc() as *mut _) }
432    }
433
434    #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
435    pub fn camellia256_ofb() -> &'static CipherRef {
436        unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ofb() as *mut _) }
437    }
438
439    #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
440    pub fn cast5_cfb64() -> &'static CipherRef {
441        unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cfb64() as *mut _) }
442    }
443
444    #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
445    pub fn cast5_ecb() -> &'static CipherRef {
446        unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ecb() as *mut _) }
447    }
448
449    #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
450    pub fn cast5_cbc() -> &'static CipherRef {
451        unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cbc() as *mut _) }
452    }
453
454    #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
455    pub fn cast5_ofb() -> &'static CipherRef {
456        unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ofb() as *mut _) }
457    }
458
459    #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
460    pub fn idea_cfb64() -> &'static CipherRef {
461        unsafe { CipherRef::from_ptr(ffi::EVP_idea_cfb64() as *mut _) }
462    }
463
464    #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
465    pub fn idea_ecb() -> &'static CipherRef {
466        unsafe { CipherRef::from_ptr(ffi::EVP_idea_ecb() as *mut _) }
467    }
468
469    #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
470    pub fn idea_cbc() -> &'static CipherRef {
471        unsafe { CipherRef::from_ptr(ffi::EVP_idea_cbc() as *mut _) }
472    }
473
474    #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
475    pub fn idea_ofb() -> &'static CipherRef {
476        unsafe { CipherRef::from_ptr(ffi::EVP_idea_ofb() as *mut _) }
477    }
478
479    #[cfg(all(any(ossl110, libressl), not(osslconf = "OPENSSL_NO_CHACHA")))]
480    pub fn chacha20() -> &'static CipherRef {
481        unsafe { CipherRef::from_ptr(ffi::EVP_chacha20() as *mut _) }
482    }
483
484    #[cfg(all(any(ossl110, libressl360, awslc), not(osslconf = "OPENSSL_NO_CHACHA")))]
485    pub fn chacha20_poly1305() -> &'static CipherRef {
486        unsafe { CipherRef::from_ptr(ffi::EVP_chacha20_poly1305() as *mut _) }
487    }
488
489    #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
490    pub fn seed_cbc() -> &'static CipherRef {
491        unsafe { CipherRef::from_ptr(ffi::EVP_seed_cbc() as *mut _) }
492    }
493
494    #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
495    pub fn seed_cfb128() -> &'static CipherRef {
496        unsafe { CipherRef::from_ptr(ffi::EVP_seed_cfb128() as *mut _) }
497    }
498
499    #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
500    pub fn seed_ecb() -> &'static CipherRef {
501        unsafe { CipherRef::from_ptr(ffi::EVP_seed_ecb() as *mut _) }
502    }
503
504    #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
505    pub fn seed_ofb() -> &'static CipherRef {
506        unsafe { CipherRef::from_ptr(ffi::EVP_seed_ofb() as *mut _) }
507    }
508
509    #[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
510    pub fn sm4_ecb() -> &'static CipherRef {
511        unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ecb() as *mut _) }
512    }
513
514    #[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
515    pub fn sm4_cbc() -> &'static CipherRef {
516        unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cbc() as *mut _) }
517    }
518
519    #[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
520    pub fn sm4_ctr() -> &'static CipherRef {
521        unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ctr() as *mut _) }
522    }
523
524    #[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
525    pub fn sm4_cfb128() -> &'static CipherRef {
526        unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cfb128() as *mut _) }
527    }
528
529    #[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
530    pub fn sm4_ofb() -> &'static CipherRef {
531        unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ofb() as *mut _) }
532    }
533}
534
535/// A reference to a [`Cipher`].
536pub struct CipherRef(Opaque);
537
538impl ForeignTypeRef for CipherRef {
539    type CType = ffi::EVP_CIPHER;
540}
541
542unsafe impl Sync for CipherRef {}
543unsafe impl Send for CipherRef {}
544
545impl CipherRef {
546    /// Returns the cipher's Nid.
547    #[corresponds(EVP_CIPHER_nid)]
548    pub fn nid(&self) -> Nid {
549        let nid = unsafe { ffi::EVP_CIPHER_nid(self.as_ptr()) };
550        Nid::from_raw(nid)
551    }
552
553    /// Returns the length of keys used with this cipher.
554    #[corresponds(EVP_CIPHER_key_length)]
555    pub fn key_length(&self) -> usize {
556        unsafe { EVP_CIPHER_key_length(self.as_ptr()) as usize }
557    }
558
559    /// Returns the length of the IV used with this cipher.
560    ///
561    /// # Note
562    ///
563    /// Ciphers that do not use an IV have an IV length of 0.
564    #[corresponds(EVP_CIPHER_iv_length)]
565    pub fn iv_length(&self) -> usize {
566        unsafe { EVP_CIPHER_iv_length(self.as_ptr()) as usize }
567    }
568
569    /// Returns the block size of the cipher.
570    ///
571    /// # Note
572    ///
573    /// Stream ciphers have a block size of 1.
574    #[corresponds(EVP_CIPHER_block_size)]
575    pub fn block_size(&self) -> usize {
576        unsafe { EVP_CIPHER_block_size(self.as_ptr()) as usize }
577    }
578}
579
580#[cfg(test)]
581mod test {
582    #[cfg(ossl300)]
583    use super::Cipher;
584
585    #[test]
586    #[cfg(ossl300)]
587    fn test_cipher_fetch_properties() {
588        assert!(Cipher::fetch(None, "AES-128-GCM", Some("provider=gibberish")).is_err());
589    }
590}