• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Symmetric ciphers.
2 
3 #[cfg(ossl300)]
4 use crate::cvt_p;
5 #[cfg(ossl300)]
6 use crate::error::ErrorStack;
7 #[cfg(ossl300)]
8 use crate::lib_ctx::LibCtxRef;
9 use crate::nid::Nid;
10 use cfg_if::cfg_if;
11 use foreign_types::{ForeignTypeRef, Opaque};
12 use openssl_macros::corresponds;
13 #[cfg(ossl300)]
14 use std::ffi::CString;
15 use std::ops::{Deref, DerefMut};
16 #[cfg(ossl300)]
17 use std::ptr;
18 
19 cfg_if! {
20     if #[cfg(any(boringssl, ossl110, libressl273))] {
21         use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
22     } else {
23         use libc::c_int;
24 
25         #[allow(bad_style)]
26         pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> c_int {
27             (*ptr).iv_len
28         }
29 
30         #[allow(bad_style)]
31         pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> c_int {
32             (*ptr).block_size
33         }
34 
35         #[allow(bad_style)]
36         pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> c_int {
37             (*ptr).key_len
38         }
39     }
40 }
41 
42 cfg_if! {
43     if #[cfg(ossl300)] {
44         use foreign_types::ForeignType;
45 
46         type Inner = *mut ffi::EVP_CIPHER;
47 
48         impl Drop for Cipher {
49             #[inline]
50             fn drop(&mut self) {
51                 unsafe {
52                     ffi::EVP_CIPHER_free(self.as_ptr());
53                 }
54             }
55         }
56 
57         impl ForeignType for Cipher {
58             type CType = ffi::EVP_CIPHER;
59             type Ref = CipherRef;
60 
61             #[inline]
62             unsafe fn from_ptr(ptr: *mut Self::CType) -> Self {
63                 Cipher(ptr)
64             }
65 
66             #[inline]
67             fn as_ptr(&self) -> *mut Self::CType {
68                 self.0
69             }
70         }
71 
72         impl Deref for Cipher {
73             type Target = CipherRef;
74 
75             #[inline]
76             fn deref(&self) -> &Self::Target {
77                 unsafe {
78                     CipherRef::from_ptr(self.as_ptr())
79                 }
80             }
81         }
82 
83         impl DerefMut for Cipher {
84             #[inline]
85             fn deref_mut(&mut self) -> &mut Self::Target {
86                 unsafe {
87                     CipherRef::from_ptr_mut(self.as_ptr())
88                 }
89             }
90         }
91     } else {
92         enum Inner {}
93 
94         impl Deref for Cipher {
95             type Target = CipherRef;
96 
97             #[inline]
98             fn deref(&self) -> &Self::Target {
99                 match self.0 {}
100             }
101         }
102 
103         impl DerefMut for Cipher {
104             #[inline]
105             fn deref_mut(&mut self) -> &mut Self::Target {
106                 match self.0 {}
107             }
108         }
109     }
110 }
111 
112 /// A symmetric cipher.
113 pub struct Cipher(Inner);
114 
115 unsafe impl Sync for Cipher {}
116 unsafe impl Send for Cipher {}
117 
118 impl Cipher {
119     /// Looks up the cipher for a certain nid.
120     #[corresponds(EVP_get_cipherbynid)]
from_nid(nid: Nid) -> Option<&'static CipherRef>121     pub fn from_nid(nid: Nid) -> Option<&'static CipherRef> {
122         unsafe {
123             let ptr = ffi::EVP_get_cipherbyname(ffi::OBJ_nid2sn(nid.as_raw()));
124             if ptr.is_null() {
125                 None
126             } else {
127                 Some(CipherRef::from_ptr(ptr as *mut _))
128             }
129         }
130     }
131 
132     /// Fetches a cipher object corresponding to the specified algorithm name and properties.
133     ///
134     /// Requires OpenSSL 3.0.0 or newer.
135     #[corresponds(EVP_CIPHER_fetch)]
136     #[cfg(ossl300)]
fetch( ctx: Option<&LibCtxRef>, algorithm: &str, properties: Option<&str>, ) -> Result<Self, ErrorStack>137     pub fn fetch(
138         ctx: Option<&LibCtxRef>,
139         algorithm: &str,
140         properties: Option<&str>,
141     ) -> Result<Self, ErrorStack> {
142         let algorithm = CString::new(algorithm).unwrap();
143         let properties = properties.map(|s| CString::new(s).unwrap());
144 
145         unsafe {
146             let ptr = cvt_p(ffi::EVP_CIPHER_fetch(
147                 ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr),
148                 algorithm.as_ptr(),
149                 properties.map_or(ptr::null_mut(), |s| s.as_ptr()),
150             ))?;
151 
152             Ok(Cipher::from_ptr(ptr))
153         }
154     }
155 
aes_128_ecb() -> &'static CipherRef156     pub fn aes_128_ecb() -> &'static CipherRef {
157         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ecb() as *mut _) }
158     }
159 
aes_128_cbc() -> &'static CipherRef160     pub fn aes_128_cbc() -> &'static CipherRef {
161         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cbc() as *mut _) }
162     }
163 
164     #[cfg(not(boringssl))]
aes_128_xts() -> &'static CipherRef165     pub fn aes_128_xts() -> &'static CipherRef {
166         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_xts() as *mut _) }
167     }
168 
169     #[cfg(not(boringssl))]
aes_128_ctr() -> &'static CipherRef170     pub fn aes_128_ctr() -> &'static CipherRef {
171         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ctr() as *mut _) }
172     }
173 
174     #[cfg(not(boringssl))]
aes_128_cfb1() -> &'static CipherRef175     pub fn aes_128_cfb1() -> &'static CipherRef {
176         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb1() as *mut _) }
177     }
178 
179     #[cfg(not(boringssl))]
aes_128_cfb128() -> &'static CipherRef180     pub fn aes_128_cfb128() -> &'static CipherRef {
181         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb128() as *mut _) }
182     }
183 
184     #[cfg(not(boringssl))]
aes_128_cfb8() -> &'static CipherRef185     pub fn aes_128_cfb8() -> &'static CipherRef {
186         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb8() as *mut _) }
187     }
188 
aes_128_gcm() -> &'static CipherRef189     pub fn aes_128_gcm() -> &'static CipherRef {
190         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_gcm() as *mut _) }
191     }
192 
193     #[cfg(not(boringssl))]
aes_128_ccm() -> &'static CipherRef194     pub fn aes_128_ccm() -> &'static CipherRef {
195         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ccm() as *mut _) }
196     }
197 
198     #[cfg(not(boringssl))]
aes_128_ofb() -> &'static CipherRef199     pub fn aes_128_ofb() -> &'static CipherRef {
200         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ofb() as *mut _) }
201     }
202 
203     /// Requires OpenSSL 1.1.0 or newer.
204     #[cfg(ossl110)]
aes_128_ocb() -> &'static CipherRef205     pub fn aes_128_ocb() -> &'static CipherRef {
206         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ocb() as *mut _) }
207     }
208 
209     /// Requires OpenSSL 1.0.2 or newer.
210     #[cfg(ossl102)]
aes_128_wrap() -> &'static CipherRef211     pub fn aes_128_wrap() -> &'static CipherRef {
212         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_wrap() as *mut _) }
213     }
214 
215     /// Requires OpenSSL 1.1.0 or newer.
216     #[cfg(ossl110)]
aes_128_wrap_pad() -> &'static CipherRef217     pub fn aes_128_wrap_pad() -> &'static CipherRef {
218         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_wrap_pad() as *mut _) }
219     }
220 
aes_192_ecb() -> &'static CipherRef221     pub fn aes_192_ecb() -> &'static CipherRef {
222         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ecb() as *mut _) }
223     }
224 
aes_192_cbc() -> &'static CipherRef225     pub fn aes_192_cbc() -> &'static CipherRef {
226         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cbc() as *mut _) }
227     }
228 
aes_192_ctr() -> &'static CipherRef229     pub fn aes_192_ctr() -> &'static CipherRef {
230         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ctr() as *mut _) }
231     }
232 
233     #[cfg(not(boringssl))]
aes_192_cfb1() -> &'static CipherRef234     pub fn aes_192_cfb1() -> &'static CipherRef {
235         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb1() as *mut _) }
236     }
237 
aes_192_cfb128() -> &'static CipherRef238     pub fn aes_192_cfb128() -> &'static CipherRef {
239         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb128() as *mut _) }
240     }
241 
242     #[cfg(not(boringssl))]
aes_192_cfb8() -> &'static CipherRef243     pub fn aes_192_cfb8() -> &'static CipherRef {
244         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb8() as *mut _) }
245     }
246 
aes_192_gcm() -> &'static CipherRef247     pub fn aes_192_gcm() -> &'static CipherRef {
248         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_gcm() as *mut _) }
249     }
250 
251     #[cfg(not(boringssl))]
aes_192_ccm() -> &'static CipherRef252     pub fn aes_192_ccm() -> &'static CipherRef {
253         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ccm() as *mut _) }
254     }
255 
aes_192_ofb() -> &'static CipherRef256     pub fn aes_192_ofb() -> &'static CipherRef {
257         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ofb() as *mut _) }
258     }
259 
260     /// Requires OpenSSL 1.1.0 or newer.
261     #[cfg(ossl110)]
aes_192_ocb() -> &'static CipherRef262     pub fn aes_192_ocb() -> &'static CipherRef {
263         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ocb() as *mut _) }
264     }
265 
266     /// Requires OpenSSL 1.0.2 or newer.
267     #[cfg(ossl102)]
aes_192_wrap() -> &'static CipherRef268     pub fn aes_192_wrap() -> &'static CipherRef {
269         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap() as *mut _) }
270     }
271 
272     /// Requires OpenSSL 1.1.0 or newer.
273     #[cfg(ossl110)]
aes_192_wrap_pad() -> &'static CipherRef274     pub fn aes_192_wrap_pad() -> &'static CipherRef {
275         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap_pad() as *mut _) }
276     }
277 
aes_256_ecb() -> &'static CipherRef278     pub fn aes_256_ecb() -> &'static CipherRef {
279         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ecb() as *mut _) }
280     }
281 
aes_256_cbc() -> &'static CipherRef282     pub fn aes_256_cbc() -> &'static CipherRef {
283         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cbc() as *mut _) }
284     }
285 
aes_256_ctr() -> &'static CipherRef286     pub fn aes_256_ctr() -> &'static CipherRef {
287         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ctr() as *mut _) }
288     }
289 
290     #[cfg(not(boringssl))]
aes_256_cfb1() -> &'static CipherRef291     pub fn aes_256_cfb1() -> &'static CipherRef {
292         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb1() as *mut _) }
293     }
294 
aes_256_cfb128() -> &'static CipherRef295     pub fn aes_256_cfb128() -> &'static CipherRef {
296         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb128() as *mut _) }
297     }
298 
299     #[cfg(not(boringssl))]
aes_256_cfb8() -> &'static CipherRef300     pub fn aes_256_cfb8() -> &'static CipherRef {
301         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb8() as *mut _) }
302     }
303 
aes_256_gcm() -> &'static CipherRef304     pub fn aes_256_gcm() -> &'static CipherRef {
305         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_gcm() as *mut _) }
306     }
307 
308     #[cfg(not(boringssl))]
aes_256_ccm() -> &'static CipherRef309     pub fn aes_256_ccm() -> &'static CipherRef {
310         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ccm() as *mut _) }
311     }
312 
aes_256_ofb() -> &'static CipherRef313     pub fn aes_256_ofb() -> &'static CipherRef {
314         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ofb() as *mut _) }
315     }
316 
317     /// Requires OpenSSL 1.1.0 or newer.
318     #[cfg(ossl110)]
aes_256_ocb() -> &'static CipherRef319     pub fn aes_256_ocb() -> &'static CipherRef {
320         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ocb() as *mut _) }
321     }
322 
323     /// Requires OpenSSL 1.0.2 or newer.
324     #[cfg(ossl102)]
aes_256_wrap() -> &'static CipherRef325     pub fn aes_256_wrap() -> &'static CipherRef {
326         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap() as *mut _) }
327     }
328 
329     /// Requires OpenSSL 1.1.0 or newer.
330     #[cfg(ossl110)]
aes_256_wrap_pad() -> &'static CipherRef331     pub fn aes_256_wrap_pad() -> &'static CipherRef {
332         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap_pad() as *mut _) }
333     }
334 
335     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
bf_cbc() -> &'static CipherRef336     pub fn bf_cbc() -> &'static CipherRef {
337         unsafe { CipherRef::from_ptr(ffi::EVP_bf_cbc() as *mut _) }
338     }
339 
340     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
bf_ecb() -> &'static CipherRef341     pub fn bf_ecb() -> &'static CipherRef {
342         unsafe { CipherRef::from_ptr(ffi::EVP_bf_ecb() as *mut _) }
343     }
344 
345     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
346     #[cfg(not(boringssl))]
bf_cfb64() -> &'static CipherRef347     pub fn bf_cfb64() -> &'static CipherRef {
348         unsafe { CipherRef::from_ptr(ffi::EVP_bf_cfb64() as *mut _) }
349     }
350 
351     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
352     #[cfg(not(boringssl))]
bf_ofb() -> &'static CipherRef353     pub fn bf_ofb() -> &'static CipherRef {
354         unsafe { CipherRef::from_ptr(ffi::EVP_bf_ofb() as *mut _) }
355     }
356 
des_cbc() -> &'static CipherRef357     pub fn des_cbc() -> &'static CipherRef {
358         unsafe { CipherRef::from_ptr(ffi::EVP_des_cbc() as *mut _) }
359     }
360 
des_ecb() -> &'static CipherRef361     pub fn des_ecb() -> &'static CipherRef {
362         unsafe { CipherRef::from_ptr(ffi::EVP_des_ecb() as *mut _) }
363     }
364 
des_ede3() -> &'static CipherRef365     pub fn des_ede3() -> &'static CipherRef {
366         unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3() as *mut _) }
367     }
368 
des_ede3_cbc() -> &'static CipherRef369     pub fn des_ede3_cbc() -> &'static CipherRef {
370         unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cbc() as *mut _) }
371     }
372 
373     #[cfg(not(boringssl))]
des_ede3_cfb64() -> &'static CipherRef374     pub fn des_ede3_cfb64() -> &'static CipherRef {
375         unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb64() as *mut _) }
376     }
377 
378     #[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
rc4() -> &'static CipherRef379     pub fn rc4() -> &'static CipherRef {
380         unsafe { CipherRef::from_ptr(ffi::EVP_rc4() as *mut _) }
381     }
382 
383     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
camellia128_cfb128() -> &'static CipherRef384     pub fn camellia128_cfb128() -> &'static CipherRef {
385         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cfb128() as *mut _) }
386     }
387 
388     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
camellia128_ecb() -> &'static CipherRef389     pub fn camellia128_ecb() -> &'static CipherRef {
390         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ecb() as *mut _) }
391     }
392 
393     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
camellia192_cfb128() -> &'static CipherRef394     pub fn camellia192_cfb128() -> &'static CipherRef {
395         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cfb128() as *mut _) }
396     }
397 
398     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
camellia192_ecb() -> &'static CipherRef399     pub fn camellia192_ecb() -> &'static CipherRef {
400         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ecb() as *mut _) }
401     }
402 
403     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
camellia256_cfb128() -> &'static CipherRef404     pub fn camellia256_cfb128() -> &'static CipherRef {
405         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cfb128() as *mut _) }
406     }
407 
408     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
camellia256_ecb() -> &'static CipherRef409     pub fn camellia256_ecb() -> &'static CipherRef {
410         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ecb() as *mut _) }
411     }
412 
413     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAST")))]
cast5_cfb64() -> &'static CipherRef414     pub fn cast5_cfb64() -> &'static CipherRef {
415         unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cfb64() as *mut _) }
416     }
417 
418     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAST")))]
cast5_ecb() -> &'static CipherRef419     pub fn cast5_ecb() -> &'static CipherRef {
420         unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ecb() as *mut _) }
421     }
422 
423     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_IDEA")))]
idea_cfb64() -> &'static CipherRef424     pub fn idea_cfb64() -> &'static CipherRef {
425         unsafe { CipherRef::from_ptr(ffi::EVP_idea_cfb64() as *mut _) }
426     }
427 
428     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_IDEA")))]
idea_ecb() -> &'static CipherRef429     pub fn idea_ecb() -> &'static CipherRef {
430         unsafe { CipherRef::from_ptr(ffi::EVP_idea_ecb() as *mut _) }
431     }
432 
433     #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))]
chacha20() -> &'static CipherRef434     pub fn chacha20() -> &'static CipherRef {
435         unsafe { CipherRef::from_ptr(ffi::EVP_chacha20() as *mut _) }
436     }
437 
438     #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))]
chacha20_poly1305() -> &'static CipherRef439     pub fn chacha20_poly1305() -> &'static CipherRef {
440         unsafe { CipherRef::from_ptr(ffi::EVP_chacha20_poly1305() as *mut _) }
441     }
442 
443     #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
444     #[cfg(not(boringssl))]
seed_cbc() -> &'static CipherRef445     pub fn seed_cbc() -> &'static CipherRef {
446         unsafe { CipherRef::from_ptr(ffi::EVP_seed_cbc() as *mut _) }
447     }
448 
449     #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
450     #[cfg(not(boringssl))]
seed_cfb128() -> &'static CipherRef451     pub fn seed_cfb128() -> &'static CipherRef {
452         unsafe { CipherRef::from_ptr(ffi::EVP_seed_cfb128() as *mut _) }
453     }
454 
455     #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
456     #[cfg(not(boringssl))]
seed_ecb() -> &'static CipherRef457     pub fn seed_ecb() -> &'static CipherRef {
458         unsafe { CipherRef::from_ptr(ffi::EVP_seed_ecb() as *mut _) }
459     }
460 
461     #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
462     #[cfg(not(boringssl))]
seed_ofb() -> &'static CipherRef463     pub fn seed_ofb() -> &'static CipherRef {
464         unsafe { CipherRef::from_ptr(ffi::EVP_seed_ofb() as *mut _) }
465     }
466 
467     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_ecb() -> &'static CipherRef468     pub fn sm4_ecb() -> &'static CipherRef {
469         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ecb() as *mut _) }
470     }
471 
472     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_cbc() -> &'static CipherRef473     pub fn sm4_cbc() -> &'static CipherRef {
474         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cbc() as *mut _) }
475     }
476 
477     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_ctr() -> &'static CipherRef478     pub fn sm4_ctr() -> &'static CipherRef {
479         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ctr() as *mut _) }
480     }
481 
482     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_cfb128() -> &'static CipherRef483     pub fn sm4_cfb128() -> &'static CipherRef {
484         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cfb128() as *mut _) }
485     }
486 
487     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_ofb() -> &'static CipherRef488     pub fn sm4_ofb() -> &'static CipherRef {
489         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ofb() as *mut _) }
490     }
491 }
492 
493 /// A reference to a [`Cipher`].
494 pub struct CipherRef(Opaque);
495 
496 impl ForeignTypeRef for CipherRef {
497     type CType = ffi::EVP_CIPHER;
498 }
499 
500 unsafe impl Sync for CipherRef {}
501 unsafe impl Send for CipherRef {}
502 
503 impl CipherRef {
504     /// Returns the cipher's Nid.
505     #[corresponds(EVP_CIPHER_nid)]
nid(&self) -> Nid506     pub fn nid(&self) -> Nid {
507         let nid = unsafe { ffi::EVP_CIPHER_nid(self.as_ptr()) };
508         Nid::from_raw(nid)
509     }
510 
511     /// Returns the length of keys used with this cipher.
512     #[corresponds(EVP_CIPHER_key_length)]
key_length(&self) -> usize513     pub fn key_length(&self) -> usize {
514         unsafe { EVP_CIPHER_key_length(self.as_ptr()) as usize }
515     }
516 
517     /// Returns the length of the IV used with this cipher.
518     ///
519     /// # Note
520     ///
521     /// Ciphers that do not use an IV have an IV length of 0.
522     #[corresponds(EVP_CIPHER_iv_length)]
iv_length(&self) -> usize523     pub fn iv_length(&self) -> usize {
524         unsafe { EVP_CIPHER_iv_length(self.as_ptr()) as usize }
525     }
526 
527     /// Returns the block size of the cipher.
528     ///
529     /// # Note
530     ///
531     /// Stream ciphers have a block size of 1.
532     #[corresponds(EVP_CIPHER_block_size)]
block_size(&self) -> usize533     pub fn block_size(&self) -> usize {
534         unsafe { EVP_CIPHER_block_size(self.as_ptr()) as usize }
535     }
536 }
537