1 //! The asymmetric encryption context.
2 //!
3 //! # Examples
4 //!
5 //! Encrypt data with RSA
6 //!
7 //! ```
8 //! use openssl::rsa::Rsa;
9 //! use openssl::pkey::PKey;
10 //! use openssl::pkey_ctx::PkeyCtx;
11 //!
12 //! let key = Rsa::generate(4096).unwrap();
13 //! let key = PKey::from_rsa(key).unwrap();
14 //!
15 //! let mut ctx = PkeyCtx::new(&key).unwrap();
16 //! ctx.encrypt_init().unwrap();
17 //!
18 //! let data = b"Some Crypto Text";
19 //! let mut ciphertext = vec![];
20 //! ctx.encrypt_to_vec(data, &mut ciphertext).unwrap();
21 //! ```
22 
23 #![cfg_attr(
24     not(boringssl),
25     doc = r#"\
26 Generate a CMAC key
27 
28 ```
29 use openssl::pkey_ctx::PkeyCtx;
30 use openssl::pkey::Id;
31 use openssl::cipher::Cipher;
32 
33 let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap();
34 ctx.keygen_init().unwrap();
35 ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap();
36 ctx.set_keygen_mac_key(b"0123456789abcdef").unwrap();
37 let cmac_key = ctx.keygen().unwrap();
38 ```"#
39 )]
40 
41 //!
42 //! Sign and verify data with RSA
43 //!
44 //! ```
45 //! use openssl::pkey_ctx::PkeyCtx;
46 //! use openssl::pkey::PKey;
47 //! use openssl::rsa::Rsa;
48 //!
49 //! // Generate a random RSA key.
50 //! let key = Rsa::generate(4096).unwrap();
51 //! let key = PKey::from_rsa(key).unwrap();
52 //!
53 //! let text = b"Some Crypto Text";
54 //!
55 //! // Create the signature.
56 //! let mut ctx = PkeyCtx::new(&key).unwrap();
57 //! ctx.sign_init().unwrap();
58 //! let mut signature = vec![];
59 //! ctx.sign_to_vec(text, &mut signature).unwrap();
60 //!
61 //! // Verify the signature.
62 //! let mut ctx = PkeyCtx::new(&key).unwrap();
63 //! ctx.verify_init().unwrap();
64 //! let valid = ctx.verify(text, &signature).unwrap();
65 //! assert!(valid);
66 //! ```
67 #[cfg(not(boringssl))]
68 use crate::cipher::CipherRef;
69 use crate::error::ErrorStack;
70 use crate::md::MdRef;
71 use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Private};
72 use crate::rsa::Padding;
73 use crate::sign::RsaPssSaltlen;
74 use crate::{cvt, cvt_p};
75 use foreign_types::{ForeignType, ForeignTypeRef};
76 #[cfg(not(boringssl))]
77 use libc::c_int;
78 use openssl_macros::corresponds;
79 use std::convert::TryFrom;
80 use std::ptr;
81 
82 /// HKDF modes of operation.
83 #[cfg(ossl111)]
84 pub struct HkdfMode(c_int);
85 
86 #[cfg(ossl111)]
87 impl HkdfMode {
88     /// This is the default mode. Calling [`derive`][PkeyCtxRef::derive] on a [`PkeyCtxRef`] set up
89     /// for HKDF will perform an extract followed by an expand operation in one go. The derived key
90     /// returned will be the result after the expand operation. The intermediate fixed-length
91     /// pseudorandom key K is not returned.
92     pub const EXTRACT_THEN_EXPAND: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND);
93 
94     /// In this mode calling [`derive`][PkeyCtxRef::derive] will just perform the extract operation.
95     /// The value returned will be the intermediate fixed-length pseudorandom key K.
96     ///
97     /// The digest, key and salt values must be set before a key is derived or an error occurs.
98     pub const EXTRACT_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY);
99 
100     /// In this mode calling [`derive`][PkeyCtxRef::derive] will just perform the expand operation.
101     /// The input key should be set to the intermediate fixed-length pseudorandom key K returned
102     /// from a previous extract operation.
103     ///
104     /// The digest, key and info values must be set before a key is derived or an error occurs.
105     pub const EXPAND_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXPAND_ONLY);
106 }
107 
108 generic_foreign_type_and_impl_send_sync! {
109     type CType = ffi::EVP_PKEY_CTX;
dropnull110     fn drop = ffi::EVP_PKEY_CTX_free;
111 
112     /// A context object which can perform asymmetric cryptography operations.
113     pub struct PkeyCtx<T>;
114     /// A reference to a [`PkeyCtx`].
115     pub struct PkeyCtxRef<T>;
116 }
117 
118 impl<T> PkeyCtx<T> {
119     /// Creates a new pkey context using the provided key.
120     #[corresponds(EVP_PKEY_CTX_new)]
121     #[inline]
newnull122     pub fn new(pkey: &PKeyRef<T>) -> Result<Self, ErrorStack> {
123         unsafe {
124             let ptr = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?;
125             Ok(PkeyCtx::from_ptr(ptr))
126         }
127     }
128 }
129 
130 impl PkeyCtx<()> {
131     /// Creates a new pkey context for the specified algorithm ID.
132     #[corresponds(EVP_PKEY_new_id)]
133     #[inline]
new_idnull134     pub fn new_id(id: Id) -> Result<Self, ErrorStack> {
135         unsafe {
136             let ptr = cvt_p(ffi::EVP_PKEY_CTX_new_id(id.as_raw(), ptr::null_mut()))?;
137             Ok(PkeyCtx::from_ptr(ptr))
138         }
139     }
140 }
141 
142 impl<T> PkeyCtxRef<T>
143 where
144     T: HasPublic,
145 {
146     /// Prepares the context for encryption using the public key.
147     #[corresponds(EVP_PKEY_encrypt_init)]
148     #[inline]
encrypt_initnull149     pub fn encrypt_init(&mut self) -> Result<(), ErrorStack> {
150         unsafe {
151             cvt(ffi::EVP_PKEY_encrypt_init(self.as_ptr()))?;
152         }
153 
154         Ok(())
155     }
156 
157     /// Prepares the context for signature verification using the public key.
158     #[corresponds(EVP_PKEY_verify_init)]
159     #[inline]
verify_initnull160     pub fn verify_init(&mut self) -> Result<(), ErrorStack> {
161         unsafe {
162             cvt(ffi::EVP_PKEY_verify_init(self.as_ptr()))?;
163         }
164 
165         Ok(())
166     }
167 
168     /// Prepares the context for signature recovery using the public key.
169     #[corresponds(EVP_PKEY_verify_recover_init)]
170     #[inline]
verify_recover_initnull171     pub fn verify_recover_init(&mut self) -> Result<(), ErrorStack> {
172         unsafe {
173             cvt(ffi::EVP_PKEY_verify_recover_init(self.as_ptr()))?;
174         }
175 
176         Ok(())
177     }
178 
179     /// Encrypts data using the public key.
180     ///
181     /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be
182     /// returned.
183     #[corresponds(EVP_PKEY_encrypt)]
184     #[inline]
encryptnull185     pub fn encrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
186         let mut written = to.as_ref().map_or(0, |b| b.len());
187         unsafe {
188             cvt(ffi::EVP_PKEY_encrypt(
189                 self.as_ptr(),
190                 to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
191                 &mut written,
192                 from.as_ptr(),
193                 from.len(),
194             ))?;
195         }
196 
197         Ok(written)
198     }
199 
200     /// Like [`Self::encrypt`] but appends ciphertext to a [`Vec`].
encrypt_to_vecnull201     pub fn encrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack> {
202         let base = out.len();
203         let len = self.encrypt(from, None)?;
204         out.resize(base + len, 0);
205         let len = self.encrypt(from, Some(&mut out[base..]))?;
206         out.truncate(base + len);
207         Ok(len)
208     }
209 
210     /// Verifies the signature of data using the public key.
211     ///
212     /// Returns `Ok(true)` if the signature is valid, `Ok(false)` if the signature is invalid, and `Err` if an error
213     /// occurred.
214     ///
215     /// # Note
216     ///
217     /// This verifies the signature of the *raw* data. It is more common to compute and verify the signature of the
218     /// cryptographic hash of an arbitrary amount of data. The [`MdCtx`](crate::md_ctx::MdCtx) type can be used to do
219     /// that.
220     #[corresponds(EVP_PKEY_verify)]
221     #[inline]
verifynull222     pub fn verify(&mut self, data: &[u8], sig: &[u8]) -> Result<bool, ErrorStack> {
223         unsafe {
224             let r = ffi::EVP_PKEY_verify(
225                 self.as_ptr(),
226                 sig.as_ptr(),
227                 sig.len(),
228                 data.as_ptr(),
229                 data.len(),
230             );
231             // `EVP_PKEY_verify` is not terribly consistent about how it,
232             // reports errors. It does not clearly distinguish between 0 and
233             // -1, and may put errors on the stack in both cases. If there's
234             // errors on the stack, we return `Err()`, else we return
235             // `Ok(false)`.
236             if r <= 0 {
237                 let errors = ErrorStack::get();
238                 if !errors.errors().is_empty() {
239                     return Err(errors);
240                 }
241             }
242 
243             Ok(r == 1)
244         }
245     }
246 
247     /// Recovers the original data signed by the private key. You almost
248     /// always want `verify` instead.
249     ///
250     /// Returns the number of bytes written to `to`, or the number of bytes
251     /// that would be written, if `to` is `None.
252     #[corresponds(EVP_PKEY_verify_recover)]
253     #[inline]
verify_recovernull254     pub fn verify_recover(
255         &mut self,
256         sig: &[u8],
257         to: Option<&mut [u8]>,
258     ) -> Result<usize, ErrorStack> {
259         let mut written = to.as_ref().map_or(0, |b| b.len());
260         unsafe {
261             cvt(ffi::EVP_PKEY_verify_recover(
262                 self.as_ptr(),
263                 to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
264                 &mut written,
265                 sig.as_ptr(),
266                 sig.len(),
267             ))?;
268         }
269 
270         Ok(written)
271     }
272 }
273 
274 impl<T> PkeyCtxRef<T>
275 where
276     T: HasPrivate,
277 {
278     /// Prepares the context for decryption using the private key.
279     #[corresponds(EVP_PKEY_decrypt_init)]
280     #[inline]
decrypt_initnull281     pub fn decrypt_init(&mut self) -> Result<(), ErrorStack> {
282         unsafe {
283             cvt(ffi::EVP_PKEY_decrypt_init(self.as_ptr()))?;
284         }
285 
286         Ok(())
287     }
288 
289     /// Prepares the context for signing using the private key.
290     #[corresponds(EVP_PKEY_sign_init)]
291     #[inline]
sign_initnull292     pub fn sign_init(&mut self) -> Result<(), ErrorStack> {
293         unsafe {
294             cvt(ffi::EVP_PKEY_sign_init(self.as_ptr()))?;
295         }
296 
297         Ok(())
298     }
299 
300     /// Sets the peer key used for secret derivation.
301     #[corresponds(EVP_PKEY_derive_set_peer)]
derive_set_peernull302     pub fn derive_set_peer<U>(&mut self, key: &PKeyRef<U>) -> Result<(), ErrorStack>
303     where
304         U: HasPublic,
305     {
306         unsafe {
307             cvt(ffi::EVP_PKEY_derive_set_peer(self.as_ptr(), key.as_ptr()))?;
308         }
309 
310         Ok(())
311     }
312 
313     /// Decrypts data using the private key.
314     ///
315     /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be
316     /// returned.
317     #[corresponds(EVP_PKEY_decrypt)]
318     #[inline]
decryptnull319     pub fn decrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
320         let mut written = to.as_ref().map_or(0, |b| b.len());
321         unsafe {
322             cvt(ffi::EVP_PKEY_decrypt(
323                 self.as_ptr(),
324                 to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
325                 &mut written,
326                 from.as_ptr(),
327                 from.len(),
328             ))?;
329         }
330 
331         Ok(written)
332     }
333 
334     /// Like [`Self::decrypt`] but appends plaintext to a [`Vec`].
decrypt_to_vecnull335     pub fn decrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack> {
336         let base = out.len();
337         let len = self.decrypt(from, None)?;
338         out.resize(base + len, 0);
339         let len = self.decrypt(from, Some(&mut out[base..]))?;
340         out.truncate(base + len);
341         Ok(len)
342     }
343 
344     /// Signs the contents of `data`.
345     ///
346     /// If `sig` is set to `None`, an upper bound on the number of bytes required for the output buffer will be
347     /// returned.
348     ///
349     /// # Note
350     ///
351     /// This computes the signature of the *raw* bytes of `data`. It is more common to sign the cryptographic hash of
352     /// an arbitrary amount of data. The [`MdCtx`](crate::md_ctx::MdCtx) type can be used to do that.
353     #[corresponds(EVP_PKEY_sign)]
354     #[inline]
signnull355     pub fn sign(&mut self, data: &[u8], sig: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
356         let mut written = sig.as_ref().map_or(0, |b| b.len());
357         unsafe {
358             cvt(ffi::EVP_PKEY_sign(
359                 self.as_ptr(),
360                 sig.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
361                 &mut written,
362                 data.as_ptr(),
363                 data.len(),
364             ))?;
365         }
366 
367         Ok(written)
368     }
369 
370     /// Like [`Self::sign`] but appends the signature to a [`Vec`].
sign_to_vecnull371     pub fn sign_to_vec(&mut self, data: &[u8], sig: &mut Vec<u8>) -> Result<usize, ErrorStack> {
372         let base = sig.len();
373         let len = self.sign(data, None)?;
374         sig.resize(base + len, 0);
375         let len = self.sign(data, Some(&mut sig[base..]))?;
376         sig.truncate(base + len);
377         Ok(len)
378     }
379 }
380 
381 impl<T> PkeyCtxRef<T> {
382     /// Prepares the context for shared secret derivation.
383     #[corresponds(EVP_PKEY_derive_init)]
384     #[inline]
derive_initnull385     pub fn derive_init(&mut self) -> Result<(), ErrorStack> {
386         unsafe {
387             cvt(ffi::EVP_PKEY_derive_init(self.as_ptr()))?;
388         }
389 
390         Ok(())
391     }
392 
393     /// Prepares the context for key generation.
394     #[corresponds(EVP_PKEY_keygen_init)]
395     #[inline]
keygen_initnull396     pub fn keygen_init(&mut self) -> Result<(), ErrorStack> {
397         unsafe {
398             cvt(ffi::EVP_PKEY_keygen_init(self.as_ptr()))?;
399         }
400 
401         Ok(())
402     }
403 
404     /// Sets which algorithm was used to compute the digest used in a
405     /// signature. With RSA signatures this causes the signature to be wrapped
406     /// in a `DigestInfo` structure. This is almost always what you want with
407     /// RSA signatures.
408     #[corresponds(EVP_PKEY_CTX_set_signature_md)]
409     #[inline]
set_signature_mdnull410     pub fn set_signature_md(&self, md: &MdRef) -> Result<(), ErrorStack> {
411         unsafe {
412             cvt(ffi::EVP_PKEY_CTX_set_signature_md(
413                 self.as_ptr(),
414                 md.as_ptr(),
415             ))?;
416         }
417         Ok(())
418     }
419 
420     /// Returns the RSA padding mode in use.
421     ///
422     /// This is only useful for RSA keys.
423     #[corresponds(EVP_PKEY_CTX_get_rsa_padding)]
424     #[inline]
rsa_paddingnull425     pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
426         let mut pad = 0;
427         unsafe {
428             cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad))?;
429         }
430 
431         Ok(Padding::from_raw(pad))
432     }
433 
434     /// Sets the RSA padding mode.
435     ///
436     /// This is only useful for RSA keys.
437     #[corresponds(EVP_PKEY_CTX_set_rsa_padding)]
438     #[inline]
set_rsa_paddingnull439     pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
440         unsafe {
441             cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
442                 self.as_ptr(),
443                 padding.as_raw(),
444             ))?;
445         }
446 
447         Ok(())
448     }
449 
450     /// Sets the RSA PSS salt length.
451     ///
452     /// This is only useful for RSA keys.
453     #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)]
454     #[inline]
set_rsa_pss_saltlennull455     pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
456         unsafe {
457             cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
458                 self.as_ptr(),
459                 len.as_raw(),
460             ))
461             .map(|_| ())
462         }
463     }
464 
465     /// Sets the RSA MGF1 algorithm.
466     ///
467     /// This is only useful for RSA keys.
468     #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)]
469     #[inline]
set_rsa_mgf1_mdnull470     pub fn set_rsa_mgf1_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> {
471         unsafe {
472             cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
473                 self.as_ptr(),
474                 md.as_ptr(),
475             ))?;
476         }
477 
478         Ok(())
479     }
480 
481     /// Sets the RSA OAEP algorithm.
482     ///
483     /// This is only useful for RSA keys.
484     #[corresponds(EVP_PKEY_CTX_set_rsa_oaep_md)]
485     #[cfg(any(ossl102, libressl310, boringssl))]
486     #[inline]
set_rsa_oaep_mdnull487     pub fn set_rsa_oaep_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> {
488         unsafe {
489             cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
490                 self.as_ptr(),
491                 md.as_ptr() as *mut _,
492             ))?;
493         }
494 
495         Ok(())
496     }
497 
498     /// Sets the RSA OAEP label.
499     ///
500     /// This is only useful for RSA keys.
501     #[corresponds(EVP_PKEY_CTX_set0_rsa_oaep_label)]
502     #[cfg(any(ossl102, libressl310, boringssl))]
set_rsa_oaep_labelnull503     pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
504         use crate::LenType;
505         let len = LenType::try_from(label.len()).unwrap();
506 
507         unsafe {
508             let p = ffi::OPENSSL_malloc(label.len() as _);
509             ptr::copy_nonoverlapping(label.as_ptr(), p as *mut _, label.len());
510 
511             let r = cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
512                 self.as_ptr(),
513                 p as *mut _,
514                 len,
515             ));
516             if r.is_err() {
517                 ffi::OPENSSL_free(p);
518             }
519             r?;
520         }
521 
522         Ok(())
523     }
524 
525     /// Sets the cipher used during key generation.
526     #[cfg(not(boringssl))]
527     #[corresponds(EVP_PKEY_CTX_ctrl)]
528     #[inline]
set_keygen_ciphernull529     pub fn set_keygen_cipher(&mut self, cipher: &CipherRef) -> Result<(), ErrorStack> {
530         unsafe {
531             cvt(ffi::EVP_PKEY_CTX_ctrl(
532                 self.as_ptr(),
533                 -1,
534                 ffi::EVP_PKEY_OP_KEYGEN,
535                 ffi::EVP_PKEY_CTRL_CIPHER,
536                 0,
537                 cipher.as_ptr() as *mut _,
538             ))?;
539         }
540 
541         Ok(())
542     }
543 
544     /// Sets the key MAC key used during key generation.
545     #[cfg(not(boringssl))]
546     #[corresponds(EVP_PKEY_CTX_ctrl)]
547     #[inline]
set_keygen_mac_keynull548     pub fn set_keygen_mac_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
549         let len = c_int::try_from(key.len()).unwrap();
550 
551         unsafe {
552             cvt(ffi::EVP_PKEY_CTX_ctrl(
553                 self.as_ptr(),
554                 -1,
555                 ffi::EVP_PKEY_OP_KEYGEN,
556                 ffi::EVP_PKEY_CTRL_SET_MAC_KEY,
557                 len,
558                 key.as_ptr() as *mut _,
559             ))?;
560         }
561 
562         Ok(())
563     }
564 
565     /// Sets the digest used for HKDF derivation.
566     ///
567     /// Requires OpenSSL 1.1.0 or newer.
568     #[corresponds(EVP_PKEY_CTX_set_hkdf_md)]
569     #[cfg(any(ossl110, boringssl))]
570     #[inline]
set_hkdf_mdnull571     pub fn set_hkdf_md(&mut self, digest: &MdRef) -> Result<(), ErrorStack> {
572         unsafe {
573             cvt(ffi::EVP_PKEY_CTX_set_hkdf_md(
574                 self.as_ptr(),
575                 digest.as_ptr(),
576             ))?;
577         }
578 
579         Ok(())
580     }
581 
582     /// Sets the HKDF mode of operation.
583     ///
584     /// Defaults to [`HkdfMode::EXTRACT_THEN_EXPAND`].
585     ///
586     /// WARNING: Although this API calls it a "mode", HKDF-Extract and HKDF-Expand are distinct
587     /// operations with distinct inputs and distinct kinds of keys. Callers should not pass input
588     /// secrets for one operation into the other.
589     ///
590     /// Requires OpenSSL 1.1.1 or newer.
591     #[corresponds(EVP_PKEY_CTX_set_hkdf_mode)]
592     #[cfg(ossl111)]
593     #[inline]
set_hkdf_modenull594     pub fn set_hkdf_mode(&mut self, mode: HkdfMode) -> Result<(), ErrorStack> {
595         unsafe {
596             cvt(ffi::EVP_PKEY_CTX_set_hkdf_mode(self.as_ptr(), mode.0))?;
597         }
598 
599         Ok(())
600     }
601 
602     /// Sets the input material for HKDF generation as the "key".
603     ///
604     /// Which input is the key depends on the "mode" (see [`set_hkdf_mode`][Self::set_hkdf_mode]).
605     /// If [`HkdfMode::EXTRACT_THEN_EXPAND`] or [`HkdfMode::EXTRACT_ONLY`], this function specifies
606     /// the input keying material (IKM) for HKDF-Extract. If [`HkdfMode::EXPAND_ONLY`], it instead
607     /// specifies the pseudorandom key (PRK) for HKDF-Expand.
608     ///
609     /// Requires OpenSSL 1.1.0 or newer.
610     #[corresponds(EVP_PKEY_CTX_set1_hkdf_key)]
611     #[cfg(any(ossl110, boringssl))]
612     #[inline]
set_hkdf_keynull613     pub fn set_hkdf_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
614         #[cfg(not(boringssl))]
615         let len = c_int::try_from(key.len()).unwrap();
616         #[cfg(boringssl)]
617         let len = key.len();
618 
619         unsafe {
620             cvt(ffi::EVP_PKEY_CTX_set1_hkdf_key(
621                 self.as_ptr(),
622                 key.as_ptr(),
623                 len,
624             ))?;
625         }
626 
627         Ok(())
628     }
629 
630     /// Sets the salt value for HKDF generation.
631     ///
632     /// If performing HKDF-Expand only, this parameter is ignored.
633     ///
634     /// Requires OpenSSL 1.1.0 or newer.
635     #[corresponds(EVP_PKEY_CTX_set1_hkdf_salt)]
636     #[cfg(any(ossl110, boringssl))]
637     #[inline]
set_hkdf_saltnull638     pub fn set_hkdf_salt(&mut self, salt: &[u8]) -> Result<(), ErrorStack> {
639         #[cfg(not(boringssl))]
640         let len = c_int::try_from(salt.len()).unwrap();
641         #[cfg(boringssl)]
642         let len = salt.len();
643 
644         unsafe {
645             cvt(ffi::EVP_PKEY_CTX_set1_hkdf_salt(
646                 self.as_ptr(),
647                 salt.as_ptr(),
648                 len,
649             ))?;
650         }
651 
652         Ok(())
653     }
654 
655     /// Appends info bytes for HKDF generation.
656     ///
657     /// If performing HKDF-Extract only, this parameter is ignored.
658     ///
659     /// Requires OpenSSL 1.1.0 or newer.
660     #[corresponds(EVP_PKEY_CTX_add1_hkdf_info)]
661     #[cfg(any(ossl110, boringssl))]
662     #[inline]
add_hkdf_infonull663     pub fn add_hkdf_info(&mut self, info: &[u8]) -> Result<(), ErrorStack> {
664         #[cfg(not(boringssl))]
665         let len = c_int::try_from(info.len()).unwrap();
666         #[cfg(boringssl)]
667         let len = info.len();
668 
669         unsafe {
670             cvt(ffi::EVP_PKEY_CTX_add1_hkdf_info(
671                 self.as_ptr(),
672                 info.as_ptr(),
673                 len,
674             ))?;
675         }
676 
677         Ok(())
678     }
679 
680     /// Derives a shared secret between two keys.
681     ///
682     /// If `buf` is set to `None`, an upper bound on the number of bytes required for the buffer will be returned.
683     #[corresponds(EVP_PKEY_derive)]
derivenull684     pub fn derive(&mut self, buf: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
685         let mut len = buf.as_ref().map_or(0, |b| b.len());
686         unsafe {
687             cvt(ffi::EVP_PKEY_derive(
688                 self.as_ptr(),
689                 buf.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
690                 &mut len,
691             ))?;
692         }
693 
694         Ok(len)
695     }
696 
697     /// Like [`Self::derive`] but appends the secret to a [`Vec`].
derive_to_vecnull698     pub fn derive_to_vec(&mut self, buf: &mut Vec<u8>) -> Result<usize, ErrorStack> {
699         let base = buf.len();
700         let len = self.derive(None)?;
701         buf.resize(base + len, 0);
702         let len = self.derive(Some(&mut buf[base..]))?;
703         buf.truncate(base + len);
704         Ok(len)
705     }
706 
707     /// Generates a new public/private keypair.
708     #[corresponds(EVP_PKEY_keygen)]
709     #[inline]
keygennull710     pub fn keygen(&mut self) -> Result<PKey<Private>, ErrorStack> {
711         unsafe {
712             let mut key = ptr::null_mut();
713             cvt(ffi::EVP_PKEY_keygen(self.as_ptr(), &mut key))?;
714             Ok(PKey::from_ptr(key))
715         }
716     }
717 }
718 
719 #[cfg(test)]
720 mod test {
721     use super::*;
722     #[cfg(not(boringssl))]
723     use crate::cipher::Cipher;
724     use crate::ec::{EcGroup, EcKey};
725     use crate::hash::{hash, MessageDigest};
726     use crate::md::Md;
727     use crate::nid::Nid;
728     use crate::pkey::PKey;
729     use crate::rsa::Rsa;
730     use crate::sign::Verifier;
731 
732     #[test]
rsanull733     fn rsa() {
734         let key = include_bytes!("../test/rsa.pem");
735         let rsa = Rsa::private_key_from_pem(key).unwrap();
736         let pkey = PKey::from_rsa(rsa).unwrap();
737 
738         let mut ctx = PkeyCtx::new(&pkey).unwrap();
739         ctx.encrypt_init().unwrap();
740         ctx.set_rsa_padding(Padding::PKCS1).unwrap();
741 
742         let pt = "hello world".as_bytes();
743         let mut ct = vec![];
744         ctx.encrypt_to_vec(pt, &mut ct).unwrap();
745 
746         ctx.decrypt_init().unwrap();
747         ctx.set_rsa_padding(Padding::PKCS1).unwrap();
748 
749         let mut out = vec![];
750         ctx.decrypt_to_vec(&ct, &mut out).unwrap();
751 
752         assert_eq!(pt, out);
753     }
754 
755     #[test]
756     #[cfg(any(ossl102, libressl310, boringssl))]
rsa_oaepnull757     fn rsa_oaep() {
758         let key = include_bytes!("../test/rsa.pem");
759         let rsa = Rsa::private_key_from_pem(key).unwrap();
760         let pkey = PKey::from_rsa(rsa).unwrap();
761 
762         let mut ctx = PkeyCtx::new(&pkey).unwrap();
763         ctx.encrypt_init().unwrap();
764         ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
765         ctx.set_rsa_oaep_md(Md::sha256()).unwrap();
766         ctx.set_rsa_mgf1_md(Md::sha256()).unwrap();
767 
768         let pt = "hello world".as_bytes();
769         let mut ct = vec![];
770         ctx.encrypt_to_vec(pt, &mut ct).unwrap();
771 
772         ctx.decrypt_init().unwrap();
773         ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
774         ctx.set_rsa_oaep_md(Md::sha256()).unwrap();
775         ctx.set_rsa_mgf1_md(Md::sha256()).unwrap();
776 
777         let mut out = vec![];
778         ctx.decrypt_to_vec(&ct, &mut out).unwrap();
779 
780         assert_eq!(pt, out);
781     }
782 
783     #[test]
rsa_signnull784     fn rsa_sign() {
785         let key = include_bytes!("../test/rsa.pem");
786         let rsa = Rsa::private_key_from_pem(key).unwrap();
787         let pkey = PKey::from_rsa(rsa).unwrap();
788 
789         let mut ctx = PkeyCtx::new(&pkey).unwrap();
790         ctx.sign_init().unwrap();
791         ctx.set_rsa_padding(Padding::PKCS1).unwrap();
792         ctx.set_signature_md(Md::sha384()).unwrap();
793 
794         let msg = b"hello world";
795         let digest = hash(MessageDigest::sha384(), msg).unwrap();
796         let mut signature = vec![];
797         ctx.sign_to_vec(&digest, &mut signature).unwrap();
798 
799         let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap();
800         verifier.update(msg).unwrap();
801         assert!(matches!(verifier.verify(&signature), Ok(true)));
802     }
803 
804     #[test]
rsa_sign_pssnull805     fn rsa_sign_pss() {
806         let key = include_bytes!("../test/rsa.pem");
807         let rsa = Rsa::private_key_from_pem(key).unwrap();
808         let pkey = PKey::from_rsa(rsa).unwrap();
809 
810         let mut ctx = PkeyCtx::new(&pkey).unwrap();
811         ctx.sign_init().unwrap();
812         ctx.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
813         ctx.set_signature_md(Md::sha384()).unwrap();
814         ctx.set_rsa_pss_saltlen(RsaPssSaltlen::custom(14)).unwrap();
815 
816         let msg = b"hello world";
817         let digest = hash(MessageDigest::sha384(), msg).unwrap();
818         let mut signature = vec![];
819         ctx.sign_to_vec(&digest, &mut signature).unwrap();
820 
821         let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap();
822         verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
823         verifier
824             .set_rsa_pss_saltlen(RsaPssSaltlen::custom(14))
825             .unwrap();
826         verifier.update(msg).unwrap();
827         assert!(matches!(verifier.verify(&signature), Ok(true)));
828     }
829 
830     #[test]
derivenull831     fn derive() {
832         let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
833         let key1 = EcKey::generate(&group).unwrap();
834         let key1 = PKey::from_ec_key(key1).unwrap();
835         let key2 = EcKey::generate(&group).unwrap();
836         let key2 = PKey::from_ec_key(key2).unwrap();
837 
838         let mut ctx = PkeyCtx::new(&key1).unwrap();
839         ctx.derive_init().unwrap();
840         ctx.derive_set_peer(&key2).unwrap();
841 
842         let mut buf = vec![];
843         ctx.derive_to_vec(&mut buf).unwrap();
844     }
845 
846     #[test]
847     #[cfg(not(boringssl))]
cmac_keygennull848     fn cmac_keygen() {
849         let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap();
850         ctx.keygen_init().unwrap();
851         ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap();
852         ctx.set_keygen_mac_key(&hex::decode("9294727a3638bb1c13f48ef8158bfc9d").unwrap())
853             .unwrap();
854         ctx.keygen().unwrap();
855     }
856 
857     #[test]
858     #[cfg(any(ossl110, boringssl))]
hkdfnull859     fn hkdf() {
860         let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
861         ctx.derive_init().unwrap();
862         ctx.set_hkdf_md(Md::sha256()).unwrap();
863         ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap())
864             .unwrap();
865         ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap())
866             .unwrap();
867         ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap())
868             .unwrap();
869         let mut out = [0; 42];
870         ctx.derive(Some(&mut out)).unwrap();
871 
872         assert_eq!(
873             &out[..],
874             hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865")
875                 .unwrap()
876         );
877     }
878 
879     #[test]
880     #[cfg(ossl111)]
hkdf_expandnull881     fn hkdf_expand() {
882         let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
883         ctx.derive_init().unwrap();
884         ctx.set_hkdf_mode(HkdfMode::EXPAND_ONLY).unwrap();
885         ctx.set_hkdf_md(Md::sha256()).unwrap();
886         ctx.set_hkdf_key(
887             &hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5")
888                 .unwrap(),
889         )
890         .unwrap();
891         ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap())
892             .unwrap();
893         let mut out = [0; 42];
894         ctx.derive(Some(&mut out)).unwrap();
895 
896         assert_eq!(
897             &out[..],
898             hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865")
899                 .unwrap()
900         );
901     }
902 
903     #[test]
904     #[cfg(ossl111)]
hkdf_extractnull905     fn hkdf_extract() {
906         let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
907         ctx.derive_init().unwrap();
908         ctx.set_hkdf_mode(HkdfMode::EXTRACT_ONLY).unwrap();
909         ctx.set_hkdf_md(Md::sha256()).unwrap();
910         ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap())
911             .unwrap();
912         ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap())
913             .unwrap();
914         let mut out = vec![];
915         ctx.derive_to_vec(&mut out).unwrap();
916 
917         assert_eq!(
918             &out[..],
919             hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5")
920                 .unwrap()
921         );
922     }
923 
924     #[test]
verify_failnull925     fn verify_fail() {
926         let key1 = Rsa::generate(4096).unwrap();
927         let key1 = PKey::from_rsa(key1).unwrap();
928 
929         let data = b"Some Crypto Text";
930 
931         let mut ctx = PkeyCtx::new(&key1).unwrap();
932         ctx.sign_init().unwrap();
933         let mut signature = vec![];
934         ctx.sign_to_vec(data, &mut signature).unwrap();
935 
936         let bad_data = b"Some Crypto text";
937 
938         ctx.verify_init().unwrap();
939         let valid = ctx.verify(bad_data, &signature);
940         assert!(matches!(valid, Ok(false) | Err(_)));
941         assert!(ErrorStack::get().errors().is_empty());
942     }
943 
944     #[test]
verify_fail_ecnull945     fn verify_fail_ec() {
946         let key1 =
947             EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap();
948         let key1 = PKey::from_ec_key(key1).unwrap();
949 
950         let data = b"Some Crypto Text";
951         let mut ctx = PkeyCtx::new(&key1).unwrap();
952         ctx.verify_init().unwrap();
953         assert!(matches!(ctx.verify(data, &[0; 64]), Ok(false) | Err(_)));
954         assert!(ErrorStack::get().errors().is_empty());
955     }
956 
957     #[test]
test_verify_recovernull958     fn test_verify_recover() {
959         let key = Rsa::generate(2048).unwrap();
960         let key = PKey::from_rsa(key).unwrap();
961 
962         let digest = [
963             0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
964             24, 25, 26, 27, 28, 29, 30, 31,
965         ];
966 
967         let mut ctx = PkeyCtx::new(&key).unwrap();
968         ctx.sign_init().unwrap();
969         ctx.set_rsa_padding(Padding::PKCS1).unwrap();
970         ctx.set_signature_md(Md::sha256()).unwrap();
971         let mut signature = vec![];
972         ctx.sign_to_vec(&digest, &mut signature).unwrap();
973 
974         // Attempt recovery of just the digest.
975         let mut ctx = PkeyCtx::new(&key).unwrap();
976         ctx.verify_recover_init().unwrap();
977         ctx.set_rsa_padding(Padding::PKCS1).unwrap();
978         ctx.set_signature_md(Md::sha256()).unwrap();
979         let length = ctx.verify_recover(&signature, None).unwrap();
980         let mut result_buf = vec![0; length];
981         let length = ctx
982             .verify_recover(&signature, Some(&mut result_buf))
983             .unwrap();
984         assert_eq!(length, digest.len());
985         // result_buf contains the digest
986         assert_eq!(result_buf[..length], digest);
987 
988         // Attempt recovery of teh entire DigestInfo
989         let mut ctx = PkeyCtx::new(&key).unwrap();
990         ctx.verify_recover_init().unwrap();
991         ctx.set_rsa_padding(Padding::PKCS1).unwrap();
992         let length = ctx.verify_recover(&signature, None).unwrap();
993         let mut result_buf = vec![0; length];
994         let length = ctx
995             .verify_recover(&signature, Some(&mut result_buf))
996             .unwrap();
997         // 32-bytes of SHA256 digest + the ASN.1 DigestInfo structure == 51 bytes
998         assert_eq!(length, 51);
999         // The digest is the end of the DigestInfo structure.
1000         assert_eq!(result_buf[length - digest.len()..length], digest);
1001     }
1002 }
1003