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