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