openssl/
encrypt.rs

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))]
43use libc::c_int;
44use std::{marker::PhantomData, ptr};
45
46use crate::error::ErrorStack;
47use crate::hash::MessageDigest;
48use crate::pkey::{HasPrivate, HasPublic, PKeyRef};
49use crate::rsa::Padding;
50use crate::{cvt, cvt_p};
51use foreign_types::ForeignTypeRef;
52
53/// A type which encrypts data.
54pub struct Encrypter<'a> {
55    pctx: *mut ffi::EVP_PKEY_CTX,
56    _p: PhantomData<&'a ()>,
57}
58
59unsafe impl Sync for Encrypter<'_> {}
60unsafe impl Send for Encrypter<'_> {}
61
62impl Drop for Encrypter<'_> {
63    fn drop(&mut self) {
64        unsafe {
65            ffi::EVP_PKEY_CTX_free(self.pctx);
66        }
67    }
68}
69
70impl<'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
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`.
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
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
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, boringssl, awslc))]
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))]
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,
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
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
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.
258pub struct Decrypter<'a> {
259    pctx: *mut ffi::EVP_PKEY_CTX,
260    _p: PhantomData<&'a ()>,
261}
262
263unsafe impl Sync for Decrypter<'_> {}
264unsafe impl Send for Decrypter<'_> {}
265
266impl Drop for Decrypter<'_> {
267    fn drop(&mut self) {
268        unsafe {
269            ffi::EVP_PKEY_CTX_free(self.pctx);
270        }
271    }
272}
273
274impl<'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
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`.
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
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
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, boringssl, awslc))]
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))]
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,
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
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
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)]
477mod test {
478    use hex::FromHex;
479
480    use crate::encrypt::{Decrypter, Encrypter};
481    #[cfg(any(ossl102, libressl310, boringssl, awslc))]
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]
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, boringssl, awslc))]
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))]
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}