1//! The asymmetric encryption context.
2//!
3//! # Examples
4//!
5//! Encrypt data with RSA
6//!
7//! ```
8//! use openssl::rsa::Rsa;
9//! use openssl::pkey::PKey;
10//! use openssl::pkey_ctx::PkeyCtx;
11//!
12//! let key = Rsa::generate(4096).unwrap();
13//! let key = PKey::from_rsa(key).unwrap();
14//!
15//! let mut ctx = PkeyCtx::new(&key).unwrap();
16//! ctx.encrypt_init().unwrap();
17//!
18//! let data = b"Some Crypto Text";
19//! let mut ciphertext = vec![];
20//! ctx.encrypt_to_vec(data, &mut ciphertext).unwrap();
21//! ```
22
23#![cfg_attr(
24 not(boringssl),
25 doc = r#"\
26Generate a CMAC key
27
28```
29use openssl::pkey_ctx::PkeyCtx;
30use openssl::pkey::Id;
31use openssl::cipher::Cipher;
32
33let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap();
34ctx.keygen_init().unwrap();
35ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap();
36ctx.set_keygen_mac_key(b"0123456789abcdef").unwrap();
37let cmac_key = ctx.keygen().unwrap();
38```"#
39)]
40
41//!
42//! Sign and verify data with RSA
43//!
44//! ```
45//! use openssl::pkey_ctx::PkeyCtx;
46//! use openssl::pkey::PKey;
47//! use openssl::rsa::Rsa;
48//!
49//! // Generate a random RSA key.
50//! let key = Rsa::generate(4096).unwrap();
51//! let key = PKey::from_rsa(key).unwrap();
52//!
53//! let text = b"Some Crypto Text";
54//!
55//! // Create the signature.
56//! let mut ctx = PkeyCtx::new(&key).unwrap();
57//! ctx.sign_init().unwrap();
58//! let mut signature = vec![];
59//! ctx.sign_to_vec(text, &mut signature).unwrap();
60//!
61//! // Verify the signature.
62//! let mut ctx = PkeyCtx::new(&key).unwrap();
63//! ctx.verify_init().unwrap();
64//! let valid = ctx.verify(text, &signature).unwrap();
65//! assert!(valid);
66//! ```
67#[cfg(not(boringssl))]
68use crate::cipher::CipherRef;
69use crate::error::ErrorStack;
70use crate::md::MdRef;
71use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Private};
72use crate::rsa::Padding;
73use crate::sign::RsaPssSaltlen;
74use crate::{cvt, cvt_p};
75use foreign_types::{ForeignType, ForeignTypeRef};
76#[cfg(not(boringssl))]
77use libc::c_int;
78#[cfg(ossl320)]
79use libc::c_uint;
80use openssl_macros::corresponds;
81use std::convert::TryFrom;
82#[cfg(ossl320)]
83use std::ffi::CStr;
84use std::ptr;
85
86/// HKDF modes of operation.
87#[cfg(any(ossl111, libressl360))]
88pub struct HkdfMode(c_int);
89
90#[cfg(any(ossl111, libressl360))]
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: *mut EVP_PKEY_CTX = cvt_p(ffi::EVP_PKEY_CTX_new(k:pkey.as_ptr(), e: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_new_id)]
152 #[inline]
153 pub fn new_id(id: Id) -> Result<Self, ErrorStack> {
154 unsafe {
155 let ptr: *mut EVP_PKEY_CTX = cvt_p(ffi::EVP_PKEY_CTX_new_id(id:id.as_raw(), e: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 /// Sets which algorithm was used to compute the digest used in a
424 /// signature. With RSA signatures this causes the signature to be wrapped
425 /// in a `DigestInfo` structure. This is almost always what you want with
426 /// RSA signatures.
427 #[corresponds(EVP_PKEY_CTX_set_signature_md)]
428 #[inline]
429 pub fn set_signature_md(&self, md: &MdRef) -> Result<(), ErrorStack> {
430 unsafe {
431 cvt(ffi::EVP_PKEY_CTX_set_signature_md(
432 self.as_ptr(),
433 md.as_ptr(),
434 ))?;
435 }
436 Ok(())
437 }
438
439 /// Returns the RSA padding mode in use.
440 ///
441 /// This is only useful for RSA keys.
442 #[corresponds(EVP_PKEY_CTX_get_rsa_padding)]
443 #[inline]
444 pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
445 let mut pad = 0;
446 unsafe {
447 cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad))?;
448 }
449
450 Ok(Padding::from_raw(pad))
451 }
452
453 /// Sets the RSA padding mode.
454 ///
455 /// This is only useful for RSA keys.
456 #[corresponds(EVP_PKEY_CTX_set_rsa_padding)]
457 #[inline]
458 pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
459 unsafe {
460 cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
461 self.as_ptr(),
462 padding.as_raw(),
463 ))?;
464 }
465
466 Ok(())
467 }
468
469 /// Sets the RSA PSS salt length.
470 ///
471 /// This is only useful for RSA keys.
472 #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)]
473 #[inline]
474 pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
475 unsafe {
476 cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
477 self.as_ptr(),
478 len.as_raw(),
479 ))
480 .map(|_| ())
481 }
482 }
483
484 /// Sets the RSA MGF1 algorithm.
485 ///
486 /// This is only useful for RSA keys.
487 #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)]
488 #[inline]
489 pub fn set_rsa_mgf1_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> {
490 unsafe {
491 cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
492 self.as_ptr(),
493 md.as_ptr(),
494 ))?;
495 }
496
497 Ok(())
498 }
499
500 /// Sets the RSA OAEP algorithm.
501 ///
502 /// This is only useful for RSA keys.
503 #[corresponds(EVP_PKEY_CTX_set_rsa_oaep_md)]
504 #[cfg(any(ossl102, libressl310, boringssl))]
505 #[inline]
506 pub fn set_rsa_oaep_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> {
507 unsafe {
508 cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
509 self.as_ptr(),
510 md.as_ptr() as *mut _,
511 ))?;
512 }
513
514 Ok(())
515 }
516
517 /// Sets the RSA OAEP label.
518 ///
519 /// This is only useful for RSA keys.
520 #[corresponds(EVP_PKEY_CTX_set0_rsa_oaep_label)]
521 #[cfg(any(ossl102, libressl310, boringssl))]
522 pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
523 use crate::LenType;
524 let len = LenType::try_from(label.len()).unwrap();
525
526 unsafe {
527 let p = ffi::OPENSSL_malloc(label.len() as _);
528 ptr::copy_nonoverlapping(label.as_ptr(), p as *mut _, label.len());
529
530 let r = cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
531 self.as_ptr(),
532 p as *mut _,
533 len,
534 ));
535 if r.is_err() {
536 ffi::OPENSSL_free(p);
537 }
538 r?;
539 }
540
541 Ok(())
542 }
543
544 /// Sets the cipher used during key generation.
545 #[cfg(not(boringssl))]
546 #[corresponds(EVP_PKEY_CTX_ctrl)]
547 #[inline]
548 pub fn set_keygen_cipher(&mut self, cipher: &CipherRef) -> Result<(), ErrorStack> {
549 unsafe {
550 cvt(ffi::EVP_PKEY_CTX_ctrl(
551 self.as_ptr(),
552 -1,
553 ffi::EVP_PKEY_OP_KEYGEN,
554 ffi::EVP_PKEY_CTRL_CIPHER,
555 0,
556 cipher.as_ptr() as *mut _,
557 ))?;
558 }
559
560 Ok(())
561 }
562
563 /// Sets the key MAC key used during key generation.
564 #[cfg(not(boringssl))]
565 #[corresponds(EVP_PKEY_CTX_ctrl)]
566 #[inline]
567 pub fn set_keygen_mac_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
568 let len = c_int::try_from(key.len()).unwrap();
569
570 unsafe {
571 cvt(ffi::EVP_PKEY_CTX_ctrl(
572 self.as_ptr(),
573 -1,
574 ffi::EVP_PKEY_OP_KEYGEN,
575 ffi::EVP_PKEY_CTRL_SET_MAC_KEY,
576 len,
577 key.as_ptr() as *mut _,
578 ))?;
579 }
580
581 Ok(())
582 }
583
584 /// Sets the digest used for HKDF derivation.
585 ///
586 /// Requires OpenSSL 1.1.0 or newer.
587 #[corresponds(EVP_PKEY_CTX_set_hkdf_md)]
588 #[cfg(any(ossl110, boringssl, libressl360))]
589 #[inline]
590 pub fn set_hkdf_md(&mut self, digest: &MdRef) -> Result<(), ErrorStack> {
591 unsafe {
592 cvt(ffi::EVP_PKEY_CTX_set_hkdf_md(
593 self.as_ptr(),
594 digest.as_ptr(),
595 ))?;
596 }
597
598 Ok(())
599 }
600
601 /// Sets the HKDF mode of operation.
602 ///
603 /// Defaults to [`HkdfMode::EXTRACT_THEN_EXPAND`].
604 ///
605 /// WARNING: Although this API calls it a "mode", HKDF-Extract and HKDF-Expand are distinct
606 /// operations with distinct inputs and distinct kinds of keys. Callers should not pass input
607 /// secrets for one operation into the other.
608 ///
609 /// Requires OpenSSL 1.1.1 or newer.
610 #[corresponds(EVP_PKEY_CTX_set_hkdf_mode)]
611 #[cfg(any(ossl111, libressl360))]
612 #[inline]
613 pub fn set_hkdf_mode(&mut self, mode: HkdfMode) -> Result<(), ErrorStack> {
614 unsafe {
615 cvt(ffi::EVP_PKEY_CTX_set_hkdf_mode(self.as_ptr(), mode.0))?;
616 }
617
618 Ok(())
619 }
620
621 /// Sets the input material for HKDF generation as the "key".
622 ///
623 /// Which input is the key depends on the "mode" (see [`set_hkdf_mode`][Self::set_hkdf_mode]).
624 /// If [`HkdfMode::EXTRACT_THEN_EXPAND`] or [`HkdfMode::EXTRACT_ONLY`], this function specifies
625 /// the input keying material (IKM) for HKDF-Extract. If [`HkdfMode::EXPAND_ONLY`], it instead
626 /// specifies the pseudorandom key (PRK) for HKDF-Expand.
627 ///
628 /// Requires OpenSSL 1.1.0 or newer.
629 #[corresponds(EVP_PKEY_CTX_set1_hkdf_key)]
630 #[cfg(any(ossl110, boringssl, libressl360))]
631 #[inline]
632 pub fn set_hkdf_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
633 #[cfg(not(boringssl))]
634 let len = c_int::try_from(key.len()).unwrap();
635 #[cfg(boringssl)]
636 let len = key.len();
637
638 unsafe {
639 cvt(ffi::EVP_PKEY_CTX_set1_hkdf_key(
640 self.as_ptr(),
641 key.as_ptr(),
642 len,
643 ))?;
644 }
645
646 Ok(())
647 }
648
649 /// Sets the salt value for HKDF generation.
650 ///
651 /// If performing HKDF-Expand only, this parameter is ignored.
652 ///
653 /// Requires OpenSSL 1.1.0 or newer.
654 #[corresponds(EVP_PKEY_CTX_set1_hkdf_salt)]
655 #[cfg(any(ossl110, boringssl, libressl360))]
656 #[inline]
657 pub fn set_hkdf_salt(&mut self, salt: &[u8]) -> Result<(), ErrorStack> {
658 #[cfg(not(boringssl))]
659 let len = c_int::try_from(salt.len()).unwrap();
660 #[cfg(boringssl)]
661 let len = salt.len();
662
663 unsafe {
664 cvt(ffi::EVP_PKEY_CTX_set1_hkdf_salt(
665 self.as_ptr(),
666 salt.as_ptr(),
667 len,
668 ))?;
669 }
670
671 Ok(())
672 }
673
674 /// Appends info bytes for HKDF generation.
675 ///
676 /// If performing HKDF-Extract only, this parameter is ignored.
677 ///
678 /// Requires OpenSSL 1.1.0 or newer.
679 #[corresponds(EVP_PKEY_CTX_add1_hkdf_info)]
680 #[cfg(any(ossl110, boringssl, libressl360))]
681 #[inline]
682 pub fn add_hkdf_info(&mut self, info: &[u8]) -> Result<(), ErrorStack> {
683 #[cfg(not(boringssl))]
684 let len = c_int::try_from(info.len()).unwrap();
685 #[cfg(boringssl)]
686 let len = info.len();
687
688 unsafe {
689 cvt(ffi::EVP_PKEY_CTX_add1_hkdf_info(
690 self.as_ptr(),
691 info.as_ptr(),
692 len,
693 ))?;
694 }
695
696 Ok(())
697 }
698
699 /// Derives a shared secret between two keys.
700 ///
701 /// If `buf` is set to `None`, an upper bound on the number of bytes required for the buffer will be returned.
702 #[corresponds(EVP_PKEY_derive)]
703 pub fn derive(&mut self, buf: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
704 let mut len = buf.as_ref().map_or(0, |b| b.len());
705 unsafe {
706 cvt(ffi::EVP_PKEY_derive(
707 self.as_ptr(),
708 buf.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
709 &mut len,
710 ))?;
711 }
712
713 Ok(len)
714 }
715
716 /// Like [`Self::derive`] but appends the secret to a [`Vec`].
717 pub fn derive_to_vec(&mut self, buf: &mut Vec<u8>) -> Result<usize, ErrorStack> {
718 let base = buf.len();
719 let len = self.derive(None)?;
720 buf.resize(base + len, 0);
721 let len = self.derive(Some(&mut buf[base..]))?;
722 buf.truncate(base + len);
723 Ok(len)
724 }
725
726 /// Generates a new public/private keypair.
727 #[corresponds(EVP_PKEY_keygen)]
728 #[inline]
729 pub fn keygen(&mut self) -> Result<PKey<Private>, ErrorStack> {
730 unsafe {
731 let mut key = ptr::null_mut();
732 cvt(ffi::EVP_PKEY_keygen(self.as_ptr(), &mut key))?;
733 Ok(PKey::from_ptr(key))
734 }
735 }
736
737 /// Sets the nonce type for a private key context.
738 ///
739 /// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979).
740 ///
741 /// This is only useful for DSA and ECDSA.
742 /// Requires OpenSSL 3.2.0 or newer.
743 #[cfg(ossl320)]
744 #[corresponds(EVP_PKEY_CTX_set_params)]
745 pub fn set_nonce_type(&mut self, nonce_type: NonceType) -> Result<(), ErrorStack> {
746 let nonce_field_name = CStr::from_bytes_with_nul(b"nonce-type\0").unwrap();
747 let mut nonce_type = nonce_type.0;
748 unsafe {
749 let param_nonce =
750 ffi::OSSL_PARAM_construct_uint(nonce_field_name.as_ptr(), &mut nonce_type);
751 let param_end = ffi::OSSL_PARAM_construct_end();
752
753 let params = [param_nonce, param_end];
754 cvt(ffi::EVP_PKEY_CTX_set_params(self.as_ptr(), params.as_ptr()))?;
755 }
756 Ok(())
757 }
758
759 /// Gets the nonce type for a private key context.
760 ///
761 /// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979).
762 ///
763 /// This is only useful for DSA and ECDSA.
764 /// Requires OpenSSL 3.2.0 or newer.
765 #[cfg(ossl320)]
766 #[corresponds(EVP_PKEY_CTX_get_params)]
767 pub fn nonce_type(&mut self) -> Result<NonceType, ErrorStack> {
768 let nonce_field_name = CStr::from_bytes_with_nul(b"nonce-type\0").unwrap();
769 let mut nonce_type: c_uint = 0;
770 unsafe {
771 let param_nonce =
772 ffi::OSSL_PARAM_construct_uint(nonce_field_name.as_ptr(), &mut nonce_type);
773 let param_end = ffi::OSSL_PARAM_construct_end();
774
775 let mut params = [param_nonce, param_end];
776 cvt(ffi::EVP_PKEY_CTX_get_params(
777 self.as_ptr(),
778 params.as_mut_ptr(),
779 ))?;
780 }
781 Ok(NonceType(nonce_type))
782 }
783}
784
785#[cfg(test)]
786mod test {
787 use super::*;
788 #[cfg(not(boringssl))]
789 use crate::cipher::Cipher;
790 use crate::ec::{EcGroup, EcKey};
791 use crate::hash::{hash, MessageDigest};
792 use crate::md::Md;
793 use crate::nid::Nid;
794 use crate::pkey::PKey;
795 use crate::rsa::Rsa;
796 use crate::sign::Verifier;
797
798 #[test]
799 fn rsa() {
800 let key = include_bytes!("../test/rsa.pem");
801 let rsa = Rsa::private_key_from_pem(key).unwrap();
802 let pkey = PKey::from_rsa(rsa).unwrap();
803
804 let mut ctx = PkeyCtx::new(&pkey).unwrap();
805 ctx.encrypt_init().unwrap();
806 ctx.set_rsa_padding(Padding::PKCS1).unwrap();
807
808 let pt = "hello world".as_bytes();
809 let mut ct = vec![];
810 ctx.encrypt_to_vec(pt, &mut ct).unwrap();
811
812 ctx.decrypt_init().unwrap();
813 ctx.set_rsa_padding(Padding::PKCS1).unwrap();
814
815 let mut out = vec![];
816 ctx.decrypt_to_vec(&ct, &mut out).unwrap();
817
818 assert_eq!(pt, out);
819 }
820
821 #[test]
822 #[cfg(any(ossl102, libressl310, boringssl))]
823 fn rsa_oaep() {
824 let key = include_bytes!("../test/rsa.pem");
825 let rsa = Rsa::private_key_from_pem(key).unwrap();
826 let pkey = PKey::from_rsa(rsa).unwrap();
827
828 let mut ctx = PkeyCtx::new(&pkey).unwrap();
829 ctx.encrypt_init().unwrap();
830 ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
831 ctx.set_rsa_oaep_md(Md::sha256()).unwrap();
832 ctx.set_rsa_mgf1_md(Md::sha256()).unwrap();
833
834 let pt = "hello world".as_bytes();
835 let mut ct = vec![];
836 ctx.encrypt_to_vec(pt, &mut ct).unwrap();
837
838 ctx.decrypt_init().unwrap();
839 ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
840 ctx.set_rsa_oaep_md(Md::sha256()).unwrap();
841 ctx.set_rsa_mgf1_md(Md::sha256()).unwrap();
842
843 let mut out = vec![];
844 ctx.decrypt_to_vec(&ct, &mut out).unwrap();
845
846 assert_eq!(pt, out);
847 }
848
849 #[test]
850 fn rsa_sign() {
851 let key = include_bytes!("../test/rsa.pem");
852 let rsa = Rsa::private_key_from_pem(key).unwrap();
853 let pkey = PKey::from_rsa(rsa).unwrap();
854
855 let mut ctx = PkeyCtx::new(&pkey).unwrap();
856 ctx.sign_init().unwrap();
857 ctx.set_rsa_padding(Padding::PKCS1).unwrap();
858 ctx.set_signature_md(Md::sha384()).unwrap();
859
860 let msg = b"hello world";
861 let digest = hash(MessageDigest::sha384(), msg).unwrap();
862 let mut signature = vec![];
863 ctx.sign_to_vec(&digest, &mut signature).unwrap();
864
865 let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap();
866 verifier.update(msg).unwrap();
867 assert!(matches!(verifier.verify(&signature), Ok(true)));
868 }
869
870 #[test]
871 fn rsa_sign_pss() {
872 let key = include_bytes!("../test/rsa.pem");
873 let rsa = Rsa::private_key_from_pem(key).unwrap();
874 let pkey = PKey::from_rsa(rsa).unwrap();
875
876 let mut ctx = PkeyCtx::new(&pkey).unwrap();
877 ctx.sign_init().unwrap();
878 ctx.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
879 ctx.set_signature_md(Md::sha384()).unwrap();
880 ctx.set_rsa_pss_saltlen(RsaPssSaltlen::custom(14)).unwrap();
881
882 let msg = b"hello world";
883 let digest = hash(MessageDigest::sha384(), msg).unwrap();
884 let mut signature = vec![];
885 ctx.sign_to_vec(&digest, &mut signature).unwrap();
886
887 let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap();
888 verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
889 verifier
890 .set_rsa_pss_saltlen(RsaPssSaltlen::custom(14))
891 .unwrap();
892 verifier.update(msg).unwrap();
893 assert!(matches!(verifier.verify(&signature), Ok(true)));
894 }
895
896 #[test]
897 fn derive() {
898 let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
899 let key1 = EcKey::generate(&group).unwrap();
900 let key1 = PKey::from_ec_key(key1).unwrap();
901 let key2 = EcKey::generate(&group).unwrap();
902 let key2 = PKey::from_ec_key(key2).unwrap();
903
904 let mut ctx = PkeyCtx::new(&key1).unwrap();
905 ctx.derive_init().unwrap();
906 ctx.derive_set_peer(&key2).unwrap();
907
908 let mut buf = vec![];
909 ctx.derive_to_vec(&mut buf).unwrap();
910 }
911
912 #[test]
913 #[cfg(not(boringssl))]
914 fn cmac_keygen() {
915 let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap();
916 ctx.keygen_init().unwrap();
917 ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap();
918 ctx.set_keygen_mac_key(&hex::decode("9294727a3638bb1c13f48ef8158bfc9d").unwrap())
919 .unwrap();
920 ctx.keygen().unwrap();
921 }
922
923 #[test]
924 #[cfg(any(ossl110, boringssl, libressl360))]
925 fn hkdf() {
926 let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
927 ctx.derive_init().unwrap();
928 ctx.set_hkdf_md(Md::sha256()).unwrap();
929 ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap())
930 .unwrap();
931 ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap())
932 .unwrap();
933 ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap())
934 .unwrap();
935 let mut out = [0; 42];
936 ctx.derive(Some(&mut out)).unwrap();
937
938 assert_eq!(
939 &out[..],
940 hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865")
941 .unwrap()
942 );
943 }
944
945 #[test]
946 #[cfg(any(ossl111, libressl360))]
947 fn hkdf_expand() {
948 let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
949 ctx.derive_init().unwrap();
950 ctx.set_hkdf_mode(HkdfMode::EXPAND_ONLY).unwrap();
951 ctx.set_hkdf_md(Md::sha256()).unwrap();
952 ctx.set_hkdf_key(
953 &hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5")
954 .unwrap(),
955 )
956 .unwrap();
957 ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap())
958 .unwrap();
959 let mut out = [0; 42];
960 ctx.derive(Some(&mut out)).unwrap();
961
962 assert_eq!(
963 &out[..],
964 hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865")
965 .unwrap()
966 );
967 }
968
969 #[test]
970 #[cfg(any(ossl111, libressl360))]
971 fn hkdf_extract() {
972 let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
973 ctx.derive_init().unwrap();
974 ctx.set_hkdf_mode(HkdfMode::EXTRACT_ONLY).unwrap();
975 ctx.set_hkdf_md(Md::sha256()).unwrap();
976 ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap())
977 .unwrap();
978 ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap())
979 .unwrap();
980 let mut out = vec![];
981 ctx.derive_to_vec(&mut out).unwrap();
982
983 assert_eq!(
984 &out[..],
985 hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5")
986 .unwrap()
987 );
988 }
989
990 #[test]
991 fn verify_fail() {
992 let key1 = Rsa::generate(4096).unwrap();
993 let key1 = PKey::from_rsa(key1).unwrap();
994
995 let data = b"Some Crypto Text";
996
997 let mut ctx = PkeyCtx::new(&key1).unwrap();
998 ctx.sign_init().unwrap();
999 let mut signature = vec![];
1000 ctx.sign_to_vec(data, &mut signature).unwrap();
1001
1002 let bad_data = b"Some Crypto text";
1003
1004 ctx.verify_init().unwrap();
1005 let valid = ctx.verify(bad_data, &signature);
1006 assert!(matches!(valid, Ok(false) | Err(_)));
1007 assert!(ErrorStack::get().errors().is_empty());
1008 }
1009
1010 #[test]
1011 fn verify_fail_ec() {
1012 let key1 =
1013 EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap();
1014 let key1 = PKey::from_ec_key(key1).unwrap();
1015
1016 let data = b"Some Crypto Text";
1017 let mut ctx = PkeyCtx::new(&key1).unwrap();
1018 ctx.verify_init().unwrap();
1019 assert!(matches!(ctx.verify(data, &[0; 64]), Ok(false) | Err(_)));
1020 assert!(ErrorStack::get().errors().is_empty());
1021 }
1022
1023 #[test]
1024 fn test_verify_recover() {
1025 let key = Rsa::generate(2048).unwrap();
1026 let key = PKey::from_rsa(key).unwrap();
1027
1028 let digest = [
1029 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
1030 24, 25, 26, 27, 28, 29, 30, 31,
1031 ];
1032
1033 let mut ctx = PkeyCtx::new(&key).unwrap();
1034 ctx.sign_init().unwrap();
1035 ctx.set_rsa_padding(Padding::PKCS1).unwrap();
1036 ctx.set_signature_md(Md::sha256()).unwrap();
1037 let mut signature = vec![];
1038 ctx.sign_to_vec(&digest, &mut signature).unwrap();
1039
1040 // Attempt recovery of just the digest.
1041 let mut ctx = PkeyCtx::new(&key).unwrap();
1042 ctx.verify_recover_init().unwrap();
1043 ctx.set_rsa_padding(Padding::PKCS1).unwrap();
1044 ctx.set_signature_md(Md::sha256()).unwrap();
1045 let length = ctx.verify_recover(&signature, None).unwrap();
1046 let mut result_buf = vec![0; length];
1047 let length = ctx
1048 .verify_recover(&signature, Some(&mut result_buf))
1049 .unwrap();
1050 assert_eq!(length, digest.len());
1051 // result_buf contains the digest
1052 assert_eq!(result_buf[..length], digest);
1053
1054 // Attempt recovery of teh entire DigestInfo
1055 let mut ctx = PkeyCtx::new(&key).unwrap();
1056 ctx.verify_recover_init().unwrap();
1057 ctx.set_rsa_padding(Padding::PKCS1).unwrap();
1058 let length = ctx.verify_recover(&signature, None).unwrap();
1059 let mut result_buf = vec![0; length];
1060 let length = ctx
1061 .verify_recover(&signature, Some(&mut result_buf))
1062 .unwrap();
1063 // 32-bytes of SHA256 digest + the ASN.1 DigestInfo structure == 51 bytes
1064 assert_eq!(length, 51);
1065 // The digest is the end of the DigestInfo structure.
1066 assert_eq!(result_buf[length - digest.len()..length], digest);
1067 }
1068
1069 #[test]
1070 #[cfg(ossl320)]
1071 fn set_nonce_type() {
1072 let key1 =
1073 EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap();
1074 let key1 = PKey::from_ec_key(key1).unwrap();
1075
1076 let mut ctx = PkeyCtx::new(&key1).unwrap();
1077 ctx.sign_init().unwrap();
1078 ctx.set_nonce_type(NonceType::DETERMINISTIC_K).unwrap();
1079 let nonce_type = ctx.nonce_type().unwrap();
1080 assert_eq!(nonce_type, NonceType::DETERMINISTIC_K);
1081 assert!(ErrorStack::get().errors().is_empty());
1082 }
1083
1084 // Test vector from
1085 // https://github.com/openssl/openssl/blob/openssl-3.2.0/test/recipes/30-test_evp_data/evppkey_ecdsa_rfc6979.txt
1086 #[test]
1087 #[cfg(ossl320)]
1088 fn ecdsa_deterministic_signature() {
1089 let private_key_pem = "-----BEGIN PRIVATE KEY-----
1090MDkCAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQEEHzAdAgEBBBhvqwNJNOTA/Jrmf1tWWanX0f79GH7g
1091n9Q=
1092-----END PRIVATE KEY-----";
1093
1094 let key1 = EcKey::private_key_from_pem(private_key_pem.as_bytes()).unwrap();
1095 let key1 = PKey::from_ec_key(key1).unwrap();
1096 let input = "sample";
1097 let expected_output = hex::decode("303502190098C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF021857A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64").unwrap();
1098
1099 let hashed_input = hash(MessageDigest::sha1(), input.as_bytes()).unwrap();
1100 let mut ctx = PkeyCtx::new(&key1).unwrap();
1101 ctx.sign_init().unwrap();
1102 ctx.set_signature_md(Md::sha1()).unwrap();
1103 ctx.set_nonce_type(NonceType::DETERMINISTIC_K).unwrap();
1104
1105 let mut output = vec![];
1106 ctx.sign_to_vec(&hashed_input, &mut output).unwrap();
1107 assert_eq!(output, expected_output);
1108 assert!(ErrorStack::get().errors().is_empty());
1109 }
1110}
1111