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
19cfg_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
42cfg_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.
113pub struct Cipher(Inner);
114
115unsafe impl Sync for Cipher {}
116unsafe impl Send for Cipher {}
117
118impl Cipher {
119 /// Looks up the cipher for a certain nid.
120 #[corresponds(EVP_get_cipherbynid)]
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)]
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
156 pub fn aes_128_ecb() -> &'static CipherRef {
157 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ecb() as *mut _) }
158 }
159
160 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))]
165 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))]
170 pub fn aes_256_xts() -> &'static CipherRef {
171 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_xts() as *mut _) }
172 }
173
174 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))]
179 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))]
184 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))]
189 pub fn aes_128_cfb8() -> &'static CipherRef {
190 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb8() as *mut _) }
191 }
192
193 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))]
198 pub fn aes_128_ccm() -> &'static CipherRef {
199 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ccm() as *mut _) }
200 }
201
202 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")))]
208 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)]
214 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)]
220 pub fn aes_128_wrap_pad() -> &'static CipherRef {
221 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_wrap_pad() as *mut _) }
222 }
223
224 pub fn aes_192_ecb() -> &'static CipherRef {
225 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ecb() as *mut _) }
226 }
227
228 pub fn aes_192_cbc() -> &'static CipherRef {
229 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cbc() as *mut _) }
230 }
231
232 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))]
237 pub fn aes_192_cfb1() -> &'static CipherRef {
238 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb1() as *mut _) }
239 }
240
241 pub fn aes_192_cfb128() -> &'static CipherRef {
242 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb128() as *mut _) }
243 }
244
245 #[cfg(not(boringssl))]
246 pub fn aes_192_cfb8() -> &'static CipherRef {
247 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb8() as *mut _) }
248 }
249
250 pub fn aes_192_gcm() -> &'static CipherRef {
251 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_gcm() as *mut _) }
252 }
253
254 #[cfg(not(boringssl))]
255 pub fn aes_192_ccm() -> &'static CipherRef {
256 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ccm() as *mut _) }
257 }
258
259 pub fn aes_192_ofb() -> &'static CipherRef {
260 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ofb() as *mut _) }
261 }
262
263 /// Requires OpenSSL 1.1.0 or newer.
264 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
265 pub fn aes_192_ocb() -> &'static CipherRef {
266 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ocb() as *mut _) }
267 }
268
269 /// Requires OpenSSL 1.0.2 or newer.
270 #[cfg(ossl102)]
271 pub fn aes_192_wrap() -> &'static CipherRef {
272 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap() as *mut _) }
273 }
274
275 /// Requires OpenSSL 1.1.0 or newer.
276 #[cfg(ossl110)]
277 pub fn aes_192_wrap_pad() -> &'static CipherRef {
278 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap_pad() as *mut _) }
279 }
280
281 pub fn aes_256_ecb() -> &'static CipherRef {
282 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ecb() as *mut _) }
283 }
284
285 pub fn aes_256_cbc() -> &'static CipherRef {
286 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cbc() as *mut _) }
287 }
288
289 pub fn aes_256_ctr() -> &'static CipherRef {
290 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ctr() as *mut _) }
291 }
292
293 #[cfg(not(boringssl))]
294 pub fn aes_256_cfb1() -> &'static CipherRef {
295 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb1() as *mut _) }
296 }
297
298 pub fn aes_256_cfb128() -> &'static CipherRef {
299 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb128() as *mut _) }
300 }
301
302 #[cfg(not(boringssl))]
303 pub fn aes_256_cfb8() -> &'static CipherRef {
304 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb8() as *mut _) }
305 }
306
307 pub fn aes_256_gcm() -> &'static CipherRef {
308 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_gcm() as *mut _) }
309 }
310
311 #[cfg(not(boringssl))]
312 pub fn aes_256_ccm() -> &'static CipherRef {
313 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ccm() as *mut _) }
314 }
315
316 pub fn aes_256_ofb() -> &'static CipherRef {
317 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ofb() as *mut _) }
318 }
319
320 /// Requires OpenSSL 1.1.0 or newer.
321 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
322 pub fn aes_256_ocb() -> &'static CipherRef {
323 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ocb() as *mut _) }
324 }
325
326 /// Requires OpenSSL 1.0.2 or newer.
327 #[cfg(ossl102)]
328 pub fn aes_256_wrap() -> &'static CipherRef {
329 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap() as *mut _) }
330 }
331
332 /// Requires OpenSSL 1.1.0 or newer.
333 #[cfg(ossl110)]
334 pub fn aes_256_wrap_pad() -> &'static CipherRef {
335 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap_pad() as *mut _) }
336 }
337
338 #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
339 pub fn bf_cbc() -> &'static CipherRef {
340 unsafe { CipherRef::from_ptr(ffi::EVP_bf_cbc() as *mut _) }
341 }
342
343 #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
344 pub fn bf_ecb() -> &'static CipherRef {
345 unsafe { CipherRef::from_ptr(ffi::EVP_bf_ecb() as *mut _) }
346 }
347
348 #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
349 pub fn bf_cfb64() -> &'static CipherRef {
350 unsafe { CipherRef::from_ptr(ffi::EVP_bf_cfb64() as *mut _) }
351 }
352
353 #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
354 pub fn bf_ofb() -> &'static CipherRef {
355 unsafe { CipherRef::from_ptr(ffi::EVP_bf_ofb() as *mut _) }
356 }
357
358 pub fn des_cbc() -> &'static CipherRef {
359 unsafe { CipherRef::from_ptr(ffi::EVP_des_cbc() as *mut _) }
360 }
361
362 pub fn des_ecb() -> &'static CipherRef {
363 unsafe { CipherRef::from_ptr(ffi::EVP_des_ecb() as *mut _) }
364 }
365
366 pub fn des_ede3() -> &'static CipherRef {
367 unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3() as *mut _) }
368 }
369
370 pub fn des_ede3_ecb() -> &'static CipherRef {
371 unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_ecb() as *mut _) }
372 }
373
374 pub fn des_ede3_cbc() -> &'static CipherRef {
375 unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cbc() as *mut _) }
376 }
377
378 #[cfg(not(boringssl))]
379 pub fn des_ede3_cfb8() -> &'static CipherRef {
380 unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb8() as *mut _) }
381 }
382
383 #[cfg(not(boringssl))]
384 pub fn des_ede3_cfb64() -> &'static CipherRef {
385 unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb64() as *mut _) }
386 }
387
388 #[cfg(not(boringssl))]
389 pub fn des_ede3_ofb() -> &'static CipherRef {
390 unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_ofb() as *mut _) }
391 }
392
393 #[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
394 pub fn rc4() -> &'static CipherRef {
395 unsafe { CipherRef::from_ptr(ffi::EVP_rc4() as *mut _) }
396 }
397
398 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
399 pub fn camellia128_cfb128() -> &'static CipherRef {
400 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cfb128() as *mut _) }
401 }
402
403 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
404 pub fn camellia128_ecb() -> &'static CipherRef {
405 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ecb() as *mut _) }
406 }
407
408 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
409 pub fn camellia128_cbc() -> &'static CipherRef {
410 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cbc() as *mut _) }
411 }
412
413 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
414 pub fn camellia128_ofb() -> &'static CipherRef {
415 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ofb() as *mut _) }
416 }
417
418 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
419 pub fn camellia192_cfb128() -> &'static CipherRef {
420 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cfb128() as *mut _) }
421 }
422
423 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
424 pub fn camellia192_ecb() -> &'static CipherRef {
425 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ecb() as *mut _) }
426 }
427
428 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
429 pub fn camellia192_cbc() -> &'static CipherRef {
430 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cbc() as *mut _) }
431 }
432
433 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
434 pub fn camellia192_ofb() -> &'static CipherRef {
435 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ofb() as *mut _) }
436 }
437
438 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
439 pub fn camellia256_cfb128() -> &'static CipherRef {
440 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cfb128() as *mut _) }
441 }
442
443 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
444 pub fn camellia256_ecb() -> &'static CipherRef {
445 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ecb() as *mut _) }
446 }
447
448 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
449 pub fn camellia256_cbc() -> &'static CipherRef {
450 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cbc() as *mut _) }
451 }
452
453 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
454 pub fn camellia256_ofb() -> &'static CipherRef {
455 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ofb() as *mut _) }
456 }
457
458 #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
459 pub fn cast5_cfb64() -> &'static CipherRef {
460 unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cfb64() as *mut _) }
461 }
462
463 #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
464 pub fn cast5_ecb() -> &'static CipherRef {
465 unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ecb() as *mut _) }
466 }
467
468 #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
469 pub fn cast5_cbc() -> &'static CipherRef {
470 unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cbc() as *mut _) }
471 }
472
473 #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
474 pub fn cast5_ofb() -> &'static CipherRef {
475 unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ofb() as *mut _) }
476 }
477
478 #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
479 pub fn idea_cfb64() -> &'static CipherRef {
480 unsafe { CipherRef::from_ptr(ffi::EVP_idea_cfb64() as *mut _) }
481 }
482
483 #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
484 pub fn idea_ecb() -> &'static CipherRef {
485 unsafe { CipherRef::from_ptr(ffi::EVP_idea_ecb() as *mut _) }
486 }
487
488 #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
489 pub fn idea_cbc() -> &'static CipherRef {
490 unsafe { CipherRef::from_ptr(ffi::EVP_idea_cbc() as *mut _) }
491 }
492
493 #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
494 pub fn idea_ofb() -> &'static CipherRef {
495 unsafe { CipherRef::from_ptr(ffi::EVP_idea_ofb() as *mut _) }
496 }
497
498 #[cfg(all(any(ossl110, libressl310), not(osslconf = "OPENSSL_NO_CHACHA")))]
499 pub fn chacha20() -> &'static CipherRef {
500 unsafe { CipherRef::from_ptr(ffi::EVP_chacha20() as *mut _) }
501 }
502
503 #[cfg(all(any(ossl110, libressl360), not(osslconf = "OPENSSL_NO_CHACHA")))]
504 pub fn chacha20_poly1305() -> &'static CipherRef {
505 unsafe { CipherRef::from_ptr(ffi::EVP_chacha20_poly1305() as *mut _) }
506 }
507
508 #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
509 pub fn seed_cbc() -> &'static CipherRef {
510 unsafe { CipherRef::from_ptr(ffi::EVP_seed_cbc() as *mut _) }
511 }
512
513 #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
514 pub fn seed_cfb128() -> &'static CipherRef {
515 unsafe { CipherRef::from_ptr(ffi::EVP_seed_cfb128() as *mut _) }
516 }
517
518 #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
519 pub fn seed_ecb() -> &'static CipherRef {
520 unsafe { CipherRef::from_ptr(ffi::EVP_seed_ecb() as *mut _) }
521 }
522
523 #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
524 pub fn seed_ofb() -> &'static CipherRef {
525 unsafe { CipherRef::from_ptr(ffi::EVP_seed_ofb() as *mut _) }
526 }
527
528 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
529 pub fn sm4_ecb() -> &'static CipherRef {
530 unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ecb() as *mut _) }
531 }
532
533 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
534 pub fn sm4_cbc() -> &'static CipherRef {
535 unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cbc() as *mut _) }
536 }
537
538 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
539 pub fn sm4_ctr() -> &'static CipherRef {
540 unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ctr() as *mut _) }
541 }
542
543 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
544 pub fn sm4_cfb128() -> &'static CipherRef {
545 unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cfb128() as *mut _) }
546 }
547
548 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
549 pub fn sm4_ofb() -> &'static CipherRef {
550 unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ofb() as *mut _) }
551 }
552}
553
554/// A reference to a [`Cipher`].
555pub struct CipherRef(Opaque);
556
557impl ForeignTypeRef for CipherRef {
558 type CType = ffi::EVP_CIPHER;
559}
560
561unsafe impl Sync for CipherRef {}
562unsafe impl Send for CipherRef {}
563
564impl CipherRef {
565 /// Returns the cipher's Nid.
566 #[corresponds(EVP_CIPHER_nid)]
567 pub fn nid(&self) -> Nid {
568 let nid = unsafe { ffi::EVP_CIPHER_nid(self.as_ptr()) };
569 Nid::from_raw(nid)
570 }
571
572 /// Returns the length of keys used with this cipher.
573 #[corresponds(EVP_CIPHER_key_length)]
574 pub fn key_length(&self) -> usize {
575 unsafe { EVP_CIPHER_key_length(self.as_ptr()) as usize }
576 }
577
578 /// Returns the length of the IV used with this cipher.
579 ///
580 /// # Note
581 ///
582 /// Ciphers that do not use an IV have an IV length of 0.
583 #[corresponds(EVP_CIPHER_iv_length)]
584 pub fn iv_length(&self) -> usize {
585 unsafe { EVP_CIPHER_iv_length(self.as_ptr()) as usize }
586 }
587
588 /// Returns the block size of the cipher.
589 ///
590 /// # Note
591 ///
592 /// Stream ciphers have a block size of 1.
593 #[corresponds(EVP_CIPHER_block_size)]
594 pub fn block_size(&self) -> usize {
595 unsafe { EVP_CIPHER_block_size(self.as_ptr()) as usize }
596 }
597}
598