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_256_xts() -> &'static CipherRef170     pub fn aes_256_xts() -> &'static CipherRef {
171         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_xts() as *mut _) }
172     }
173 
aes_128_ctr() -> &'static CipherRef174     pub fn aes_128_ctr() -> &'static CipherRef {
175         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ctr() as *mut _) }
176     }
177 
178     #[cfg(not(boringssl))]
aes_128_cfb1() -> &'static CipherRef179     pub fn aes_128_cfb1() -> &'static CipherRef {
180         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb1() as *mut _) }
181     }
182 
183     #[cfg(not(boringssl))]
aes_128_cfb128() -> &'static CipherRef184     pub fn aes_128_cfb128() -> &'static CipherRef {
185         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb128() as *mut _) }
186     }
187 
188     #[cfg(not(boringssl))]
aes_128_cfb8() -> &'static CipherRef189     pub fn aes_128_cfb8() -> &'static CipherRef {
190         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb8() as *mut _) }
191     }
192 
aes_128_gcm() -> &'static CipherRef193     pub fn aes_128_gcm() -> &'static CipherRef {
194         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_gcm() as *mut _) }
195     }
196 
197     #[cfg(not(boringssl))]
aes_128_ccm() -> &'static CipherRef198     pub fn aes_128_ccm() -> &'static CipherRef {
199         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ccm() as *mut _) }
200     }
201 
aes_128_ofb() -> &'static CipherRef202     pub fn aes_128_ofb() -> &'static CipherRef {
203         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ofb() as *mut _) }
204     }
205 
206     /// Requires OpenSSL 1.1.0 or newer.
207     #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
aes_128_ocb() -> &'static CipherRef208     pub fn aes_128_ocb() -> &'static CipherRef {
209         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ocb() as *mut _) }
210     }
211 
212     /// Requires OpenSSL 1.0.2 or newer.
213     #[cfg(ossl102)]
aes_128_wrap() -> &'static CipherRef214     pub fn aes_128_wrap() -> &'static CipherRef {
215         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_wrap() as *mut _) }
216     }
217 
218     /// Requires OpenSSL 1.1.0 or newer.
219     #[cfg(ossl110)]
aes_128_wrap_pad() -> &'static CipherRef220     pub fn aes_128_wrap_pad() -> &'static CipherRef {
221         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_wrap_pad() as *mut _) }
222     }
223 
aes_192_ecb() -> &'static CipherRef224     pub fn aes_192_ecb() -> &'static CipherRef {
225         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ecb() as *mut _) }
226     }
227 
aes_192_cbc() -> &'static CipherRef228     pub fn aes_192_cbc() -> &'static CipherRef {
229         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cbc() as *mut _) }
230     }
231 
aes_192_ctr() -> &'static CipherRef232     pub fn aes_192_ctr() -> &'static CipherRef {
233         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ctr() as *mut _) }
234     }
235 
236     #[cfg(not(boringssl))]
aes_192_cfb1() -> &'static CipherRef237     pub fn aes_192_cfb1() -> &'static CipherRef {
238         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb1() as *mut _) }
239     }
240 
241     #[cfg(not(boringssl))]
aes_192_cfb128() -> &'static CipherRef242     pub fn aes_192_cfb128() -> &'static CipherRef {
243         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb128() as *mut _) }
244     }
245 
246     #[cfg(not(boringssl))]
aes_192_cfb8() -> &'static CipherRef247     pub fn aes_192_cfb8() -> &'static CipherRef {
248         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb8() as *mut _) }
249     }
250 
aes_192_gcm() -> &'static CipherRef251     pub fn aes_192_gcm() -> &'static CipherRef {
252         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_gcm() as *mut _) }
253     }
254 
255     #[cfg(not(boringssl))]
aes_192_ccm() -> &'static CipherRef256     pub fn aes_192_ccm() -> &'static CipherRef {
257         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ccm() as *mut _) }
258     }
259 
aes_192_ofb() -> &'static CipherRef260     pub fn aes_192_ofb() -> &'static CipherRef {
261         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ofb() as *mut _) }
262     }
263 
264     /// Requires OpenSSL 1.1.0 or newer.
265     #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
aes_192_ocb() -> &'static CipherRef266     pub fn aes_192_ocb() -> &'static CipherRef {
267         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ocb() as *mut _) }
268     }
269 
270     /// Requires OpenSSL 1.0.2 or newer.
271     #[cfg(ossl102)]
aes_192_wrap() -> &'static CipherRef272     pub fn aes_192_wrap() -> &'static CipherRef {
273         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap() as *mut _) }
274     }
275 
276     /// Requires OpenSSL 1.1.0 or newer.
277     #[cfg(ossl110)]
aes_192_wrap_pad() -> &'static CipherRef278     pub fn aes_192_wrap_pad() -> &'static CipherRef {
279         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap_pad() as *mut _) }
280     }
281 
aes_256_ecb() -> &'static CipherRef282     pub fn aes_256_ecb() -> &'static CipherRef {
283         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ecb() as *mut _) }
284     }
285 
aes_256_cbc() -> &'static CipherRef286     pub fn aes_256_cbc() -> &'static CipherRef {
287         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cbc() as *mut _) }
288     }
289 
aes_256_ctr() -> &'static CipherRef290     pub fn aes_256_ctr() -> &'static CipherRef {
291         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ctr() as *mut _) }
292     }
293 
294     #[cfg(not(boringssl))]
aes_256_cfb1() -> &'static CipherRef295     pub fn aes_256_cfb1() -> &'static CipherRef {
296         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb1() as *mut _) }
297     }
298 
299     #[cfg(not(boringssl))]
aes_256_cfb128() -> &'static CipherRef300     pub fn aes_256_cfb128() -> &'static CipherRef {
301         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb128() as *mut _) }
302     }
303 
304     #[cfg(not(boringssl))]
aes_256_cfb8() -> &'static CipherRef305     pub fn aes_256_cfb8() -> &'static CipherRef {
306         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb8() as *mut _) }
307     }
308 
aes_256_gcm() -> &'static CipherRef309     pub fn aes_256_gcm() -> &'static CipherRef {
310         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_gcm() as *mut _) }
311     }
312 
313     #[cfg(not(boringssl))]
aes_256_ccm() -> &'static CipherRef314     pub fn aes_256_ccm() -> &'static CipherRef {
315         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ccm() as *mut _) }
316     }
317 
aes_256_ofb() -> &'static CipherRef318     pub fn aes_256_ofb() -> &'static CipherRef {
319         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ofb() as *mut _) }
320     }
321 
322     /// Requires OpenSSL 1.1.0 or newer.
323     #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
aes_256_ocb() -> &'static CipherRef324     pub fn aes_256_ocb() -> &'static CipherRef {
325         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ocb() as *mut _) }
326     }
327 
328     /// Requires OpenSSL 1.0.2 or newer.
329     #[cfg(ossl102)]
aes_256_wrap() -> &'static CipherRef330     pub fn aes_256_wrap() -> &'static CipherRef {
331         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap() as *mut _) }
332     }
333 
334     /// Requires OpenSSL 1.1.0 or newer.
335     #[cfg(ossl110)]
aes_256_wrap_pad() -> &'static CipherRef336     pub fn aes_256_wrap_pad() -> &'static CipherRef {
337         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap_pad() as *mut _) }
338     }
339 
340     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
341     #[cfg(not(boringssl))]
bf_cbc() -> &'static CipherRef342     pub fn bf_cbc() -> &'static CipherRef {
343         unsafe { CipherRef::from_ptr(ffi::EVP_bf_cbc() as *mut _) }
344     }
345 
346     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
347     #[cfg(not(boringssl))]
bf_ecb() -> &'static CipherRef348     pub fn bf_ecb() -> &'static CipherRef {
349         unsafe { CipherRef::from_ptr(ffi::EVP_bf_ecb() as *mut _) }
350     }
351 
352     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
353     #[cfg(not(boringssl))]
bf_cfb64() -> &'static CipherRef354     pub fn bf_cfb64() -> &'static CipherRef {
355         unsafe { CipherRef::from_ptr(ffi::EVP_bf_cfb64() as *mut _) }
356     }
357 
358     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
359     #[cfg(not(boringssl))]
bf_ofb() -> &'static CipherRef360     pub fn bf_ofb() -> &'static CipherRef {
361         unsafe { CipherRef::from_ptr(ffi::EVP_bf_ofb() as *mut _) }
362     }
363 
des_cbc() -> &'static CipherRef364     pub fn des_cbc() -> &'static CipherRef {
365         unsafe { CipherRef::from_ptr(ffi::EVP_des_cbc() as *mut _) }
366     }
367 
des_ecb() -> &'static CipherRef368     pub fn des_ecb() -> &'static CipherRef {
369         unsafe { CipherRef::from_ptr(ffi::EVP_des_ecb() as *mut _) }
370     }
371 
des_ede3() -> &'static CipherRef372     pub fn des_ede3() -> &'static CipherRef {
373         unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3() as *mut _) }
374     }
375 
des_ede3_ecb() -> &'static CipherRef376     pub fn des_ede3_ecb() -> &'static CipherRef {
377         unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_ecb() as *mut _) }
378     }
379 
des_ede3_cbc() -> &'static CipherRef380     pub fn des_ede3_cbc() -> &'static CipherRef {
381         unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cbc() as *mut _) }
382     }
383 
384     #[cfg(not(boringssl))]
des_ede3_cfb8() -> &'static CipherRef385     pub fn des_ede3_cfb8() -> &'static CipherRef {
386         unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb8() as *mut _) }
387     }
388 
389     #[cfg(not(boringssl))]
des_ede3_cfb64() -> &'static CipherRef390     pub fn des_ede3_cfb64() -> &'static CipherRef {
391         unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb64() as *mut _) }
392     }
393 
394     #[cfg(not(boringssl))]
des_ede3_ofb() -> &'static CipherRef395     pub fn des_ede3_ofb() -> &'static CipherRef {
396         unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_ofb() as *mut _) }
397     }
398 
399     #[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
rc4() -> &'static CipherRef400     pub fn rc4() -> &'static CipherRef {
401         unsafe { CipherRef::from_ptr(ffi::EVP_rc4() as *mut _) }
402     }
403 
404     #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
405     #[cfg(not(boringssl))]
camellia128_cfb128() -> &'static CipherRef406     pub fn camellia128_cfb128() -> &'static CipherRef {
407         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cfb128() as *mut _) }
408     }
409 
410     #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
411     #[cfg(not(boringssl))]
camellia128_ecb() -> &'static CipherRef412     pub fn camellia128_ecb() -> &'static CipherRef {
413         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ecb() as *mut _) }
414     }
415 
416     #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
417     #[cfg(not(boringssl))]
camellia128_cbc() -> &'static CipherRef418     pub fn camellia128_cbc() -> &'static CipherRef {
419         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cbc() as *mut _) }
420     }
421 
422     #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
423     #[cfg(not(boringssl))]
camellia128_ofb() -> &'static CipherRef424     pub fn camellia128_ofb() -> &'static CipherRef {
425         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ofb() as *mut _) }
426     }
427 
428     #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
429     #[cfg(not(boringssl))]
camellia192_cfb128() -> &'static CipherRef430     pub fn camellia192_cfb128() -> &'static CipherRef {
431         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cfb128() as *mut _) }
432     }
433 
434     #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
435     #[cfg(not(boringssl))]
camellia192_ecb() -> &'static CipherRef436     pub fn camellia192_ecb() -> &'static CipherRef {
437         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ecb() as *mut _) }
438     }
439 
440     #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
441     #[cfg(not(boringssl))]
camellia192_cbc() -> &'static CipherRef442     pub fn camellia192_cbc() -> &'static CipherRef {
443         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cbc() as *mut _) }
444     }
445 
446     #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
447     #[cfg(not(boringssl))]
camellia192_ofb() -> &'static CipherRef448     pub fn camellia192_ofb() -> &'static CipherRef {
449         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ofb() as *mut _) }
450     }
451 
452     #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
453     #[cfg(not(boringssl))]
camellia256_cfb128() -> &'static CipherRef454     pub fn camellia256_cfb128() -> &'static CipherRef {
455         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cfb128() as *mut _) }
456     }
457 
458     #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
459     #[cfg(not(boringssl))]
camellia256_ecb() -> &'static CipherRef460     pub fn camellia256_ecb() -> &'static CipherRef {
461         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ecb() as *mut _) }
462     }
463 
464     #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
465     #[cfg(not(boringssl))]
camellia256_cbc() -> &'static CipherRef466     pub fn camellia256_cbc() -> &'static CipherRef {
467         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cbc() as *mut _) }
468     }
469 
470     #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
471     #[cfg(not(boringssl))]
camellia256_ofb() -> &'static CipherRef472     pub fn camellia256_ofb() -> &'static CipherRef {
473         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ofb() as *mut _) }
474     }
475 
476     #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
477     #[cfg(not(boringssl))]
cast5_cfb64() -> &'static CipherRef478     pub fn cast5_cfb64() -> &'static CipherRef {
479         unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cfb64() as *mut _) }
480     }
481 
482     #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
483     #[cfg(not(boringssl))]
cast5_ecb() -> &'static CipherRef484     pub fn cast5_ecb() -> &'static CipherRef {
485         unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ecb() as *mut _) }
486     }
487 
488     #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
489     #[cfg(not(boringssl))]
cast5_cbc() -> &'static CipherRef490     pub fn cast5_cbc() -> &'static CipherRef {
491         unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cbc() as *mut _) }
492     }
493 
494     #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
495     #[cfg(not(boringssl))]
cast5_ofb() -> &'static CipherRef496     pub fn cast5_ofb() -> &'static CipherRef {
497         unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ofb() as *mut _) }
498     }
499 
500     #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
501     #[cfg(not(boringssl))]
idea_cfb64() -> &'static CipherRef502     pub fn idea_cfb64() -> &'static CipherRef {
503         unsafe { CipherRef::from_ptr(ffi::EVP_idea_cfb64() as *mut _) }
504     }
505 
506     #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
507     #[cfg(not(boringssl))]
idea_ecb() -> &'static CipherRef508     pub fn idea_ecb() -> &'static CipherRef {
509         unsafe { CipherRef::from_ptr(ffi::EVP_idea_ecb() as *mut _) }
510     }
511 
512     #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
513     #[cfg(not(boringssl))]
idea_cbc() -> &'static CipherRef514     pub fn idea_cbc() -> &'static CipherRef {
515         unsafe { CipherRef::from_ptr(ffi::EVP_idea_cbc() as *mut _) }
516     }
517 
518     #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
519     #[cfg(not(boringssl))]
idea_ofb() -> &'static CipherRef520     pub fn idea_ofb() -> &'static CipherRef {
521         unsafe { CipherRef::from_ptr(ffi::EVP_idea_ofb() as *mut _) }
522     }
523 
524     #[cfg(all(any(ossl110, libressl310), not(osslconf = "OPENSSL_NO_CHACHA")))]
chacha20() -> &'static CipherRef525     pub fn chacha20() -> &'static CipherRef {
526         unsafe { CipherRef::from_ptr(ffi::EVP_chacha20() as *mut _) }
527     }
528 
529     #[cfg(all(any(ossl110, libressl360), not(osslconf = "OPENSSL_NO_CHACHA")))]
chacha20_poly1305() -> &'static CipherRef530     pub fn chacha20_poly1305() -> &'static CipherRef {
531         unsafe { CipherRef::from_ptr(ffi::EVP_chacha20_poly1305() as *mut _) }
532     }
533 
534     #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
535     #[cfg(not(boringssl))]
seed_cbc() -> &'static CipherRef536     pub fn seed_cbc() -> &'static CipherRef {
537         unsafe { CipherRef::from_ptr(ffi::EVP_seed_cbc() as *mut _) }
538     }
539 
540     #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
541     #[cfg(not(boringssl))]
seed_cfb128() -> &'static CipherRef542     pub fn seed_cfb128() -> &'static CipherRef {
543         unsafe { CipherRef::from_ptr(ffi::EVP_seed_cfb128() as *mut _) }
544     }
545 
546     #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
547     #[cfg(not(boringssl))]
seed_ecb() -> &'static CipherRef548     pub fn seed_ecb() -> &'static CipherRef {
549         unsafe { CipherRef::from_ptr(ffi::EVP_seed_ecb() as *mut _) }
550     }
551 
552     #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
553     #[cfg(not(boringssl))]
seed_ofb() -> &'static CipherRef554     pub fn seed_ofb() -> &'static CipherRef {
555         unsafe { CipherRef::from_ptr(ffi::EVP_seed_ofb() as *mut _) }
556     }
557 
558     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_ecb() -> &'static CipherRef559     pub fn sm4_ecb() -> &'static CipherRef {
560         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ecb() as *mut _) }
561     }
562 
563     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_cbc() -> &'static CipherRef564     pub fn sm4_cbc() -> &'static CipherRef {
565         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cbc() as *mut _) }
566     }
567 
568     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_ctr() -> &'static CipherRef569     pub fn sm4_ctr() -> &'static CipherRef {
570         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ctr() as *mut _) }
571     }
572 
573     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_cfb128() -> &'static CipherRef574     pub fn sm4_cfb128() -> &'static CipherRef {
575         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cfb128() as *mut _) }
576     }
577 
578     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_ofb() -> &'static CipherRef579     pub fn sm4_ofb() -> &'static CipherRef {
580         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ofb() as *mut _) }
581     }
582 }
583 
584 /// A reference to a [`Cipher`].
585 pub struct CipherRef(Opaque);
586 
587 impl ForeignTypeRef for CipherRef {
588     type CType = ffi::EVP_CIPHER;
589 }
590 
591 unsafe impl Sync for CipherRef {}
592 unsafe impl Send for CipherRef {}
593 
594 impl CipherRef {
595     /// Returns the cipher's Nid.
596     #[corresponds(EVP_CIPHER_nid)]
nid(&self) -> Nid597     pub fn nid(&self) -> Nid {
598         let nid = unsafe { ffi::EVP_CIPHER_nid(self.as_ptr()) };
599         Nid::from_raw(nid)
600     }
601 
602     /// Returns the length of keys used with this cipher.
603     #[corresponds(EVP_CIPHER_key_length)]
key_length(&self) -> usize604     pub fn key_length(&self) -> usize {
605         unsafe { EVP_CIPHER_key_length(self.as_ptr()) as usize }
606     }
607 
608     /// Returns the length of the IV used with this cipher.
609     ///
610     /// # Note
611     ///
612     /// Ciphers that do not use an IV have an IV length of 0.
613     #[corresponds(EVP_CIPHER_iv_length)]
iv_length(&self) -> usize614     pub fn iv_length(&self) -> usize {
615         unsafe { EVP_CIPHER_iv_length(self.as_ptr()) as usize }
616     }
617 
618     /// Returns the block size of the cipher.
619     ///
620     /// # Note
621     ///
622     /// Stream ciphers have a block size of 1.
623     #[corresponds(EVP_CIPHER_block_size)]
block_size(&self) -> usize624     pub fn block_size(&self) -> usize {
625         unsafe { EVP_CIPHER_block_size(self.as_ptr()) as usize }
626     }
627 }
628