1#![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
41use crate::bn::BigNumRef;
68#[cfg(not(any(boringssl, awslc)))]
69use crate::cipher::CipherRef;
70use crate::error::ErrorStack;
71use crate::md::MdRef;
72use crate::nid::Nid;
73use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Params, Private};
74use crate::rsa::Padding;
75use crate::sign::RsaPssSaltlen;
76use crate::{cvt, cvt_p};
77use cfg_if::cfg_if;
78use foreign_types::{ForeignType, ForeignTypeRef};
79#[cfg(not(any(boringssl, awslc)))]
80use libc::c_int;
81#[cfg(ossl320)]
82use libc::c_uint;
83use openssl_macros::corresponds;
84use std::convert::TryFrom;
85#[cfg(ossl320)]
86use std::ffi::CStr;
87use std::ptr;
88
89#[cfg(any(ossl111, libressl360))]
91pub struct HkdfMode(c_int);
92
93#[cfg(any(ossl111, libressl360))]
94impl HkdfMode {
95 pub const EXTRACT_THEN_EXPAND: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND);
100
101 pub const EXTRACT_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY);
106
107 pub const EXPAND_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXPAND_ONLY);
113}
114
115#[cfg(ossl320)]
117#[derive(Debug, PartialEq)]
118pub struct NonceType(c_uint);
119
120#[cfg(ossl320)]
121impl NonceType {
122 pub const RANDOM_K: Self = NonceType(0);
125
126 pub const DETERMINISTIC_K: Self = NonceType(1);
128}
129
130generic_foreign_type_and_impl_send_sync! {
131 type CType = ffi::EVP_PKEY_CTX;
132 fn drop = ffi::EVP_PKEY_CTX_free;
133
134 pub struct PkeyCtx<T>;
136 pub struct PkeyCtxRef<T>;
138}
139
140impl<T> PkeyCtx<T> {
141 #[corresponds(EVP_PKEY_CTX_new)]
143 #[inline]
144 pub fn new(pkey: &PKeyRef<T>) -> Result<Self, ErrorStack> {
145 unsafe {
146 let ptr = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?;
147 Ok(PkeyCtx::from_ptr(ptr))
148 }
149 }
150}
151
152impl PkeyCtx<()> {
153 #[corresponds(EVP_PKEY_CTX_new_id)]
155 #[inline]
156 pub fn new_id(id: Id) -> Result<Self, ErrorStack> {
157 unsafe {
158 let ptr = cvt_p(ffi::EVP_PKEY_CTX_new_id(id.as_raw(), ptr::null_mut()))?;
159 Ok(PkeyCtx::from_ptr(ptr))
160 }
161 }
162}
163
164impl<T> PkeyCtxRef<T>
165where
166 T: HasPublic,
167{
168 #[corresponds(EVP_PKEY_encrypt_init)]
170 #[inline]
171 pub fn encrypt_init(&mut self) -> Result<(), ErrorStack> {
172 unsafe {
173 cvt(ffi::EVP_PKEY_encrypt_init(self.as_ptr()))?;
174 }
175
176 Ok(())
177 }
178
179 #[corresponds(EVP_PKEY_verify_init)]
181 #[inline]
182 pub fn verify_init(&mut self) -> Result<(), ErrorStack> {
183 unsafe {
184 cvt(ffi::EVP_PKEY_verify_init(self.as_ptr()))?;
185 }
186
187 Ok(())
188 }
189
190 #[corresponds(EVP_PKEY_verify_recover_init)]
192 #[inline]
193 pub fn verify_recover_init(&mut self) -> Result<(), ErrorStack> {
194 unsafe {
195 cvt(ffi::EVP_PKEY_verify_recover_init(self.as_ptr()))?;
196 }
197
198 Ok(())
199 }
200
201 #[corresponds(EVP_PKEY_encrypt)]
206 #[inline]
207 pub fn encrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
208 let mut written = to.as_ref().map_or(0, |b| b.len());
209 unsafe {
210 cvt(ffi::EVP_PKEY_encrypt(
211 self.as_ptr(),
212 to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
213 &mut written,
214 from.as_ptr(),
215 from.len(),
216 ))?;
217 }
218
219 Ok(written)
220 }
221
222 pub fn encrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack> {
224 let base = out.len();
225 let len = self.encrypt(from, None)?;
226 out.resize(base + len, 0);
227 let len = self.encrypt(from, Some(&mut out[base..]))?;
228 out.truncate(base + len);
229 Ok(len)
230 }
231
232 #[corresponds(EVP_PKEY_verify)]
243 #[inline]
244 pub fn verify(&mut self, data: &[u8], sig: &[u8]) -> Result<bool, ErrorStack> {
245 unsafe {
246 let r = ffi::EVP_PKEY_verify(
247 self.as_ptr(),
248 sig.as_ptr(),
249 sig.len(),
250 data.as_ptr(),
251 data.len(),
252 );
253 if r <= 0 {
259 let errors = ErrorStack::get();
260 if !errors.errors().is_empty() {
261 return Err(errors);
262 }
263 }
264
265 Ok(r == 1)
266 }
267 }
268
269 #[corresponds(EVP_PKEY_verify_recover)]
275 #[inline]
276 pub fn verify_recover(
277 &mut self,
278 sig: &[u8],
279 to: Option<&mut [u8]>,
280 ) -> Result<usize, ErrorStack> {
281 let mut written = to.as_ref().map_or(0, |b| b.len());
282 unsafe {
283 cvt(ffi::EVP_PKEY_verify_recover(
284 self.as_ptr(),
285 to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
286 &mut written,
287 sig.as_ptr(),
288 sig.len(),
289 ))?;
290 }
291
292 Ok(written)
293 }
294}
295
296impl<T> PkeyCtxRef<T>
297where
298 T: HasPrivate,
299{
300 #[corresponds(EVP_PKEY_decrypt_init)]
302 #[inline]
303 pub fn decrypt_init(&mut self) -> Result<(), ErrorStack> {
304 unsafe {
305 cvt(ffi::EVP_PKEY_decrypt_init(self.as_ptr()))?;
306 }
307
308 Ok(())
309 }
310
311 #[corresponds(EVP_PKEY_sign_init)]
313 #[inline]
314 pub fn sign_init(&mut self) -> Result<(), ErrorStack> {
315 unsafe {
316 cvt(ffi::EVP_PKEY_sign_init(self.as_ptr()))?;
317 }
318
319 Ok(())
320 }
321
322 #[corresponds(EVP_PKEY_derive_set_peer)]
324 pub fn derive_set_peer<U>(&mut self, key: &PKeyRef<U>) -> Result<(), ErrorStack>
325 where
326 U: HasPublic,
327 {
328 unsafe {
329 cvt(ffi::EVP_PKEY_derive_set_peer(self.as_ptr(), key.as_ptr()))?;
330 }
331
332 Ok(())
333 }
334
335 #[corresponds(EVP_PKEY_decrypt)]
340 #[inline]
341 pub fn decrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
342 let mut written = to.as_ref().map_or(0, |b| b.len());
343 unsafe {
344 cvt(ffi::EVP_PKEY_decrypt(
345 self.as_ptr(),
346 to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
347 &mut written,
348 from.as_ptr(),
349 from.len(),
350 ))?;
351 }
352
353 Ok(written)
354 }
355
356 pub fn decrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack> {
358 let base = out.len();
359 let len = self.decrypt(from, None)?;
360 out.resize(base + len, 0);
361 let len = self.decrypt(from, Some(&mut out[base..]))?;
362 out.truncate(base + len);
363 Ok(len)
364 }
365
366 #[corresponds(EVP_PKEY_sign)]
376 #[inline]
377 pub fn sign(&mut self, data: &[u8], sig: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
378 let mut written = sig.as_ref().map_or(0, |b| b.len());
379 unsafe {
380 cvt(ffi::EVP_PKEY_sign(
381 self.as_ptr(),
382 sig.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
383 &mut written,
384 data.as_ptr(),
385 data.len(),
386 ))?;
387 }
388
389 Ok(written)
390 }
391
392 pub fn sign_to_vec(&mut self, data: &[u8], sig: &mut Vec<u8>) -> Result<usize, ErrorStack> {
394 let base = sig.len();
395 let len = self.sign(data, None)?;
396 sig.resize(base + len, 0);
397 let len = self.sign(data, Some(&mut sig[base..]))?;
398 sig.truncate(base + len);
399 Ok(len)
400 }
401}
402
403impl<T> PkeyCtxRef<T> {
404 #[corresponds(EVP_PKEY_derive_init)]
406 #[inline]
407 pub fn derive_init(&mut self) -> Result<(), ErrorStack> {
408 unsafe {
409 cvt(ffi::EVP_PKEY_derive_init(self.as_ptr()))?;
410 }
411
412 Ok(())
413 }
414
415 #[corresponds(EVP_PKEY_keygen_init)]
417 #[inline]
418 pub fn keygen_init(&mut self) -> Result<(), ErrorStack> {
419 unsafe {
420 cvt(ffi::EVP_PKEY_keygen_init(self.as_ptr()))?;
421 }
422
423 Ok(())
424 }
425
426 #[corresponds(EVP_PKEY_paramgen_init)]
428 #[inline]
429 pub fn paramgen_init(&mut self) -> Result<(), ErrorStack> {
430 unsafe {
431 cvt(ffi::EVP_PKEY_paramgen_init(self.as_ptr()))?;
432 }
433
434 Ok(())
435 }
436
437 #[corresponds(EVP_PKEY_CTX_set_signature_md)]
442 #[inline]
443 pub fn set_signature_md(&self, md: &MdRef) -> Result<(), ErrorStack> {
444 unsafe {
445 cvt(ffi::EVP_PKEY_CTX_set_signature_md(
446 self.as_ptr(),
447 md.as_ptr(),
448 ))?;
449 }
450 Ok(())
451 }
452
453 #[corresponds(EVP_PKEY_CTX_set_dh_paramgen_prime_len)]
457 #[cfg(not(boringssl))]
458 #[inline]
459 pub fn set_dh_paramgen_prime_len(&mut self, bits: u32) -> Result<(), ErrorStack> {
460 unsafe {
461 cvt(ffi::EVP_PKEY_CTX_set_dh_paramgen_prime_len(
462 self.as_ptr(),
463 bits as i32,
464 ))?;
465 }
466
467 Ok(())
468 }
469
470 #[corresponds(EVP_PKEY_CTX_set_dh_paramgen_generator)]
474 #[cfg(not(boringssl))]
475 #[inline]
476 pub fn set_dh_paramgen_generator(&mut self, bits: u32) -> Result<(), ErrorStack> {
477 unsafe {
478 cvt(ffi::EVP_PKEY_CTX_set_dh_paramgen_generator(
479 self.as_ptr(),
480 bits as i32,
481 ))?;
482 }
483
484 Ok(())
485 }
486
487 #[corresponds(EVP_PKEY_CTX_set_dsa_paramgen_bits)]
491 #[inline]
492 pub fn set_dsa_paramgen_bits(&mut self, bits: u32) -> Result<(), ErrorStack> {
493 unsafe {
494 cvt(ffi::EVP_PKEY_CTX_set_dsa_paramgen_bits(
495 self.as_ptr(),
496 bits as i32,
497 ))?;
498 }
499
500 Ok(())
501 }
502
503 #[corresponds(EVP_PKEY_CTX_set_ec_paramgen_curve_nid)]
507 #[inline]
508 pub fn set_ec_paramgen_curve_nid(&mut self, nid: Nid) -> Result<(), ErrorStack> {
509 unsafe {
510 cvt(ffi::EVP_PKEY_CTX_set_ec_paramgen_curve_nid(
511 self.as_ptr(),
512 nid.as_raw(),
513 ))?;
514 }
515
516 Ok(())
517 }
518
519 #[corresponds(EVP_PKEY_CTX_get_rsa_padding)]
523 #[inline]
524 pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
525 let mut pad = 0;
526 unsafe {
527 cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad))?;
528 }
529
530 Ok(Padding::from_raw(pad))
531 }
532
533 #[corresponds(EVP_PKEY_CTX_set_rsa_padding)]
537 #[inline]
538 pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
539 unsafe {
540 cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
541 self.as_ptr(),
542 padding.as_raw(),
543 ))?;
544 }
545
546 Ok(())
547 }
548
549 #[corresponds(EVP_PKEY_CTX_set_rsa_keygen_bits)]
553 #[inline]
554 pub fn set_rsa_keygen_bits(&mut self, bits: u32) -> Result<(), ErrorStack> {
555 unsafe {
556 cvt(ffi::EVP_PKEY_CTX_set_rsa_keygen_bits(
557 self.as_ptr(),
558 bits as i32,
559 ))?;
560 }
561
562 Ok(())
563 }
564
565 #[corresponds(EVP_PKEY_CTX_set1_rsa_keygen_pubexp)]
569 #[inline]
570 pub fn set_rsa_keygen_pubexp(&mut self, pubexp: &BigNumRef) -> Result<(), ErrorStack> {
571 unsafe {
572 cfg_if! {
573 if #[cfg(ossl300)] {
574 cvt(ffi::EVP_PKEY_CTX_set1_rsa_keygen_pubexp(
575 self.as_ptr(),
576 pubexp.as_ptr(),
577 ))?;
578 } else {
579 cvt(ffi::EVP_PKEY_CTX_set_rsa_keygen_pubexp(
580 self.as_ptr(),
581 cvt_p(ffi::BN_dup(pubexp.as_ptr()))?,
583 ))?;
584 }
585 }
586 }
587
588 Ok(())
589 }
590
591 #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)]
595 #[inline]
596 pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
597 unsafe {
598 cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
599 self.as_ptr(),
600 len.as_raw(),
601 ))
602 .map(|_| ())
603 }
604 }
605
606 #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)]
610 #[inline]
611 pub fn set_rsa_mgf1_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> {
612 unsafe {
613 cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
614 self.as_ptr(),
615 md.as_ptr(),
616 ))?;
617 }
618
619 Ok(())
620 }
621
622 #[corresponds(EVP_PKEY_CTX_set_rsa_oaep_md)]
626 #[inline]
627 pub fn set_rsa_oaep_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> {
628 unsafe {
629 cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
630 self.as_ptr(),
631 md.as_ptr() as *mut _,
632 ))?;
633 }
634
635 Ok(())
636 }
637
638 #[corresponds(EVP_PKEY_CTX_set0_rsa_oaep_label)]
642 pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
643 use crate::LenType;
644 let len = LenType::try_from(label.len()).unwrap();
645
646 unsafe {
647 let p = cvt_p(ffi::OPENSSL_malloc(label.len() as _))?;
648 ptr::copy_nonoverlapping(label.as_ptr(), p as *mut _, label.len());
649
650 let r = cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
651 self.as_ptr(),
652 p as *mut _,
653 len,
654 ));
655 if r.is_err() {
656 ffi::OPENSSL_free(p);
657 }
658 r?;
659 }
660
661 Ok(())
662 }
663
664 #[cfg(not(any(boringssl, awslc)))]
666 #[corresponds(EVP_PKEY_CTX_ctrl)]
667 #[inline]
668 pub fn set_keygen_cipher(&mut self, cipher: &CipherRef) -> Result<(), ErrorStack> {
669 unsafe {
670 cvt(ffi::EVP_PKEY_CTX_ctrl(
671 self.as_ptr(),
672 -1,
673 ffi::EVP_PKEY_OP_KEYGEN,
674 ffi::EVP_PKEY_CTRL_CIPHER,
675 0,
676 cipher.as_ptr() as *mut _,
677 ))?;
678 }
679
680 Ok(())
681 }
682
683 #[cfg(not(any(boringssl, awslc)))]
685 #[corresponds(EVP_PKEY_CTX_ctrl)]
686 #[inline]
687 pub fn set_keygen_mac_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
688 let len = c_int::try_from(key.len()).unwrap();
689
690 unsafe {
691 cvt(ffi::EVP_PKEY_CTX_ctrl(
692 self.as_ptr(),
693 -1,
694 ffi::EVP_PKEY_OP_KEYGEN,
695 ffi::EVP_PKEY_CTRL_SET_MAC_KEY,
696 len,
697 key.as_ptr() as *mut _,
698 ))?;
699 }
700
701 Ok(())
702 }
703
704 #[corresponds(EVP_PKEY_CTX_set_hkdf_md)]
708 #[cfg(any(ossl110, boringssl, libressl360, awslc))]
709 #[inline]
710 pub fn set_hkdf_md(&mut self, digest: &MdRef) -> Result<(), ErrorStack> {
711 unsafe {
712 cvt(ffi::EVP_PKEY_CTX_set_hkdf_md(
713 self.as_ptr(),
714 digest.as_ptr(),
715 ))?;
716 }
717
718 Ok(())
719 }
720
721 #[corresponds(EVP_PKEY_CTX_set_hkdf_mode)]
731 #[cfg(any(ossl111, libressl360))]
732 #[inline]
733 pub fn set_hkdf_mode(&mut self, mode: HkdfMode) -> Result<(), ErrorStack> {
734 unsafe {
735 cvt(ffi::EVP_PKEY_CTX_set_hkdf_mode(self.as_ptr(), mode.0))?;
736 }
737
738 Ok(())
739 }
740
741 #[corresponds(EVP_PKEY_CTX_set1_hkdf_key)]
750 #[cfg(any(ossl110, boringssl, libressl360, awslc))]
751 #[inline]
752 pub fn set_hkdf_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
753 #[cfg(not(any(boringssl, awslc)))]
754 let len = c_int::try_from(key.len()).unwrap();
755 #[cfg(any(boringssl, awslc))]
756 let len = key.len();
757
758 unsafe {
759 cvt(ffi::EVP_PKEY_CTX_set1_hkdf_key(
760 self.as_ptr(),
761 key.as_ptr(),
762 len,
763 ))?;
764 }
765
766 Ok(())
767 }
768
769 #[corresponds(EVP_PKEY_CTX_set1_hkdf_salt)]
775 #[cfg(any(ossl110, boringssl, libressl360, awslc))]
776 #[inline]
777 pub fn set_hkdf_salt(&mut self, salt: &[u8]) -> Result<(), ErrorStack> {
778 #[cfg(not(any(boringssl, awslc)))]
779 let len = c_int::try_from(salt.len()).unwrap();
780 #[cfg(any(boringssl, awslc))]
781 let len = salt.len();
782
783 unsafe {
784 cvt(ffi::EVP_PKEY_CTX_set1_hkdf_salt(
785 self.as_ptr(),
786 salt.as_ptr(),
787 len,
788 ))?;
789 }
790
791 Ok(())
792 }
793
794 #[corresponds(EVP_PKEY_CTX_add1_hkdf_info)]
800 #[cfg(any(ossl110, boringssl, libressl360, awslc))]
801 #[inline]
802 pub fn add_hkdf_info(&mut self, info: &[u8]) -> Result<(), ErrorStack> {
803 #[cfg(not(any(boringssl, awslc)))]
804 let len = c_int::try_from(info.len()).unwrap();
805 #[cfg(any(boringssl, awslc))]
806 let len = info.len();
807
808 unsafe {
809 cvt(ffi::EVP_PKEY_CTX_add1_hkdf_info(
810 self.as_ptr(),
811 info.as_ptr(),
812 len,
813 ))?;
814 }
815
816 Ok(())
817 }
818
819 #[corresponds(EVP_PKEY_derive)]
823 #[allow(unused_mut)]
824 pub fn derive(&mut self, mut buf: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
825 #[cfg(any(all(ossl110, not(ossl300)), libressl))]
850 {
851 if let Some(b) = buf.as_deref_mut() {
852 let mut required = 0;
853 let probe_ok = unsafe {
854 ffi::EVP_PKEY_derive(self.as_ptr(), ptr::null_mut(), &mut required) == 1
855 };
856 if !probe_ok {
857 let _ = ErrorStack::get();
858 } else if required != usize::MAX && b.len() < required {
859 let mut temp = vec![0u8; required];
860 let mut len = required;
861 unsafe {
862 cvt(ffi::EVP_PKEY_derive(
863 self.as_ptr(),
864 temp.as_mut_ptr(),
865 &mut len,
866 ))?;
867 }
868 let copy_len = b.len().min(len);
869 b[..copy_len].copy_from_slice(&temp[..copy_len]);
870 return Ok(copy_len);
871 }
872 }
873 }
874 let mut len = buf.as_ref().map_or(0, |b| b.len());
875 unsafe {
876 cvt(ffi::EVP_PKEY_derive(
877 self.as_ptr(),
878 buf.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
879 &mut len,
880 ))?;
881 }
882
883 Ok(len)
884 }
885
886 pub fn derive_to_vec(&mut self, buf: &mut Vec<u8>) -> Result<usize, ErrorStack> {
888 let base = buf.len();
889 let len = self.derive(None)?;
890 buf.resize(base + len, 0);
891 let len = self.derive(Some(&mut buf[base..]))?;
892 buf.truncate(base + len);
893 Ok(len)
894 }
895
896 #[corresponds(EVP_PKEY_keygen)]
898 #[inline]
899 pub fn keygen(&mut self) -> Result<PKey<Private>, ErrorStack> {
900 unsafe {
901 let mut key = ptr::null_mut();
902 cvt(ffi::EVP_PKEY_keygen(self.as_ptr(), &mut key))?;
903 Ok(PKey::from_ptr(key))
904 }
905 }
906
907 #[corresponds(EVP_PKEY_paramgen)]
909 #[inline]
910 pub fn paramgen(&mut self) -> Result<PKey<Params>, ErrorStack> {
911 unsafe {
912 let mut key = ptr::null_mut();
913 cvt(ffi::EVP_PKEY_paramgen(self.as_ptr(), &mut key))?;
914 Ok(PKey::from_ptr(key))
915 }
916 }
917
918 #[cfg(ossl320)]
925 #[corresponds(EVP_PKEY_CTX_set_params)]
926 pub fn set_nonce_type(&mut self, nonce_type: NonceType) -> Result<(), ErrorStack> {
927 let nonce_field_name = CStr::from_bytes_with_nul(b"nonce-type\0").unwrap();
928 let mut nonce_type = nonce_type.0;
929 unsafe {
930 let param_nonce =
931 ffi::OSSL_PARAM_construct_uint(nonce_field_name.as_ptr(), &mut nonce_type);
932 let param_end = ffi::OSSL_PARAM_construct_end();
933
934 let params = [param_nonce, param_end];
935 cvt(ffi::EVP_PKEY_CTX_set_params(self.as_ptr(), params.as_ptr()))?;
936 }
937 Ok(())
938 }
939
940 #[cfg(ossl320)]
947 #[corresponds(EVP_PKEY_CTX_get_params)]
948 pub fn nonce_type(&mut self) -> Result<NonceType, ErrorStack> {
949 let nonce_field_name = CStr::from_bytes_with_nul(b"nonce-type\0").unwrap();
950 let mut nonce_type: c_uint = 0;
951 unsafe {
952 let param_nonce =
953 ffi::OSSL_PARAM_construct_uint(nonce_field_name.as_ptr(), &mut nonce_type);
954 let param_end = ffi::OSSL_PARAM_construct_end();
955
956 let mut params = [param_nonce, param_end];
957 cvt(ffi::EVP_PKEY_CTX_get_params(
958 self.as_ptr(),
959 params.as_mut_ptr(),
960 ))?;
961 }
962 Ok(NonceType(nonce_type))
963 }
964}
965
966#[cfg(test)]
967mod test {
968 use super::*;
969 use crate::bn::BigNum;
970 #[cfg(not(any(boringssl, awslc)))]
971 use crate::cipher::Cipher;
972 use crate::ec::{EcGroup, EcKey};
973 use crate::hash::{hash, MessageDigest};
974 use crate::md::Md;
975 use crate::nid::Nid;
976 use crate::pkey::PKey;
977 use crate::rsa::Rsa;
978 use crate::sign::Verifier;
979 #[cfg(not(boringssl))]
980 use cfg_if::cfg_if;
981
982 #[test]
983 fn rsa() {
984 let key = include_bytes!("../test/rsa.pem");
985 let rsa = Rsa::private_key_from_pem(key).unwrap();
986 let pkey = PKey::from_rsa(rsa).unwrap();
987
988 let mut ctx = PkeyCtx::new(&pkey).unwrap();
989 ctx.encrypt_init().unwrap();
990 ctx.set_rsa_padding(Padding::PKCS1).unwrap();
991
992 let pt = "hello world".as_bytes();
993 let mut ct = vec![];
994 ctx.encrypt_to_vec(pt, &mut ct).unwrap();
995
996 ctx.decrypt_init().unwrap();
997 ctx.set_rsa_padding(Padding::PKCS1).unwrap();
998
999 let mut out = vec![];
1000 ctx.decrypt_to_vec(&ct, &mut out).unwrap();
1001
1002 assert_eq!(pt, out);
1003 }
1004
1005 #[test]
1006 fn rsa_oaep() {
1007 let key = include_bytes!("../test/rsa.pem");
1008 let rsa = Rsa::private_key_from_pem(key).unwrap();
1009 let pkey = PKey::from_rsa(rsa).unwrap();
1010
1011 let mut ctx = PkeyCtx::new(&pkey).unwrap();
1012 ctx.encrypt_init().unwrap();
1013 ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
1014 ctx.set_rsa_oaep_md(Md::sha256()).unwrap();
1015 ctx.set_rsa_mgf1_md(Md::sha256()).unwrap();
1016
1017 let pt = "hello world".as_bytes();
1018 let mut ct = vec![];
1019 ctx.encrypt_to_vec(pt, &mut ct).unwrap();
1020
1021 ctx.decrypt_init().unwrap();
1022 ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
1023 ctx.set_rsa_oaep_md(Md::sha256()).unwrap();
1024 ctx.set_rsa_mgf1_md(Md::sha256()).unwrap();
1025
1026 let mut out = vec![];
1027 ctx.decrypt_to_vec(&ct, &mut out).unwrap();
1028
1029 assert_eq!(pt, out);
1030 }
1031
1032 #[test]
1033 fn rsa_sign() {
1034 let key = include_bytes!("../test/rsa.pem");
1035 let rsa = Rsa::private_key_from_pem(key).unwrap();
1036 let pkey = PKey::from_rsa(rsa).unwrap();
1037
1038 let mut ctx = PkeyCtx::new(&pkey).unwrap();
1039 ctx.sign_init().unwrap();
1040 ctx.set_rsa_padding(Padding::PKCS1).unwrap();
1041 ctx.set_signature_md(Md::sha384()).unwrap();
1042
1043 let msg = b"hello world";
1044 let digest = hash(MessageDigest::sha384(), msg).unwrap();
1045 let mut signature = vec![];
1046 ctx.sign_to_vec(&digest, &mut signature).unwrap();
1047
1048 let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap();
1049 verifier.update(msg).unwrap();
1050 assert!(matches!(verifier.verify(&signature), Ok(true)));
1051 }
1052
1053 #[test]
1054 fn rsa_sign_pss() {
1055 let key = include_bytes!("../test/rsa.pem");
1056 let rsa = Rsa::private_key_from_pem(key).unwrap();
1057 let pkey = PKey::from_rsa(rsa).unwrap();
1058
1059 let mut ctx = PkeyCtx::new(&pkey).unwrap();
1060 ctx.sign_init().unwrap();
1061 ctx.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
1062 ctx.set_signature_md(Md::sha384()).unwrap();
1063 ctx.set_rsa_pss_saltlen(RsaPssSaltlen::custom(14)).unwrap();
1064
1065 let msg = b"hello world";
1066 let digest = hash(MessageDigest::sha384(), msg).unwrap();
1067 let mut signature = vec![];
1068 ctx.sign_to_vec(&digest, &mut signature).unwrap();
1069
1070 let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap();
1071 verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
1072 verifier
1073 .set_rsa_pss_saltlen(RsaPssSaltlen::custom(14))
1074 .unwrap();
1075 verifier.update(msg).unwrap();
1076 assert!(matches!(verifier.verify(&signature), Ok(true)));
1077 }
1078
1079 #[test]
1080 fn derive() {
1081 let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
1082 let key1 = EcKey::generate(&group).unwrap();
1083 let key1 = PKey::from_ec_key(key1).unwrap();
1084 let key2 = EcKey::generate(&group).unwrap();
1085 let key2 = PKey::from_ec_key(key2).unwrap();
1086
1087 let mut ctx = PkeyCtx::new(&key1).unwrap();
1088 ctx.derive_init().unwrap();
1089 ctx.derive_set_peer(&key2).unwrap();
1090
1091 let mut buf = vec![];
1092 ctx.derive_to_vec(&mut buf).unwrap();
1093 }
1094
1095 #[test]
1096 #[cfg(any(ossl111, libressl370))]
1097 fn derive_undersized_buffer() {
1098 let key1 = PKey::generate_x25519().unwrap();
1104 let key2 = PKey::generate_x25519().unwrap();
1105
1106 let mut ctx = PkeyCtx::new(&key1).unwrap();
1107 ctx.derive_init().unwrap();
1108 ctx.derive_set_peer(&key2).unwrap();
1109
1110 let mut buf = [0u8; 4];
1111 let result = ctx.derive(Some(&mut buf));
1112 #[cfg(any(all(ossl110, not(ossl300)), libressl))]
1113 assert_eq!(result.unwrap(), 4);
1114 #[cfg(all(ossl300, not(libressl)))]
1115 assert!(result.is_err());
1116 }
1117
1118 #[test]
1119 #[cfg(not(any(boringssl, awslc)))]
1120 fn cmac_keygen() {
1121 let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap();
1122 ctx.keygen_init().unwrap();
1123 ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap();
1124 ctx.set_keygen_mac_key(&hex::decode("9294727a3638bb1c13f48ef8158bfc9d").unwrap())
1125 .unwrap();
1126 ctx.keygen().unwrap();
1127 }
1128
1129 #[test]
1130 #[cfg(not(boringssl))]
1131 fn dh_paramgen() {
1132 let mut ctx = PkeyCtx::new_id(Id::DH).unwrap();
1133 ctx.paramgen_init().unwrap();
1134 ctx.set_dh_paramgen_prime_len(512).unwrap();
1135 ctx.set_dh_paramgen_generator(2).unwrap();
1136 let params = ctx.paramgen().unwrap();
1137
1138 assert_eq!(params.size(), 64);
1139 }
1140
1141 #[test]
1142 #[cfg(not(boringssl))]
1143 fn dsa_paramgen() {
1144 let mut ctx = PkeyCtx::new_id(Id::DSA).unwrap();
1145 ctx.paramgen_init().unwrap();
1146 ctx.set_dsa_paramgen_bits(2048).unwrap();
1147 let params = ctx.paramgen().unwrap();
1148
1149 let size = {
1150 cfg_if! {
1151 if #[cfg(awslc)] {
1152 72
1153 } else if #[cfg(libressl)] {
1154 48
1155 } else {
1156 64
1157 }
1158 }
1159 };
1160 assert_eq!(params.size(), size);
1161 }
1162
1163 #[test]
1164 fn ec_keygen() {
1165 let mut ctx = PkeyCtx::new_id(Id::EC).unwrap();
1166 ctx.paramgen_init().unwrap();
1167 ctx.set_ec_paramgen_curve_nid(Nid::X9_62_PRIME256V1)
1168 .unwrap();
1169 let params = ctx.paramgen().unwrap();
1170
1171 assert_eq!(params.size(), 72);
1172 }
1173
1174 #[test]
1175 fn rsa_keygen() {
1176 let pubexp = BigNum::from_u32(65537).unwrap();
1177 let mut ctx = PkeyCtx::new_id(Id::RSA).unwrap();
1178 ctx.keygen_init().unwrap();
1179 ctx.set_rsa_keygen_pubexp(&pubexp).unwrap();
1180 ctx.set_rsa_keygen_bits(2048).unwrap();
1181 let key = ctx.keygen().unwrap();
1182
1183 assert_eq!(key.bits(), 2048);
1184 }
1185
1186 #[test]
1187 #[cfg(any(ossl110, boringssl, libressl360, awslc))]
1188 fn hkdf() {
1189 let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
1190 ctx.derive_init().unwrap();
1191 ctx.set_hkdf_md(Md::sha256()).unwrap();
1192 ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap())
1193 .unwrap();
1194 ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap())
1195 .unwrap();
1196 ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap())
1197 .unwrap();
1198 let mut out = [0; 42];
1199 ctx.derive(Some(&mut out)).unwrap();
1200
1201 assert_eq!(
1202 &out[..],
1203 hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865")
1204 .unwrap()
1205 );
1206 }
1207
1208 #[test]
1209 #[cfg(any(ossl111, libressl360))]
1210 fn hkdf_expand() {
1211 let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
1212 ctx.derive_init().unwrap();
1213 ctx.set_hkdf_mode(HkdfMode::EXPAND_ONLY).unwrap();
1214 ctx.set_hkdf_md(Md::sha256()).unwrap();
1215 ctx.set_hkdf_key(
1216 &hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5")
1217 .unwrap(),
1218 )
1219 .unwrap();
1220 ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap())
1221 .unwrap();
1222 let mut out = [0; 42];
1223 ctx.derive(Some(&mut out)).unwrap();
1224
1225 assert_eq!(
1226 &out[..],
1227 hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865")
1228 .unwrap()
1229 );
1230 }
1231
1232 #[test]
1233 #[cfg(any(ossl111, libressl360))]
1234 fn hkdf_extract() {
1235 let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
1236 ctx.derive_init().unwrap();
1237 ctx.set_hkdf_mode(HkdfMode::EXTRACT_ONLY).unwrap();
1238 ctx.set_hkdf_md(Md::sha256()).unwrap();
1239 ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap())
1240 .unwrap();
1241 ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap())
1242 .unwrap();
1243 let mut out = vec![];
1244 ctx.derive_to_vec(&mut out).unwrap();
1245
1246 assert_eq!(
1247 &out[..],
1248 hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5")
1249 .unwrap()
1250 );
1251 }
1252
1253 #[test]
1254 fn verify_fail() {
1255 let key1 = Rsa::generate(4096).unwrap();
1256 let key1 = PKey::from_rsa(key1).unwrap();
1257
1258 let data = b"Some Crypto Text";
1259
1260 let mut ctx = PkeyCtx::new(&key1).unwrap();
1261 ctx.sign_init().unwrap();
1262 let mut signature = vec![];
1263 ctx.sign_to_vec(data, &mut signature).unwrap();
1264
1265 let bad_data = b"Some Crypto text";
1266
1267 ctx.verify_init().unwrap();
1268 let valid = ctx.verify(bad_data, &signature);
1269 assert!(matches!(valid, Ok(false) | Err(_)));
1270 assert!(ErrorStack::get().errors().is_empty());
1271 }
1272
1273 #[test]
1274 fn verify_fail_ec() {
1275 let key1 =
1276 EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap();
1277 let key1 = PKey::from_ec_key(key1).unwrap();
1278
1279 let data = b"Some Crypto Text";
1280 let mut ctx = PkeyCtx::new(&key1).unwrap();
1281 ctx.verify_init().unwrap();
1282 assert!(matches!(ctx.verify(data, &[0; 64]), Ok(false) | Err(_)));
1283 assert!(ErrorStack::get().errors().is_empty());
1284 }
1285
1286 #[test]
1287 fn test_verify_recover() {
1288 let key = Rsa::generate(2048).unwrap();
1289 let key = PKey::from_rsa(key).unwrap();
1290
1291 let digest = [
1292 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
1293 24, 25, 26, 27, 28, 29, 30, 31,
1294 ];
1295
1296 let mut ctx = PkeyCtx::new(&key).unwrap();
1297 ctx.sign_init().unwrap();
1298 ctx.set_rsa_padding(Padding::PKCS1).unwrap();
1299 ctx.set_signature_md(Md::sha256()).unwrap();
1300 let mut signature = vec![];
1301 ctx.sign_to_vec(&digest, &mut signature).unwrap();
1302
1303 let mut ctx = PkeyCtx::new(&key).unwrap();
1305 ctx.verify_recover_init().unwrap();
1306 ctx.set_rsa_padding(Padding::PKCS1).unwrap();
1307 ctx.set_signature_md(Md::sha256()).unwrap();
1308 let length = ctx.verify_recover(&signature, None).unwrap();
1309 let mut result_buf = vec![0; length];
1310 let length = ctx
1311 .verify_recover(&signature, Some(&mut result_buf))
1312 .unwrap();
1313 assert_eq!(length, digest.len());
1314 assert_eq!(result_buf[..length], digest);
1316
1317 let mut ctx = PkeyCtx::new(&key).unwrap();
1319 ctx.verify_recover_init().unwrap();
1320 ctx.set_rsa_padding(Padding::PKCS1).unwrap();
1321 let length = ctx.verify_recover(&signature, None).unwrap();
1322 let mut result_buf = vec![0; length];
1323 let length = ctx
1324 .verify_recover(&signature, Some(&mut result_buf))
1325 .unwrap();
1326 assert_eq!(length, 51);
1328 assert_eq!(result_buf[length - digest.len()..length], digest);
1330 }
1331
1332 #[test]
1333 #[cfg(ossl320)]
1334 fn set_nonce_type() {
1335 let key1 =
1336 EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap();
1337 let key1 = PKey::from_ec_key(key1).unwrap();
1338
1339 let mut ctx = PkeyCtx::new(&key1).unwrap();
1340 ctx.sign_init().unwrap();
1341 ctx.set_nonce_type(NonceType::DETERMINISTIC_K).unwrap();
1342 let nonce_type = ctx.nonce_type().unwrap();
1343 assert_eq!(nonce_type, NonceType::DETERMINISTIC_K);
1344 assert!(ErrorStack::get().errors().is_empty());
1345 }
1346
1347 #[test]
1350 #[cfg(ossl320)]
1351 fn ecdsa_deterministic_signature() {
1352 let private_key_pem = "-----BEGIN PRIVATE KEY-----
1353MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCDJr6nYRbp1FmtcIVdnsdaTTlDD2zbo
1354mxJ7imIrEg9nIQ==
1355-----END PRIVATE KEY-----";
1356
1357 let key1 = EcKey::private_key_from_pem(private_key_pem.as_bytes()).unwrap();
1358 let key1 = PKey::from_ec_key(key1).unwrap();
1359 let input = "sample";
1360 let expected_output = hex::decode("3046022100EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716022100F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8").unwrap();
1361
1362 let hashed_input = hash(MessageDigest::sha256(), input.as_bytes()).unwrap();
1363 let mut ctx = PkeyCtx::new(&key1).unwrap();
1364 ctx.sign_init().unwrap();
1365 ctx.set_signature_md(Md::sha256()).unwrap();
1366 ctx.set_nonce_type(NonceType::DETERMINISTIC_K).unwrap();
1367
1368 let mut output = vec![];
1369 ctx.sign_to_vec(&hashed_input, &mut output).unwrap();
1370 assert_eq!(output, expected_output);
1371 assert!(ErrorStack::get().errors().is_empty());
1372 }
1373}