• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::{cvt, cvt_n, cvt_p};
74 use foreign_types::{ForeignType, ForeignTypeRef};
75 #[cfg(not(boringssl))]
76 use libc::c_int;
77 use openssl_macros::corresponds;
78 use std::convert::TryFrom;
79 use std::ptr;
80 
81 /// HKDF modes of operation.
82 #[cfg(ossl111)]
83 pub struct HkdfMode(c_int);
84 
85 #[cfg(ossl111)]
86 impl HkdfMode {
87     pub const EXTRACT_THEN_EXPAND: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND);
88     pub const EXTRACT_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY);
89     pub const EXPAND_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXPAND_ONLY);
90 }
91 
92 generic_foreign_type_and_impl_send_sync! {
93     type CType = ffi::EVP_PKEY_CTX;
94     fn drop = ffi::EVP_PKEY_CTX_free;
95 
96     /// A context object which can perform asymmetric cryptography operations.
97     pub struct PkeyCtx<T>;
98     /// A reference to a [`PkeyCtx`].
99     pub struct PkeyCtxRef<T>;
100 }
101 
102 impl<T> PkeyCtx<T> {
103     /// Creates a new pkey context using the provided key.
104     #[corresponds(EVP_PKEY_CTX_new)]
105     #[inline]
new(pkey: &PKeyRef<T>) -> Result<Self, ErrorStack>106     pub fn new(pkey: &PKeyRef<T>) -> Result<Self, ErrorStack> {
107         unsafe {
108             let ptr = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?;
109             Ok(PkeyCtx::from_ptr(ptr))
110         }
111     }
112 }
113 
114 impl PkeyCtx<()> {
115     /// Creates a new pkey context for the specified algorithm ID.
116     #[corresponds(EVP_PKEY_new_id)]
117     #[inline]
new_id(id: Id) -> Result<Self, ErrorStack>118     pub fn new_id(id: Id) -> Result<Self, ErrorStack> {
119         unsafe {
120             let ptr = cvt_p(ffi::EVP_PKEY_CTX_new_id(id.as_raw(), ptr::null_mut()))?;
121             Ok(PkeyCtx::from_ptr(ptr))
122         }
123     }
124 }
125 
126 impl<T> PkeyCtxRef<T>
127 where
128     T: HasPublic,
129 {
130     /// Prepares the context for encryption using the public key.
131     #[corresponds(EVP_PKEY_encrypt_init)]
132     #[inline]
encrypt_init(&mut self) -> Result<(), ErrorStack>133     pub fn encrypt_init(&mut self) -> Result<(), ErrorStack> {
134         unsafe {
135             cvt(ffi::EVP_PKEY_encrypt_init(self.as_ptr()))?;
136         }
137 
138         Ok(())
139     }
140 
141     /// Prepares the context for signature verification using the public key.
142     #[corresponds(EVP_PKEY_verify_init)]
143     #[inline]
verify_init(&mut self) -> Result<(), ErrorStack>144     pub fn verify_init(&mut self) -> Result<(), ErrorStack> {
145         unsafe {
146             cvt(ffi::EVP_PKEY_verify_init(self.as_ptr()))?;
147         }
148 
149         Ok(())
150     }
151 
152     /// Encrypts data using the public key.
153     ///
154     /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be
155     /// returned.
156     #[corresponds(EVP_PKEY_encrypt)]
157     #[inline]
encrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack>158     pub fn encrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
159         let mut written = to.as_ref().map_or(0, |b| b.len());
160         unsafe {
161             cvt(ffi::EVP_PKEY_encrypt(
162                 self.as_ptr(),
163                 to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
164                 &mut written,
165                 from.as_ptr(),
166                 from.len(),
167             ))?;
168         }
169 
170         Ok(written)
171     }
172 
173     /// Like [`Self::encrypt`] but appends ciphertext to a [`Vec`].
encrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack>174     pub fn encrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack> {
175         let base = out.len();
176         let len = self.encrypt(from, None)?;
177         out.resize(base + len, 0);
178         let len = self.encrypt(from, Some(&mut out[base..]))?;
179         out.truncate(base + len);
180         Ok(len)
181     }
182 
183     /// Verifies the signature of data using the public key.
184     ///
185     /// Returns `Ok(true)` if the signature is valid, `Ok(false)` if the signature is invalid, and `Err` if an error
186     /// occurred.
187     ///
188     /// # Note
189     ///
190     /// This verifies the signature of the *raw* data. It is more common to compute and verify the signature of the
191     /// cryptographic hash of an arbitrary amount of data. The [`MdCtx`](crate::md_ctx::MdCtx) type can be used to do
192     /// that.
193     #[corresponds(EVP_PKEY_verify)]
194     #[inline]
verify(&mut self, data: &[u8], sig: &[u8]) -> Result<bool, ErrorStack>195     pub fn verify(&mut self, data: &[u8], sig: &[u8]) -> Result<bool, ErrorStack> {
196         unsafe {
197             let r = cvt_n(ffi::EVP_PKEY_verify(
198                 self.as_ptr(),
199                 sig.as_ptr(),
200                 sig.len(),
201                 data.as_ptr(),
202                 data.len(),
203             ))?;
204             Ok(r == 1)
205         }
206     }
207 }
208 
209 impl<T> PkeyCtxRef<T>
210 where
211     T: HasPrivate,
212 {
213     /// Prepares the context for decryption using the private key.
214     #[corresponds(EVP_PKEY_decrypt_init)]
215     #[inline]
decrypt_init(&mut self) -> Result<(), ErrorStack>216     pub fn decrypt_init(&mut self) -> Result<(), ErrorStack> {
217         unsafe {
218             cvt(ffi::EVP_PKEY_decrypt_init(self.as_ptr()))?;
219         }
220 
221         Ok(())
222     }
223 
224     /// Prepares the context for signing using the private key.
225     #[corresponds(EVP_PKEY_sign_init)]
226     #[inline]
sign_init(&mut self) -> Result<(), ErrorStack>227     pub fn sign_init(&mut self) -> Result<(), ErrorStack> {
228         unsafe {
229             cvt(ffi::EVP_PKEY_sign_init(self.as_ptr()))?;
230         }
231 
232         Ok(())
233     }
234 
235     /// Sets the peer key used for secret derivation.
236     #[corresponds(EVP_PKEY_derive_set_peer)]
derive_set_peer<U>(&mut self, key: &PKeyRef<U>) -> Result<(), ErrorStack> where U: HasPublic,237     pub fn derive_set_peer<U>(&mut self, key: &PKeyRef<U>) -> Result<(), ErrorStack>
238     where
239         U: HasPublic,
240     {
241         unsafe {
242             cvt(ffi::EVP_PKEY_derive_set_peer(self.as_ptr(), key.as_ptr()))?;
243         }
244 
245         Ok(())
246     }
247 
248     /// Decrypts data using the private key.
249     ///
250     /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be
251     /// returned.
252     #[corresponds(EVP_PKEY_decrypt)]
253     #[inline]
decrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack>254     pub fn decrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
255         let mut written = to.as_ref().map_or(0, |b| b.len());
256         unsafe {
257             cvt(ffi::EVP_PKEY_decrypt(
258                 self.as_ptr(),
259                 to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
260                 &mut written,
261                 from.as_ptr(),
262                 from.len(),
263             ))?;
264         }
265 
266         Ok(written)
267     }
268 
269     /// Like [`Self::decrypt`] but appends plaintext to a [`Vec`].
decrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack>270     pub fn decrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack> {
271         let base = out.len();
272         let len = self.decrypt(from, None)?;
273         out.resize(base + len, 0);
274         let len = self.decrypt(from, Some(&mut out[base..]))?;
275         out.truncate(base + len);
276         Ok(len)
277     }
278 
279     /// Signs the contents of `data`.
280     ///
281     /// If `sig` is set to `None`, an upper bound on the number of bytes required for the output buffer will be
282     /// returned.
283     ///
284     /// # Note
285     ///
286     /// This computes the signature of the *raw* bytes of `data`. It is more common to sign the cryptographic hash of
287     /// an arbitrary amount of data. The [`MdCtx`](crate::md_ctx::MdCtx) type can be used to do that.
288     #[corresponds(EVP_PKEY_sign)]
289     #[inline]
sign(&mut self, data: &[u8], sig: Option<&mut [u8]>) -> Result<usize, ErrorStack>290     pub fn sign(&mut self, data: &[u8], sig: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
291         let mut written = sig.as_ref().map_or(0, |b| b.len());
292         unsafe {
293             cvt(ffi::EVP_PKEY_sign(
294                 self.as_ptr(),
295                 sig.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
296                 &mut written,
297                 data.as_ptr(),
298                 data.len(),
299             ))?;
300         }
301 
302         Ok(written)
303     }
304 
305     /// Like [`Self::sign`] but appends the signature to a [`Vec`].
sign_to_vec(&mut self, data: &[u8], sig: &mut Vec<u8>) -> Result<usize, ErrorStack>306     pub fn sign_to_vec(&mut self, data: &[u8], sig: &mut Vec<u8>) -> Result<usize, ErrorStack> {
307         let base = sig.len();
308         let len = self.sign(data, None)?;
309         sig.resize(base + len, 0);
310         let len = self.sign(data, Some(&mut sig[base..]))?;
311         sig.truncate(base + len);
312         Ok(len)
313     }
314 }
315 
316 impl<T> PkeyCtxRef<T> {
317     /// Prepares the context for shared secret derivation.
318     #[corresponds(EVP_PKEY_derive_init)]
319     #[inline]
derive_init(&mut self) -> Result<(), ErrorStack>320     pub fn derive_init(&mut self) -> Result<(), ErrorStack> {
321         unsafe {
322             cvt(ffi::EVP_PKEY_derive_init(self.as_ptr()))?;
323         }
324 
325         Ok(())
326     }
327 
328     /// Prepares the context for key generation.
329     #[corresponds(EVP_PKEY_keygen_init)]
330     #[inline]
keygen_init(&mut self) -> Result<(), ErrorStack>331     pub fn keygen_init(&mut self) -> Result<(), ErrorStack> {
332         unsafe {
333             cvt(ffi::EVP_PKEY_keygen_init(self.as_ptr()))?;
334         }
335 
336         Ok(())
337     }
338 
339     /// Returns the RSA padding mode in use.
340     ///
341     /// This is only useful for RSA keys.
342     #[corresponds(EVP_PKEY_CTX_get_rsa_padding)]
343     #[inline]
rsa_padding(&self) -> Result<Padding, ErrorStack>344     pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
345         let mut pad = 0;
346         unsafe {
347             cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad))?;
348         }
349 
350         Ok(Padding::from_raw(pad))
351     }
352 
353     /// Sets the RSA padding mode.
354     ///
355     /// This is only useful for RSA keys.
356     #[corresponds(EVP_PKEY_CTX_set_rsa_padding)]
357     #[inline]
set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack>358     pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
359         unsafe {
360             cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
361                 self.as_ptr(),
362                 padding.as_raw(),
363             ))?;
364         }
365 
366         Ok(())
367     }
368 
369     /// Sets the RSA MGF1 algorithm.
370     ///
371     /// This is only useful for RSA keys.
372     #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)]
373     #[inline]
set_rsa_mgf1_md(&mut self, md: &MdRef) -> Result<(), ErrorStack>374     pub fn set_rsa_mgf1_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> {
375         unsafe {
376             cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
377                 self.as_ptr(),
378                 md.as_ptr(),
379             ))?;
380         }
381 
382         Ok(())
383     }
384 
385     /// Sets the RSA OAEP algorithm.
386     ///
387     /// This is only useful for RSA keys.
388     #[corresponds(EVP_PKEY_CTX_set_rsa_oaep_md)]
389     #[cfg(any(ossl102, libressl310))]
390     #[inline]
set_rsa_oaep_md(&mut self, md: &MdRef) -> Result<(), ErrorStack>391     pub fn set_rsa_oaep_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> {
392         unsafe {
393             cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
394                 self.as_ptr(),
395                 md.as_ptr() as *mut _,
396             ))?;
397         }
398 
399         Ok(())
400     }
401 
402     /// Sets the RSA OAEP label.
403     ///
404     /// This is only useful for RSA keys.
405     #[corresponds(EVP_PKEY_CTX_set0_rsa_oaep_label)]
406     #[cfg(any(ossl102, libressl310, boringssl))]
set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack>407     pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
408         use crate::LenType;
409         let len = LenType::try_from(label.len()).unwrap();
410 
411         unsafe {
412             let p = ffi::OPENSSL_malloc(label.len() as _);
413             ptr::copy_nonoverlapping(label.as_ptr(), p as *mut _, label.len());
414 
415             let r = cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
416                 self.as_ptr(),
417                 p as *mut _,
418                 len,
419             ));
420             if r.is_err() {
421                 ffi::OPENSSL_free(p);
422             }
423             r?;
424         }
425 
426         Ok(())
427     }
428 
429     /// Sets the cipher used during key generation.
430     #[cfg(not(boringssl))]
431     #[corresponds(EVP_PKEY_CTX_ctrl)]
432     #[inline]
set_keygen_cipher(&mut self, cipher: &CipherRef) -> Result<(), ErrorStack>433     pub fn set_keygen_cipher(&mut self, cipher: &CipherRef) -> Result<(), ErrorStack> {
434         unsafe {
435             cvt(ffi::EVP_PKEY_CTX_ctrl(
436                 self.as_ptr(),
437                 -1,
438                 ffi::EVP_PKEY_OP_KEYGEN,
439                 ffi::EVP_PKEY_CTRL_CIPHER,
440                 0,
441                 cipher.as_ptr() as *mut _,
442             ))?;
443         }
444 
445         Ok(())
446     }
447 
448     /// Sets the key MAC key used during key generation.
449     #[cfg(not(boringssl))]
450     #[corresponds(EVP_PKEY_CTX_ctrl)]
451     #[inline]
set_keygen_mac_key(&mut self, key: &[u8]) -> Result<(), ErrorStack>452     pub fn set_keygen_mac_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
453         let len = c_int::try_from(key.len()).unwrap();
454 
455         unsafe {
456             cvt(ffi::EVP_PKEY_CTX_ctrl(
457                 self.as_ptr(),
458                 -1,
459                 ffi::EVP_PKEY_OP_KEYGEN,
460                 ffi::EVP_PKEY_CTRL_SET_MAC_KEY,
461                 len,
462                 key.as_ptr() as *mut _,
463             ))?;
464         }
465 
466         Ok(())
467     }
468 
469     /// Sets the digest used for HKDF derivation.
470     ///
471     /// Requires OpenSSL 1.1.0 or newer.
472     #[corresponds(EVP_PKEY_CTX_set_hkdf_md)]
473     #[cfg(ossl110)]
474     #[inline]
set_hkdf_md(&mut self, digest: &MdRef) -> Result<(), ErrorStack>475     pub fn set_hkdf_md(&mut self, digest: &MdRef) -> Result<(), ErrorStack> {
476         unsafe {
477             cvt(ffi::EVP_PKEY_CTX_set_hkdf_md(
478                 self.as_ptr(),
479                 digest.as_ptr(),
480             ))?;
481         }
482 
483         Ok(())
484     }
485 
486     /// Sets the HKDF mode of operation.
487     ///
488     /// Defaults to [`HkdfMode::EXTRACT_THEN_EXPAND`].
489     ///
490     /// Requires OpenSSL 1.1.1 or newer.
491     #[corresponds(EVP_PKEY_CTX_set_hkdf_mode)]
492     #[cfg(ossl111)]
493     #[inline]
set_hkdf_mode(&mut self, mode: HkdfMode) -> Result<(), ErrorStack>494     pub fn set_hkdf_mode(&mut self, mode: HkdfMode) -> Result<(), ErrorStack> {
495         unsafe {
496             cvt(ffi::EVP_PKEY_CTX_set_hkdf_mode(self.as_ptr(), mode.0))?;
497         }
498 
499         Ok(())
500     }
501 
502     /// Sets the input keying material for HKDF generation.
503     ///
504     /// Requires OpenSSL 1.1.0 or newer.
505     #[corresponds(EVP_PKEY_CTX_set1_hkdf_key)]
506     #[cfg(ossl110)]
507     #[inline]
set_hkdf_key(&mut self, key: &[u8]) -> Result<(), ErrorStack>508     pub fn set_hkdf_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
509         let len = c_int::try_from(key.len()).unwrap();
510 
511         unsafe {
512             cvt(ffi::EVP_PKEY_CTX_set1_hkdf_key(
513                 self.as_ptr(),
514                 key.as_ptr(),
515                 len,
516             ))?;
517         }
518 
519         Ok(())
520     }
521 
522     /// Sets the salt value for HKDF generation.
523     ///
524     /// Requires OpenSSL 1.1.0 or newer.
525     #[corresponds(EVP_PKEY_CTX_set1_hkdf_salt)]
526     #[cfg(ossl110)]
527     #[inline]
set_hkdf_salt(&mut self, salt: &[u8]) -> Result<(), ErrorStack>528     pub fn set_hkdf_salt(&mut self, salt: &[u8]) -> Result<(), ErrorStack> {
529         let len = c_int::try_from(salt.len()).unwrap();
530 
531         unsafe {
532             cvt(ffi::EVP_PKEY_CTX_set1_hkdf_salt(
533                 self.as_ptr(),
534                 salt.as_ptr(),
535                 len,
536             ))?;
537         }
538 
539         Ok(())
540     }
541 
542     /// Appends info bytes for HKDF generation.
543     ///
544     /// Requires OpenSSL 1.1.0 or newer.
545     #[corresponds(EVP_PKEY_CTX_add1_hkdf_info)]
546     #[cfg(ossl110)]
547     #[inline]
add_hkdf_info(&mut self, info: &[u8]) -> Result<(), ErrorStack>548     pub fn add_hkdf_info(&mut self, info: &[u8]) -> Result<(), ErrorStack> {
549         let len = c_int::try_from(info.len()).unwrap();
550 
551         unsafe {
552             cvt(ffi::EVP_PKEY_CTX_add1_hkdf_info(
553                 self.as_ptr(),
554                 info.as_ptr(),
555                 len,
556             ))?;
557         }
558 
559         Ok(())
560     }
561 
562     /// Derives a shared secret between two keys.
563     ///
564     /// If `buf` is set to `None`, an upper bound on the number of bytes required for the buffer will be returned.
565     #[corresponds(EVP_PKEY_derive)]
derive(&mut self, buf: Option<&mut [u8]>) -> Result<usize, ErrorStack>566     pub fn derive(&mut self, buf: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
567         let mut len = buf.as_ref().map_or(0, |b| b.len());
568         unsafe {
569             cvt(ffi::EVP_PKEY_derive(
570                 self.as_ptr(),
571                 buf.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
572                 &mut len,
573             ))?;
574         }
575 
576         Ok(len)
577     }
578 
579     /// Like [`Self::derive`] but appends the secret to a [`Vec`].
derive_to_vec(&mut self, buf: &mut Vec<u8>) -> Result<usize, ErrorStack>580     pub fn derive_to_vec(&mut self, buf: &mut Vec<u8>) -> Result<usize, ErrorStack> {
581         let base = buf.len();
582         let len = self.derive(None)?;
583         buf.resize(base + len, 0);
584         let len = self.derive(Some(&mut buf[base..]))?;
585         buf.truncate(base + len);
586         Ok(len)
587     }
588 
589     /// Generates a new public/private keypair.
590     #[corresponds(EVP_PKEY_keygen)]
591     #[inline]
keygen(&mut self) -> Result<PKey<Private>, ErrorStack>592     pub fn keygen(&mut self) -> Result<PKey<Private>, ErrorStack> {
593         unsafe {
594             let mut key = ptr::null_mut();
595             cvt(ffi::EVP_PKEY_keygen(self.as_ptr(), &mut key))?;
596             Ok(PKey::from_ptr(key))
597         }
598     }
599 }
600 
601 #[cfg(test)]
602 mod test {
603     use super::*;
604     #[cfg(not(boringssl))]
605     use crate::cipher::Cipher;
606     use crate::ec::{EcGroup, EcKey};
607     #[cfg(any(ossl102, libressl310))]
608     use crate::md::Md;
609     use crate::nid::Nid;
610     use crate::pkey::PKey;
611     use crate::rsa::Rsa;
612 
613     #[test]
rsa()614     fn rsa() {
615         let key = include_bytes!("../test/rsa.pem");
616         let rsa = Rsa::private_key_from_pem(key).unwrap();
617         let pkey = PKey::from_rsa(rsa).unwrap();
618 
619         let mut ctx = PkeyCtx::new(&pkey).unwrap();
620         ctx.encrypt_init().unwrap();
621         ctx.set_rsa_padding(Padding::PKCS1).unwrap();
622 
623         let pt = "hello world".as_bytes();
624         let mut ct = vec![];
625         ctx.encrypt_to_vec(pt, &mut ct).unwrap();
626 
627         ctx.decrypt_init().unwrap();
628         ctx.set_rsa_padding(Padding::PKCS1).unwrap();
629 
630         let mut out = vec![];
631         ctx.decrypt_to_vec(&ct, &mut out).unwrap();
632 
633         assert_eq!(pt, out);
634     }
635 
636     #[test]
637     #[cfg(any(ossl102, libressl310))]
rsa_oaep()638     fn rsa_oaep() {
639         let key = include_bytes!("../test/rsa.pem");
640         let rsa = Rsa::private_key_from_pem(key).unwrap();
641         let pkey = PKey::from_rsa(rsa).unwrap();
642 
643         let mut ctx = PkeyCtx::new(&pkey).unwrap();
644         ctx.encrypt_init().unwrap();
645         ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
646         ctx.set_rsa_oaep_md(Md::sha256()).unwrap();
647         ctx.set_rsa_mgf1_md(Md::sha256()).unwrap();
648 
649         let pt = "hello world".as_bytes();
650         let mut ct = vec![];
651         ctx.encrypt_to_vec(pt, &mut ct).unwrap();
652 
653         ctx.decrypt_init().unwrap();
654         ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
655         ctx.set_rsa_oaep_md(Md::sha256()).unwrap();
656         ctx.set_rsa_mgf1_md(Md::sha256()).unwrap();
657 
658         let mut out = vec![];
659         ctx.decrypt_to_vec(&ct, &mut out).unwrap();
660 
661         assert_eq!(pt, out);
662     }
663 
664     #[test]
derive()665     fn derive() {
666         let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
667         let key1 = EcKey::generate(&group).unwrap();
668         let key1 = PKey::from_ec_key(key1).unwrap();
669         let key2 = EcKey::generate(&group).unwrap();
670         let key2 = PKey::from_ec_key(key2).unwrap();
671 
672         let mut ctx = PkeyCtx::new(&key1).unwrap();
673         ctx.derive_init().unwrap();
674         ctx.derive_set_peer(&key2).unwrap();
675 
676         let mut buf = vec![];
677         ctx.derive_to_vec(&mut buf).unwrap();
678     }
679 
680     #[test]
681     #[cfg(not(boringssl))]
cmac_keygen()682     fn cmac_keygen() {
683         let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap();
684         ctx.keygen_init().unwrap();
685         ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap();
686         ctx.set_keygen_mac_key(&hex::decode("9294727a3638bb1c13f48ef8158bfc9d").unwrap())
687             .unwrap();
688         ctx.keygen().unwrap();
689     }
690 
691     #[test]
692     #[cfg(ossl110)]
hkdf()693     fn hkdf() {
694         let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
695         ctx.derive_init().unwrap();
696         ctx.set_hkdf_md(Md::sha256()).unwrap();
697         ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap())
698             .unwrap();
699         ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap())
700             .unwrap();
701         ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap())
702             .unwrap();
703         let mut out = [0; 42];
704         ctx.derive(Some(&mut out)).unwrap();
705 
706         assert_eq!(
707             &out[..],
708             hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865")
709                 .unwrap()
710         );
711     }
712 
713     #[test]
714     #[cfg(ossl111)]
hkdf_expand()715     fn hkdf_expand() {
716         let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
717         ctx.derive_init().unwrap();
718         ctx.set_hkdf_mode(HkdfMode::EXPAND_ONLY).unwrap();
719         ctx.set_hkdf_md(Md::sha256()).unwrap();
720         ctx.set_hkdf_key(
721             &hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5")
722                 .unwrap(),
723         )
724         .unwrap();
725         ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap())
726             .unwrap();
727         let mut out = [0; 42];
728         ctx.derive(Some(&mut out)).unwrap();
729 
730         assert_eq!(
731             &out[..],
732             hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865")
733                 .unwrap()
734         );
735     }
736 
737     #[test]
738     #[cfg(ossl111)]
hkdf_extract()739     fn hkdf_extract() {
740         let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
741         ctx.derive_init().unwrap();
742         ctx.set_hkdf_mode(HkdfMode::EXTRACT_ONLY).unwrap();
743         ctx.set_hkdf_md(Md::sha256()).unwrap();
744         ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap())
745             .unwrap();
746         ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap())
747             .unwrap();
748         let mut out = vec![];
749         ctx.derive_to_vec(&mut out).unwrap();
750 
751         assert_eq!(
752             &out[..],
753             hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5")
754                 .unwrap()
755         );
756     }
757 
758     #[test]
verify_fail()759     fn verify_fail() {
760         let key1 = Rsa::generate(4096).unwrap();
761         let key1 = PKey::from_rsa(key1).unwrap();
762 
763         let data = b"Some Crypto Text";
764 
765         let mut ctx = PkeyCtx::new(&key1).unwrap();
766         ctx.sign_init().unwrap();
767         let mut signature = vec![];
768         ctx.sign_to_vec(data, &mut signature).unwrap();
769 
770         let bad_data = b"Some Crypto text";
771 
772         ctx.verify_init().unwrap();
773         let valid = ctx.verify(bad_data, &signature).unwrap();
774         assert!(!valid);
775     }
776 }
777