Skip to main content

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