From bac600ba2e75f2f480def969654d964e80d90f48 Mon Sep 17 00:00:00 2001 From: mamoniot Date: Sat, 25 Feb 2023 20:27:16 -0500 Subject: [PATCH] added a port of aes_gmac_siv --- openssl-zt/src/aes_gmac_siv.rs | 174 +++++++++++++++++++++------------ 1 file changed, 111 insertions(+), 63 deletions(-) diff --git a/openssl-zt/src/aes_gmac_siv.rs b/openssl-zt/src/aes_gmac_siv.rs index dc4dbd384..b1b182235 100644 --- a/openssl-zt/src/aes_gmac_siv.rs +++ b/openssl-zt/src/aes_gmac_siv.rs @@ -1,3 +1,10 @@ +use std::ptr; + +use foreign_types::ForeignType; + +use crate::cipher_ctx::CipherCtx; + +pub const ZEROES: [u8; 64] = [0_u8; 64]; /// AES-GMAC-SIV encryptor/decryptor. pub struct AesGmacSiv { @@ -5,8 +12,8 @@ pub struct AesGmacSiv { tmp: [u8; 16], k0: Vec, k1: Vec, - ctr: Option, - gmac: Option, + ctr: Option, + gmac: Option, } impl AesGmacSiv { @@ -41,15 +48,18 @@ impl AesGmacSiv { pub fn encrypt_init(&mut self, iv: &[u8]) { self.tag[0..8].copy_from_slice(iv); self.tag[8..12].fill(0); - let _ = self.gmac.replace( - Crypter::new( - aes_gcm_by_key_size(self.k0.len()), - Mode::Encrypt, - self.k0.as_slice(), - Some(&self.tag[0..12]), - ) - .unwrap(), - ); + + let mut ctx = CipherCtx::new().unwrap(); + unsafe { + let t = match self.k0.len() { + 16 => ffi::EVP_aes_128_gcm(), + 24 => ffi::EVP_aes_192_gcm(), + 32 => ffi::EVP_aes_256_gcm(), + _ => panic!("Aes KEY_SIZE must be 16, 24 or 32") + }; + ctx.cipher_init::(t, self.k0.as_mut_ptr(), self.tag[0..12].as_ptr()).unwrap(); + } + let _ = self.gmac.replace(ctx); } /// Set additional authenticated data (data to be authenticated but not encrypted). @@ -57,11 +67,13 @@ impl AesGmacSiv { #[inline(always)] pub fn encrypt_set_aad(&mut self, data: &[u8]) { let gmac = self.gmac.as_mut().unwrap(); - let _ = gmac.aad_update(data); - let mut pad = data.len() & 0xf; - if pad != 0 { - pad = 16 - pad; - let _ = gmac.aad_update(&crate::ZEROES[0..pad]); + unsafe { + gmac.update::(data, ptr::null_mut()).unwrap(); + let mut pad = data.len() & 0xf; + if pad != 0 { + pad = 16 - pad; + gmac.update::(&ZEROES[0..pad], ptr::null_mut()).unwrap(); + } } } @@ -69,15 +81,20 @@ impl AesGmacSiv { /// This may be called more than once. #[inline(always)] pub fn encrypt_first_pass(&mut self, plaintext: &[u8]) { - let _ = self.gmac.as_mut().unwrap().aad_update(plaintext); + unsafe { + self.gmac.as_mut().unwrap().update::(plaintext, ptr::null_mut()).unwrap(); + } } /// Finish first pass and begin second pass. #[inline(always)] pub fn encrypt_first_pass_finish(&mut self) { let gmac = self.gmac.as_mut().unwrap(); - let _ = gmac.finalize(&mut self.tmp); - let _ = gmac.get_tag(&mut self.tmp); + unsafe { + gmac.finalize::(self.tmp.as_mut_ptr()).unwrap(); + gmac.tag(&mut self.tmp).unwrap(); + } + self.tag[8] = self.tmp[0] ^ self.tmp[8]; self.tag[9] = self.tmp[1] ^ self.tmp[9]; self.tag[10] = self.tmp[2] ^ self.tmp[10]; @@ -88,41 +105,54 @@ impl AesGmacSiv { self.tag[15] = self.tmp[7] ^ self.tmp[15]; let mut tag_tmp = [0_u8; 32]; - let mut ecb = Crypter::new(aes_ecb_by_key_size(self.k1.len()), Mode::Encrypt, self.k1.as_slice(), None).unwrap(); - ecb.pad(false); - if ecb.update(&self.tag, &mut tag_tmp).unwrap() != 16 { - assert_eq!(ecb.finalize(&mut tag_tmp).unwrap(), 16); + + let mut ctx = CipherCtx::new().unwrap(); + unsafe { + let t = match self.k1.len() { + 16 => ffi::EVP_aes_128_ecb(), + 24 => ffi::EVP_aes_192_ecb(), + 32 => ffi::EVP_aes_256_ecb(), + _ => panic!("Aes KEY_SIZE must be 16, 24 or 32") + }; + ctx.cipher_init::(t, self.k1.as_mut_ptr(), ptr::null_mut()).unwrap(); + ffi::EVP_CIPHER_CTX_set_padding(ctx.as_ptr(), 0); + ctx.update::(&self.tag, tag_tmp.as_mut_ptr()).unwrap(); } self.tag.copy_from_slice(&tag_tmp[0..16]); self.tmp.copy_from_slice(&tag_tmp[0..16]); self.tmp[12] &= 0x7f; - let _ = self.ctr.replace( - Crypter::new( - aes_ctr_by_key_size(self.k1.len()), - Mode::Encrypt, - self.k1.as_slice(), - Some(&self.tmp), - ) - .unwrap(), - ); + + let mut ctx = CipherCtx::new().unwrap(); + unsafe { + let t = match self.k1.len() { + 16 => ffi::EVP_aes_128_ctr(), + 24 => ffi::EVP_aes_192_ctr(), + 32 => ffi::EVP_aes_256_ctr(), + _ => panic!("Aes KEY_SIZE must be 16, 24 or 32") + }; + ctx.cipher_init::(t, self.k1.as_mut_ptr(), self.tmp.as_ptr()).unwrap(); + } + let _ = self.ctr.replace(ctx); } /// Feed plaintext for second pass and write ciphertext to supplied buffer. /// This may be called more than once. #[inline(always)] pub fn encrypt_second_pass(&mut self, plaintext: &[u8], ciphertext: &mut [u8]) { - let _ = self.ctr.as_mut().unwrap().update(plaintext, ciphertext); + unsafe { + self.ctr.as_mut().unwrap().update::(plaintext, ciphertext.as_mut_ptr()).unwrap(); + } } /// Encrypt plaintext in place. /// This may be called more than once. #[inline(always)] pub fn encrypt_second_pass_in_place(&mut self, plaintext_to_ciphertext: &mut [u8]) { - let _ = self.ctr.as_mut().unwrap().update( - unsafe { std::slice::from_raw_parts(plaintext_to_ciphertext.as_ptr(), plaintext_to_ciphertext.len()) }, - plaintext_to_ciphertext, - ); + unsafe { + let out = plaintext_to_ciphertext.as_mut_ptr(); + self.ctr.as_mut().unwrap().update::(plaintext_to_ciphertext, out).unwrap(); + } } /// Finish second pass and return a reference to the tag for this message. @@ -138,33 +168,47 @@ impl AesGmacSiv { pub fn decrypt_init(&mut self, tag: &[u8]) { self.tmp.copy_from_slice(tag); self.tmp[12] &= 0x7f; - let _ = self.ctr.replace( - Crypter::new( - aes_ctr_by_key_size(self.k1.len()), - Mode::Decrypt, - self.k1.as_slice(), - Some(&self.tmp), - ) - .unwrap(), - ); + + let mut ctx = CipherCtx::new().unwrap(); + unsafe { + let t = match self.k1.len() { + 16 => ffi::EVP_aes_128_ctr(), + 24 => ffi::EVP_aes_192_ctr(), + 32 => ffi::EVP_aes_256_ctr(), + _ => panic!("Aes KEY_SIZE must be 16, 24 or 32") + }; + ctx.cipher_init::(t, self.k1.as_mut_ptr(), self.tmp.as_ptr()).unwrap(); + } + let _ = self.ctr.replace(ctx); let mut tag_tmp = [0_u8; 32]; - let mut ecb = Crypter::new(aes_ecb_by_key_size(self.k1.len()), Mode::Decrypt, self.k1.as_slice(), None).unwrap(); - ecb.pad(false); - if ecb.update(tag, &mut tag_tmp).unwrap() != 16 { - assert_eq!(ecb.finalize(&mut tag_tmp).unwrap(), 16); + + let mut ctx = CipherCtx::new().unwrap(); + unsafe { + let t = match self.k1.len() { + 16 => ffi::EVP_aes_128_ecb(), + 24 => ffi::EVP_aes_192_ecb(), + 32 => ffi::EVP_aes_256_ecb(), + _ => panic!("Aes KEY_SIZE must be 16, 24 or 32") + }; + ctx.cipher_init::(t, self.k1.as_mut_ptr(), ptr::null_mut()).unwrap(); + ffi::EVP_CIPHER_CTX_set_padding(ctx.as_ptr(), 0); + ctx.update::(&self.tag, tag_tmp.as_mut_ptr()).unwrap(); } self.tag.copy_from_slice(&tag_tmp[0..16]); tag_tmp[8..12].fill(0); - let _ = self.gmac.replace( - Crypter::new( - aes_gcm_by_key_size(self.k0.len()), - Mode::Encrypt, - self.k0.as_slice(), - Some(&tag_tmp[0..12]), - ) - .unwrap(), - ); + + let mut ctx = CipherCtx::new().unwrap(); + unsafe { + let t = match self.k0.len() { + 16 => ffi::EVP_aes_128_gcm(), + 24 => ffi::EVP_aes_192_gcm(), + 32 => ffi::EVP_aes_256_gcm(), + _ => panic!("Aes KEY_SIZE must be 16, 24 or 32") + }; + ctx.cipher_init::(t, self.k0.as_mut_ptr(), self.tag[0..12].as_ptr()).unwrap(); + } + let _ = self.gmac.replace(ctx); } /// Set additional authenticated data to be checked. @@ -177,8 +221,10 @@ impl AesGmacSiv { /// This may be called more than once. #[inline(always)] pub fn decrypt(&mut self, ciphertext: &[u8], plaintext: &mut [u8]) { - let _ = self.ctr.as_mut().unwrap().update(ciphertext, plaintext); - let _ = self.gmac.as_mut().unwrap().aad_update(plaintext); + unsafe { + self.ctr.as_mut().unwrap().update::(ciphertext, plaintext.as_mut_ptr()).unwrap(); + self.gmac.as_mut().unwrap().update::(plaintext, ptr::null_mut()).unwrap(); + } } /// Decrypt ciphertext in place. @@ -196,8 +242,10 @@ impl AesGmacSiv { #[inline(always)] pub fn decrypt_finish(&mut self) -> Option<&[u8; 16]> { let gmac = self.gmac.as_mut().unwrap(); - let _ = gmac.finalize(&mut self.tmp); - let _ = gmac.get_tag(&mut self.tmp); + unsafe { + gmac.finalize::(self.tmp.as_mut_ptr()).unwrap(); + gmac.tag(&mut self.tmp).unwrap(); + } if (self.tag[8] == self.tmp[0] ^ self.tmp[8]) && (self.tag[9] == self.tmp[1] ^ self.tmp[9]) && (self.tag[10] == self.tmp[2] ^ self.tmp[10])