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#"\
26Generate a CMAC key
27
28```
29use openssl::pkey_ctx::PkeyCtx;
30use openssl::pkey::Id;
31use openssl::cipher::Cipher;
32
33let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap();
34ctx.keygen_init().unwrap();
35ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap();
36ctx.set_keygen_mac_key(b"0123456789abcdef").unwrap();
37let 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))]
68use crate::cipher::CipherRef;
69use crate::error::ErrorStack;
70use crate::md::MdRef;
71use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Private};
72use crate::rsa::Padding;
73use crate::sign::RsaPssSaltlen;
74use crate::{cvt, cvt_p};
75use foreign_types::{ForeignType, ForeignTypeRef};
76#[cfg(not(boringssl))]
77use libc::c_int;
78use openssl_macros::corresponds;
79use std::convert::TryFrom;
80use std::ptr;
81
82/// HKDF modes of operation.
83#[cfg(ossl111)]
84pub struct HkdfMode(c_int);
85
86#[cfg(ossl111)]
87impl 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
108generic_foreign_type_and_impl_send_sync! {
109    type CType = ffi::EVP_PKEY_CTX;
110    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
118impl<T> PkeyCtx<T> {
119    /// Creates a new pkey context using the provided key.
120    #[corresponds(EVP_PKEY_CTX_new)]
121    #[inline]
122    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
130impl PkeyCtx<()> {
131    /// Creates a new pkey context for the specified algorithm ID.
132    #[corresponds(EVP_PKEY_new_id)]
133    #[inline]
134    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
142impl<T> PkeyCtxRef<T>
143where
144    T: HasPublic,
145{
146    /// Prepares the context for encryption using the public key.
147    #[corresponds(EVP_PKEY_encrypt_init)]
148    #[inline]
149    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]
160    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]
171    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]
185    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`].
201    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]
222    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]
254    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
274impl<T> PkeyCtxRef<T>
275where
276    T: HasPrivate,
277{
278    /// Prepares the context for decryption using the private key.
279    #[corresponds(EVP_PKEY_decrypt_init)]
280    #[inline]
281    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]
292    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)]
302    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]
319    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`].
335    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]
355    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`].
371    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
381impl<T> PkeyCtxRef<T> {
382    /// Prepares the context for shared secret derivation.
383    #[corresponds(EVP_PKEY_derive_init)]
384    #[inline]
385    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]
396    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]
410    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]
425    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]
439    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]
455    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]
470    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]
487    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))]
503    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]
529    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]
548    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]
571    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]
594    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]
613    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]
638    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]
663    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)]
684    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`].
698    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]
710    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)]
720mod 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]
733    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))]
757    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]
784    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]
805    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]
831    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))]
848    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))]
859    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)]
881    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)]
905    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]
925    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]
945    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]
958    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