Loading openssl-sys/src/lib.rs +9 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,7 @@ pub const PEM_R_NO_START_LINE: c_int = 108; pub const EVP_MAX_MD_SIZE: c_uint = 64; pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption; pub const EVP_PKEY_HMAC: c_int = NID_hmac; pub const EVP_PKEY_CMAC: c_int = NID_cmac; pub const EVP_PKEY_DSA: c_int = NID_dsa; pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement; pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey; Loading @@ -233,6 +234,10 @@ pub const EVP_PKEY_CTRL_RSA_PSS_SALTLEN: c_int = EVP_PKEY_ALG_CTRL + 2; pub const EVP_PKEY_CTRL_RSA_MGF1_MD: c_int = EVP_PKEY_ALG_CTRL + 5; pub const EVP_PKEY_CTRL_GET_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 6; pub const EVP_PKEY_CTRL_SET_MAC_KEY: c_int = 6; pub const EVP_PKEY_CTRL_CIPHER: c_int = 12; pub const EVP_PKEY_OP_KEYGEN: c_int = 1 << 2; pub const EVP_PKEY_OP_SIGN: c_int = 1 << 3; pub const EVP_PKEY_OP_VERIFY: c_int = 1 << 4; pub const EVP_PKEY_OP_VERIFYRECOVER: c_int = 1 << 5; Loading Loading @@ -2093,6 +2098,7 @@ extern "C" { ) -> *mut EVP_PKEY; pub fn EVP_PKEY_CTX_new(k: *mut EVP_PKEY, e: *mut ENGINE) -> *mut EVP_PKEY_CTX; pub fn EVP_PKEY_CTX_new_id(id: c_int, e: *mut ENGINE) -> *mut EVP_PKEY_CTX; pub fn EVP_PKEY_CTX_free(ctx: *mut EVP_PKEY_CTX); pub fn EVP_PKEY_CTX_ctrl( ctx: *mut EVP_PKEY_CTX, Loading @@ -2103,6 +2109,9 @@ extern "C" { p2: *mut c_void, ) -> c_int; pub fn EVP_PKEY_keygen_init(ctx: *mut EVP_PKEY_CTX) -> c_int; pub fn EVP_PKEY_keygen(ctx: *mut EVP_PKEY_CTX, key: *mut *mut EVP_PKEY) -> c_int; pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *mut HMAC_CTX) -> c_int; pub fn OBJ_obj2nid(o: *const ASN1_OBJECT) -> c_int; Loading openssl/src/pkey.rs +62 −0 Original line number Diff line number Diff line Loading @@ -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. /// Loading openssl/src/sign.rs +36 −1 Original line number Diff line number Diff line Loading @@ -127,6 +127,26 @@ impl<'a> Signer<'a> { /// /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack> where T: HasPrivate, { Self::new_intern(Some(type_), pkey) } /// Creates a new `Signer` without a digest. /// /// This can be used to create a CMAC. /// OpenSSL documentation at [`EVP_DigestSignInit`]. /// /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack> where T: HasPrivate, { Self::new_intern(None, pkey) } pub fn new_intern<T>(type_: Option<MessageDigest>, pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack> where T: HasPrivate, { Loading @@ -138,7 +158,7 @@ impl<'a> Signer<'a> { let r = ffi::EVP_DigestSignInit( ctx, &mut pctx, type_.as_ptr(), type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()), ptr::null_mut(), pkey.as_ptr(), ); Loading Loading @@ -638,6 +658,21 @@ mod test { test_hmac(MessageDigest::sha1(), &tests); } #[cfg(ossl110)] #[test] fn test_cmac() { let cipher = ::symm::Cipher::aes_128_cbc(); let key = Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap(); let pkey = PKey::cmac(&cipher, &key).unwrap(); let mut signer = Signer::new_without_digest(&pkey).unwrap(); let data = b"Hi There"; signer.update(data as &[u8]).unwrap(); let expected = vec![136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19]; assert_eq!(signer.sign_to_vec().unwrap(), expected); } #[test] fn ec() { let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); Loading Loading
openssl-sys/src/lib.rs +9 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,7 @@ pub const PEM_R_NO_START_LINE: c_int = 108; pub const EVP_MAX_MD_SIZE: c_uint = 64; pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption; pub const EVP_PKEY_HMAC: c_int = NID_hmac; pub const EVP_PKEY_CMAC: c_int = NID_cmac; pub const EVP_PKEY_DSA: c_int = NID_dsa; pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement; pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey; Loading @@ -233,6 +234,10 @@ pub const EVP_PKEY_CTRL_RSA_PSS_SALTLEN: c_int = EVP_PKEY_ALG_CTRL + 2; pub const EVP_PKEY_CTRL_RSA_MGF1_MD: c_int = EVP_PKEY_ALG_CTRL + 5; pub const EVP_PKEY_CTRL_GET_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 6; pub const EVP_PKEY_CTRL_SET_MAC_KEY: c_int = 6; pub const EVP_PKEY_CTRL_CIPHER: c_int = 12; pub const EVP_PKEY_OP_KEYGEN: c_int = 1 << 2; pub const EVP_PKEY_OP_SIGN: c_int = 1 << 3; pub const EVP_PKEY_OP_VERIFY: c_int = 1 << 4; pub const EVP_PKEY_OP_VERIFYRECOVER: c_int = 1 << 5; Loading Loading @@ -2093,6 +2098,7 @@ extern "C" { ) -> *mut EVP_PKEY; pub fn EVP_PKEY_CTX_new(k: *mut EVP_PKEY, e: *mut ENGINE) -> *mut EVP_PKEY_CTX; pub fn EVP_PKEY_CTX_new_id(id: c_int, e: *mut ENGINE) -> *mut EVP_PKEY_CTX; pub fn EVP_PKEY_CTX_free(ctx: *mut EVP_PKEY_CTX); pub fn EVP_PKEY_CTX_ctrl( ctx: *mut EVP_PKEY_CTX, Loading @@ -2103,6 +2109,9 @@ extern "C" { p2: *mut c_void, ) -> c_int; pub fn EVP_PKEY_keygen_init(ctx: *mut EVP_PKEY_CTX) -> c_int; pub fn EVP_PKEY_keygen(ctx: *mut EVP_PKEY_CTX, key: *mut *mut EVP_PKEY) -> c_int; pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *mut HMAC_CTX) -> c_int; pub fn OBJ_obj2nid(o: *const ASN1_OBJECT) -> c_int; Loading
openssl/src/pkey.rs +62 −0 Original line number Diff line number Diff line Loading @@ -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. /// Loading
openssl/src/sign.rs +36 −1 Original line number Diff line number Diff line Loading @@ -127,6 +127,26 @@ impl<'a> Signer<'a> { /// /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack> where T: HasPrivate, { Self::new_intern(Some(type_), pkey) } /// Creates a new `Signer` without a digest. /// /// This can be used to create a CMAC. /// OpenSSL documentation at [`EVP_DigestSignInit`]. /// /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack> where T: HasPrivate, { Self::new_intern(None, pkey) } pub fn new_intern<T>(type_: Option<MessageDigest>, pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack> where T: HasPrivate, { Loading @@ -138,7 +158,7 @@ impl<'a> Signer<'a> { let r = ffi::EVP_DigestSignInit( ctx, &mut pctx, type_.as_ptr(), type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()), ptr::null_mut(), pkey.as_ptr(), ); Loading Loading @@ -638,6 +658,21 @@ mod test { test_hmac(MessageDigest::sha1(), &tests); } #[cfg(ossl110)] #[test] fn test_cmac() { let cipher = ::symm::Cipher::aes_128_cbc(); let key = Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap(); let pkey = PKey::cmac(&cipher, &key).unwrap(); let mut signer = Signer::new_without_digest(&pkey).unwrap(); let data = b"Hi There"; signer.update(data as &[u8]).unwrap(); let expected = vec![136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19]; assert_eq!(signer.sign_to_vec().unwrap(), expected); } #[test] fn ec() { let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); Loading