From 28216d2e2f623917abfb5b793490c2eed65f11f3 Mon Sep 17 00:00:00 2001 From: 0xalivecow Date: Sat, 2 Nov 2024 17:58:53 +0100 Subject: [PATCH] WIP: feat: start on gcm --- src/utils/ciphers.rs | 48 ++++++++++++++++++++--- src/utils/field.rs | 92 +++++++++++++++++++++++++------------------- src/utils/poly.rs | 19 ++++----- 3 files changed, 104 insertions(+), 55 deletions(-) diff --git a/src/utils/ciphers.rs b/src/utils/ciphers.rs index 885b1c3..7c70808 100644 --- a/src/utils/ciphers.rs +++ b/src/utils/ciphers.rs @@ -65,12 +65,12 @@ pub fn xex_encrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result let mut output: Vec = vec![]; //assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); //assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); - let mut tweak_block: ByteArray = ByteArray(sea_128_encrypt(&key2, tweak)?); + let mut tweak_block: ByteArray = ByteArray::from(sea_128_encrypt(&key2, tweak)?); //dbg!("input_chunks: {:001X?}", &input_chunks); for chunk in input_chunks { - let plaintext_intermediate = xor_bytes(&tweak_block.0, chunk)?; + let plaintext_intermediate = xor_bytes(&tweak_block.vector, chunk)?; /* assert!( plaintext_intermediate.len() % 16 == 0, @@ -81,7 +81,7 @@ pub fn xex_encrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result //assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); //assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); let cypher_block_intermediate = sea_128_encrypt(&key, &plaintext_intermediate)?; - let mut cypher_block = xor_bytes(&tweak_block.0, cypher_block_intermediate)?; + let mut cypher_block = xor_bytes(&tweak_block.vector, cypher_block_intermediate)?; output.append(cypher_block.as_mut()); tweak_block.left_shift_reduce("xex"); } @@ -99,10 +99,10 @@ pub fn xex_decrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result let mut output: Vec = vec![]; //assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); //assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); - let mut tweak_block: ByteArray = ByteArray(sea_128_encrypt(&key2, tweak)?); + let mut tweak_block: ByteArray = ByteArray::from(sea_128_encrypt(&key2, tweak)?); for chunk in input_chunks { - let cyphertext_intermediate = xor_bytes(&tweak_block.0, chunk)?; + let cyphertext_intermediate = xor_bytes(&tweak_block.vector, chunk)?; /* assert!( @@ -114,7 +114,7 @@ pub fn xex_decrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); */ let plaintext_block_intermediate = sea_128_decrypt(&key, &cyphertext_intermediate)?; - let mut cypher_block = xor_bytes(&tweak_block.0, plaintext_block_intermediate)?; + let mut cypher_block = xor_bytes(&tweak_block.vector, plaintext_block_intermediate)?; output.append(cypher_block.as_mut()); tweak_block.left_shift_reduce("xex"); } @@ -122,6 +122,42 @@ pub fn xex_decrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result Ok(output) } +pub fn gcm_aes_encrypt( + action: &str, + mut nonce: Vec, + key: Vec, + plaintext: Vec, + ad: ByteArray, +) -> Result> { + nonce.append(vec![0x01].as_mut()); + + let auth_text_xor_block = aes_128_encrypt(&key, &nonce); + + let auth_key_h = aes_128_encrypt(&key, &vec![0]); + + let plaintext: Vec> = plaintext.chunks(16).map(|x| x.to_vec()).collect(); + + let mut output: Vec> = vec![]; + + for (ctr, chunk) in plaintext.iter().enumerate() { + nonce.pop(); + nonce.push(ctr as u8); + + let intermediate = aes_128_encrypt(&key, &nonce)?; + + let intermediate2 = xor_bytes(chunk, intermediate)?; + + output.push(intermediate2); + } + todo!(); +} + +pub fn ghash(auth_key_h: Vec, ad: Vec, ciphertext: Vec>) { + let output: Vec = vec![0, 16]; + + let inter1 = xor_bytes(&output, ad); +} + /* * let mut bytes: [u8; 16] = [0u8; 16]; bytes.copy_from_slice(&ciphertext); diff --git a/src/utils/field.rs b/src/utils/field.rs index afa9b06..98deb9e 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -4,14 +4,16 @@ use base64::Engine; use super::poly::gfmul; #[derive(Debug)] -pub struct ByteArray(pub Vec); +pub struct ByteArray { + pub vector: Vec, +} impl ByteArray { pub fn left_shift(&mut self, semantic: &str) -> Result { match semantic { "xex" => { let mut carry = 0u8; - for byte in self.0.iter_mut() { + for byte in self.vector.iter_mut() { let new_carry = *byte >> 7; *byte = (*byte << 1) | carry; carry = new_carry; @@ -20,7 +22,7 @@ impl ByteArray { } "gcm" => { let mut carry = 0u8; - for byte in self.0.iter_mut() { + for byte in self.vector.iter_mut() { let new_carry = *byte & 1; *byte = (*byte >> 1) | (carry << 7); carry = new_carry; @@ -37,13 +39,13 @@ impl ByteArray { let alpha_poly: Vec = base64::prelude::BASE64_STANDARD .decode("AgAAAAAAAAAAAAAAAAAAAA==") .expect("Decode failed"); - self.0 = gfmul(self.0.clone(), alpha_poly, "xex").unwrap(); + self.vector = gfmul(self.vector.clone(), alpha_poly, "xex").unwrap(); } "gcm" => { let alpha_poly: Vec = base64::prelude::BASE64_STANDARD .decode("AgAAAAAAAAAAAAAAAAAAAA==") .expect("Decode failed"); - self.0 = gfmul(self.0.clone(), alpha_poly, "gcm").unwrap(); + self.vector = gfmul(self.vector.clone(), alpha_poly, "gcm").unwrap(); } _ => {} } @@ -53,7 +55,7 @@ impl ByteArray { match semantic { "xex" => { let mut carry = 0u8; - for byte in self.0.iter_mut().rev() { + for byte in self.vector.iter_mut().rev() { let new_carry = *byte & 1; *byte = (*byte >> 1) | (carry << 7); carry = new_carry; @@ -62,7 +64,7 @@ impl ByteArray { } "gcm" => { let mut carry = 0u8; - for byte in self.0.iter_mut().rev() { + for byte in self.vector.iter_mut().rev() { let new_carry = *byte & 1; *byte = (*byte << 1) | carry; carry = new_carry; @@ -74,28 +76,38 @@ impl ByteArray { } pub fn xor_byte_arrays(&mut self, vec2: &ByteArray) { - self.0 + self.vector .iter_mut() - .zip(vec2.0.iter()) + .zip(vec2.vector.iter()) .for_each(|(x1, x2)| *x1 ^= *x2); } pub fn LSB_is_one(&self) -> bool { - (self.0.first().unwrap() & 1) == 1 + (self.vector.first().unwrap() & 1) == 1 } pub fn msb_is_one(&self) -> bool { - (self.0.last().unwrap() & 1) == 1 + (self.vector.last().unwrap() & 1) == 1 } pub fn is_empty(&self) -> bool { - for i in self.0.iter() { + for i in self.vector.iter() { if *i != 0 { return false; } } true } + + pub fn append_vec(&mut self, mut other: Vec) { + self.vector.append(other.as_mut()); + } +} + +impl From> for ByteArray { + fn from(item: Vec) -> Self { + ByteArray { vector: item } + } } #[cfg(test)] @@ -105,94 +117,94 @@ mod tests { #[test] fn test_byte_array_shift1() { - let mut byte_array: ByteArray = ByteArray(vec![0x00, 0x01]); - let shifted_array: ByteArray = ByteArray(vec![0x00, 0x02]); + let mut byte_array: ByteArray = ByteArray::from(vec![0x00, 0x01]); + let shifted_array: ByteArray = ByteArray::from(vec![0x00, 0x02]); byte_array.left_shift("xex"); - assert_eq!(byte_array.0, shifted_array.0); + assert_eq!(byte_array.vector, shifted_array.vector); } #[test] fn test_byte_array_shift2() { - let mut byte_array: ByteArray = ByteArray(vec![0xFF, 0x00]); - let shifted_array: ByteArray = ByteArray(vec![0xFE, 0x01]); + let mut byte_array: ByteArray = ByteArray::from(vec![0xFF, 0x00]); + let shifted_array: ByteArray = ByteArray::from(vec![0xFE, 0x01]); byte_array.left_shift("xex"); assert_eq!( - byte_array.0, shifted_array.0, + byte_array.vector, shifted_array.vector, "Failure: Shifted array was: {:?}", - byte_array.0 + byte_array.vector ); } #[test] fn test_byte_array_shift1_gcm() { - let mut byte_array: ByteArray = ByteArray(vec![0xFF, 0x00]); - let shifted_array: ByteArray = ByteArray(vec![0x7F, 0x80]); + let mut byte_array: ByteArray = ByteArray::from(vec![0xFF, 0x00]); + let shifted_array: ByteArray = ByteArray::from(vec![0x7F, 0x80]); byte_array.left_shift("gcm"); assert_eq!( - byte_array.0, shifted_array.0, + byte_array.vector, shifted_array.vector, "Failure: Shifted array was: {:02X?}", - byte_array.0 + byte_array.vector ); } #[test] fn test_byte_array_shift1_right_gcm() { - let mut byte_array: ByteArray = ByteArray(vec![0xFF, 0x00]); - let shifted_array: ByteArray = ByteArray(vec![0xFE, 0x00]); + let mut byte_array: ByteArray = ByteArray::from(vec![0xFF, 0x00]); + let shifted_array: ByteArray = ByteArray::from(vec![0xFE, 0x00]); byte_array.right_shift("gcm"); assert_eq!( - byte_array.0, shifted_array.0, + byte_array.vector, shifted_array.vector, "Failure: Shifted array was: {:02X?}", - byte_array.0 + byte_array.vector ); } #[test] fn test_byte_array_shift_right() { - let mut byte_array: ByteArray = ByteArray(vec![0x02]); - let shifted_array: ByteArray = ByteArray(vec![0x01]); + let mut byte_array: ByteArray = ByteArray::from(vec![0x02]); + let shifted_array: ByteArray = ByteArray::from(vec![0x01]); byte_array.right_shift("xex"); assert_eq!( - byte_array.0, shifted_array.0, + byte_array.vector, shifted_array.vector, "Failure: Shifted array was: {:?}", - byte_array.0 + byte_array.vector ); } #[test] fn test_lsb_one() { - let byte_array: ByteArray = ByteArray(vec![0x00, 0xFF]); + let byte_array: ByteArray = ByteArray::from(vec![0x00, 0xFF]); assert!(!byte_array.LSB_is_one()); - let byte_array2: ByteArray = ByteArray(vec![0x02, 0xFF]); + let byte_array2: ByteArray = ByteArray::from(vec![0x02, 0xFF]); assert!(!byte_array2.LSB_is_one()); - let byte_array3: ByteArray = ByteArray(vec![0xFF, 0x00]); + let byte_array3: ByteArray = ByteArray::from(vec![0xFF, 0x00]); assert!(byte_array3.LSB_is_one()); } #[test] fn test_byte_xor() { - let mut byte_array: ByteArray = ByteArray(vec![0x25, 0x25]); - let byte_array2: ByteArray = ByteArray(vec![0x55, 0x55]); + let mut byte_array: ByteArray = ByteArray::from(vec![0x25, 0x25]); + let byte_array2: ByteArray = ByteArray::from(vec![0x55, 0x55]); byte_array.xor_byte_arrays(&byte_array2); - assert_eq!(byte_array.0, vec![0x70, 0x70]); + assert_eq!(byte_array.vector, vec![0x70, 0x70]); } #[test] fn test_byte_xor2() { - let mut byte_array: ByteArray = ByteArray(vec![0x00, 0x00]); - let byte_array2: ByteArray = ByteArray(vec![0x55, 0x55]); + let mut byte_array: ByteArray = ByteArray::from(vec![0x00, 0x00]); + let byte_array2: ByteArray = ByteArray::from(vec![0x55, 0x55]); byte_array.xor_byte_arrays(&byte_array2); - assert_eq!(byte_array.0, vec![0x55, 0x55]); + assert_eq!(byte_array.vector, vec![0x55, 0x55]); } } diff --git a/src/utils/poly.rs b/src/utils/poly.rs index ec316a4..3dedd5d 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -8,16 +8,17 @@ use super::field; pub const RED_POLY: u128 = 0x87000000_00000000_00000000_00000000; pub fn gfmul(poly_a: Vec, poly_b: Vec, semantic: &str) -> Result> { - let mut red_poly_bytes: ByteArray = ByteArray(RED_POLY.to_be_bytes().to_vec()); - red_poly_bytes.0.push(0x01); + let mut red_poly_bytes: ByteArray = ByteArray::from(RED_POLY.to_be_bytes().to_vec()); + red_poly_bytes.vector.push(0x01); - let mut poly1: ByteArray = ByteArray(poly_a); - poly1.0.push(0x00); + let mut poly1: ByteArray = ByteArray::from(poly_a); + poly1.vector.push(0x00); - let mut poly2: ByteArray = ByteArray(poly_b); - poly2.0.push(0x00); + let mut poly2: ByteArray = ByteArray::from(poly_b); + poly2.vector.push(0x00); - let mut result: ByteArray = ByteArray(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + let mut result: ByteArray = + ByteArray::from(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); if poly2.LSB_is_one() { result.xor_byte_arrays(&poly1); @@ -38,9 +39,9 @@ pub fn gfmul(poly_a: Vec, poly_b: Vec, semantic: &str) -> Result poly2.right_shift(semantic)?; } - result.0.remove(16); + result.vector.remove(16); - Ok(result.0) + Ok(result.vector) } pub fn convert_gcm_to_xex(gcm_poly: Vec) -> Result> {