• 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 #[cfg(ossl300)]
16 use std::ptr;
17 
18 cfg_if! {
19     if #[cfg(any(boringssl, ossl110, libressl273))] {
20         use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
21     } else {
22         use libc::c_int;
23 
24         #[allow(bad_style)]
25         pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> c_int {
26             (*ptr).iv_len
27         }
28 
29         #[allow(bad_style)]
30         pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> c_int {
31             (*ptr).block_size
32         }
33 
34         #[allow(bad_style)]
35         pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> c_int {
36             (*ptr).key_len
37         }
38     }
39 }
40 
41 cfg_if! {
42     if #[cfg(ossl300)] {
43         use foreign_types::ForeignType;
44         use std::ops::{Deref, DerefMut};
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 }
95 
96 /// A symmetric cipher.
97 pub struct Cipher(Inner);
98 
99 unsafe impl Sync for Cipher {}
100 unsafe impl Send for Cipher {}
101 
102 impl Cipher {
103     /// Looks up the cipher for a certain nid.
104     #[corresponds(EVP_get_cipherbynid)]
from_nid(nid: Nid) -> Option<&'static CipherRef>105     pub fn from_nid(nid: Nid) -> Option<&'static CipherRef> {
106         unsafe {
107             let ptr = ffi::EVP_get_cipherbyname(ffi::OBJ_nid2sn(nid.as_raw()));
108             if ptr.is_null() {
109                 None
110             } else {
111                 Some(CipherRef::from_ptr(ptr as *mut _))
112             }
113         }
114     }
115 
116     /// Fetches a cipher object corresponding to the specified algorithm name and properties.
117     ///
118     /// Requires OpenSSL 3.0.0 or newer.
119     #[corresponds(EVP_CIPHER_fetch)]
120     #[cfg(ossl300)]
fetch( ctx: Option<&LibCtxRef>, algorithm: &str, properties: Option<&str>, ) -> Result<Self, ErrorStack>121     pub fn fetch(
122         ctx: Option<&LibCtxRef>,
123         algorithm: &str,
124         properties: Option<&str>,
125     ) -> Result<Self, ErrorStack> {
126         let algorithm = CString::new(algorithm).unwrap();
127         let properties = properties.map(|s| CString::new(s).unwrap());
128 
129         unsafe {
130             let ptr = cvt_p(ffi::EVP_CIPHER_fetch(
131                 ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr),
132                 algorithm.as_ptr(),
133                 properties.map_or(ptr::null_mut(), |s| s.as_ptr()),
134             ))?;
135 
136             Ok(Cipher::from_ptr(ptr))
137         }
138     }
139 
aes_128_ecb() -> &'static CipherRef140     pub fn aes_128_ecb() -> &'static CipherRef {
141         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ecb() as *mut _) }
142     }
143 
aes_128_cbc() -> &'static CipherRef144     pub fn aes_128_cbc() -> &'static CipherRef {
145         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cbc() as *mut _) }
146     }
147 
148     #[cfg(not(boringssl))]
aes_128_xts() -> &'static CipherRef149     pub fn aes_128_xts() -> &'static CipherRef {
150         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_xts() as *mut _) }
151     }
152 
153     #[cfg(not(boringssl))]
aes_128_ctr() -> &'static CipherRef154     pub fn aes_128_ctr() -> &'static CipherRef {
155         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ctr() as *mut _) }
156     }
157 
158     #[cfg(not(boringssl))]
aes_128_cfb1() -> &'static CipherRef159     pub fn aes_128_cfb1() -> &'static CipherRef {
160         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb1() as *mut _) }
161     }
162 
163     #[cfg(not(boringssl))]
aes_128_cfb128() -> &'static CipherRef164     pub fn aes_128_cfb128() -> &'static CipherRef {
165         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb128() as *mut _) }
166     }
167 
168     #[cfg(not(boringssl))]
aes_128_cfb8() -> &'static CipherRef169     pub fn aes_128_cfb8() -> &'static CipherRef {
170         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb8() as *mut _) }
171     }
172 
173     #[cfg(not(boringssl))]
aes_128_gcm() -> &'static CipherRef174     pub fn aes_128_gcm() -> &'static CipherRef {
175         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_gcm() as *mut _) }
176     }
177 
178     #[cfg(not(boringssl))]
aes_128_ccm() -> &'static CipherRef179     pub fn aes_128_ccm() -> &'static CipherRef {
180         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ccm() as *mut _) }
181     }
182 
183     #[cfg(not(boringssl))]
aes_128_ofb() -> &'static CipherRef184     pub fn aes_128_ofb() -> &'static CipherRef {
185         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ofb() as *mut _) }
186     }
187 
188     /// Requires OpenSSL 1.1.0 or newer.
189     #[cfg(ossl110)]
aes_128_ocb() -> &'static CipherRef190     pub fn aes_128_ocb() -> &'static CipherRef {
191         unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ocb() as *mut _) }
192     }
193 
aes_192_ecb() -> &'static CipherRef194     pub fn aes_192_ecb() -> &'static CipherRef {
195         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ecb() as *mut _) }
196     }
197 
aes_192_cbc() -> &'static CipherRef198     pub fn aes_192_cbc() -> &'static CipherRef {
199         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cbc() as *mut _) }
200     }
201 
aes_192_ctr() -> &'static CipherRef202     pub fn aes_192_ctr() -> &'static CipherRef {
203         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ctr() as *mut _) }
204     }
205 
206     #[cfg(not(boringssl))]
aes_192_cfb1() -> &'static CipherRef207     pub fn aes_192_cfb1() -> &'static CipherRef {
208         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb1() as *mut _) }
209     }
210 
aes_192_cfb128() -> &'static CipherRef211     pub fn aes_192_cfb128() -> &'static CipherRef {
212         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb128() as *mut _) }
213     }
214 
215     #[cfg(not(boringssl))]
aes_192_cfb8() -> &'static CipherRef216     pub fn aes_192_cfb8() -> &'static CipherRef {
217         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb8() as *mut _) }
218     }
219 
aes_192_gcm() -> &'static CipherRef220     pub fn aes_192_gcm() -> &'static CipherRef {
221         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_gcm() as *mut _) }
222     }
223 
224     #[cfg(not(boringssl))]
aes_192_ccm() -> &'static CipherRef225     pub fn aes_192_ccm() -> &'static CipherRef {
226         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ccm() as *mut _) }
227     }
228 
aes_192_ofb() -> &'static CipherRef229     pub fn aes_192_ofb() -> &'static CipherRef {
230         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ofb() as *mut _) }
231     }
232 
233     /// Requires OpenSSL 1.1.0 or newer.
234     #[cfg(ossl110)]
aes_192_ocb() -> &'static CipherRef235     pub fn aes_192_ocb() -> &'static CipherRef {
236         unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ocb() as *mut _) }
237     }
238 
aes_256_ecb() -> &'static CipherRef239     pub fn aes_256_ecb() -> &'static CipherRef {
240         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ecb() as *mut _) }
241     }
242 
aes_256_cbc() -> &'static CipherRef243     pub fn aes_256_cbc() -> &'static CipherRef {
244         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cbc() as *mut _) }
245     }
246 
aes_256_ctr() -> &'static CipherRef247     pub fn aes_256_ctr() -> &'static CipherRef {
248         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ctr() as *mut _) }
249     }
250 
251     #[cfg(not(boringssl))]
aes_256_cfb1() -> &'static CipherRef252     pub fn aes_256_cfb1() -> &'static CipherRef {
253         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb1() as *mut _) }
254     }
255 
aes_256_cfb128() -> &'static CipherRef256     pub fn aes_256_cfb128() -> &'static CipherRef {
257         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb128() as *mut _) }
258     }
259 
260     #[cfg(not(boringssl))]
aes_256_cfb8() -> &'static CipherRef261     pub fn aes_256_cfb8() -> &'static CipherRef {
262         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb8() as *mut _) }
263     }
264 
aes_256_gcm() -> &'static CipherRef265     pub fn aes_256_gcm() -> &'static CipherRef {
266         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_gcm() as *mut _) }
267     }
268 
269     #[cfg(not(boringssl))]
aes_256_ccm() -> &'static CipherRef270     pub fn aes_256_ccm() -> &'static CipherRef {
271         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ccm() as *mut _) }
272     }
273 
aes_256_ofb() -> &'static CipherRef274     pub fn aes_256_ofb() -> &'static CipherRef {
275         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ofb() as *mut _) }
276     }
277 
278     /// Requires OpenSSL 1.1.0 or newer.
279     #[cfg(ossl110)]
aes_256_ocb() -> &'static CipherRef280     pub fn aes_256_ocb() -> &'static CipherRef {
281         unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ocb() as *mut _) }
282     }
283 
284     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
bf_cbc() -> &'static CipherRef285     pub fn bf_cbc() -> &'static CipherRef {
286         unsafe { CipherRef::from_ptr(ffi::EVP_bf_cbc() as *mut _) }
287     }
288 
289     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
bf_ecb() -> &'static CipherRef290     pub fn bf_ecb() -> &'static CipherRef {
291         unsafe { CipherRef::from_ptr(ffi::EVP_bf_ecb() as *mut _) }
292     }
293 
294     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
295     #[cfg(not(boringssl))]
bf_cfb64() -> &'static CipherRef296     pub fn bf_cfb64() -> &'static CipherRef {
297         unsafe { CipherRef::from_ptr(ffi::EVP_bf_cfb64() as *mut _) }
298     }
299 
300     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
301     #[cfg(not(boringssl))]
bf_ofb() -> &'static CipherRef302     pub fn bf_ofb() -> &'static CipherRef {
303         unsafe { CipherRef::from_ptr(ffi::EVP_bf_ofb() as *mut _) }
304     }
305 
des_cbc() -> &'static CipherRef306     pub fn des_cbc() -> &'static CipherRef {
307         unsafe { CipherRef::from_ptr(ffi::EVP_des_cbc() as *mut _) }
308     }
309 
des_ecb() -> &'static CipherRef310     pub fn des_ecb() -> &'static CipherRef {
311         unsafe { CipherRef::from_ptr(ffi::EVP_des_ecb() as *mut _) }
312     }
313 
des_ede3() -> &'static CipherRef314     pub fn des_ede3() -> &'static CipherRef {
315         unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3() as *mut _) }
316     }
317 
des_ede3_cbc() -> &'static CipherRef318     pub fn des_ede3_cbc() -> &'static CipherRef {
319         unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cbc() as *mut _) }
320     }
321 
322     #[cfg(not(boringssl))]
des_ede3_cfb64() -> &'static CipherRef323     pub fn des_ede3_cfb64() -> &'static CipherRef {
324         unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb64() as *mut _) }
325     }
326 
rc4() -> &'static CipherRef327     pub fn rc4() -> &'static CipherRef {
328         unsafe { CipherRef::from_ptr(ffi::EVP_rc4() as *mut _) }
329     }
330 
331     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
camellia128_cfb128() -> &'static CipherRef332     pub fn camellia128_cfb128() -> &'static CipherRef {
333         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cfb128() as *mut _) }
334     }
335 
336     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
camellia128_ecb() -> &'static CipherRef337     pub fn camellia128_ecb() -> &'static CipherRef {
338         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ecb() as *mut _) }
339     }
340 
341     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
camellia192_cfb128() -> &'static CipherRef342     pub fn camellia192_cfb128() -> &'static CipherRef {
343         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cfb128() as *mut _) }
344     }
345 
346     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
camellia192_ecb() -> &'static CipherRef347     pub fn camellia192_ecb() -> &'static CipherRef {
348         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ecb() as *mut _) }
349     }
350 
351     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
camellia256_cfb128() -> &'static CipherRef352     pub fn camellia256_cfb128() -> &'static CipherRef {
353         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cfb128() as *mut _) }
354     }
355 
356     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
camellia256_ecb() -> &'static CipherRef357     pub fn camellia256_ecb() -> &'static CipherRef {
358         unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ecb() as *mut _) }
359     }
360 
361     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAST")))]
cast5_cfb64() -> &'static CipherRef362     pub fn cast5_cfb64() -> &'static CipherRef {
363         unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cfb64() as *mut _) }
364     }
365 
366     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAST")))]
cast5_ecb() -> &'static CipherRef367     pub fn cast5_ecb() -> &'static CipherRef {
368         unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ecb() as *mut _) }
369     }
370 
371     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_IDEA")))]
idea_cfb64() -> &'static CipherRef372     pub fn idea_cfb64() -> &'static CipherRef {
373         unsafe { CipherRef::from_ptr(ffi::EVP_idea_cfb64() as *mut _) }
374     }
375 
376     #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_IDEA")))]
idea_ecb() -> &'static CipherRef377     pub fn idea_ecb() -> &'static CipherRef {
378         unsafe { CipherRef::from_ptr(ffi::EVP_idea_ecb() as *mut _) }
379     }
380 
381     #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))]
chacha20() -> &'static CipherRef382     pub fn chacha20() -> &'static CipherRef {
383         unsafe { CipherRef::from_ptr(ffi::EVP_chacha20() as *mut _) }
384     }
385 
386     #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))]
chacha20_poly1305() -> &'static CipherRef387     pub fn chacha20_poly1305() -> &'static CipherRef {
388         unsafe { CipherRef::from_ptr(ffi::EVP_chacha20_poly1305() as *mut _) }
389     }
390 
391     #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
392     #[cfg(not(boringssl))]
seed_cbc() -> &'static CipherRef393     pub fn seed_cbc() -> &'static CipherRef {
394         unsafe { CipherRef::from_ptr(ffi::EVP_seed_cbc() as *mut _) }
395     }
396 
397     #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
398     #[cfg(not(boringssl))]
seed_cfb128() -> &'static CipherRef399     pub fn seed_cfb128() -> &'static CipherRef {
400         unsafe { CipherRef::from_ptr(ffi::EVP_seed_cfb128() as *mut _) }
401     }
402 
403     #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
404     #[cfg(not(boringssl))]
seed_ecb() -> &'static CipherRef405     pub fn seed_ecb() -> &'static CipherRef {
406         unsafe { CipherRef::from_ptr(ffi::EVP_seed_ecb() as *mut _) }
407     }
408 
409     #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
410     #[cfg(not(boringssl))]
seed_ofb() -> &'static CipherRef411     pub fn seed_ofb() -> &'static CipherRef {
412         unsafe { CipherRef::from_ptr(ffi::EVP_seed_ofb() as *mut _) }
413     }
414 
415     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_ecb() -> &'static CipherRef416     pub fn sm4_ecb() -> &'static CipherRef {
417         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ecb() as *mut _) }
418     }
419 
420     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_cbc() -> &'static CipherRef421     pub fn sm4_cbc() -> &'static CipherRef {
422         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cbc() as *mut _) }
423     }
424 
425     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_ctr() -> &'static CipherRef426     pub fn sm4_ctr() -> &'static CipherRef {
427         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ctr() as *mut _) }
428     }
429 
430     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_cfb128() -> &'static CipherRef431     pub fn sm4_cfb128() -> &'static CipherRef {
432         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cfb128() as *mut _) }
433     }
434 
435     #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
sm4_ofb() -> &'static CipherRef436     pub fn sm4_ofb() -> &'static CipherRef {
437         unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ofb() as *mut _) }
438     }
439 }
440 
441 /// A reference to a [`Cipher`].
442 pub struct CipherRef(Opaque);
443 
444 impl ForeignTypeRef for CipherRef {
445     type CType = ffi::EVP_CIPHER;
446 }
447 
448 unsafe impl Sync for CipherRef {}
449 unsafe impl Send for CipherRef {}
450 
451 impl CipherRef {
452     /// Returns the cipher's Nid.
453     #[corresponds(EVP_CIPHER_nid)]
nid(&self) -> Nid454     pub fn nid(&self) -> Nid {
455         let nid = unsafe { ffi::EVP_CIPHER_nid(self.as_ptr()) };
456         Nid::from_raw(nid)
457     }
458 
459     /// Returns the length of keys used with this cipher.
460     #[corresponds(EVP_CIPHER_key_length)]
key_length(&self) -> usize461     pub fn key_length(&self) -> usize {
462         unsafe { EVP_CIPHER_key_length(self.as_ptr()) as usize }
463     }
464 
465     /// Returns the length of the IV used with this cipher.
466     ///
467     /// # Note
468     ///
469     /// Ciphers that do not use an IV have an IV length of 0.
470     #[corresponds(EVP_CIPHER_iv_length)]
iv_length(&self) -> usize471     pub fn iv_length(&self) -> usize {
472         unsafe { EVP_CIPHER_iv_length(self.as_ptr()) as usize }
473     }
474 
475     /// Returns the block size of the cipher.
476     ///
477     /// # Note
478     ///
479     /// Stream ciphers have a block size of 1.
480     #[corresponds(EVP_CIPHER_block_size)]
block_size(&self) -> usize481     pub fn block_size(&self) -> usize {
482         unsafe { EVP_CIPHER_block_size(self.as_ptr()) as usize }
483     }
484 }
485