openssl/
pkey_ctx.rs

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(any(boringssl, awslc)),
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//! ```
67use crate::bn::BigNumRef;
68#[cfg(not(any(boringssl, awslc)))]
69use crate::cipher::CipherRef;
70use crate::error::ErrorStack;
71use crate::md::MdRef;
72use crate::nid::Nid;
73use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Params, Private};
74use crate::rsa::Padding;
75use crate::sign::RsaPssSaltlen;
76use crate::{cvt, cvt_p};
77use cfg_if::cfg_if;
78use foreign_types::{ForeignType, ForeignTypeRef};
79#[cfg(not(any(boringssl, awslc)))]
80use libc::c_int;
81#[cfg(ossl320)]
82use libc::c_uint;
83use openssl_macros::corresponds;
84use std::convert::TryFrom;
85#[cfg(ossl320)]
86use std::ffi::CStr;
87use std::ptr;
88
89/// HKDF modes of operation.
90#[cfg(any(ossl111, libressl360))]
91pub struct HkdfMode(c_int);
92
93#[cfg(any(ossl111, libressl360))]
94impl HkdfMode {
95    /// This is the default mode. Calling [`derive`][PkeyCtxRef::derive] on a [`PkeyCtxRef`] set up
96    /// for HKDF will perform an extract followed by an expand operation in one go. The derived key
97    /// returned will be the result after the expand operation. The intermediate fixed-length
98    /// pseudorandom key K is not returned.
99    pub const EXTRACT_THEN_EXPAND: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND);
100
101    /// In this mode calling [`derive`][PkeyCtxRef::derive] will just perform the extract operation.
102    /// The value returned will be the intermediate fixed-length pseudorandom key K.
103    ///
104    /// The digest, key and salt values must be set before a key is derived or an error occurs.
105    pub const EXTRACT_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY);
106
107    /// In this mode calling [`derive`][PkeyCtxRef::derive] will just perform the expand operation.
108    /// The input key should be set to the intermediate fixed-length pseudorandom key K returned
109    /// from a previous extract operation.
110    ///
111    /// The digest, key and info values must be set before a key is derived or an error occurs.
112    pub const EXPAND_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXPAND_ONLY);
113}
114
115/// Nonce type for ECDSA and DSA.
116#[cfg(ossl320)]
117#[derive(Debug, PartialEq)]
118pub struct NonceType(c_uint);
119
120#[cfg(ossl320)]
121impl NonceType {
122    /// This is the default mode. It uses a random value for the nonce k as defined in FIPS 186-4 Section 6.3
123    /// “Secret Number Generation”.
124    pub const RANDOM_K: Self = NonceType(0);
125
126    /// Uses a deterministic value for the nonce k as defined in RFC #6979 (See Section 3.2 “Generation of k”).
127    pub const DETERMINISTIC_K: Self = NonceType(1);
128}
129
130generic_foreign_type_and_impl_send_sync! {
131    type CType = ffi::EVP_PKEY_CTX;
132    fn drop = ffi::EVP_PKEY_CTX_free;
133
134    /// A context object which can perform asymmetric cryptography operations.
135    pub struct PkeyCtx<T>;
136    /// A reference to a [`PkeyCtx`].
137    pub struct PkeyCtxRef<T>;
138}
139
140impl<T> PkeyCtx<T> {
141    /// Creates a new pkey context using the provided key.
142    #[corresponds(EVP_PKEY_CTX_new)]
143    #[inline]
144    pub fn new(pkey: &PKeyRef<T>) -> Result<Self, ErrorStack> {
145        unsafe {
146            let ptr = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?;
147            Ok(PkeyCtx::from_ptr(ptr))
148        }
149    }
150}
151
152impl PkeyCtx<()> {
153    /// Creates a new pkey context for the specified algorithm ID.
154    #[corresponds(EVP_PKEY_CTX_new_id)]
155    #[inline]
156    pub fn new_id(id: Id) -> Result<Self, ErrorStack> {
157        unsafe {
158            let ptr = cvt_p(ffi::EVP_PKEY_CTX_new_id(id.as_raw(), ptr::null_mut()))?;
159            Ok(PkeyCtx::from_ptr(ptr))
160        }
161    }
162}
163
164impl<T> PkeyCtxRef<T>
165where
166    T: HasPublic,
167{
168    /// Prepares the context for encryption using the public key.
169    #[corresponds(EVP_PKEY_encrypt_init)]
170    #[inline]
171    pub fn encrypt_init(&mut self) -> Result<(), ErrorStack> {
172        unsafe {
173            cvt(ffi::EVP_PKEY_encrypt_init(self.as_ptr()))?;
174        }
175
176        Ok(())
177    }
178
179    /// Prepares the context for signature verification using the public key.
180    #[corresponds(EVP_PKEY_verify_init)]
181    #[inline]
182    pub fn verify_init(&mut self) -> Result<(), ErrorStack> {
183        unsafe {
184            cvt(ffi::EVP_PKEY_verify_init(self.as_ptr()))?;
185        }
186
187        Ok(())
188    }
189
190    /// Prepares the context for signature recovery using the public key.
191    #[corresponds(EVP_PKEY_verify_recover_init)]
192    #[inline]
193    pub fn verify_recover_init(&mut self) -> Result<(), ErrorStack> {
194        unsafe {
195            cvt(ffi::EVP_PKEY_verify_recover_init(self.as_ptr()))?;
196        }
197
198        Ok(())
199    }
200
201    /// Encrypts data using the public key.
202    ///
203    /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be
204    /// returned.
205    #[corresponds(EVP_PKEY_encrypt)]
206    #[inline]
207    pub fn encrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
208        let mut written = to.as_ref().map_or(0, |b| b.len());
209        unsafe {
210            cvt(ffi::EVP_PKEY_encrypt(
211                self.as_ptr(),
212                to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
213                &mut written,
214                from.as_ptr(),
215                from.len(),
216            ))?;
217        }
218
219        Ok(written)
220    }
221
222    /// Like [`Self::encrypt`] but appends ciphertext to a [`Vec`].
223    pub fn encrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack> {
224        let base = out.len();
225        let len = self.encrypt(from, None)?;
226        out.resize(base + len, 0);
227        let len = self.encrypt(from, Some(&mut out[base..]))?;
228        out.truncate(base + len);
229        Ok(len)
230    }
231
232    /// Verifies the signature of data using the public key.
233    ///
234    /// Returns `Ok(true)` if the signature is valid, `Ok(false)` if the signature is invalid, and `Err` if an error
235    /// occurred.
236    ///
237    /// # Note
238    ///
239    /// This verifies the signature of the *raw* data. It is more common to compute and verify the signature of the
240    /// cryptographic hash of an arbitrary amount of data. The [`MdCtx`](crate::md_ctx::MdCtx) type can be used to do
241    /// that.
242    #[corresponds(EVP_PKEY_verify)]
243    #[inline]
244    pub fn verify(&mut self, data: &[u8], sig: &[u8]) -> Result<bool, ErrorStack> {
245        unsafe {
246            let r = ffi::EVP_PKEY_verify(
247                self.as_ptr(),
248                sig.as_ptr(),
249                sig.len(),
250                data.as_ptr(),
251                data.len(),
252            );
253            // `EVP_PKEY_verify` is not terribly consistent about how it,
254            // reports errors. It does not clearly distinguish between 0 and
255            // -1, and may put errors on the stack in both cases. If there's
256            // errors on the stack, we return `Err()`, else we return
257            // `Ok(false)`.
258            if r <= 0 {
259                let errors = ErrorStack::get();
260                if !errors.errors().is_empty() {
261                    return Err(errors);
262                }
263            }
264
265            Ok(r == 1)
266        }
267    }
268
269    /// Recovers the original data signed by the private key. You almost
270    /// always want `verify` instead.
271    ///
272    /// Returns the number of bytes written to `to`, or the number of bytes
273    /// that would be written, if `to` is `None.
274    #[corresponds(EVP_PKEY_verify_recover)]
275    #[inline]
276    pub fn verify_recover(
277        &mut self,
278        sig: &[u8],
279        to: Option<&mut [u8]>,
280    ) -> Result<usize, ErrorStack> {
281        let mut written = to.as_ref().map_or(0, |b| b.len());
282        unsafe {
283            cvt(ffi::EVP_PKEY_verify_recover(
284                self.as_ptr(),
285                to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
286                &mut written,
287                sig.as_ptr(),
288                sig.len(),
289            ))?;
290        }
291
292        Ok(written)
293    }
294}
295
296impl<T> PkeyCtxRef<T>
297where
298    T: HasPrivate,
299{
300    /// Prepares the context for decryption using the private key.
301    #[corresponds(EVP_PKEY_decrypt_init)]
302    #[inline]
303    pub fn decrypt_init(&mut self) -> Result<(), ErrorStack> {
304        unsafe {
305            cvt(ffi::EVP_PKEY_decrypt_init(self.as_ptr()))?;
306        }
307
308        Ok(())
309    }
310
311    /// Prepares the context for signing using the private key.
312    #[corresponds(EVP_PKEY_sign_init)]
313    #[inline]
314    pub fn sign_init(&mut self) -> Result<(), ErrorStack> {
315        unsafe {
316            cvt(ffi::EVP_PKEY_sign_init(self.as_ptr()))?;
317        }
318
319        Ok(())
320    }
321
322    /// Sets the peer key used for secret derivation.
323    #[corresponds(EVP_PKEY_derive_set_peer)]
324    pub fn derive_set_peer<U>(&mut self, key: &PKeyRef<U>) -> Result<(), ErrorStack>
325    where
326        U: HasPublic,
327    {
328        unsafe {
329            cvt(ffi::EVP_PKEY_derive_set_peer(self.as_ptr(), key.as_ptr()))?;
330        }
331
332        Ok(())
333    }
334
335    /// Decrypts data using the private key.
336    ///
337    /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be
338    /// returned.
339    #[corresponds(EVP_PKEY_decrypt)]
340    #[inline]
341    pub fn decrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
342        let mut written = to.as_ref().map_or(0, |b| b.len());
343        unsafe {
344            cvt(ffi::EVP_PKEY_decrypt(
345                self.as_ptr(),
346                to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
347                &mut written,
348                from.as_ptr(),
349                from.len(),
350            ))?;
351        }
352
353        Ok(written)
354    }
355
356    /// Like [`Self::decrypt`] but appends plaintext to a [`Vec`].
357    pub fn decrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack> {
358        let base = out.len();
359        let len = self.decrypt(from, None)?;
360        out.resize(base + len, 0);
361        let len = self.decrypt(from, Some(&mut out[base..]))?;
362        out.truncate(base + len);
363        Ok(len)
364    }
365
366    /// Signs the contents of `data`.
367    ///
368    /// If `sig` is set to `None`, an upper bound on the number of bytes required for the output buffer will be
369    /// returned.
370    ///
371    /// # Note
372    ///
373    /// This computes the signature of the *raw* bytes of `data`. It is more common to sign the cryptographic hash of
374    /// an arbitrary amount of data. The [`MdCtx`](crate::md_ctx::MdCtx) type can be used to do that.
375    #[corresponds(EVP_PKEY_sign)]
376    #[inline]
377    pub fn sign(&mut self, data: &[u8], sig: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
378        let mut written = sig.as_ref().map_or(0, |b| b.len());
379        unsafe {
380            cvt(ffi::EVP_PKEY_sign(
381                self.as_ptr(),
382                sig.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
383                &mut written,
384                data.as_ptr(),
385                data.len(),
386            ))?;
387        }
388
389        Ok(written)
390    }
391
392    /// Like [`Self::sign`] but appends the signature to a [`Vec`].
393    pub fn sign_to_vec(&mut self, data: &[u8], sig: &mut Vec<u8>) -> Result<usize, ErrorStack> {
394        let base = sig.len();
395        let len = self.sign(data, None)?;
396        sig.resize(base + len, 0);
397        let len = self.sign(data, Some(&mut sig[base..]))?;
398        sig.truncate(base + len);
399        Ok(len)
400    }
401}
402
403impl<T> PkeyCtxRef<T> {
404    /// Prepares the context for shared secret derivation.
405    #[corresponds(EVP_PKEY_derive_init)]
406    #[inline]
407    pub fn derive_init(&mut self) -> Result<(), ErrorStack> {
408        unsafe {
409            cvt(ffi::EVP_PKEY_derive_init(self.as_ptr()))?;
410        }
411
412        Ok(())
413    }
414
415    /// Prepares the context for key generation.
416    #[corresponds(EVP_PKEY_keygen_init)]
417    #[inline]
418    pub fn keygen_init(&mut self) -> Result<(), ErrorStack> {
419        unsafe {
420            cvt(ffi::EVP_PKEY_keygen_init(self.as_ptr()))?;
421        }
422
423        Ok(())
424    }
425
426    /// Prepares the context for key parameter generation.
427    #[corresponds(EVP_PKEY_paramgen_init)]
428    #[inline]
429    pub fn paramgen_init(&mut self) -> Result<(), ErrorStack> {
430        unsafe {
431            cvt(ffi::EVP_PKEY_paramgen_init(self.as_ptr()))?;
432        }
433
434        Ok(())
435    }
436
437    /// Sets which algorithm was used to compute the digest used in a
438    /// signature. With RSA signatures this causes the signature to be wrapped
439    /// in a `DigestInfo` structure. This is almost always what you want with
440    /// RSA signatures.
441    #[corresponds(EVP_PKEY_CTX_set_signature_md)]
442    #[inline]
443    pub fn set_signature_md(&self, md: &MdRef) -> Result<(), ErrorStack> {
444        unsafe {
445            cvt(ffi::EVP_PKEY_CTX_set_signature_md(
446                self.as_ptr(),
447                md.as_ptr(),
448            ))?;
449        }
450        Ok(())
451    }
452
453    /// Sets the DH paramgen prime length.
454    ///
455    /// This is only useful for DH keys.
456    #[corresponds(EVP_PKEY_CTX_set_dh_paramgen_prime_len)]
457    #[cfg(not(boringssl))]
458    #[inline]
459    pub fn set_dh_paramgen_prime_len(&mut self, bits: u32) -> Result<(), ErrorStack> {
460        unsafe {
461            cvt(ffi::EVP_PKEY_CTX_set_dh_paramgen_prime_len(
462                self.as_ptr(),
463                bits as i32,
464            ))?;
465        }
466
467        Ok(())
468    }
469
470    /// Sets the DH paramgen generator.
471    ///
472    /// This is only useful for DH keys.
473    #[corresponds(EVP_PKEY_CTX_set_dh_paramgen_generator)]
474    #[cfg(not(boringssl))]
475    #[inline]
476    pub fn set_dh_paramgen_generator(&mut self, bits: u32) -> Result<(), ErrorStack> {
477        unsafe {
478            cvt(ffi::EVP_PKEY_CTX_set_dh_paramgen_generator(
479                self.as_ptr(),
480                bits as i32,
481            ))?;
482        }
483
484        Ok(())
485    }
486
487    /// Sets the DSA paramgen bits.
488    ///
489    /// This is only useful for DSA keys.
490    #[corresponds(EVP_PKEY_CTX_set_dsa_paramgen_bits)]
491    #[inline]
492    pub fn set_dsa_paramgen_bits(&mut self, bits: u32) -> Result<(), ErrorStack> {
493        unsafe {
494            cvt(ffi::EVP_PKEY_CTX_set_dsa_paramgen_bits(
495                self.as_ptr(),
496                bits as i32,
497            ))?;
498        }
499
500        Ok(())
501    }
502
503    /// Sets the EC paramgen curve NID.
504    ///
505    /// This is only useful for EC keys.
506    #[corresponds(EVP_PKEY_CTX_set_ec_paramgen_curve_nid)]
507    #[inline]
508    pub fn set_ec_paramgen_curve_nid(&mut self, nid: Nid) -> Result<(), ErrorStack> {
509        unsafe {
510            cvt(ffi::EVP_PKEY_CTX_set_ec_paramgen_curve_nid(
511                self.as_ptr(),
512                nid.as_raw(),
513            ))?;
514        }
515
516        Ok(())
517    }
518
519    /// Returns the RSA padding mode in use.
520    ///
521    /// This is only useful for RSA keys.
522    #[corresponds(EVP_PKEY_CTX_get_rsa_padding)]
523    #[inline]
524    pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
525        let mut pad = 0;
526        unsafe {
527            cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad))?;
528        }
529
530        Ok(Padding::from_raw(pad))
531    }
532
533    /// Sets the RSA padding mode.
534    ///
535    /// This is only useful for RSA keys.
536    #[corresponds(EVP_PKEY_CTX_set_rsa_padding)]
537    #[inline]
538    pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
539        unsafe {
540            cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
541                self.as_ptr(),
542                padding.as_raw(),
543            ))?;
544        }
545
546        Ok(())
547    }
548
549    /// Sets the RSA keygen bits.
550    ///
551    /// This is only useful for RSA keys.
552    #[corresponds(EVP_PKEY_CTX_set_rsa_keygen_bits)]
553    #[inline]
554    pub fn set_rsa_keygen_bits(&mut self, bits: u32) -> Result<(), ErrorStack> {
555        unsafe {
556            cvt(ffi::EVP_PKEY_CTX_set_rsa_keygen_bits(
557                self.as_ptr(),
558                bits as i32,
559            ))?;
560        }
561
562        Ok(())
563    }
564
565    /// Sets the RSA keygen public exponent.
566    ///
567    /// This is only useful for RSA keys.
568    #[corresponds(EVP_PKEY_CTX_set1_rsa_keygen_pubexp)]
569    #[inline]
570    pub fn set_rsa_keygen_pubexp(&mut self, pubexp: &BigNumRef) -> Result<(), ErrorStack> {
571        unsafe {
572            cfg_if! {
573                if #[cfg(ossl300)] {
574                    cvt(ffi::EVP_PKEY_CTX_set1_rsa_keygen_pubexp(
575                        self.as_ptr(),
576                        pubexp.as_ptr(),
577                    ))?;
578                } else {
579                    cvt(ffi::EVP_PKEY_CTX_set_rsa_keygen_pubexp(
580                        self.as_ptr(),
581                        // Dupe the BN because the EVP_PKEY_CTX takes ownership of it and will free it.
582                        cvt_p(ffi::BN_dup(pubexp.as_ptr()))?,
583                    ))?;
584                }
585            }
586        }
587
588        Ok(())
589    }
590
591    /// Sets the RSA PSS salt length.
592    ///
593    /// This is only useful for RSA keys.
594    #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)]
595    #[inline]
596    pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
597        unsafe {
598            cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
599                self.as_ptr(),
600                len.as_raw(),
601            ))
602            .map(|_| ())
603        }
604    }
605
606    /// Sets the RSA MGF1 algorithm.
607    ///
608    /// This is only useful for RSA keys.
609    #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)]
610    #[inline]
611    pub fn set_rsa_mgf1_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> {
612        unsafe {
613            cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
614                self.as_ptr(),
615                md.as_ptr(),
616            ))?;
617        }
618
619        Ok(())
620    }
621
622    /// Sets the RSA OAEP algorithm.
623    ///
624    /// This is only useful for RSA keys.
625    #[corresponds(EVP_PKEY_CTX_set_rsa_oaep_md)]
626    #[inline]
627    pub fn set_rsa_oaep_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> {
628        unsafe {
629            cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
630                self.as_ptr(),
631                md.as_ptr() as *mut _,
632            ))?;
633        }
634
635        Ok(())
636    }
637
638    /// Sets the RSA OAEP label.
639    ///
640    /// This is only useful for RSA keys.
641    #[corresponds(EVP_PKEY_CTX_set0_rsa_oaep_label)]
642    pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
643        use crate::LenType;
644        let len = LenType::try_from(label.len()).unwrap();
645
646        unsafe {
647            let p = ffi::OPENSSL_malloc(label.len() as _);
648            ptr::copy_nonoverlapping(label.as_ptr(), p as *mut _, label.len());
649
650            let r = cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
651                self.as_ptr(),
652                p as *mut _,
653                len,
654            ));
655            if r.is_err() {
656                ffi::OPENSSL_free(p);
657            }
658            r?;
659        }
660
661        Ok(())
662    }
663
664    /// Sets the cipher used during key generation.
665    #[cfg(not(any(boringssl, awslc)))]
666    #[corresponds(EVP_PKEY_CTX_ctrl)]
667    #[inline]
668    pub fn set_keygen_cipher(&mut self, cipher: &CipherRef) -> Result<(), ErrorStack> {
669        unsafe {
670            cvt(ffi::EVP_PKEY_CTX_ctrl(
671                self.as_ptr(),
672                -1,
673                ffi::EVP_PKEY_OP_KEYGEN,
674                ffi::EVP_PKEY_CTRL_CIPHER,
675                0,
676                cipher.as_ptr() as *mut _,
677            ))?;
678        }
679
680        Ok(())
681    }
682
683    /// Sets the key MAC key used during key generation.
684    #[cfg(not(any(boringssl, awslc)))]
685    #[corresponds(EVP_PKEY_CTX_ctrl)]
686    #[inline]
687    pub fn set_keygen_mac_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
688        let len = c_int::try_from(key.len()).unwrap();
689
690        unsafe {
691            cvt(ffi::EVP_PKEY_CTX_ctrl(
692                self.as_ptr(),
693                -1,
694                ffi::EVP_PKEY_OP_KEYGEN,
695                ffi::EVP_PKEY_CTRL_SET_MAC_KEY,
696                len,
697                key.as_ptr() as *mut _,
698            ))?;
699        }
700
701        Ok(())
702    }
703
704    /// Sets the digest used for HKDF derivation.
705    ///
706    /// Requires OpenSSL 1.1.0 or newer.
707    #[corresponds(EVP_PKEY_CTX_set_hkdf_md)]
708    #[cfg(any(ossl110, boringssl, libressl360, awslc))]
709    #[inline]
710    pub fn set_hkdf_md(&mut self, digest: &MdRef) -> Result<(), ErrorStack> {
711        unsafe {
712            cvt(ffi::EVP_PKEY_CTX_set_hkdf_md(
713                self.as_ptr(),
714                digest.as_ptr(),
715            ))?;
716        }
717
718        Ok(())
719    }
720
721    /// Sets the HKDF mode of operation.
722    ///
723    /// Defaults to [`HkdfMode::EXTRACT_THEN_EXPAND`].
724    ///
725    /// WARNING: Although this API calls it a "mode", HKDF-Extract and HKDF-Expand are distinct
726    /// operations with distinct inputs and distinct kinds of keys. Callers should not pass input
727    /// secrets for one operation into the other.
728    ///
729    /// Requires OpenSSL 1.1.1 or newer.
730    #[corresponds(EVP_PKEY_CTX_set_hkdf_mode)]
731    #[cfg(any(ossl111, libressl360))]
732    #[inline]
733    pub fn set_hkdf_mode(&mut self, mode: HkdfMode) -> Result<(), ErrorStack> {
734        unsafe {
735            cvt(ffi::EVP_PKEY_CTX_set_hkdf_mode(self.as_ptr(), mode.0))?;
736        }
737
738        Ok(())
739    }
740
741    /// Sets the input material for HKDF generation as the "key".
742    ///
743    /// Which input is the key depends on the "mode" (see [`set_hkdf_mode`][Self::set_hkdf_mode]).
744    /// If [`HkdfMode::EXTRACT_THEN_EXPAND`] or [`HkdfMode::EXTRACT_ONLY`], this function specifies
745    /// the input keying material (IKM) for HKDF-Extract. If [`HkdfMode::EXPAND_ONLY`], it instead
746    /// specifies the pseudorandom key (PRK) for HKDF-Expand.
747    ///
748    /// Requires OpenSSL 1.1.0 or newer.
749    #[corresponds(EVP_PKEY_CTX_set1_hkdf_key)]
750    #[cfg(any(ossl110, boringssl, libressl360, awslc))]
751    #[inline]
752    pub fn set_hkdf_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
753        #[cfg(not(any(boringssl, awslc)))]
754        let len = c_int::try_from(key.len()).unwrap();
755        #[cfg(any(boringssl, awslc))]
756        let len = key.len();
757
758        unsafe {
759            cvt(ffi::EVP_PKEY_CTX_set1_hkdf_key(
760                self.as_ptr(),
761                key.as_ptr(),
762                len,
763            ))?;
764        }
765
766        Ok(())
767    }
768
769    /// Sets the salt value for HKDF generation.
770    ///
771    /// If performing HKDF-Expand only, this parameter is ignored.
772    ///
773    /// Requires OpenSSL 1.1.0 or newer.
774    #[corresponds(EVP_PKEY_CTX_set1_hkdf_salt)]
775    #[cfg(any(ossl110, boringssl, libressl360, awslc))]
776    #[inline]
777    pub fn set_hkdf_salt(&mut self, salt: &[u8]) -> Result<(), ErrorStack> {
778        #[cfg(not(any(boringssl, awslc)))]
779        let len = c_int::try_from(salt.len()).unwrap();
780        #[cfg(any(boringssl, awslc))]
781        let len = salt.len();
782
783        unsafe {
784            cvt(ffi::EVP_PKEY_CTX_set1_hkdf_salt(
785                self.as_ptr(),
786                salt.as_ptr(),
787                len,
788            ))?;
789        }
790
791        Ok(())
792    }
793
794    /// Appends info bytes for HKDF generation.
795    ///
796    /// If performing HKDF-Extract only, this parameter is ignored.
797    ///
798    /// Requires OpenSSL 1.1.0 or newer.
799    #[corresponds(EVP_PKEY_CTX_add1_hkdf_info)]
800    #[cfg(any(ossl110, boringssl, libressl360, awslc))]
801    #[inline]
802    pub fn add_hkdf_info(&mut self, info: &[u8]) -> Result<(), ErrorStack> {
803        #[cfg(not(any(boringssl, awslc)))]
804        let len = c_int::try_from(info.len()).unwrap();
805        #[cfg(any(boringssl, awslc))]
806        let len = info.len();
807
808        unsafe {
809            cvt(ffi::EVP_PKEY_CTX_add1_hkdf_info(
810                self.as_ptr(),
811                info.as_ptr(),
812                len,
813            ))?;
814        }
815
816        Ok(())
817    }
818
819    /// Derives a shared secret between two keys.
820    ///
821    /// If `buf` is set to `None`, an upper bound on the number of bytes required for the buffer will be returned.
822    #[corresponds(EVP_PKEY_derive)]
823    pub fn derive(&mut self, buf: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
824        let mut len = buf.as_ref().map_or(0, |b| b.len());
825        unsafe {
826            cvt(ffi::EVP_PKEY_derive(
827                self.as_ptr(),
828                buf.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
829                &mut len,
830            ))?;
831        }
832
833        Ok(len)
834    }
835
836    /// Like [`Self::derive`] but appends the secret to a [`Vec`].
837    pub fn derive_to_vec(&mut self, buf: &mut Vec<u8>) -> Result<usize, ErrorStack> {
838        let base = buf.len();
839        let len = self.derive(None)?;
840        buf.resize(base + len, 0);
841        let len = self.derive(Some(&mut buf[base..]))?;
842        buf.truncate(base + len);
843        Ok(len)
844    }
845
846    /// Generates a new public/private keypair.
847    #[corresponds(EVP_PKEY_keygen)]
848    #[inline]
849    pub fn keygen(&mut self) -> Result<PKey<Private>, ErrorStack> {
850        unsafe {
851            let mut key = ptr::null_mut();
852            cvt(ffi::EVP_PKEY_keygen(self.as_ptr(), &mut key))?;
853            Ok(PKey::from_ptr(key))
854        }
855    }
856
857    /// Generates a new set of key parameters.
858    #[corresponds(EVP_PKEY_paramgen)]
859    #[inline]
860    pub fn paramgen(&mut self) -> Result<PKey<Params>, ErrorStack> {
861        unsafe {
862            let mut key = ptr::null_mut();
863            cvt(ffi::EVP_PKEY_paramgen(self.as_ptr(), &mut key))?;
864            Ok(PKey::from_ptr(key))
865        }
866    }
867
868    /// Sets the nonce type for a private key context.
869    ///
870    /// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979).
871    ///
872    /// This is only useful for DSA and ECDSA.
873    /// Requires OpenSSL 3.2.0 or newer.
874    #[cfg(ossl320)]
875    #[corresponds(EVP_PKEY_CTX_set_params)]
876    pub fn set_nonce_type(&mut self, nonce_type: NonceType) -> Result<(), ErrorStack> {
877        let nonce_field_name = CStr::from_bytes_with_nul(b"nonce-type\0").unwrap();
878        let mut nonce_type = nonce_type.0;
879        unsafe {
880            let param_nonce =
881                ffi::OSSL_PARAM_construct_uint(nonce_field_name.as_ptr(), &mut nonce_type);
882            let param_end = ffi::OSSL_PARAM_construct_end();
883
884            let params = [param_nonce, param_end];
885            cvt(ffi::EVP_PKEY_CTX_set_params(self.as_ptr(), params.as_ptr()))?;
886        }
887        Ok(())
888    }
889
890    /// Gets the nonce type for a private key context.
891    ///
892    /// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979).
893    ///
894    /// This is only useful for DSA and ECDSA.
895    /// Requires OpenSSL 3.2.0 or newer.
896    #[cfg(ossl320)]
897    #[corresponds(EVP_PKEY_CTX_get_params)]
898    pub fn nonce_type(&mut self) -> Result<NonceType, ErrorStack> {
899        let nonce_field_name = CStr::from_bytes_with_nul(b"nonce-type\0").unwrap();
900        let mut nonce_type: c_uint = 0;
901        unsafe {
902            let param_nonce =
903                ffi::OSSL_PARAM_construct_uint(nonce_field_name.as_ptr(), &mut nonce_type);
904            let param_end = ffi::OSSL_PARAM_construct_end();
905
906            let mut params = [param_nonce, param_end];
907            cvt(ffi::EVP_PKEY_CTX_get_params(
908                self.as_ptr(),
909                params.as_mut_ptr(),
910            ))?;
911        }
912        Ok(NonceType(nonce_type))
913    }
914}
915
916#[cfg(test)]
917mod test {
918    use super::*;
919    use crate::bn::BigNum;
920    #[cfg(not(any(boringssl, awslc)))]
921    use crate::cipher::Cipher;
922    use crate::ec::{EcGroup, EcKey};
923    use crate::hash::{hash, MessageDigest};
924    use crate::md::Md;
925    use crate::nid::Nid;
926    use crate::pkey::PKey;
927    use crate::rsa::Rsa;
928    use crate::sign::Verifier;
929    #[cfg(not(boringssl))]
930    use cfg_if::cfg_if;
931
932    #[test]
933    fn rsa() {
934        let key = include_bytes!("../test/rsa.pem");
935        let rsa = Rsa::private_key_from_pem(key).unwrap();
936        let pkey = PKey::from_rsa(rsa).unwrap();
937
938        let mut ctx = PkeyCtx::new(&pkey).unwrap();
939        ctx.encrypt_init().unwrap();
940        ctx.set_rsa_padding(Padding::PKCS1).unwrap();
941
942        let pt = "hello world".as_bytes();
943        let mut ct = vec![];
944        ctx.encrypt_to_vec(pt, &mut ct).unwrap();
945
946        ctx.decrypt_init().unwrap();
947        ctx.set_rsa_padding(Padding::PKCS1).unwrap();
948
949        let mut out = vec![];
950        ctx.decrypt_to_vec(&ct, &mut out).unwrap();
951
952        assert_eq!(pt, out);
953    }
954
955    #[test]
956    fn rsa_oaep() {
957        let key = include_bytes!("../test/rsa.pem");
958        let rsa = Rsa::private_key_from_pem(key).unwrap();
959        let pkey = PKey::from_rsa(rsa).unwrap();
960
961        let mut ctx = PkeyCtx::new(&pkey).unwrap();
962        ctx.encrypt_init().unwrap();
963        ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
964        ctx.set_rsa_oaep_md(Md::sha256()).unwrap();
965        ctx.set_rsa_mgf1_md(Md::sha256()).unwrap();
966
967        let pt = "hello world".as_bytes();
968        let mut ct = vec![];
969        ctx.encrypt_to_vec(pt, &mut ct).unwrap();
970
971        ctx.decrypt_init().unwrap();
972        ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
973        ctx.set_rsa_oaep_md(Md::sha256()).unwrap();
974        ctx.set_rsa_mgf1_md(Md::sha256()).unwrap();
975
976        let mut out = vec![];
977        ctx.decrypt_to_vec(&ct, &mut out).unwrap();
978
979        assert_eq!(pt, out);
980    }
981
982    #[test]
983    fn rsa_sign() {
984        let key = include_bytes!("../test/rsa.pem");
985        let rsa = Rsa::private_key_from_pem(key).unwrap();
986        let pkey = PKey::from_rsa(rsa).unwrap();
987
988        let mut ctx = PkeyCtx::new(&pkey).unwrap();
989        ctx.sign_init().unwrap();
990        ctx.set_rsa_padding(Padding::PKCS1).unwrap();
991        ctx.set_signature_md(Md::sha384()).unwrap();
992
993        let msg = b"hello world";
994        let digest = hash(MessageDigest::sha384(), msg).unwrap();
995        let mut signature = vec![];
996        ctx.sign_to_vec(&digest, &mut signature).unwrap();
997
998        let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap();
999        verifier.update(msg).unwrap();
1000        assert!(matches!(verifier.verify(&signature), Ok(true)));
1001    }
1002
1003    #[test]
1004    fn rsa_sign_pss() {
1005        let key = include_bytes!("../test/rsa.pem");
1006        let rsa = Rsa::private_key_from_pem(key).unwrap();
1007        let pkey = PKey::from_rsa(rsa).unwrap();
1008
1009        let mut ctx = PkeyCtx::new(&pkey).unwrap();
1010        ctx.sign_init().unwrap();
1011        ctx.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
1012        ctx.set_signature_md(Md::sha384()).unwrap();
1013        ctx.set_rsa_pss_saltlen(RsaPssSaltlen::custom(14)).unwrap();
1014
1015        let msg = b"hello world";
1016        let digest = hash(MessageDigest::sha384(), msg).unwrap();
1017        let mut signature = vec![];
1018        ctx.sign_to_vec(&digest, &mut signature).unwrap();
1019
1020        let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap();
1021        verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
1022        verifier
1023            .set_rsa_pss_saltlen(RsaPssSaltlen::custom(14))
1024            .unwrap();
1025        verifier.update(msg).unwrap();
1026        assert!(matches!(verifier.verify(&signature), Ok(true)));
1027    }
1028
1029    #[test]
1030    fn derive() {
1031        let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
1032        let key1 = EcKey::generate(&group).unwrap();
1033        let key1 = PKey::from_ec_key(key1).unwrap();
1034        let key2 = EcKey::generate(&group).unwrap();
1035        let key2 = PKey::from_ec_key(key2).unwrap();
1036
1037        let mut ctx = PkeyCtx::new(&key1).unwrap();
1038        ctx.derive_init().unwrap();
1039        ctx.derive_set_peer(&key2).unwrap();
1040
1041        let mut buf = vec![];
1042        ctx.derive_to_vec(&mut buf).unwrap();
1043    }
1044
1045    #[test]
1046    #[cfg(not(any(boringssl, awslc)))]
1047    fn cmac_keygen() {
1048        let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap();
1049        ctx.keygen_init().unwrap();
1050        ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap();
1051        ctx.set_keygen_mac_key(&hex::decode("9294727a3638bb1c13f48ef8158bfc9d").unwrap())
1052            .unwrap();
1053        ctx.keygen().unwrap();
1054    }
1055
1056    #[test]
1057    #[cfg(not(boringssl))]
1058    fn dh_paramgen() {
1059        let mut ctx = PkeyCtx::new_id(Id::DH).unwrap();
1060        ctx.paramgen_init().unwrap();
1061        ctx.set_dh_paramgen_prime_len(512).unwrap();
1062        ctx.set_dh_paramgen_generator(2).unwrap();
1063        let params = ctx.paramgen().unwrap();
1064
1065        assert_eq!(params.size(), 64);
1066    }
1067
1068    #[test]
1069    #[cfg(not(boringssl))]
1070    fn dsa_paramgen() {
1071        let mut ctx = PkeyCtx::new_id(Id::DSA).unwrap();
1072        ctx.paramgen_init().unwrap();
1073        ctx.set_dsa_paramgen_bits(2048).unwrap();
1074        let params = ctx.paramgen().unwrap();
1075
1076        let size = {
1077            cfg_if! {
1078                if #[cfg(awslc)] {
1079                    72
1080                } else if #[cfg(libressl)] {
1081                    48
1082                } else {
1083                    64
1084                }
1085            }
1086        };
1087        assert_eq!(params.size(), size);
1088    }
1089
1090    #[test]
1091    fn ec_keygen() {
1092        let mut ctx = PkeyCtx::new_id(Id::EC).unwrap();
1093        ctx.paramgen_init().unwrap();
1094        ctx.set_ec_paramgen_curve_nid(Nid::X9_62_PRIME256V1)
1095            .unwrap();
1096        let params = ctx.paramgen().unwrap();
1097
1098        assert_eq!(params.size(), 72);
1099    }
1100
1101    #[test]
1102    fn rsa_keygen() {
1103        let pubexp = BigNum::from_u32(65537).unwrap();
1104        let mut ctx = PkeyCtx::new_id(Id::RSA).unwrap();
1105        ctx.keygen_init().unwrap();
1106        ctx.set_rsa_keygen_pubexp(&pubexp).unwrap();
1107        ctx.set_rsa_keygen_bits(2048).unwrap();
1108        let key = ctx.keygen().unwrap();
1109
1110        assert_eq!(key.bits(), 2048);
1111    }
1112
1113    #[test]
1114    #[cfg(any(ossl110, boringssl, libressl360, awslc))]
1115    fn hkdf() {
1116        let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
1117        ctx.derive_init().unwrap();
1118        ctx.set_hkdf_md(Md::sha256()).unwrap();
1119        ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap())
1120            .unwrap();
1121        ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap())
1122            .unwrap();
1123        ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap())
1124            .unwrap();
1125        let mut out = [0; 42];
1126        ctx.derive(Some(&mut out)).unwrap();
1127
1128        assert_eq!(
1129            &out[..],
1130            hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865")
1131                .unwrap()
1132        );
1133    }
1134
1135    #[test]
1136    #[cfg(any(ossl111, libressl360))]
1137    fn hkdf_expand() {
1138        let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
1139        ctx.derive_init().unwrap();
1140        ctx.set_hkdf_mode(HkdfMode::EXPAND_ONLY).unwrap();
1141        ctx.set_hkdf_md(Md::sha256()).unwrap();
1142        ctx.set_hkdf_key(
1143            &hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5")
1144                .unwrap(),
1145        )
1146        .unwrap();
1147        ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap())
1148            .unwrap();
1149        let mut out = [0; 42];
1150        ctx.derive(Some(&mut out)).unwrap();
1151
1152        assert_eq!(
1153            &out[..],
1154            hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865")
1155                .unwrap()
1156        );
1157    }
1158
1159    #[test]
1160    #[cfg(any(ossl111, libressl360))]
1161    fn hkdf_extract() {
1162        let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
1163        ctx.derive_init().unwrap();
1164        ctx.set_hkdf_mode(HkdfMode::EXTRACT_ONLY).unwrap();
1165        ctx.set_hkdf_md(Md::sha256()).unwrap();
1166        ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap())
1167            .unwrap();
1168        ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap())
1169            .unwrap();
1170        let mut out = vec![];
1171        ctx.derive_to_vec(&mut out).unwrap();
1172
1173        assert_eq!(
1174            &out[..],
1175            hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5")
1176                .unwrap()
1177        );
1178    }
1179
1180    #[test]
1181    fn verify_fail() {
1182        let key1 = Rsa::generate(4096).unwrap();
1183        let key1 = PKey::from_rsa(key1).unwrap();
1184
1185        let data = b"Some Crypto Text";
1186
1187        let mut ctx = PkeyCtx::new(&key1).unwrap();
1188        ctx.sign_init().unwrap();
1189        let mut signature = vec![];
1190        ctx.sign_to_vec(data, &mut signature).unwrap();
1191
1192        let bad_data = b"Some Crypto text";
1193
1194        ctx.verify_init().unwrap();
1195        let valid = ctx.verify(bad_data, &signature);
1196        assert!(matches!(valid, Ok(false) | Err(_)));
1197        assert!(ErrorStack::get().errors().is_empty());
1198    }
1199
1200    #[test]
1201    fn verify_fail_ec() {
1202        let key1 =
1203            EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap();
1204        let key1 = PKey::from_ec_key(key1).unwrap();
1205
1206        let data = b"Some Crypto Text";
1207        let mut ctx = PkeyCtx::new(&key1).unwrap();
1208        ctx.verify_init().unwrap();
1209        assert!(matches!(ctx.verify(data, &[0; 64]), Ok(false) | Err(_)));
1210        assert!(ErrorStack::get().errors().is_empty());
1211    }
1212
1213    #[test]
1214    fn test_verify_recover() {
1215        let key = Rsa::generate(2048).unwrap();
1216        let key = PKey::from_rsa(key).unwrap();
1217
1218        let digest = [
1219            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
1220            24, 25, 26, 27, 28, 29, 30, 31,
1221        ];
1222
1223        let mut ctx = PkeyCtx::new(&key).unwrap();
1224        ctx.sign_init().unwrap();
1225        ctx.set_rsa_padding(Padding::PKCS1).unwrap();
1226        ctx.set_signature_md(Md::sha256()).unwrap();
1227        let mut signature = vec![];
1228        ctx.sign_to_vec(&digest, &mut signature).unwrap();
1229
1230        // Attempt recovery of just the digest.
1231        let mut ctx = PkeyCtx::new(&key).unwrap();
1232        ctx.verify_recover_init().unwrap();
1233        ctx.set_rsa_padding(Padding::PKCS1).unwrap();
1234        ctx.set_signature_md(Md::sha256()).unwrap();
1235        let length = ctx.verify_recover(&signature, None).unwrap();
1236        let mut result_buf = vec![0; length];
1237        let length = ctx
1238            .verify_recover(&signature, Some(&mut result_buf))
1239            .unwrap();
1240        assert_eq!(length, digest.len());
1241        // result_buf contains the digest
1242        assert_eq!(result_buf[..length], digest);
1243
1244        // Attempt recovery of teh entire DigestInfo
1245        let mut ctx = PkeyCtx::new(&key).unwrap();
1246        ctx.verify_recover_init().unwrap();
1247        ctx.set_rsa_padding(Padding::PKCS1).unwrap();
1248        let length = ctx.verify_recover(&signature, None).unwrap();
1249        let mut result_buf = vec![0; length];
1250        let length = ctx
1251            .verify_recover(&signature, Some(&mut result_buf))
1252            .unwrap();
1253        // 32-bytes of SHA256 digest + the ASN.1 DigestInfo structure == 51 bytes
1254        assert_eq!(length, 51);
1255        // The digest is the end of the DigestInfo structure.
1256        assert_eq!(result_buf[length - digest.len()..length], digest);
1257    }
1258
1259    #[test]
1260    #[cfg(ossl320)]
1261    fn set_nonce_type() {
1262        let key1 =
1263            EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap();
1264        let key1 = PKey::from_ec_key(key1).unwrap();
1265
1266        let mut ctx = PkeyCtx::new(&key1).unwrap();
1267        ctx.sign_init().unwrap();
1268        ctx.set_nonce_type(NonceType::DETERMINISTIC_K).unwrap();
1269        let nonce_type = ctx.nonce_type().unwrap();
1270        assert_eq!(nonce_type, NonceType::DETERMINISTIC_K);
1271        assert!(ErrorStack::get().errors().is_empty());
1272    }
1273
1274    // Test vector from
1275    // https://github.com/openssl/openssl/blob/openssl-3.2.0/test/recipes/30-test_evp_data/evppkey_ecdsa_rfc6979.txt
1276    #[test]
1277    #[cfg(ossl320)]
1278    fn ecdsa_deterministic_signature() {
1279        let private_key_pem = "-----BEGIN PRIVATE KEY-----
1280MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCDJr6nYRbp1FmtcIVdnsdaTTlDD2zbo
1281mxJ7imIrEg9nIQ==
1282-----END PRIVATE KEY-----";
1283
1284        let key1 = EcKey::private_key_from_pem(private_key_pem.as_bytes()).unwrap();
1285        let key1 = PKey::from_ec_key(key1).unwrap();
1286        let input = "sample";
1287        let expected_output = hex::decode("3044022061340C88C3AAEBEB4F6D667F672CA9759A6CCAA9FA8811313039EE4A35471D3202206D7F147DAC089441BB2E2FE8F7A3FA264B9C475098FDCF6E00D7C996E1B8B7EB").unwrap();
1288
1289        let hashed_input = hash(MessageDigest::sha1(), input.as_bytes()).unwrap();
1290        let mut ctx = PkeyCtx::new(&key1).unwrap();
1291        ctx.sign_init().unwrap();
1292        ctx.set_signature_md(Md::sha1()).unwrap();
1293        ctx.set_nonce_type(NonceType::DETERMINISTIC_K).unwrap();
1294
1295        let mut output = vec![];
1296        ctx.sign_to_vec(&hashed_input, &mut output).unwrap();
1297        assert_eq!(output, expected_output);
1298        assert!(ErrorStack::get().errors().is_empty());
1299    }
1300}