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#"\ 26 Generate a CMAC key 27 28 ``` 29 use openssl::pkey_ctx::PkeyCtx; 30 use openssl::pkey::Id; 31 use openssl::cipher::Cipher; 32 33 let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap(); 34 ctx.keygen_init().unwrap(); 35 ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap(); 36 ctx.set_keygen_mac_key(b"0123456789abcdef").unwrap(); 37 let 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))] 68 use crate::cipher::CipherRef; 69 use crate::error::ErrorStack; 70 use crate::md::MdRef; 71 use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Private}; 72 use crate::rsa::Padding; 73 use crate::{cvt, cvt_n, cvt_p}; 74 use foreign_types::{ForeignType, ForeignTypeRef}; 75 #[cfg(not(boringssl))] 76 use libc::c_int; 77 use openssl_macros::corresponds; 78 use std::convert::TryFrom; 79 use std::ptr; 80 81 /// HKDF modes of operation. 82 #[cfg(ossl111)] 83 pub struct HkdfMode(c_int); 84 85 #[cfg(ossl111)] 86 impl HkdfMode { 87 pub const EXTRACT_THEN_EXPAND: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND); 88 pub const EXTRACT_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY); 89 pub const EXPAND_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXPAND_ONLY); 90 } 91 92 generic_foreign_type_and_impl_send_sync! { 93 type CType = ffi::EVP_PKEY_CTX; 94 fn drop = ffi::EVP_PKEY_CTX_free; 95 96 /// A context object which can perform asymmetric cryptography operations. 97 pub struct PkeyCtx<T>; 98 /// A reference to a [`PkeyCtx`]. 99 pub struct PkeyCtxRef<T>; 100 } 101 102 impl<T> PkeyCtx<T> { 103 /// Creates a new pkey context using the provided key. 104 #[corresponds(EVP_PKEY_CTX_new)] 105 #[inline] new(pkey: &PKeyRef<T>) -> Result<Self, ErrorStack>106 pub fn new(pkey: &PKeyRef<T>) -> Result<Self, ErrorStack> { 107 unsafe { 108 let ptr = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?; 109 Ok(PkeyCtx::from_ptr(ptr)) 110 } 111 } 112 } 113 114 impl PkeyCtx<()> { 115 /// Creates a new pkey context for the specified algorithm ID. 116 #[corresponds(EVP_PKEY_new_id)] 117 #[inline] new_id(id: Id) -> Result<Self, ErrorStack>118 pub fn new_id(id: Id) -> Result<Self, ErrorStack> { 119 unsafe { 120 let ptr = cvt_p(ffi::EVP_PKEY_CTX_new_id(id.as_raw(), ptr::null_mut()))?; 121 Ok(PkeyCtx::from_ptr(ptr)) 122 } 123 } 124 } 125 126 impl<T> PkeyCtxRef<T> 127 where 128 T: HasPublic, 129 { 130 /// Prepares the context for encryption using the public key. 131 #[corresponds(EVP_PKEY_encrypt_init)] 132 #[inline] encrypt_init(&mut self) -> Result<(), ErrorStack>133 pub fn encrypt_init(&mut self) -> Result<(), ErrorStack> { 134 unsafe { 135 cvt(ffi::EVP_PKEY_encrypt_init(self.as_ptr()))?; 136 } 137 138 Ok(()) 139 } 140 141 /// Prepares the context for signature verification using the public key. 142 #[corresponds(EVP_PKEY_verify_init)] 143 #[inline] verify_init(&mut self) -> Result<(), ErrorStack>144 pub fn verify_init(&mut self) -> Result<(), ErrorStack> { 145 unsafe { 146 cvt(ffi::EVP_PKEY_verify_init(self.as_ptr()))?; 147 } 148 149 Ok(()) 150 } 151 152 /// Encrypts data using the public key. 153 /// 154 /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be 155 /// returned. 156 #[corresponds(EVP_PKEY_encrypt)] 157 #[inline] encrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack>158 pub fn encrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack> { 159 let mut written = to.as_ref().map_or(0, |b| b.len()); 160 unsafe { 161 cvt(ffi::EVP_PKEY_encrypt( 162 self.as_ptr(), 163 to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), 164 &mut written, 165 from.as_ptr(), 166 from.len(), 167 ))?; 168 } 169 170 Ok(written) 171 } 172 173 /// Like [`Self::encrypt`] but appends ciphertext to a [`Vec`]. encrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack>174 pub fn encrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack> { 175 let base = out.len(); 176 let len = self.encrypt(from, None)?; 177 out.resize(base + len, 0); 178 let len = self.encrypt(from, Some(&mut out[base..]))?; 179 out.truncate(base + len); 180 Ok(len) 181 } 182 183 /// Verifies the signature of data using the public key. 184 /// 185 /// Returns `Ok(true)` if the signature is valid, `Ok(false)` if the signature is invalid, and `Err` if an error 186 /// occurred. 187 /// 188 /// # Note 189 /// 190 /// This verifies the signature of the *raw* data. It is more common to compute and verify the signature of the 191 /// cryptographic hash of an arbitrary amount of data. The [`MdCtx`](crate::md_ctx::MdCtx) type can be used to do 192 /// that. 193 #[corresponds(EVP_PKEY_verify)] 194 #[inline] verify(&mut self, data: &[u8], sig: &[u8]) -> Result<bool, ErrorStack>195 pub fn verify(&mut self, data: &[u8], sig: &[u8]) -> Result<bool, ErrorStack> { 196 unsafe { 197 let r = cvt_n(ffi::EVP_PKEY_verify( 198 self.as_ptr(), 199 sig.as_ptr(), 200 sig.len(), 201 data.as_ptr(), 202 data.len(), 203 ))?; 204 Ok(r == 1) 205 } 206 } 207 } 208 209 impl<T> PkeyCtxRef<T> 210 where 211 T: HasPrivate, 212 { 213 /// Prepares the context for decryption using the private key. 214 #[corresponds(EVP_PKEY_decrypt_init)] 215 #[inline] decrypt_init(&mut self) -> Result<(), ErrorStack>216 pub fn decrypt_init(&mut self) -> Result<(), ErrorStack> { 217 unsafe { 218 cvt(ffi::EVP_PKEY_decrypt_init(self.as_ptr()))?; 219 } 220 221 Ok(()) 222 } 223 224 /// Prepares the context for signing using the private key. 225 #[corresponds(EVP_PKEY_sign_init)] 226 #[inline] sign_init(&mut self) -> Result<(), ErrorStack>227 pub fn sign_init(&mut self) -> Result<(), ErrorStack> { 228 unsafe { 229 cvt(ffi::EVP_PKEY_sign_init(self.as_ptr()))?; 230 } 231 232 Ok(()) 233 } 234 235 /// Sets the peer key used for secret derivation. 236 #[corresponds(EVP_PKEY_derive_set_peer)] derive_set_peer<U>(&mut self, key: &PKeyRef<U>) -> Result<(), ErrorStack> where U: HasPublic,237 pub fn derive_set_peer<U>(&mut self, key: &PKeyRef<U>) -> Result<(), ErrorStack> 238 where 239 U: HasPublic, 240 { 241 unsafe { 242 cvt(ffi::EVP_PKEY_derive_set_peer(self.as_ptr(), key.as_ptr()))?; 243 } 244 245 Ok(()) 246 } 247 248 /// Decrypts data using the private key. 249 /// 250 /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be 251 /// returned. 252 #[corresponds(EVP_PKEY_decrypt)] 253 #[inline] decrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack>254 pub fn decrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result<usize, ErrorStack> { 255 let mut written = to.as_ref().map_or(0, |b| b.len()); 256 unsafe { 257 cvt(ffi::EVP_PKEY_decrypt( 258 self.as_ptr(), 259 to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), 260 &mut written, 261 from.as_ptr(), 262 from.len(), 263 ))?; 264 } 265 266 Ok(written) 267 } 268 269 /// Like [`Self::decrypt`] but appends plaintext to a [`Vec`]. decrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack>270 pub fn decrypt_to_vec(&mut self, from: &[u8], out: &mut Vec<u8>) -> Result<usize, ErrorStack> { 271 let base = out.len(); 272 let len = self.decrypt(from, None)?; 273 out.resize(base + len, 0); 274 let len = self.decrypt(from, Some(&mut out[base..]))?; 275 out.truncate(base + len); 276 Ok(len) 277 } 278 279 /// Signs the contents of `data`. 280 /// 281 /// If `sig` is set to `None`, an upper bound on the number of bytes required for the output buffer will be 282 /// returned. 283 /// 284 /// # Note 285 /// 286 /// This computes the signature of the *raw* bytes of `data`. It is more common to sign the cryptographic hash of 287 /// an arbitrary amount of data. The [`MdCtx`](crate::md_ctx::MdCtx) type can be used to do that. 288 #[corresponds(EVP_PKEY_sign)] 289 #[inline] sign(&mut self, data: &[u8], sig: Option<&mut [u8]>) -> Result<usize, ErrorStack>290 pub fn sign(&mut self, data: &[u8], sig: Option<&mut [u8]>) -> Result<usize, ErrorStack> { 291 let mut written = sig.as_ref().map_or(0, |b| b.len()); 292 unsafe { 293 cvt(ffi::EVP_PKEY_sign( 294 self.as_ptr(), 295 sig.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), 296 &mut written, 297 data.as_ptr(), 298 data.len(), 299 ))?; 300 } 301 302 Ok(written) 303 } 304 305 /// Like [`Self::sign`] but appends the signature to a [`Vec`]. sign_to_vec(&mut self, data: &[u8], sig: &mut Vec<u8>) -> Result<usize, ErrorStack>306 pub fn sign_to_vec(&mut self, data: &[u8], sig: &mut Vec<u8>) -> Result<usize, ErrorStack> { 307 let base = sig.len(); 308 let len = self.sign(data, None)?; 309 sig.resize(base + len, 0); 310 let len = self.sign(data, Some(&mut sig[base..]))?; 311 sig.truncate(base + len); 312 Ok(len) 313 } 314 } 315 316 impl<T> PkeyCtxRef<T> { 317 /// Prepares the context for shared secret derivation. 318 #[corresponds(EVP_PKEY_derive_init)] 319 #[inline] derive_init(&mut self) -> Result<(), ErrorStack>320 pub fn derive_init(&mut self) -> Result<(), ErrorStack> { 321 unsafe { 322 cvt(ffi::EVP_PKEY_derive_init(self.as_ptr()))?; 323 } 324 325 Ok(()) 326 } 327 328 /// Prepares the context for key generation. 329 #[corresponds(EVP_PKEY_keygen_init)] 330 #[inline] keygen_init(&mut self) -> Result<(), ErrorStack>331 pub fn keygen_init(&mut self) -> Result<(), ErrorStack> { 332 unsafe { 333 cvt(ffi::EVP_PKEY_keygen_init(self.as_ptr()))?; 334 } 335 336 Ok(()) 337 } 338 339 /// Returns the RSA padding mode in use. 340 /// 341 /// This is only useful for RSA keys. 342 #[corresponds(EVP_PKEY_CTX_get_rsa_padding)] 343 #[inline] rsa_padding(&self) -> Result<Padding, ErrorStack>344 pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> { 345 let mut pad = 0; 346 unsafe { 347 cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad))?; 348 } 349 350 Ok(Padding::from_raw(pad)) 351 } 352 353 /// Sets the RSA padding mode. 354 /// 355 /// This is only useful for RSA keys. 356 #[corresponds(EVP_PKEY_CTX_set_rsa_padding)] 357 #[inline] set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack>358 pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> { 359 unsafe { 360 cvt(ffi::EVP_PKEY_CTX_set_rsa_padding( 361 self.as_ptr(), 362 padding.as_raw(), 363 ))?; 364 } 365 366 Ok(()) 367 } 368 369 /// Sets the RSA MGF1 algorithm. 370 /// 371 /// This is only useful for RSA keys. 372 #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)] 373 #[inline] set_rsa_mgf1_md(&mut self, md: &MdRef) -> Result<(), ErrorStack>374 pub fn set_rsa_mgf1_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> { 375 unsafe { 376 cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( 377 self.as_ptr(), 378 md.as_ptr(), 379 ))?; 380 } 381 382 Ok(()) 383 } 384 385 /// Sets the RSA OAEP algorithm. 386 /// 387 /// This is only useful for RSA keys. 388 #[corresponds(EVP_PKEY_CTX_set_rsa_oaep_md)] 389 #[cfg(any(ossl102, libressl310))] 390 #[inline] set_rsa_oaep_md(&mut self, md: &MdRef) -> Result<(), ErrorStack>391 pub fn set_rsa_oaep_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> { 392 unsafe { 393 cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md( 394 self.as_ptr(), 395 md.as_ptr() as *mut _, 396 ))?; 397 } 398 399 Ok(()) 400 } 401 402 /// Sets the RSA OAEP label. 403 /// 404 /// This is only useful for RSA keys. 405 #[corresponds(EVP_PKEY_CTX_set0_rsa_oaep_label)] 406 #[cfg(any(ossl102, libressl310, boringssl))] set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack>407 pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> { 408 use crate::LenType; 409 let len = LenType::try_from(label.len()).unwrap(); 410 411 unsafe { 412 let p = ffi::OPENSSL_malloc(label.len() as _); 413 ptr::copy_nonoverlapping(label.as_ptr(), p as *mut _, label.len()); 414 415 let r = cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label( 416 self.as_ptr(), 417 p as *mut _, 418 len, 419 )); 420 if r.is_err() { 421 ffi::OPENSSL_free(p); 422 } 423 r?; 424 } 425 426 Ok(()) 427 } 428 429 /// Sets the cipher used during key generation. 430 #[cfg(not(boringssl))] 431 #[corresponds(EVP_PKEY_CTX_ctrl)] 432 #[inline] set_keygen_cipher(&mut self, cipher: &CipherRef) -> Result<(), ErrorStack>433 pub fn set_keygen_cipher(&mut self, cipher: &CipherRef) -> Result<(), ErrorStack> { 434 unsafe { 435 cvt(ffi::EVP_PKEY_CTX_ctrl( 436 self.as_ptr(), 437 -1, 438 ffi::EVP_PKEY_OP_KEYGEN, 439 ffi::EVP_PKEY_CTRL_CIPHER, 440 0, 441 cipher.as_ptr() as *mut _, 442 ))?; 443 } 444 445 Ok(()) 446 } 447 448 /// Sets the key MAC key used during key generation. 449 #[cfg(not(boringssl))] 450 #[corresponds(EVP_PKEY_CTX_ctrl)] 451 #[inline] set_keygen_mac_key(&mut self, key: &[u8]) -> Result<(), ErrorStack>452 pub fn set_keygen_mac_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> { 453 let len = c_int::try_from(key.len()).unwrap(); 454 455 unsafe { 456 cvt(ffi::EVP_PKEY_CTX_ctrl( 457 self.as_ptr(), 458 -1, 459 ffi::EVP_PKEY_OP_KEYGEN, 460 ffi::EVP_PKEY_CTRL_SET_MAC_KEY, 461 len, 462 key.as_ptr() as *mut _, 463 ))?; 464 } 465 466 Ok(()) 467 } 468 469 /// Sets the digest used for HKDF derivation. 470 /// 471 /// Requires OpenSSL 1.1.0 or newer. 472 #[corresponds(EVP_PKEY_CTX_set_hkdf_md)] 473 #[cfg(ossl110)] 474 #[inline] set_hkdf_md(&mut self, digest: &MdRef) -> Result<(), ErrorStack>475 pub fn set_hkdf_md(&mut self, digest: &MdRef) -> Result<(), ErrorStack> { 476 unsafe { 477 cvt(ffi::EVP_PKEY_CTX_set_hkdf_md( 478 self.as_ptr(), 479 digest.as_ptr(), 480 ))?; 481 } 482 483 Ok(()) 484 } 485 486 /// Sets the HKDF mode of operation. 487 /// 488 /// Defaults to [`HkdfMode::EXTRACT_THEN_EXPAND`]. 489 /// 490 /// Requires OpenSSL 1.1.1 or newer. 491 #[corresponds(EVP_PKEY_CTX_set_hkdf_mode)] 492 #[cfg(ossl111)] 493 #[inline] set_hkdf_mode(&mut self, mode: HkdfMode) -> Result<(), ErrorStack>494 pub fn set_hkdf_mode(&mut self, mode: HkdfMode) -> Result<(), ErrorStack> { 495 unsafe { 496 cvt(ffi::EVP_PKEY_CTX_set_hkdf_mode(self.as_ptr(), mode.0))?; 497 } 498 499 Ok(()) 500 } 501 502 /// Sets the input keying material for HKDF generation. 503 /// 504 /// Requires OpenSSL 1.1.0 or newer. 505 #[corresponds(EVP_PKEY_CTX_set1_hkdf_key)] 506 #[cfg(ossl110)] 507 #[inline] set_hkdf_key(&mut self, key: &[u8]) -> Result<(), ErrorStack>508 pub fn set_hkdf_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> { 509 let len = c_int::try_from(key.len()).unwrap(); 510 511 unsafe { 512 cvt(ffi::EVP_PKEY_CTX_set1_hkdf_key( 513 self.as_ptr(), 514 key.as_ptr(), 515 len, 516 ))?; 517 } 518 519 Ok(()) 520 } 521 522 /// Sets the salt value for HKDF generation. 523 /// 524 /// Requires OpenSSL 1.1.0 or newer. 525 #[corresponds(EVP_PKEY_CTX_set1_hkdf_salt)] 526 #[cfg(ossl110)] 527 #[inline] set_hkdf_salt(&mut self, salt: &[u8]) -> Result<(), ErrorStack>528 pub fn set_hkdf_salt(&mut self, salt: &[u8]) -> Result<(), ErrorStack> { 529 let len = c_int::try_from(salt.len()).unwrap(); 530 531 unsafe { 532 cvt(ffi::EVP_PKEY_CTX_set1_hkdf_salt( 533 self.as_ptr(), 534 salt.as_ptr(), 535 len, 536 ))?; 537 } 538 539 Ok(()) 540 } 541 542 /// Appends info bytes for HKDF generation. 543 /// 544 /// Requires OpenSSL 1.1.0 or newer. 545 #[corresponds(EVP_PKEY_CTX_add1_hkdf_info)] 546 #[cfg(ossl110)] 547 #[inline] add_hkdf_info(&mut self, info: &[u8]) -> Result<(), ErrorStack>548 pub fn add_hkdf_info(&mut self, info: &[u8]) -> Result<(), ErrorStack> { 549 let len = c_int::try_from(info.len()).unwrap(); 550 551 unsafe { 552 cvt(ffi::EVP_PKEY_CTX_add1_hkdf_info( 553 self.as_ptr(), 554 info.as_ptr(), 555 len, 556 ))?; 557 } 558 559 Ok(()) 560 } 561 562 /// Derives a shared secret between two keys. 563 /// 564 /// If `buf` is set to `None`, an upper bound on the number of bytes required for the buffer will be returned. 565 #[corresponds(EVP_PKEY_derive)] derive(&mut self, buf: Option<&mut [u8]>) -> Result<usize, ErrorStack>566 pub fn derive(&mut self, buf: Option<&mut [u8]>) -> Result<usize, ErrorStack> { 567 let mut len = buf.as_ref().map_or(0, |b| b.len()); 568 unsafe { 569 cvt(ffi::EVP_PKEY_derive( 570 self.as_ptr(), 571 buf.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), 572 &mut len, 573 ))?; 574 } 575 576 Ok(len) 577 } 578 579 /// Like [`Self::derive`] but appends the secret to a [`Vec`]. derive_to_vec(&mut self, buf: &mut Vec<u8>) -> Result<usize, ErrorStack>580 pub fn derive_to_vec(&mut self, buf: &mut Vec<u8>) -> Result<usize, ErrorStack> { 581 let base = buf.len(); 582 let len = self.derive(None)?; 583 buf.resize(base + len, 0); 584 let len = self.derive(Some(&mut buf[base..]))?; 585 buf.truncate(base + len); 586 Ok(len) 587 } 588 589 /// Generates a new public/private keypair. 590 #[corresponds(EVP_PKEY_keygen)] 591 #[inline] keygen(&mut self) -> Result<PKey<Private>, ErrorStack>592 pub fn keygen(&mut self) -> Result<PKey<Private>, ErrorStack> { 593 unsafe { 594 let mut key = ptr::null_mut(); 595 cvt(ffi::EVP_PKEY_keygen(self.as_ptr(), &mut key))?; 596 Ok(PKey::from_ptr(key)) 597 } 598 } 599 } 600 601 #[cfg(test)] 602 mod test { 603 use super::*; 604 #[cfg(not(boringssl))] 605 use crate::cipher::Cipher; 606 use crate::ec::{EcGroup, EcKey}; 607 #[cfg(any(ossl102, libressl310))] 608 use crate::md::Md; 609 use crate::nid::Nid; 610 use crate::pkey::PKey; 611 use crate::rsa::Rsa; 612 613 #[test] rsa()614 fn rsa() { 615 let key = include_bytes!("../test/rsa.pem"); 616 let rsa = Rsa::private_key_from_pem(key).unwrap(); 617 let pkey = PKey::from_rsa(rsa).unwrap(); 618 619 let mut ctx = PkeyCtx::new(&pkey).unwrap(); 620 ctx.encrypt_init().unwrap(); 621 ctx.set_rsa_padding(Padding::PKCS1).unwrap(); 622 623 let pt = "hello world".as_bytes(); 624 let mut ct = vec![]; 625 ctx.encrypt_to_vec(pt, &mut ct).unwrap(); 626 627 ctx.decrypt_init().unwrap(); 628 ctx.set_rsa_padding(Padding::PKCS1).unwrap(); 629 630 let mut out = vec![]; 631 ctx.decrypt_to_vec(&ct, &mut out).unwrap(); 632 633 assert_eq!(pt, out); 634 } 635 636 #[test] 637 #[cfg(any(ossl102, libressl310))] rsa_oaep()638 fn rsa_oaep() { 639 let key = include_bytes!("../test/rsa.pem"); 640 let rsa = Rsa::private_key_from_pem(key).unwrap(); 641 let pkey = PKey::from_rsa(rsa).unwrap(); 642 643 let mut ctx = PkeyCtx::new(&pkey).unwrap(); 644 ctx.encrypt_init().unwrap(); 645 ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap(); 646 ctx.set_rsa_oaep_md(Md::sha256()).unwrap(); 647 ctx.set_rsa_mgf1_md(Md::sha256()).unwrap(); 648 649 let pt = "hello world".as_bytes(); 650 let mut ct = vec![]; 651 ctx.encrypt_to_vec(pt, &mut ct).unwrap(); 652 653 ctx.decrypt_init().unwrap(); 654 ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap(); 655 ctx.set_rsa_oaep_md(Md::sha256()).unwrap(); 656 ctx.set_rsa_mgf1_md(Md::sha256()).unwrap(); 657 658 let mut out = vec![]; 659 ctx.decrypt_to_vec(&ct, &mut out).unwrap(); 660 661 assert_eq!(pt, out); 662 } 663 664 #[test] derive()665 fn derive() { 666 let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); 667 let key1 = EcKey::generate(&group).unwrap(); 668 let key1 = PKey::from_ec_key(key1).unwrap(); 669 let key2 = EcKey::generate(&group).unwrap(); 670 let key2 = PKey::from_ec_key(key2).unwrap(); 671 672 let mut ctx = PkeyCtx::new(&key1).unwrap(); 673 ctx.derive_init().unwrap(); 674 ctx.derive_set_peer(&key2).unwrap(); 675 676 let mut buf = vec![]; 677 ctx.derive_to_vec(&mut buf).unwrap(); 678 } 679 680 #[test] 681 #[cfg(not(boringssl))] cmac_keygen()682 fn cmac_keygen() { 683 let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap(); 684 ctx.keygen_init().unwrap(); 685 ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap(); 686 ctx.set_keygen_mac_key(&hex::decode("9294727a3638bb1c13f48ef8158bfc9d").unwrap()) 687 .unwrap(); 688 ctx.keygen().unwrap(); 689 } 690 691 #[test] 692 #[cfg(ossl110)] hkdf()693 fn hkdf() { 694 let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap(); 695 ctx.derive_init().unwrap(); 696 ctx.set_hkdf_md(Md::sha256()).unwrap(); 697 ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap()) 698 .unwrap(); 699 ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap()) 700 .unwrap(); 701 ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap()) 702 .unwrap(); 703 let mut out = [0; 42]; 704 ctx.derive(Some(&mut out)).unwrap(); 705 706 assert_eq!( 707 &out[..], 708 hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865") 709 .unwrap() 710 ); 711 } 712 713 #[test] 714 #[cfg(ossl111)] hkdf_expand()715 fn hkdf_expand() { 716 let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap(); 717 ctx.derive_init().unwrap(); 718 ctx.set_hkdf_mode(HkdfMode::EXPAND_ONLY).unwrap(); 719 ctx.set_hkdf_md(Md::sha256()).unwrap(); 720 ctx.set_hkdf_key( 721 &hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5") 722 .unwrap(), 723 ) 724 .unwrap(); 725 ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap()) 726 .unwrap(); 727 let mut out = [0; 42]; 728 ctx.derive(Some(&mut out)).unwrap(); 729 730 assert_eq!( 731 &out[..], 732 hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865") 733 .unwrap() 734 ); 735 } 736 737 #[test] 738 #[cfg(ossl111)] hkdf_extract()739 fn hkdf_extract() { 740 let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap(); 741 ctx.derive_init().unwrap(); 742 ctx.set_hkdf_mode(HkdfMode::EXTRACT_ONLY).unwrap(); 743 ctx.set_hkdf_md(Md::sha256()).unwrap(); 744 ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap()) 745 .unwrap(); 746 ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap()) 747 .unwrap(); 748 let mut out = vec![]; 749 ctx.derive_to_vec(&mut out).unwrap(); 750 751 assert_eq!( 752 &out[..], 753 hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5") 754 .unwrap() 755 ); 756 } 757 758 #[test] verify_fail()759 fn verify_fail() { 760 let key1 = Rsa::generate(4096).unwrap(); 761 let key1 = PKey::from_rsa(key1).unwrap(); 762 763 let data = b"Some Crypto Text"; 764 765 let mut ctx = PkeyCtx::new(&key1).unwrap(); 766 ctx.sign_init().unwrap(); 767 let mut signature = vec![]; 768 ctx.sign_to_vec(data, &mut signature).unwrap(); 769 770 let bad_data = b"Some Crypto text"; 771 772 ctx.verify_init().unwrap(); 773 let valid = ctx.verify(bad_data, &signature).unwrap(); 774 assert!(!valid); 775 } 776 } 777