diff options
-rw-r--r-- | src/aes.rs | 30 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | tests/lib.rs | 13 |
3 files changed, 44 insertions, 0 deletions
@@ -1,4 +1,5 @@ use openssl; +use std; use primitives::{fixed_xor, pad_pkcs7, unpad_pkcs7}; @@ -53,6 +54,35 @@ pub fn encrypt_aes_128_cbc (bytes: &[u8], key: &[u8], iv: &[u8]) -> Vec<u8> { return ciphertext; } +pub fn aes_128_ctr (bytes: &[u8], key: &[u8], nonce: u64) -> Vec<u8> { + let nonce_array: [u8; 8] = unsafe { + std::mem::transmute(nonce.to_le()) + }; + let mut counter = 0u64; + let mut ret = vec![]; + for block in bytes.chunks(16) { + let counter_array: [u8; 8] = unsafe { + std::mem::transmute(counter.to_le()) + }; + let keystream = encrypt_aes_128_ecb( + &pad_pkcs7( + &nonce_array + .iter() + .chain(counter_array.iter()) + .map(|x| *x) + .collect::<Vec<u8>>()[..], + 16 + )[..], + key + ); + for c in fixed_xor(block, &keystream[..]) { + ret.push(c); + } + counter += 1; + } + return ret; +} + #[test] fn test_encrypt_decrypt () { let plaintext = b"Summertime and the wind is blowing outside in lower \ @@ -12,6 +12,7 @@ pub use aes::decrypt_aes_128_ecb; pub use aes::decrypt_aes_128_cbc; pub use aes::encrypt_aes_128_ecb; pub use aes::encrypt_aes_128_cbc; +pub use aes::aes_128_ctr; pub use base64::to_base64; pub use http::parse_query_string; pub use http::create_query_string; diff --git a/tests/lib.rs b/tests/lib.rs index 5fb8261..f0ead77 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -392,3 +392,16 @@ fn problem_17 () { assert_eq!(&plaintext, expected); } } + +#[test] +fn problem_18 () { + let ciphertext = b"L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syL\ + XzhPweyyMTJULu/6/kXX0KSvoOLSFQ==".from_base64().unwrap(); + let plaintext = &b"Yo, VIP Let's kick it Ice, Ice, baby Ice, Ice, baby "[..]; + let got = matasano::aes_128_ctr( + &ciphertext[..], + b"YELLOW SUBMARINE", + 0 + ); + assert_eq!(got, plaintext); +} |