From 0860115156bdcb88c2da932114a43fafb71d47fb Mon Sep 17 00:00:00 2001 From: Flakebi Date: Sun, 14 Jan 2018 23:41:11 +0100 Subject: 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. --- openssl/src/sign.rs | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'openssl/src/sign.rs') diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs index 6a49cb49..9270d222 100644 --- a/openssl/src/sign.rs +++ b/openssl/src/sign.rs @@ -127,6 +127,26 @@ impl<'a> Signer<'a> { /// /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html pub fn new(type_: MessageDigest, pkey: &'a PKeyRef) -> Result, 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(pkey: &'a PKeyRef) -> Result, ErrorStack> + where + T: HasPrivate, + { + Self::new_intern(None, pkey) + } + + pub fn new_intern(type_: Option, pkey: &'a PKeyRef) -> Result, ErrorStack> where T: HasPrivate, { @@ -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(), ); @@ -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(); -- cgit v1.2.3