1 //! The symmetric encryption context.
2 //!
3 //! # Examples
4 //!
5 //! Encrypt data with AES128 CBC
6 //!
7 //! ```
8 //! use openssl::cipher::Cipher;
9 //! use openssl::cipher_ctx::CipherCtx;
10 //!
11 //! let cipher = Cipher::aes_128_cbc();
12 //! let data = b"Some Crypto Text";
13 //! let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F";
14 //! let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07";
15 //!
16 //! let mut ctx = CipherCtx::new().unwrap();
17 //! ctx.encrypt_init(Some(cipher), Some(key), Some(iv)).unwrap();
18 //!
19 //! let mut ciphertext = vec![];
20 //! ctx.cipher_update_vec(data, &mut ciphertext).unwrap();
21 //! ctx.cipher_final_vec(&mut ciphertext).unwrap();
22 //!
23 //! assert_eq!(
24 //!     b"\xB4\xB9\xE7\x30\xD6\xD6\xF7\xDE\x77\x3F\x1C\xFF\xB3\x3E\x44\x5A\x91\xD7\x27\x62\x87\x4D\
25 //!       \xFB\x3C\x5E\xC4\x59\x72\x4A\xF4\x7C\xA1",
26 //!     &ciphertext[..],
27 //! );
28 //! ```
29 //!
30 //! Decrypt data with AES128 CBC
31 //!
32 //! ```
33 //! use openssl::cipher::Cipher;
34 //! use openssl::cipher_ctx::CipherCtx;
35 //!
36 //! let cipher = Cipher::aes_128_cbc();
37 //! let data = b"\xB4\xB9\xE7\x30\xD6\xD6\xF7\xDE\x77\x3F\x1C\xFF\xB3\x3E\x44\x5A\x91\xD7\x27\x62\
38 //!              \x87\x4D\xFB\x3C\x5E\xC4\x59\x72\x4A\xF4\x7C\xA1";
39 //! let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F";
40 //! let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07";
41 //!
42 //! let mut ctx = CipherCtx::new().unwrap();
43 //! ctx.decrypt_init(Some(cipher), Some(key), Some(iv)).unwrap();
44 //!
45 //! let mut plaintext = vec![];
46 //! ctx.cipher_update_vec(data, &mut plaintext).unwrap();
47 //! ctx.cipher_final_vec(&mut plaintext).unwrap();
48 //!
49 //! assert_eq!(b"Some Crypto Text", &plaintext[..]);
50 //! ```
51 #![warn(missing_docs)]
52 
53 use crate::cipher::CipherRef;
54 use crate::error::ErrorStack;
55 #[cfg(not(boringssl))]
56 use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef};
57 use crate::{cvt, cvt_p};
58 #[cfg(ossl102)]
59 use bitflags::bitflags;
60 use cfg_if::cfg_if;
61 use foreign_types::{ForeignType, ForeignTypeRef};
62 use libc::{c_int, c_uchar};
63 use openssl_macros::corresponds;
64 use std::convert::{TryFrom, TryInto};
65 use std::ptr;
66 
67 cfg_if! {
68     if #[cfg(ossl300)] {
69         use ffi::EVP_CIPHER_CTX_get0_cipher;
70     } else {
71         use ffi::EVP_CIPHER_CTX_cipher as EVP_CIPHER_CTX_get0_cipher;
72     }
73 }
74 
75 foreign_type_and_impl_send_sync! {
76     type CType = ffi::EVP_CIPHER_CTX;
dropnull77     fn drop = ffi::EVP_CIPHER_CTX_free;
78 
79     /// A context object used to perform symmetric encryption operations.
80     pub struct CipherCtx;
81     /// A reference to a [`CipherCtx`].
82     pub struct CipherCtxRef;
83 }
84 
85 #[cfg(ossl102)]
86 bitflags! {
87     /// Flags for `EVP_CIPHER_CTX`.
88     pub struct CipherCtxFlags : c_int {
89         /// The flag used to opt into AES key wrap ciphers.
90         const FLAG_WRAP_ALLOW = ffi::EVP_CIPHER_CTX_FLAG_WRAP_ALLOW;
91     }
92 }
93 
94 impl CipherCtx {
95     /// Creates a new context.
96     #[corresponds(EVP_CIPHER_CTX_new)]
newnull97     pub fn new() -> Result<Self, ErrorStack> {
98         ffi::init();
99 
100         unsafe {
101             let ptr = cvt_p(ffi::EVP_CIPHER_CTX_new())?;
102             Ok(CipherCtx::from_ptr(ptr))
103         }
104     }
105 }
106 
107 impl CipherCtxRef {
108     /// Initializes the context for encryption.
109     ///
110     /// Normally this is called once to set all of the cipher, key, and IV. However, this process can be split up
111     /// by first setting the cipher with no key or IV and then setting the key and IV with no cipher. This can be used
112     /// to, for example, use a nonstandard IV size.
113     ///
114     /// # Panics
115     ///
116     /// Panics if the key buffer is smaller than the key size of the cipher, the IV buffer is smaller than the IV size
117     /// of the cipher, or if a key or IV is provided before a cipher.
118     #[corresponds(EVP_EncryptInit_ex)]
encrypt_initnull119     pub fn encrypt_init(
120         &mut self,
121         type_: Option<&CipherRef>,
122         key: Option<&[u8]>,
123         iv: Option<&[u8]>,
124     ) -> Result<(), ErrorStack> {
125         self.cipher_init(type_, key, iv, ffi::EVP_EncryptInit_ex)
126     }
127 
128     /// Initializes the context for decryption.
129     ///
130     /// Normally this is called once to set all of the cipher, key, and IV. However, this process can be split up
131     /// by first setting the cipher with no key or IV and then setting the key and IV with no cipher. This can be used
132     /// to, for example, use a nonstandard IV size.
133     ///
134     /// # Panics
135     ///
136     /// Panics if the key buffer is smaller than the key size of the cipher, the IV buffer is smaller than the IV size
137     /// of the cipher, or if a key or IV is provided before a cipher.
138     #[corresponds(EVP_DecryptInit_ex)]
decrypt_initnull139     pub fn decrypt_init(
140         &mut self,
141         type_: Option<&CipherRef>,
142         key: Option<&[u8]>,
143         iv: Option<&[u8]>,
144     ) -> Result<(), ErrorStack> {
145         self.cipher_init(type_, key, iv, ffi::EVP_DecryptInit_ex)
146     }
147 
cipher_initnull148     fn cipher_init(
149         &mut self,
150         type_: Option<&CipherRef>,
151         key: Option<&[u8]>,
152         iv: Option<&[u8]>,
153         f: unsafe extern "C" fn(
154             *mut ffi::EVP_CIPHER_CTX,
155             *const ffi::EVP_CIPHER,
156             *mut ffi::ENGINE,
157             *const c_uchar,
158             *const c_uchar,
159         ) -> c_int,
160     ) -> Result<(), ErrorStack> {
161         if let Some(key) = key {
162             let key_len = type_.map_or_else(|| self.key_length(), |c| c.key_length());
163             assert!(key_len <= key.len());
164         }
165 
166         if let Some(iv) = iv {
167             let iv_len = type_.map_or_else(|| self.iv_length(), |c| c.iv_length());
168             assert!(iv_len <= iv.len());
169         }
170 
171         unsafe {
172             cvt(f(
173                 self.as_ptr(),
174                 type_.map_or(ptr::null(), |p| p.as_ptr()),
175                 ptr::null_mut(),
176                 key.map_or(ptr::null(), |k| k.as_ptr()),
177                 iv.map_or(ptr::null(), |iv| iv.as_ptr()),
178             ))?;
179         }
180 
181         Ok(())
182     }
183 
184     /// Initializes the context to perform envelope encryption.
185     ///
186     /// Normally this is called once to set both the cipher and public keys. However, this process may be split up by
187     /// first providing the cipher with no public keys and then setting the public keys with no cipher.
188     ///
189     /// `encrypted_keys` will contain the generated symmetric key encrypted with each corresponding asymmetric private
190     /// key. The generated IV will be written to `iv`.
191     ///
192     /// # Panics
193     ///
194     /// Panics if `pub_keys` is not the same size as `encrypted_keys`, the IV buffer is smaller than the cipher's IV
195     /// size, or if an IV is provided before the cipher.
196     #[corresponds(EVP_SealInit)]
197     #[cfg(not(boringssl))]
seal_initnull198     pub fn seal_init<T>(
199         &mut self,
200         type_: Option<&CipherRef>,
201         pub_keys: &[PKey<T>],
202         encrypted_keys: &mut [Vec<u8>],
203         iv: Option<&mut [u8]>,
204     ) -> Result<(), ErrorStack>
205     where
206         T: HasPublic,
207     {
208         assert_eq!(pub_keys.len(), encrypted_keys.len());
209         if !pub_keys.is_empty() {
210             let iv_len = type_.map_or_else(|| self.iv_length(), |c| c.iv_length());
211             assert!(iv.as_ref().map_or(0, |b| b.len()) >= iv_len);
212         }
213 
214         for (pub_key, buf) in pub_keys.iter().zip(&mut *encrypted_keys) {
215             buf.resize(pub_key.size(), 0);
216         }
217 
218         let mut keys = encrypted_keys
219             .iter_mut()
220             .map(|b| b.as_mut_ptr())
221             .collect::<Vec<_>>();
222         let mut key_lengths = vec![0; pub_keys.len()];
223         let pub_keys_len = i32::try_from(pub_keys.len()).unwrap();
224 
225         unsafe {
226             cvt(ffi::EVP_SealInit(
227                 self.as_ptr(),
228                 type_.map_or(ptr::null(), |p| p.as_ptr()),
229                 keys.as_mut_ptr(),
230                 key_lengths.as_mut_ptr(),
231                 iv.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
232                 pub_keys.as_ptr() as *mut _,
233                 pub_keys_len,
234             ))?;
235         }
236 
237         for (buf, len) in encrypted_keys.iter_mut().zip(key_lengths) {
238             buf.truncate(len as usize);
239         }
240 
241         Ok(())
242     }
243 
244     /// Initializes the context to perform envelope decryption.
245     ///
246     /// Normally this is called once with all of the arguments present. However, this process may be split up by first
247     /// providing the cipher alone and then after providing the rest of the arguments in a second call.
248     ///
249     /// # Panics
250     ///
251     /// Panics if the IV buffer is smaller than the cipher's required IV size or if the IV is provided before the
252     /// cipher.
253     #[corresponds(EVP_OpenInit)]
254     #[cfg(not(boringssl))]
open_initnull255     pub fn open_init<T>(
256         &mut self,
257         type_: Option<&CipherRef>,
258         encrypted_key: &[u8],
259         iv: Option<&[u8]>,
260         priv_key: Option<&PKeyRef<T>>,
261     ) -> Result<(), ErrorStack>
262     where
263         T: HasPrivate,
264     {
265         if priv_key.is_some() {
266             let iv_len = type_.map_or_else(|| self.iv_length(), |c| c.iv_length());
267             assert!(iv.map_or(0, |b| b.len()) >= iv_len);
268         }
269 
270         let len = c_int::try_from(encrypted_key.len()).unwrap();
271         unsafe {
272             cvt(ffi::EVP_OpenInit(
273                 self.as_ptr(),
274                 type_.map_or(ptr::null(), |p| p.as_ptr()),
275                 encrypted_key.as_ptr(),
276                 len,
277                 iv.map_or(ptr::null(), |b| b.as_ptr()),
278                 priv_key.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr),
279             ))?;
280         }
281 
282         Ok(())
283     }
284 
assert_ciphernull285     fn assert_cipher(&self) {
286         unsafe {
287             assert!(!EVP_CIPHER_CTX_get0_cipher(self.as_ptr()).is_null());
288         }
289     }
290 
291     /// Returns the block size of the context's cipher.
292     ///
293     /// Stream ciphers will report a block size of 1.
294     ///
295     /// # Panics
296     ///
297     /// Panics if the context has not been initialized with a cipher.
298     #[corresponds(EVP_CIPHER_CTX_block_size)]
block_sizenull299     pub fn block_size(&self) -> usize {
300         self.assert_cipher();
301 
302         unsafe { ffi::EVP_CIPHER_CTX_block_size(self.as_ptr()) as usize }
303     }
304 
305     /// Returns the key length of the context's cipher.
306     ///
307     /// # Panics
308     ///
309     /// Panics if the context has not been initialized with a cipher.
310     #[corresponds(EVP_CIPHER_CTX_key_length)]
key_lengthnull311     pub fn key_length(&self) -> usize {
312         self.assert_cipher();
313 
314         unsafe { ffi::EVP_CIPHER_CTX_key_length(self.as_ptr()) as usize }
315     }
316 
317     /// Generates a random key based on the configured cipher.
318     ///
319     /// # Panics
320     ///
321     /// Panics if the context has not been initialized with a cipher or if the buffer is smaller than the cipher's key
322     /// length.
323     ///
324     /// This corresponds to [`EVP_CIPHER_CTX_rand_key`].
325     ///
326     /// [`EVP_CIPHER_CTX_rand_key`]: https://www.openssl.org/docs/manmaster/man3/EVP_CIPHER_CTX_rand_key.html
327     #[corresponds(EVP_CIPHER_CTX_rand_key)]
328     #[cfg(not(boringssl))]
rand_keynull329     pub fn rand_key(&self, buf: &mut [u8]) -> Result<(), ErrorStack> {
330         assert!(buf.len() >= self.key_length());
331 
332         unsafe {
333             cvt(ffi::EVP_CIPHER_CTX_rand_key(
334                 self.as_ptr(),
335                 buf.as_mut_ptr(),
336             ))?;
337         }
338 
339         Ok(())
340     }
341 
342     /// Sets the length of the key expected by the context.
343     ///
344     /// Only some ciphers support configurable key lengths.
345     ///
346     /// # Panics
347     ///
348     /// Panics if the context has not been initialized with a cipher.
349     #[corresponds(EVP_CIPHER_CTX_set_key_length)]
set_key_lengthnull350     pub fn set_key_length(&mut self, len: usize) -> Result<(), ErrorStack> {
351         self.assert_cipher();
352 
353         unsafe {
354             cvt(ffi::EVP_CIPHER_CTX_set_key_length(
355                 self.as_ptr(),
356                 len.try_into().unwrap(),
357             ))?;
358         }
359 
360         Ok(())
361     }
362 
363     /// Returns the length of the IV expected by this context.
364     ///
365     /// Returns 0 if the cipher does not use an IV.
366     ///
367     /// # Panics
368     ///
369     /// Panics if the context has not been initialized with a cipher.
370     #[corresponds(EVP_CIPHER_CTX_iv_length)]
iv_lengthnull371     pub fn iv_length(&self) -> usize {
372         self.assert_cipher();
373 
374         unsafe { ffi::EVP_CIPHER_CTX_iv_length(self.as_ptr()) as usize }
375     }
376 
377     /// Returns the `num` parameter of the cipher.
378     ///
379     /// Built-in ciphers typically use this to track how much of the
380     /// current underlying block has been "used" already.
381     ///
382     /// # Panics
383     ///
384     /// Panics if the context has not been initialized with a cipher.
385     #[corresponds(EVP_CIPHER_CTX_num)]
386     #[cfg(ossl110)]
numnull387     pub fn num(&self) -> usize {
388         self.assert_cipher();
389 
390         unsafe { ffi::EVP_CIPHER_CTX_num(self.as_ptr()) as usize }
391     }
392 
393     /// Sets the length of the IV expected by this context.
394     ///
395     /// Only some ciphers support configurable IV lengths.
396     ///
397     /// # Panics
398     ///
399     /// Panics if the context has not been initialized with a cipher.
400     #[corresponds(EVP_CIPHER_CTX_ctrl)]
set_iv_lengthnull401     pub fn set_iv_length(&mut self, len: usize) -> Result<(), ErrorStack> {
402         self.assert_cipher();
403 
404         let len = c_int::try_from(len).unwrap();
405 
406         unsafe {
407             cvt(ffi::EVP_CIPHER_CTX_ctrl(
408                 self.as_ptr(),
409                 ffi::EVP_CTRL_GCM_SET_IVLEN,
410                 len,
411                 ptr::null_mut(),
412             ))?;
413         }
414 
415         Ok(())
416     }
417 
418     /// Returns the length of the authentication tag expected by this context.
419     ///
420     /// Returns 0 if the cipher is not authenticated.
421     ///
422     /// # Panics
423     ///
424     /// Panics if the context has not been initialized with a cipher.
425     ///
426     /// Requires OpenSSL 3.0.0 or newer.
427     #[corresponds(EVP_CIPHER_CTX_get_tag_length)]
428     #[cfg(ossl300)]
tag_lengthnull429     pub fn tag_length(&self) -> usize {
430         self.assert_cipher();
431 
432         unsafe { ffi::EVP_CIPHER_CTX_get_tag_length(self.as_ptr()) as usize }
433     }
434 
435     /// Retrieves the calculated authentication tag from the context.
436     ///
437     /// This should be called after [`Self::cipher_final`], and is only supported by authenticated ciphers.
438     ///
439     /// The size of the buffer indicates the size of the tag. While some ciphers support a range of tag sizes, it is
440     /// recommended to pick the maximum size.
441     #[corresponds(EVP_CIPHER_CTX_ctrl)]
tagnull442     pub fn tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
443         let len = c_int::try_from(tag.len()).unwrap();
444 
445         unsafe {
446             cvt(ffi::EVP_CIPHER_CTX_ctrl(
447                 self.as_ptr(),
448                 ffi::EVP_CTRL_GCM_GET_TAG,
449                 len,
450                 tag.as_mut_ptr() as *mut _,
451             ))?;
452         }
453 
454         Ok(())
455     }
456 
457     /// Sets the length of the generated authentication tag.
458     ///
459     /// This must be called when encrypting with a cipher in CCM mode to use a tag size other than the default.
460     #[corresponds(EVP_CIPHER_CTX_ctrl)]
set_tag_lengthnull461     pub fn set_tag_length(&mut self, len: usize) -> Result<(), ErrorStack> {
462         let len = c_int::try_from(len).unwrap();
463 
464         unsafe {
465             cvt(ffi::EVP_CIPHER_CTX_ctrl(
466                 self.as_ptr(),
467                 ffi::EVP_CTRL_GCM_SET_TAG,
468                 len,
469                 ptr::null_mut(),
470             ))?;
471         }
472 
473         Ok(())
474     }
475 
476     /// Sets the authentication tag for verification during decryption.
477     #[corresponds(EVP_CIPHER_CTX_ctrl)]
set_tagnull478     pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> {
479         let len = c_int::try_from(tag.len()).unwrap();
480 
481         unsafe {
482             cvt(ffi::EVP_CIPHER_CTX_ctrl(
483                 self.as_ptr(),
484                 ffi::EVP_CTRL_GCM_SET_TAG,
485                 len,
486                 tag.as_ptr() as *mut _,
487             ))?;
488         }
489 
490         Ok(())
491     }
492 
493     /// Enables or disables padding.
494     ///
495     /// If padding is disabled, the plaintext must be an exact multiple of the cipher's block size.
496     #[corresponds(EVP_CIPHER_CTX_set_padding)]
set_paddingnull497     pub fn set_padding(&mut self, padding: bool) {
498         unsafe {
499             ffi::EVP_CIPHER_CTX_set_padding(self.as_ptr(), padding as c_int);
500         }
501     }
502 
503     /// Sets the total length of plaintext data.
504     ///
505     /// This is required for ciphers operating in CCM mode.
506     #[corresponds(EVP_CipherUpdate)]
set_data_lennull507     pub fn set_data_len(&mut self, len: usize) -> Result<(), ErrorStack> {
508         let len = c_int::try_from(len).unwrap();
509 
510         unsafe {
511             cvt(ffi::EVP_CipherUpdate(
512                 self.as_ptr(),
513                 ptr::null_mut(),
514                 &mut 0,
515                 ptr::null(),
516                 len,
517             ))?;
518         }
519 
520         Ok(())
521     }
522 
523     /// Set ctx flags.
524     ///
525     /// This function is currently used to enable AES key wrap feature supported by OpenSSL 1.0.2 or newer.
526     #[corresponds(EVP_CIPHER_CTX_set_flags)]
527     #[cfg(ossl102)]
set_flagsnull528     pub fn set_flags(&mut self, flags: CipherCtxFlags) {
529         unsafe {
530             ffi::EVP_CIPHER_CTX_set_flags(self.as_ptr(), flags.bits());
531         }
532     }
533 
534     /// Writes data into the context.
535     ///
536     /// Providing no output buffer will cause the input to be considered additional authenticated data (AAD).
537     ///
538     /// Returns the number of bytes written to `output`.
539     ///
540     /// # Panics
541     ///
542     /// Panics if `output` doesn't contain enough space for data to be
543     /// written as specified by [`Self::minimal_output_size`].
544     #[corresponds(EVP_CipherUpdate)]
cipher_updatenull545     pub fn cipher_update(
546         &mut self,
547         input: &[u8],
548         output: Option<&mut [u8]>,
549     ) -> Result<usize, ErrorStack> {
550         if let Some(output) = &output {
551             let mut block_size = self.block_size();
552             if block_size == 1 {
553                 block_size = 0;
554             }
555             let min_output_size = input.len() + block_size;
556             assert!(
557                 output.len() >= min_output_size,
558                 "Output buffer size should be at least {} bytes.",
559                 min_output_size
560             );
561         }
562 
563         unsafe { self.cipher_update_unchecked(input, output) }
564     }
565 
566     /// Writes data into the context.
567     ///
568     /// Providing no output buffer will cause the input to be considered additional authenticated data (AAD).
569     ///
570     /// Returns the number of bytes written to `output`.
571     ///
572     /// This function is the same as [`Self::cipher_update`] but with the
573     /// output size check removed. It can be used when the exact
574     /// buffer size control is maintained by the caller.
575     ///
576     /// # Safety
577     /// The caller is expected to provide `output` buffer
578     /// large enough to contain correct number of bytes. For streaming
579     /// ciphers the output buffer size should be at least as big as
580     /// the input buffer. For block ciphers the size of the output
581     /// buffer depends on the state of partially updated blocks.
582     #[corresponds(EVP_CipherUpdate)]
cipher_update_uncheckednull583     pub unsafe fn cipher_update_unchecked(
584         &mut self,
585         input: &[u8],
586         output: Option<&mut [u8]>,
587     ) -> Result<usize, ErrorStack> {
588         let inlen = c_int::try_from(input.len()).unwrap();
589 
590         let mut outlen = 0;
591 
592         cvt(ffi::EVP_CipherUpdate(
593             self.as_ptr(),
594             output.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
595             &mut outlen,
596             input.as_ptr(),
597             inlen,
598         ))?;
599 
600         Ok(outlen as usize)
601     }
602 
603     /// Like [`Self::cipher_update`] except that it appends output to a [`Vec`].
cipher_update_vecnull604     pub fn cipher_update_vec(
605         &mut self,
606         input: &[u8],
607         output: &mut Vec<u8>,
608     ) -> Result<usize, ErrorStack> {
609         let base = output.len();
610         output.resize(base + input.len() + self.block_size(), 0);
611         let len = self.cipher_update(input, Some(&mut output[base..]))?;
612         output.truncate(base + len);
613 
614         Ok(len)
615     }
616 
617     /// Like [`Self::cipher_update`] except that it writes output into the
618     /// `data` buffer. The `inlen` parameter specifies the number of bytes in
619     /// `data` that are considered the input. For streaming ciphers, the size of
620     /// `data` must be at least the input size. Otherwise, it must be at least
621     /// an additional block size larger.
622     ///
623     /// Note: Use [`Self::cipher_update`] with no output argument to write AAD.
624     ///
625     /// # Panics
626     ///
627     /// This function panics if the input size cannot be represented as `int` or
628     /// exceeds the buffer size, or if the output buffer does not contain enough
629     /// additional space.
630     #[corresponds(EVP_CipherUpdate)]
cipher_update_inplacenull631     pub fn cipher_update_inplace(
632         &mut self,
633         data: &mut [u8],
634         inlen: usize,
635     ) -> Result<usize, ErrorStack> {
636         assert!(inlen <= data.len(), "Input size may not exceed buffer size");
637         let block_size = self.block_size();
638         if block_size != 1 {
639             assert!(
640                 data.len() >= inlen + block_size,
641                 "Output buffer size must be at least {} bytes.",
642                 inlen + block_size
643             );
644         }
645 
646         let inlen = c_int::try_from(inlen).unwrap();
647         let mut outlen = 0;
648         unsafe {
649             cvt(ffi::EVP_CipherUpdate(
650                 self.as_ptr(),
651                 data.as_mut_ptr(),
652                 &mut outlen,
653                 data.as_ptr(),
654                 inlen,
655             ))
656         }?;
657 
658         Ok(outlen as usize)
659     }
660 
661     /// Finalizes the encryption or decryption process.
662     ///
663     /// Any remaining data will be written to the output buffer.
664     ///
665     /// Returns the number of bytes written to `output`.
666     ///
667     /// # Panics
668     ///
669     /// Panics if `output` is smaller than the cipher's block size.
670     #[corresponds(EVP_CipherFinal)]
cipher_finalnull671     pub fn cipher_final(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
672         let block_size = self.block_size();
673         if block_size > 1 {
674             assert!(output.len() >= block_size);
675         }
676 
677         unsafe { self.cipher_final_unchecked(output) }
678     }
679 
680     /// Finalizes the encryption or decryption process.
681     ///
682     /// Any remaining data will be written to the output buffer.
683     ///
684     /// Returns the number of bytes written to `output`.
685     ///
686     /// This function is the same as [`Self::cipher_final`] but with
687     /// the output buffer size check removed.
688     ///
689     /// # Safety
690     /// The caller is expected to provide `output` buffer
691     /// large enough to contain correct number of bytes. For streaming
692     /// ciphers the output buffer can be empty, for block ciphers the
693     /// output buffer should be at least as big as the block.
694     #[corresponds(EVP_CipherFinal)]
cipher_final_uncheckednull695     pub unsafe fn cipher_final_unchecked(
696         &mut self,
697         output: &mut [u8],
698     ) -> Result<usize, ErrorStack> {
699         let mut outl = 0;
700 
701         cvt(ffi::EVP_CipherFinal(
702             self.as_ptr(),
703             output.as_mut_ptr(),
704             &mut outl,
705         ))?;
706 
707         Ok(outl as usize)
708     }
709 
710     /// Like [`Self::cipher_final`] except that it appends output to a [`Vec`].
cipher_final_vecnull711     pub fn cipher_final_vec(&mut self, output: &mut Vec<u8>) -> Result<usize, ErrorStack> {
712         let base = output.len();
713         output.resize(base + self.block_size(), 0);
714         let len = self.cipher_final(&mut output[base..])?;
715         output.truncate(base + len);
716 
717         Ok(len)
718     }
719 }
720 
721 #[cfg(test)]
722 mod test {
723     use super::*;
724     use crate::{cipher::Cipher, rand::rand_bytes};
725     #[cfg(not(boringssl))]
726     use std::slice;
727 
728     #[test]
729     #[cfg(not(boringssl))]
seal_opennull730     fn seal_open() {
731         let private_pem = include_bytes!("../test/rsa.pem");
732         let public_pem = include_bytes!("../test/rsa.pem.pub");
733         let private_key = PKey::private_key_from_pem(private_pem).unwrap();
734         let public_key = PKey::public_key_from_pem(public_pem).unwrap();
735         let cipher = Cipher::aes_256_cbc();
736         let secret = b"My secret message";
737 
738         let mut ctx = CipherCtx::new().unwrap();
739         let mut encrypted_key = vec![];
740         let mut iv = vec![0; cipher.iv_length()];
741         let mut encrypted = vec![];
742         ctx.seal_init(
743             Some(cipher),
744             &[public_key],
745             slice::from_mut(&mut encrypted_key),
746             Some(&mut iv),
747         )
748         .unwrap();
749         ctx.cipher_update_vec(secret, &mut encrypted).unwrap();
750         ctx.cipher_final_vec(&mut encrypted).unwrap();
751 
752         let mut decrypted = vec![];
753         ctx.open_init(Some(cipher), &encrypted_key, Some(&iv), Some(&private_key))
754             .unwrap();
755         ctx.cipher_update_vec(&encrypted, &mut decrypted).unwrap();
756         ctx.cipher_final_vec(&mut decrypted).unwrap();
757 
758         assert_eq!(secret, &decrypted[..]);
759     }
760 
aes_128_cbcnull761     fn aes_128_cbc(cipher: &CipherRef) {
762         // from https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf
763         let key = hex::decode("2b7e151628aed2a6abf7158809cf4f3c").unwrap();
764         let iv = hex::decode("000102030405060708090a0b0c0d0e0f").unwrap();
765         let pt = hex::decode("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51")
766             .unwrap();
767         let ct = hex::decode("7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b2")
768             .unwrap();
769 
770         let mut ctx = CipherCtx::new().unwrap();
771 
772         ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
773             .unwrap();
774         ctx.set_padding(false);
775 
776         let mut buf = vec![];
777         ctx.cipher_update_vec(&pt, &mut buf).unwrap();
778         ctx.cipher_final_vec(&mut buf).unwrap();
779 
780         assert_eq!(buf, ct);
781 
782         ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
783             .unwrap();
784         ctx.set_padding(false);
785 
786         let mut buf = vec![];
787         ctx.cipher_update_vec(&ct, &mut buf).unwrap();
788         ctx.cipher_final_vec(&mut buf).unwrap();
789 
790         assert_eq!(buf, pt);
791     }
792 
793     #[test]
794     #[cfg(ossl300)]
fetched_aes_128_cbcnull795     fn fetched_aes_128_cbc() {
796         let cipher = Cipher::fetch(None, "AES-128-CBC", None).unwrap();
797         aes_128_cbc(&cipher);
798     }
799 
800     #[test]
default_aes_128_cbcnull801     fn default_aes_128_cbc() {
802         let cipher = Cipher::aes_128_cbc();
803         aes_128_cbc(cipher);
804     }
805 
806     #[test]
test_stream_ciphersnull807     fn test_stream_ciphers() {
808         test_stream_cipher(Cipher::aes_192_ctr());
809         test_stream_cipher(Cipher::aes_256_ctr());
810     }
811 
test_stream_ciphernull812     fn test_stream_cipher(cipher: &'static CipherRef) {
813         let mut key = vec![0; cipher.key_length()];
814         rand_bytes(&mut key).unwrap();
815         let mut iv = vec![0; cipher.iv_length()];
816         rand_bytes(&mut iv).unwrap();
817 
818         let mut ctx = CipherCtx::new().unwrap();
819 
820         ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
821             .unwrap();
822         ctx.set_padding(false);
823 
824         assert_eq!(
825             1,
826             cipher.block_size(),
827             "Need a stream cipher, not a block cipher"
828         );
829 
830         // update cipher with non-full block
831         // this is a streaming cipher so the number of output bytes
832         // will be the same as the number of input bytes
833         let mut output = vec![0; 32];
834         let outlen = ctx
835             .cipher_update(&[1; 15], Some(&mut output[0..15]))
836             .unwrap();
837         assert_eq!(15, outlen);
838 
839         // update cipher with missing bytes from the previous block
840         // as previously it will output the same number of bytes as
841         // the input
842         let outlen = ctx
843             .cipher_update(&[1; 17], Some(&mut output[15..]))
844             .unwrap();
845         assert_eq!(17, outlen);
846 
847         ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
848 
849         // encrypt again, but use in-place encryption this time
850         // First reset the IV
851         ctx.encrypt_init(None, None, Some(&iv)).unwrap();
852         ctx.set_padding(false);
853         let mut data_inplace: [u8; 32] = [1; 32];
854         let outlen = ctx
855             .cipher_update_inplace(&mut data_inplace[0..15], 15)
856             .unwrap();
857         assert_eq!(15, outlen);
858 
859         let outlen = ctx
860             .cipher_update_inplace(&mut data_inplace[15..32], 17)
861             .unwrap();
862         assert_eq!(17, outlen);
863 
864         ctx.cipher_final(&mut [0u8; 0]).unwrap();
865 
866         // Check that the resulting data is encrypted in the same manner
867         assert_eq!(data_inplace.as_slice(), output.as_slice());
868 
869         // try to decrypt
870         ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
871             .unwrap();
872         ctx.set_padding(false);
873 
874         // update cipher with non-full block
875         // expect that the output for stream cipher will contain
876         // the same number of bytes as the input
877         let mut output_decrypted = vec![0; 32];
878         let outlen = ctx
879             .cipher_update(&output[0..15], Some(&mut output_decrypted[0..15]))
880             .unwrap();
881         assert_eq!(15, outlen);
882 
883         let outlen = ctx
884             .cipher_update(&output[15..], Some(&mut output_decrypted[15..]))
885             .unwrap();
886         assert_eq!(17, outlen);
887 
888         ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
889         // check if the decrypted blocks are the same as input (all ones)
890         assert_eq!(output_decrypted, vec![1; 32]);
891 
892         // decrypt again, but now the output in-place
893         ctx.decrypt_init(None, None, Some(&iv)).unwrap();
894         ctx.set_padding(false);
895 
896         let outlen = ctx.cipher_update_inplace(&mut output[0..15], 15).unwrap();
897         assert_eq!(15, outlen);
898 
899         let outlen = ctx.cipher_update_inplace(&mut output[15..], 17).unwrap();
900         assert_eq!(17, outlen);
901 
902         ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
903         assert_eq!(output_decrypted, output);
904     }
905 
906     #[test]
907     #[should_panic(expected = "Output buffer size should be at least 33 bytes.")]
full_block_updates_aes_128null908     fn full_block_updates_aes_128() {
909         output_buffer_too_small(Cipher::aes_128_cbc());
910     }
911 
912     #[test]
913     #[should_panic(expected = "Output buffer size should be at least 33 bytes.")]
full_block_updates_aes_256null914     fn full_block_updates_aes_256() {
915         output_buffer_too_small(Cipher::aes_256_cbc());
916     }
917 
918     #[test]
919     #[should_panic(expected = "Output buffer size should be at least 17 bytes.")]
full_block_updates_3desnull920     fn full_block_updates_3des() {
921         output_buffer_too_small(Cipher::des_ede3_cbc());
922     }
923 
output_buffer_too_smallnull924     fn output_buffer_too_small(cipher: &'static CipherRef) {
925         let mut key = vec![0; cipher.key_length()];
926         rand_bytes(&mut key).unwrap();
927         let mut iv = vec![0; cipher.iv_length()];
928         rand_bytes(&mut iv).unwrap();
929 
930         let mut ctx = CipherCtx::new().unwrap();
931 
932         ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
933             .unwrap();
934         ctx.set_padding(false);
935 
936         let block_size = cipher.block_size();
937         assert!(block_size > 1, "Need a block cipher, not a stream cipher");
938 
939         ctx.cipher_update(&vec![0; block_size + 1], Some(&mut vec![0; block_size - 1]))
940             .unwrap();
941     }
942 
943     #[cfg(ossl102)]
cipher_wrap_testnull944     fn cipher_wrap_test(cipher: &CipherRef, pt: &str, ct: &str, key: &str, iv: Option<&str>) {
945         let pt = hex::decode(pt).unwrap();
946         let key = hex::decode(key).unwrap();
947         let expected = hex::decode(ct).unwrap();
948         let iv = iv.map(|v| hex::decode(v).unwrap());
949         let padding = 8 - pt.len() % 8;
950         let mut computed = vec![0; pt.len() + padding + cipher.block_size() * 2];
951         let mut ctx = CipherCtx::new().unwrap();
952 
953         ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
954         ctx.encrypt_init(Some(cipher), Some(&key), iv.as_deref())
955             .unwrap();
956 
957         let count = ctx.cipher_update(&pt, Some(&mut computed)).unwrap();
958         let rest = ctx.cipher_final(&mut computed[count..]).unwrap();
959         computed.truncate(count + rest);
960 
961         if computed != expected {
962             println!("Computed: {}", hex::encode(&computed));
963             println!("Expected: {}", hex::encode(&expected));
964             if computed.len() != expected.len() {
965                 println!(
966                     "Lengths differ: {} in computed vs {} expected",
967                     computed.len(),
968                     expected.len()
969                 );
970             }
971             panic!("test failure");
972         }
973     }
974 
975     #[test]
976     #[cfg(ossl102)]
test_aes128_wrapnull977     fn test_aes128_wrap() {
978         let pt = "00112233445566778899aabbccddeeff";
979         let ct = "7940ff694448b5bb5139c959a4896832e55d69aa04daa27e";
980         let key = "2b7e151628aed2a6abf7158809cf4f3c";
981         let iv = "0001020304050607";
982 
983         cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, Some(iv));
984     }
985 
986     #[test]
987     #[cfg(ossl102)]
test_aes128_wrap_default_ivnull988     fn test_aes128_wrap_default_iv() {
989         let pt = "00112233445566778899aabbccddeeff";
990         let ct = "38f1215f0212526f8a70b51955b9fbdc9fe3041d9832306e";
991         let key = "2b7e151628aed2a6abf7158809cf4f3c";
992 
993         cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, None);
994     }
995 
996     #[test]
997     #[cfg(ossl110)]
test_aes128_wrap_padnull998     fn test_aes128_wrap_pad() {
999         let pt = "00112233445566778899aabbccddee";
1000         let ct = "f13998f5ab32ef82a1bdbcbe585e1d837385b529572a1e1b";
1001         let key = "2b7e151628aed2a6abf7158809cf4f3c";
1002         let iv = "00010203";
1003 
1004         cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, Some(iv));
1005     }
1006 
1007     #[test]
1008     #[cfg(ossl110)]
test_aes128_wrap_pad_default_ivnull1009     fn test_aes128_wrap_pad_default_iv() {
1010         let pt = "00112233445566778899aabbccddee";
1011         let ct = "3a501085fb8cf66f4186b7df851914d471ed823411598add";
1012         let key = "2b7e151628aed2a6abf7158809cf4f3c";
1013 
1014         cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, None);
1015     }
1016 
1017     #[test]
1018     #[cfg(ossl102)]
test_aes192_wrapnull1019     fn test_aes192_wrap() {
1020         let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
1021         let ct = "83b89142dfeeb4871e078bfb81134d33e23fedc19b03a1cf689973d3831b6813";
1022         let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1023         let iv = "0001020304050607";
1024 
1025         cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, Some(iv));
1026     }
1027 
1028     #[test]
1029     #[cfg(ossl102)]
test_aes192_wrap_default_ivnull1030     fn test_aes192_wrap_default_iv() {
1031         let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
1032         let ct = "c02c2cf11505d3e4851030d5534cbf5a1d7eca7ba8839adbf239756daf1b43e6";
1033         let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1034 
1035         cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, None);
1036     }
1037 
1038     #[test]
1039     #[cfg(ossl110)]
test_aes192_wrap_padnull1040     fn test_aes192_wrap_pad() {
1041         let pt = "00112233445566778899aabbccddee";
1042         let ct = "b4f6bb167ef7caf061a74da82b36ad038ca057ab51e98d3a";
1043         let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1044         let iv = "00010203";
1045 
1046         cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, Some(iv));
1047     }
1048 
1049     #[test]
1050     #[cfg(ossl110)]
test_aes192_wrap_pad_default_ivnull1051     fn test_aes192_wrap_pad_default_iv() {
1052         let pt = "00112233445566778899aabbccddee";
1053         let ct = "b2c37a28cc602753a7c944a4c2555a2df9c98b2eded5312e";
1054         let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1055 
1056         cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, None);
1057     }
1058 
1059     #[test]
1060     #[cfg(ossl102)]
test_aes256_wrapnull1061     fn test_aes256_wrap() {
1062         let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
1063         let ct = "cc05da2a7f56f7dd0c144231f90bce58648fa20a8278f5a6b7d13bba6aa57a33229d4333866b7fd6";
1064         let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1065         let iv = "0001020304050607";
1066 
1067         cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, Some(iv));
1068     }
1069 
1070     #[test]
1071     #[cfg(ossl102)]
test_aes256_wrap_default_ivnull1072     fn test_aes256_wrap_default_iv() {
1073         let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
1074         let ct = "0b24f068b50e52bc6987868411c36e1b03900866ed12af81eb87cef70a8d1911731c1d7abf789d88";
1075         let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1076 
1077         cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, None);
1078     }
1079 
1080     #[test]
1081     #[cfg(ossl110)]
test_aes256_wrap_padnull1082     fn test_aes256_wrap_pad() {
1083         let pt = "00112233445566778899aabbccddee";
1084         let ct = "91594e044ccc06130d60e6c84a996aa4f96a9faff8c5f6e7";
1085         let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1086         let iv = "00010203";
1087 
1088         cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, Some(iv));
1089     }
1090 
1091     #[test]
1092     #[cfg(ossl110)]
test_aes256_wrap_pad_default_ivnull1093     fn test_aes256_wrap_pad_default_iv() {
1094         let pt = "00112233445566778899aabbccddee";
1095         let ct = "dc3c166a854afd68aea624a4272693554bf2e4fcbae602cd";
1096         let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1097 
1098         cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, None);
1099     }
1100 }
1101