• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Message encryption.
2 //!
3 //! The [`Encrypter`] allows for encryption of data given a public key. The [`Decrypter`] can be
4 //! used with the corresponding private key to decrypt the data.
5 //!
6 //! # Examples
7 //!
8 //! Encrypt and decrypt data given an RSA keypair:
9 //!
10 //! ```rust
11 //! use openssl::encrypt::{Encrypter, Decrypter};
12 //! use openssl::rsa::{Rsa, Padding};
13 //! use openssl::pkey::PKey;
14 //!
15 //! // Generate a keypair
16 //! let keypair = Rsa::generate(2048).unwrap();
17 //! let keypair = PKey::from_rsa(keypair).unwrap();
18 //!
19 //! let data = b"hello, world!";
20 //!
21 //! // Encrypt the data with RSA PKCS1
22 //! let mut encrypter = Encrypter::new(&keypair).unwrap();
23 //! encrypter.set_rsa_padding(Padding::PKCS1).unwrap();
24 //! // Create an output buffer
25 //! let buffer_len = encrypter.encrypt_len(data).unwrap();
26 //! let mut encrypted = vec![0; buffer_len];
27 //! // Encrypt and truncate the buffer
28 //! let encrypted_len = encrypter.encrypt(data, &mut encrypted).unwrap();
29 //! encrypted.truncate(encrypted_len);
30 //!
31 //! // Decrypt the data
32 //! let mut decrypter = Decrypter::new(&keypair).unwrap();
33 //! decrypter.set_rsa_padding(Padding::PKCS1).unwrap();
34 //! // Create an output buffer
35 //! let buffer_len = decrypter.decrypt_len(&encrypted).unwrap();
36 //! let mut decrypted = vec![0; buffer_len];
37 //! // Encrypt and truncate the buffer
38 //! let decrypted_len = decrypter.decrypt(&encrypted, &mut decrypted).unwrap();
39 //! decrypted.truncate(decrypted_len);
40 //! assert_eq!(&*decrypted, data);
41 //! ```
42 #[cfg(any(ossl102, libressl310))]
43 use libc::{c_int, c_void};
44 use std::{marker::PhantomData, ptr};
45 
46 use crate::error::ErrorStack;
47 use crate::hash::MessageDigest;
48 use crate::pkey::{HasPrivate, HasPublic, PKeyRef};
49 use crate::rsa::Padding;
50 use crate::{cvt, cvt_p};
51 use foreign_types::ForeignTypeRef;
52 
53 /// A type which encrypts data.
54 pub struct Encrypter<'a> {
55     pctx: *mut ffi::EVP_PKEY_CTX,
56     _p: PhantomData<&'a ()>,
57 }
58 
59 unsafe impl<'a> Sync for Encrypter<'a> {}
60 unsafe impl<'a> Send for Encrypter<'a> {}
61 
62 impl<'a> Drop for Encrypter<'a> {
drop(&mut self)63     fn drop(&mut self) {
64         unsafe {
65             ffi::EVP_PKEY_CTX_free(self.pctx);
66         }
67     }
68 }
69 
70 impl<'a> Encrypter<'a> {
71     /// Creates a new `Encrypter`.
72     ///
73     /// OpenSSL documentation at [`EVP_PKEY_encrypt_init`].
74     ///
75     /// [`EVP_PKEY_encrypt_init`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_encrypt_init.html
new<T>(pkey: &'a PKeyRef<T>) -> Result<Encrypter<'a>, ErrorStack> where T: HasPublic,76     pub fn new<T>(pkey: &'a PKeyRef<T>) -> Result<Encrypter<'a>, ErrorStack>
77     where
78         T: HasPublic,
79     {
80         unsafe {
81             ffi::init();
82 
83             let pctx = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?;
84             let r = ffi::EVP_PKEY_encrypt_init(pctx);
85             if r != 1 {
86                 ffi::EVP_PKEY_CTX_free(pctx);
87                 return Err(ErrorStack::get());
88             }
89 
90             Ok(Encrypter {
91                 pctx,
92                 _p: PhantomData,
93             })
94         }
95     }
96 
97     /// Returns the RSA padding mode in use.
98     ///
99     /// This is only useful for RSA keys.
100     ///
101     /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`.
rsa_padding(&self) -> Result<Padding, ErrorStack>102     pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
103         unsafe {
104             let mut pad = 0;
105             cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
106                 .map(|_| Padding::from_raw(pad))
107         }
108     }
109 
110     /// Sets the RSA padding mode.
111     ///
112     /// This is only useful for RSA keys.
113     ///
114     /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`].
115     ///
116     /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_padding.html
set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack>117     pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
118         unsafe {
119             cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
120                 self.pctx,
121                 padding.as_raw(),
122             ))
123             .map(|_| ())
124         }
125     }
126 
127     /// Sets the RSA MGF1 algorithm.
128     ///
129     /// This is only useful for RSA keys.
130     ///
131     /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`].
132     ///
133     /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html
set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack>134     pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
135         unsafe {
136             cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
137                 self.pctx,
138                 md.as_ptr() as *mut _,
139             ))
140             .map(|_| ())
141         }
142     }
143 
144     /// Sets the RSA OAEP algorithm.
145     ///
146     /// This is only useful for RSA keys.
147     ///
148     /// This corresponds to [`EVP_PKEY_CTX_set_rsa_oaep_md`].
149     ///
150     /// [`EVP_PKEY_CTX_set_rsa_oaep_md`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set_rsa_oaep_md.html
151     #[cfg(any(ossl102, libressl310))]
set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack>152     pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
153         unsafe {
154             cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
155                 self.pctx,
156                 md.as_ptr() as *mut _,
157             ))
158             .map(|_| ())
159         }
160     }
161 
162     /// Sets the RSA OAEP label.
163     ///
164     /// This is only useful for RSA keys.
165     ///
166     /// This corresponds to [`EVP_PKEY_CTX_set0_rsa_oaep_label`].
167     ///
168     /// [`EVP_PKEY_CTX_set0_rsa_oaep_label`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set0_rsa_oaep_label.html
169     #[cfg(any(ossl102, libressl310))]
set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack>170     pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
171         unsafe {
172             let p = cvt_p(ffi::OPENSSL_malloc(label.len() as _))?;
173             ptr::copy_nonoverlapping(label.as_ptr(), p as *mut u8, label.len());
174 
175             cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
176                 self.pctx,
177                 p as *mut c_void,
178                 label.len() as c_int,
179             ))
180             .map(|_| ())
181             .map_err(|e| {
182                 ffi::OPENSSL_free(p);
183                 e
184             })
185         }
186     }
187 
188     /// Performs public key encryption.
189     ///
190     /// In order to know the size needed for the output buffer, use [`encrypt_len`](Encrypter::encrypt_len).
191     /// Note that the length of the output buffer can be greater of the length of the encoded data.
192     /// ```
193     /// # use openssl::{
194     /// #   encrypt::Encrypter,
195     /// #   pkey::PKey,
196     /// #   rsa::{Rsa, Padding},
197     /// # };
198     /// #
199     /// # let key = include_bytes!("../test/rsa.pem");
200     /// # let private_key = Rsa::private_key_from_pem(key).unwrap();
201     /// # let pkey = PKey::from_rsa(private_key).unwrap();
202     /// # let input = b"hello world".to_vec();
203     /// #
204     /// let mut encrypter = Encrypter::new(&pkey).unwrap();
205     /// encrypter.set_rsa_padding(Padding::PKCS1).unwrap();
206     ///
207     /// // Get the length of the output buffer
208     /// let buffer_len = encrypter.encrypt_len(&input).unwrap();
209     /// let mut encoded = vec![0u8; buffer_len];
210     ///
211     /// // Encode the data and get its length
212     /// let encoded_len = encrypter.encrypt(&input, &mut encoded).unwrap();
213     ///
214     /// // Use only the part of the buffer with the encoded data
215     /// let encoded = &encoded[..encoded_len];
216     /// ```
217     ///
218     /// This corresponds to [`EVP_PKEY_encrypt`].
219     ///
220     /// [`EVP_PKEY_encrypt`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_encrypt.html
encrypt(&self, from: &[u8], to: &mut [u8]) -> Result<usize, ErrorStack>221     pub fn encrypt(&self, from: &[u8], to: &mut [u8]) -> Result<usize, ErrorStack> {
222         let mut written = to.len();
223         unsafe {
224             cvt(ffi::EVP_PKEY_encrypt(
225                 self.pctx,
226                 to.as_mut_ptr(),
227                 &mut written,
228                 from.as_ptr(),
229                 from.len(),
230             ))?;
231         }
232 
233         Ok(written)
234     }
235 
236     /// Gets the size of the buffer needed to encrypt the input data.
237     ///
238     /// This corresponds to [`EVP_PKEY_encrypt`] called with a null pointer as output argument.
239     ///
240     /// [`EVP_PKEY_encrypt`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_encrypt.html
encrypt_len(&self, from: &[u8]) -> Result<usize, ErrorStack>241     pub fn encrypt_len(&self, from: &[u8]) -> Result<usize, ErrorStack> {
242         let mut written = 0;
243         unsafe {
244             cvt(ffi::EVP_PKEY_encrypt(
245                 self.pctx,
246                 ptr::null_mut(),
247                 &mut written,
248                 from.as_ptr(),
249                 from.len(),
250             ))?;
251         }
252 
253         Ok(written)
254     }
255 }
256 
257 /// A type which decrypts data.
258 pub struct Decrypter<'a> {
259     pctx: *mut ffi::EVP_PKEY_CTX,
260     _p: PhantomData<&'a ()>,
261 }
262 
263 unsafe impl<'a> Sync for Decrypter<'a> {}
264 unsafe impl<'a> Send for Decrypter<'a> {}
265 
266 impl<'a> Drop for Decrypter<'a> {
drop(&mut self)267     fn drop(&mut self) {
268         unsafe {
269             ffi::EVP_PKEY_CTX_free(self.pctx);
270         }
271     }
272 }
273 
274 impl<'a> Decrypter<'a> {
275     /// Creates a new `Decrypter`.
276     ///
277     /// OpenSSL documentation at [`EVP_PKEY_decrypt_init`].
278     ///
279     /// [`EVP_PKEY_decrypt_init`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_decrypt_init.html
new<T>(pkey: &'a PKeyRef<T>) -> Result<Decrypter<'a>, ErrorStack> where T: HasPrivate,280     pub fn new<T>(pkey: &'a PKeyRef<T>) -> Result<Decrypter<'a>, ErrorStack>
281     where
282         T: HasPrivate,
283     {
284         unsafe {
285             ffi::init();
286 
287             let pctx = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?;
288             let r = ffi::EVP_PKEY_decrypt_init(pctx);
289             if r != 1 {
290                 ffi::EVP_PKEY_CTX_free(pctx);
291                 return Err(ErrorStack::get());
292             }
293 
294             Ok(Decrypter {
295                 pctx,
296                 _p: PhantomData,
297             })
298         }
299     }
300 
301     /// Returns the RSA padding mode in use.
302     ///
303     /// This is only useful for RSA keys.
304     ///
305     /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`.
rsa_padding(&self) -> Result<Padding, ErrorStack>306     pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
307         unsafe {
308             let mut pad = 0;
309             cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
310                 .map(|_| Padding::from_raw(pad))
311         }
312     }
313 
314     /// Sets the RSA padding mode.
315     ///
316     /// This is only useful for RSA keys.
317     ///
318     /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`].
319     ///
320     /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_padding.html
set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack>321     pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
322         unsafe {
323             cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
324                 self.pctx,
325                 padding.as_raw(),
326             ))
327             .map(|_| ())
328         }
329     }
330 
331     /// Sets the RSA MGF1 algorithm.
332     ///
333     /// This is only useful for RSA keys.
334     ///
335     /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`].
336     ///
337     /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html
set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack>338     pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
339         unsafe {
340             cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
341                 self.pctx,
342                 md.as_ptr() as *mut _,
343             ))
344             .map(|_| ())
345         }
346     }
347 
348     /// Sets the RSA OAEP algorithm.
349     ///
350     /// This is only useful for RSA keys.
351     ///
352     /// This corresponds to [`EVP_PKEY_CTX_set_rsa_oaep_md`].
353     ///
354     /// [`EVP_PKEY_CTX_set_rsa_oaep_md`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set_rsa_oaep_md.html
355     #[cfg(any(ossl102, libressl310))]
set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack>356     pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
357         unsafe {
358             cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
359                 self.pctx,
360                 md.as_ptr() as *mut _,
361             ))
362             .map(|_| ())
363         }
364     }
365 
366     /// Sets the RSA OAEP label.
367     ///
368     /// This is only useful for RSA keys.
369     ///
370     /// This corresponds to [`EVP_PKEY_CTX_set0_rsa_oaep_label`].
371     ///
372     /// [`EVP_PKEY_CTX_set0_rsa_oaep_label`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set0_rsa_oaep_label.html
373     #[cfg(any(ossl102, libressl310))]
set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack>374     pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
375         unsafe {
376             let p = cvt_p(ffi::OPENSSL_malloc(label.len() as _))?;
377             ptr::copy_nonoverlapping(label.as_ptr(), p as *mut u8, label.len());
378 
379             cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
380                 self.pctx,
381                 p as *mut c_void,
382                 label.len() as c_int,
383             ))
384             .map(|_| ())
385             .map_err(|e| {
386                 ffi::OPENSSL_free(p);
387                 e
388             })
389         }
390     }
391 
392     /// Performs public key decryption.
393     ///
394     /// In order to know the size needed for the output buffer, use [`decrypt_len`](Decrypter::decrypt_len).
395     /// Note that the length of the output buffer can be greater of the length of the decoded data.
396     /// ```
397     /// # use openssl::{
398     /// #   encrypt::Decrypter,
399     /// #   pkey::PKey,
400     /// #   rsa::{Rsa, Padding},
401     /// # };
402     /// #
403     /// # const INPUT: &[u8] = b"\
404     /// #     \x26\xa1\xc1\x13\xc5\x7f\xb4\x9f\xa0\xb4\xde\x61\x5e\x2e\xc6\xfb\x76\x5c\xd1\x2b\x5f\
405     /// #     \x1d\x36\x60\xfa\xf8\xe8\xb3\x21\xf4\x9c\x70\xbc\x03\xea\xea\xac\xce\x4b\xb3\xf6\x45\
406     /// #     \xcc\xb3\x80\x9e\xa8\xf7\xc3\x5d\x06\x12\x7a\xa3\x0c\x30\x67\xf1\xe7\x94\x6c\xf6\x26\
407     /// #     \xac\x28\x17\x59\x69\xe1\xdc\xed\x7e\xc0\xe9\x62\x57\x49\xce\xdd\x13\x07\xde\x18\x03\
408     /// #     \x0f\x9d\x61\x65\xb9\x23\x8c\x78\x4b\xad\x23\x49\x75\x47\x64\xa0\xa0\xa2\x90\xc1\x49\
409     /// #     \x1b\x05\x24\xc2\xe9\x2c\x0d\x49\x78\x72\x61\x72\xed\x8b\x6f\x8a\xe8\xca\x05\x5c\x58\
410     /// #     \xd6\x95\xd6\x7b\xe3\x2d\x0d\xaa\x3e\x6d\x3c\x9a\x1c\x1d\xb4\x6c\x42\x9d\x9a\x82\x55\
411     /// #     \xd9\xde\xc8\x08\x7b\x17\xac\xd7\xaf\x86\x7b\x69\x9e\x3c\xf4\x5e\x1c\x39\x52\x6d\x62\
412     /// #     \x50\x51\xbd\xa6\xc8\x4e\xe9\x34\xf0\x37\x0d\xa9\xa9\x77\xe6\xf5\xc2\x47\x2d\xa8\xee\
413     /// #     \x3f\x69\x78\xff\xa9\xdc\x70\x22\x20\x9a\x5c\x9b\x70\x15\x90\xd3\xb4\x0e\x54\x9e\x48\
414     /// #     \xed\xb6\x2c\x88\xfc\xb4\xa9\x37\x10\xfa\x71\xb2\xec\x75\xe7\xe7\x0e\xf4\x60\x2c\x7b\
415     /// #     \x58\xaf\xa0\x53\xbd\x24\xf1\x12\xe3\x2e\x99\x25\x0a\x54\x54\x9d\xa1\xdb\xca\x41\x85\
416     /// #     \xf4\x62\x78\x64";
417     /// #
418     /// # let key = include_bytes!("../test/rsa.pem");
419     /// # let private_key = Rsa::private_key_from_pem(key).unwrap();
420     /// # let pkey = PKey::from_rsa(private_key).unwrap();
421     /// # let input = INPUT.to_vec();
422     /// #
423     /// let mut decrypter = Decrypter::new(&pkey).unwrap();
424     /// decrypter.set_rsa_padding(Padding::PKCS1).unwrap();
425     ///
426     /// // Get the length of the output buffer
427     /// let buffer_len = decrypter.decrypt_len(&input).unwrap();
428     /// let mut decoded = vec![0u8; buffer_len];
429     ///
430     /// // Decrypt the data and get its length
431     /// let decoded_len = decrypter.decrypt(&input, &mut decoded).unwrap();
432     ///
433     /// // Use only the part of the buffer with the decrypted data
434     /// let decoded = &decoded[..decoded_len];
435     /// ```
436     ///
437     /// This corresponds to [`EVP_PKEY_decrypt`].
438     ///
439     /// [`EVP_PKEY_decrypt`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_decrypt.html
decrypt(&self, from: &[u8], to: &mut [u8]) -> Result<usize, ErrorStack>440     pub fn decrypt(&self, from: &[u8], to: &mut [u8]) -> Result<usize, ErrorStack> {
441         let mut written = to.len();
442         unsafe {
443             cvt(ffi::EVP_PKEY_decrypt(
444                 self.pctx,
445                 to.as_mut_ptr(),
446                 &mut written,
447                 from.as_ptr(),
448                 from.len(),
449             ))?;
450         }
451 
452         Ok(written)
453     }
454 
455     /// Gets the size of the buffer needed to decrypt the input data.
456     ///
457     /// This corresponds to [`EVP_PKEY_decrypt`] called with a null pointer as output argument.
458     ///
459     /// [`EVP_PKEY_decrypt`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_decrypt.html
decrypt_len(&self, from: &[u8]) -> Result<usize, ErrorStack>460     pub fn decrypt_len(&self, from: &[u8]) -> Result<usize, ErrorStack> {
461         let mut written = 0;
462         unsafe {
463             cvt(ffi::EVP_PKEY_decrypt(
464                 self.pctx,
465                 ptr::null_mut(),
466                 &mut written,
467                 from.as_ptr(),
468                 from.len(),
469             ))?;
470         }
471 
472         Ok(written)
473     }
474 }
475 
476 #[cfg(test)]
477 mod test {
478     use hex::FromHex;
479 
480     use crate::encrypt::{Decrypter, Encrypter};
481     #[cfg(any(ossl102, libressl310))]
482     use crate::hash::MessageDigest;
483     use crate::pkey::PKey;
484     use crate::rsa::{Padding, Rsa};
485 
486     const INPUT: &str =
487         "65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\
488          654841694f6a457a4d4441344d546b7a4f44417344516f67496d6830644841364c79396c654746746347786c4c\
489          6d4e76625339706331397962323930496a7030636e566c6651";
490 
491     #[test]
rsa_encrypt_decrypt()492     fn rsa_encrypt_decrypt() {
493         let key = include_bytes!("../test/rsa.pem");
494         let private_key = Rsa::private_key_from_pem(key).unwrap();
495         let pkey = PKey::from_rsa(private_key).unwrap();
496 
497         let mut encrypter = Encrypter::new(&pkey).unwrap();
498         encrypter.set_rsa_padding(Padding::PKCS1).unwrap();
499         let input = Vec::from_hex(INPUT).unwrap();
500         let buffer_len = encrypter.encrypt_len(&input).unwrap();
501         let mut encoded = vec![0u8; buffer_len];
502         let encoded_len = encrypter.encrypt(&input, &mut encoded).unwrap();
503         let encoded = &encoded[..encoded_len];
504 
505         let mut decrypter = Decrypter::new(&pkey).unwrap();
506         decrypter.set_rsa_padding(Padding::PKCS1).unwrap();
507         let buffer_len = decrypter.decrypt_len(encoded).unwrap();
508         let mut decoded = vec![0u8; buffer_len];
509         let decoded_len = decrypter.decrypt(encoded, &mut decoded).unwrap();
510         let decoded = &decoded[..decoded_len];
511 
512         assert_eq!(decoded, &*input);
513     }
514 
515     #[test]
516     #[cfg(any(ossl102, libressl310))]
rsa_encrypt_decrypt_with_sha256()517     fn rsa_encrypt_decrypt_with_sha256() {
518         let key = include_bytes!("../test/rsa.pem");
519         let private_key = Rsa::private_key_from_pem(key).unwrap();
520         let pkey = PKey::from_rsa(private_key).unwrap();
521 
522         let md = MessageDigest::sha256();
523 
524         let mut encrypter = Encrypter::new(&pkey).unwrap();
525         encrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
526         encrypter.set_rsa_oaep_md(md).unwrap();
527         encrypter.set_rsa_mgf1_md(md).unwrap();
528         let input = Vec::from_hex(INPUT).unwrap();
529         let buffer_len = encrypter.encrypt_len(&input).unwrap();
530         let mut encoded = vec![0u8; buffer_len];
531         let encoded_len = encrypter.encrypt(&input, &mut encoded).unwrap();
532         let encoded = &encoded[..encoded_len];
533 
534         let mut decrypter = Decrypter::new(&pkey).unwrap();
535         decrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
536         decrypter.set_rsa_oaep_md(md).unwrap();
537         decrypter.set_rsa_mgf1_md(md).unwrap();
538         let buffer_len = decrypter.decrypt_len(encoded).unwrap();
539         let mut decoded = vec![0u8; buffer_len];
540         let decoded_len = decrypter.decrypt(encoded, &mut decoded).unwrap();
541         let decoded = &decoded[..decoded_len];
542 
543         assert_eq!(decoded, &*input);
544     }
545 
546     #[test]
547     #[cfg(any(ossl102, libressl310))]
rsa_encrypt_decrypt_oaep_label()548     fn rsa_encrypt_decrypt_oaep_label() {
549         let key = include_bytes!("../test/rsa.pem");
550         let private_key = Rsa::private_key_from_pem(key).unwrap();
551         let pkey = PKey::from_rsa(private_key).unwrap();
552 
553         let mut encrypter = Encrypter::new(&pkey).unwrap();
554         encrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
555         encrypter.set_rsa_oaep_label(b"test_oaep_label").unwrap();
556         let input = Vec::from_hex(INPUT).unwrap();
557         let buffer_len = encrypter.encrypt_len(&input).unwrap();
558         let mut encoded = vec![0u8; buffer_len];
559         let encoded_len = encrypter.encrypt(&input, &mut encoded).unwrap();
560         let encoded = &encoded[..encoded_len];
561 
562         let mut decrypter = Decrypter::new(&pkey).unwrap();
563         decrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
564         decrypter.set_rsa_oaep_label(b"test_oaep_label").unwrap();
565         let buffer_len = decrypter.decrypt_len(encoded).unwrap();
566         let mut decoded = vec![0u8; buffer_len];
567         let decoded_len = decrypter.decrypt(encoded, &mut decoded).unwrap();
568         let decoded = &decoded[..decoded_len];
569 
570         assert_eq!(decoded, &*input);
571 
572         decrypter.set_rsa_oaep_label(b"wrong_oaep_label").unwrap();
573         let buffer_len = decrypter.decrypt_len(encoded).unwrap();
574         let mut decoded = vec![0u8; buffer_len];
575 
576         assert!(decrypter.decrypt(encoded, &mut decoded).is_err());
577     }
578 }
579