diff --git a/src/decryptor.rs b/src/decryptor.rs index 0271221..b821922 100644 --- a/src/decryptor.rs +++ b/src/decryptor.rs @@ -1,11 +1,18 @@ -use aes::Aes128; +use aes::{Aes128, Aes192, Aes256}; use aes::cipher::{Block, BlockEncrypt, KeyInit}; use aes::cipher::generic_array::GenericArray; use crate::util::{gmul_128, inc_32, msb_s, normalize_nonce, u8to128}; -pub struct Aes128GcmStreamDecryptor { - crypto: Aes128, +macro_rules! define_aes_gcm_stream_decryptor_impl { + ( + $module:tt, + $aesn:tt, + $key_size:tt + ) => { + +pub struct $module { + crypto: $aesn, message_buffer: Vec, integrality_buffer: Vec, ghash_key: u128, @@ -16,10 +23,10 @@ pub struct Aes128GcmStreamDecryptor { message_len: usize, } -impl Aes128GcmStreamDecryptor { - pub fn new(key: [u8; 16], nonce: &[u8]) -> Self { +impl $module { + pub fn new(key: [u8; $key_size], nonce: &[u8]) -> Self { let key = GenericArray::from(key); - let aes = Aes128::new(&key); + let aes = $aesn::new(&key); let mut s = Self { crypto: aes, @@ -60,7 +67,7 @@ impl Aes128GcmStreamDecryptor { for i in 0..blocks_count { self.encryption_nonce = inc_32(self.encryption_nonce); let mut ctr = self.encryption_nonce.to_be_bytes(); - let block = Block::::from_mut_slice(&mut ctr); + let block = Block::<$aesn>::from_mut_slice(&mut ctr); self.crypto.encrypt_block(block); let chunk = &message_buffer_slice[i * 16..(i + 1) * 16]; let y = u8to128(chunk) ^ u8to128(&block.as_slice()); @@ -115,7 +122,7 @@ impl Aes128GcmStreamDecryptor { fn calculate_tag(&mut self) -> Vec { let mut bs = self.init_nonce.to_be_bytes().clone(); - let block = Block::::from_mut_slice(&mut bs); + let block = Block::<$aesn>::from_mut_slice(&mut bs); self.crypto.encrypt_block(block); let tag_trunk = self.ghash_val.to_be_bytes(); let y = u8to128(&tag_trunk) ^ u8to128(&block.as_slice()); @@ -137,7 +144,7 @@ impl Aes128GcmStreamDecryptor { fn ghash_key(&mut self) -> u128 { let mut block = [0u8; 16]; - let block = Block::::from_mut_slice(&mut block); + let block = Block::<$aesn>::from_mut_slice(&mut block); self.crypto.encrypt_block(block); u8to128(&block.as_slice()) } @@ -146,4 +153,10 @@ impl Aes128GcmStreamDecryptor { let ghash_key = self.ghash_key(); normalize_nonce(ghash_key, nonce_bytes) } -} \ No newline at end of file +} + } +} + +define_aes_gcm_stream_decryptor_impl!(Aes128GcmStreamDecryptor, Aes128, 16); +define_aes_gcm_stream_decryptor_impl!(Aes192GcmStreamDecryptor, Aes192, 24); +define_aes_gcm_stream_decryptor_impl!(Aes256GcmStreamDecryptor, Aes256, 32); diff --git a/src/encryptor.rs b/src/encryptor.rs index 355ed43..d42a6ef 100644 --- a/src/encryptor.rs +++ b/src/encryptor.rs @@ -1,11 +1,18 @@ -use aes::Aes128; +use aes::{Aes128, Aes192, Aes256}; use aes::cipher::{Block, BlockEncrypt, KeyInit}; use aes::cipher::generic_array::GenericArray; use crate::util::{gmul_128, inc_32, msb_s, normalize_nonce, u8to128}; -pub struct Aes128GcmStreamEncryptor { - crypto: Aes128, +macro_rules! define_aes_gcm_stream_encryptor_impl { + ( + $module:tt, + $aesn:tt, + $key_size:tt + ) => { + +pub struct $module { + crypto: $aesn, message_buffer: Vec, integrality_buffer: Vec, ghash_key: u128, @@ -16,10 +23,10 @@ pub struct Aes128GcmStreamEncryptor { message_len: usize, } -impl Aes128GcmStreamEncryptor { - pub fn new(key: [u8; 16], nonce: &[u8]) -> Self { +impl $module { + pub fn new(key: [u8; $key_size], nonce: &[u8]) -> Self { let key = GenericArray::from(key); - let aes = Aes128::new(&key); + let aes = $aesn::new(&key); let mut s = Self { crypto: aes, @@ -108,7 +115,7 @@ impl Aes128GcmStreamEncryptor { fn calculate_tag(&mut self) -> Vec { let mut bs = self.init_nonce.to_be_bytes().clone(); - let block = Block::::from_mut_slice(&mut bs); + let block = Block::<$aesn>::from_mut_slice(&mut bs); self.crypto.encrypt_block(block); let tag_trunk = self.ghash_val.to_be_bytes(); let y = u8to128(&tag_trunk) ^ u8to128(&block.as_slice()); @@ -130,7 +137,7 @@ impl Aes128GcmStreamEncryptor { fn ghash_key(&mut self) -> u128 { let mut block = [0u8; 16]; - let block = Block::::from_mut_slice(&mut block); + let block = Block::<$aesn>::from_mut_slice(&mut block); self.crypto.encrypt_block(block); u8to128(&block.as_slice()) } @@ -139,4 +146,10 @@ impl Aes128GcmStreamEncryptor { let ghash_key = self.ghash_key(); normalize_nonce(ghash_key, nonce_bytes) } -} \ No newline at end of file +} + } +} + +define_aes_gcm_stream_encryptor_impl!(Aes128GcmStreamEncryptor, Aes128, 16); +define_aes_gcm_stream_encryptor_impl!(Aes192GcmStreamEncryptor, Aes192, 24); +define_aes_gcm_stream_encryptor_impl!(Aes256GcmStreamEncryptor, Aes256, 32); diff --git a/src/lib.rs b/src/lib.rs index 433b2bd..45c8790 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,81 @@ -pub use encryptor::Aes128GcmStreamEncryptor; +// ---------------------------------------- pub use decryptor::Aes128GcmStreamDecryptor; +pub use decryptor::Aes192GcmStreamDecryptor; +pub use decryptor::Aes256GcmStreamDecryptor; +// ---------------------------------------- +pub use encryptor::Aes128GcmStreamEncryptor; +pub use encryptor::Aes192GcmStreamEncryptor; +pub use encryptor::Aes256GcmStreamEncryptor; mod util; mod encryptor; mod decryptor; +#[test] +fn test256() { + use aes_gcm::{aead::{Aead, Nonce, Payload}, Aes256Gcm, KeyInit}; + let knp = vec![ + ([0; 32], [0; 12], &[] as &[u8], b"Hello World!" as &[u8]), + ([0; 32], [0; 12], &[1; 16], b"Hello World!" as &[u8]), + ([0; 32], [0; 12], &[1; 17], b"Hello World!" as &[u8]), + ([0; 32], [0; 12], &[1; 32], b"Hello World!" as &[u8]), + ([0; 32], [0; 12], &[1; 64], b"Hello World!" as &[u8]), + ([0; 32], [0; 12], &[1, 2, 3], b"Hello World!" as &[u8]), + ([1; 32], [0; 12], &[], b"Hello World!"), + ([0; 32], [1; 12], &[], b"Hello World!"), + ([1; 32], [1; 12], &[], b"Hello World ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!"), + ([1; 32], [1; 12], &[0; 129], b"Hello World ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!"), + ([0xff; 32], [0; 12], &[], b"Hello World!"), + ([0; 32], [0xff; 12], &[], b"Hello World!"), + ([0xff; 32], [0xff; 12], &[], b"Hello World ~~~~~~~~~~~~~~~~~\ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ + ~~~~~~~~~!"), + ([0xff; 32], [0xff; 12], &[11, 22, 33], b"Hello World ~~~~~~~~~~~~~~~~~\ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ + ~~~~~~~~~!"), + ]; + + for (key, nonce, aad, plaintext) in knp { + // encrypt + let mut ciphertext = vec![]; + let mut encryptor = Aes256GcmStreamEncryptor::new(key.clone(), &nonce); + if !aad.is_empty() { + encryptor.init_adata(aad); + } + ciphertext.extend_from_slice(&encryptor.next(plaintext)); + let (last_block, tag) = encryptor.finalize(); + ciphertext.extend_from_slice(&last_block); + ciphertext.extend_from_slice(&tag); + + // decrypt 1 + let mut decryptor = Aes256GcmStreamDecryptor::new(key.clone(), &nonce); + if !aad.is_empty() { + decryptor.init_adata(aad); + } + let mut plaintext1 = decryptor.next(ciphertext.as_slice()); + let plaintext2 = decryptor.finalize().expect("decryptor decrypt"); + plaintext1.extend_from_slice(&plaintext2); + assert_eq!(plaintext, plaintext1.as_slice()); + + // decrypt 2 + let cipher = Aes256Gcm::new_from_slice(&key).expect("new from key slice"); + let mut decrypt_nonce = Nonce::::default(); + let m: &mut [u8] = decrypt_nonce.as_mut(); + for i in 0..m.len() { + m[i] = nonce[i]; + } + let decrypted_plaintext = if aad.is_empty() { + cipher.decrypt(&decrypt_nonce, ciphertext.as_slice()).expect("decrypt1") + } else { + cipher.decrypt(&decrypt_nonce, Payload { + msg: ciphertext.as_slice(), + aad, + }).expect("decrypt2") + }; + assert_eq!(plaintext, decrypted_plaintext.as_slice()); + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 8aad3a8..0000000 --- a/src/main.rs +++ /dev/null @@ -1,51 +0,0 @@ -use aes::cipher::KeyInit; -use aes_gcm::{AeadInPlace, Aes128Gcm, Key}; -use aes_gcm::aead::{Aead, Nonce}; - -use aes_gcm_stream::{Aes128GcmStreamDecryptor, Aes128GcmStreamEncryptor}; - -fn main() { - let plaintext = [0u8; 69]; - - // --------------------------------------------------------------------------------------- - - let key: &[u8; 16] = &[0; 16]; - let key: &Key = key.into(); - let cipher = Aes128Gcm::new(&key); - - let mut nonce = Nonce::::default(); - let m: &mut [u8] = nonce.as_mut(); - for i in 0..m.len() { - m[i] = 0; - } - // println!("nonce\t:{}", hex::encode(nonce.as_slice())); - - let ciphertext = cipher.encrypt(&nonce, plaintext.as_slice()).unwrap(); - println!("{}", hex::encode(&ciphertext)); - let mut ciphertext = vec![0u8; plaintext.len()]; - let tag = cipher.encrypt_in_place_detached(&nonce, &[], ciphertext.as_mut_slice()).unwrap(); - println!("{}", hex::encode(&ciphertext)); - println!("{} : TAG", hex::encode(tag.as_slice())); - - let mut ciphertext = plaintext.to_vec(); - cipher.encrypt_in_place(&nonce, &[], &mut ciphertext).unwrap(); - println!("{}", hex::encode(ciphertext.as_slice())); - - let mut aes128_gcm_stream_encryptor = Aes128GcmStreamEncryptor::new([0; 16], &[0u8; 12]); - aes128_gcm_stream_encryptor.init_adata(&[]); - let o1 = aes128_gcm_stream_encryptor.next(&plaintext[0..21]); - let o2 = aes128_gcm_stream_encryptor.next(&plaintext[21..64]); - let o3 = aes128_gcm_stream_encryptor.next(&[0; 5]); - let (o4, tag) = aes128_gcm_stream_encryptor.finalize(); - println!("{}: E1", hex::encode(&o1)); - println!("{}: E2", hex::encode(&o2)); - println!("{}: E3", hex::encode(&o3)); - println!("{}: E4", hex::encode(&o4)); - println!("{} : TAG", hex::encode(&tag)); - - let mut aes128_gcm_stream_decryptor = Aes128GcmStreamDecryptor::new([0; 16], &[0u8; 12]); - let o1 = aes128_gcm_stream_decryptor.next(&hex::decode("0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8c992f32a52151e1c2adceb7c6138e042").unwrap()); - let o2_result = aes128_gcm_stream_decryptor.finalize(); - println!("{}", hex::encode(&o1)); - println!("{:?}", o2_result); -} \ No newline at end of file