diff options
| author | Flakebi <[email protected]> | 2018-01-14 23:41:11 +0100 |
|---|---|---|
| committer | Flakebi <[email protected]> | 2018-03-19 21:02:46 +0100 |
| commit | 0860115156bdcb88c2da932114a43fafb71d47fb (patch) | |
| tree | ad39036116e33224232f1a64f93b25146ed1c904 /openssl/src/pkey.rs | |
| parent | Merge pull request #874 from rohit-lshift/priv-key-from-num (diff) | |
| download | rust-openssl-0860115156bdcb88c2da932114a43fafb71d47fb.tar.xz rust-openssl-0860115156bdcb88c2da932114a43fafb71d47fb.zip | |
Make it possible to use cmac
This adds Signer::new_without_digest to create Signers which don't have
a digest (like cmac, which is based on aes).
As openssl supports cmac since version 1.1.0, the functions are behind
the ossl110 feature.
This allows building CMAC/OMAC1 and the EAX AEAD on top of this library.
Diffstat (limited to 'openssl/src/pkey.rs')
| -rw-r--r-- | openssl/src/pkey.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index 66ff33d6..322e6416 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -365,6 +365,68 @@ impl PKey<Private> { } } + /// Creates a new `PKey` containing a CMAC key. + /// + /// CMAC is only supported since the version 1.1.0 of OpenSSL. + /// + /// # Note + /// + /// To compute CMAC values, use the `sign` module. + #[cfg(any(all(ossl110, feature = "v110"), all(ossl111, feature = "v111")))] + pub fn cmac(cipher: &::symm::Cipher, key: &[u8]) -> Result<PKey<Private>, ErrorStack> { + unsafe { + assert!(key.len() <= c_int::max_value() as usize); + let kctx = cvt_p(ffi::EVP_PKEY_CTX_new_id( + ffi::EVP_PKEY_CMAC, + ptr::null_mut(), + ))?; + + let ret = (|| { + cvt(ffi::EVP_PKEY_keygen_init(kctx))?; + + // Set cipher for cmac + cvt(ffi::EVP_PKEY_CTX_ctrl( + kctx, + -1, + ffi::EVP_PKEY_OP_KEYGEN, + ffi::EVP_PKEY_CTRL_CIPHER, + 0, + cipher.as_ptr() as *mut _, + ))?; + + // Set the key data + cvt(ffi::EVP_PKEY_CTX_ctrl( + kctx, + -1, + ffi::EVP_PKEY_OP_KEYGEN, + ffi::EVP_PKEY_CTRL_SET_MAC_KEY, + key.len() as c_int, + key.as_ptr() as *mut _, + ))?; + Ok(()) + })(); + + if let Err(e) = ret { + // Free memory + ffi::EVP_PKEY_CTX_free(kctx); + return Err(e); + } + + // Generate key + let mut key = ptr::null_mut(); + let ret = cvt(ffi::EVP_PKEY_keygen(kctx, &mut key)); + + // Free memory + ffi::EVP_PKEY_CTX_free(kctx); + + if let Err(e) = ret { + return Err(e); + } + + Ok(PKey::from_ptr(key)) + } + } + private_key_from_pem! { /// Deserializes a private key from a PEM-encoded key type specific format. /// |