diff options
Diffstat (limited to 'src/aes.rs')
-rw-r--r-- | src/aes.rs | 97 |
1 files changed, 61 insertions, 36 deletions
@@ -1,24 +1,42 @@ -use primitives::{fixed_xor, pad_pkcs7, unpad_pkcs7}; +use crate::primitives::{fixed_xor, pad_pkcs7, unpad_pkcs7}; -pub fn decrypt_aes_128_ecb (bytes: &[u8], key: &[u8]) -> Option<Vec<u8>> { - // openssl already doesn't return differentiable results for invalid - // padding, so we can't either - return Some(::openssl::crypto::symm::decrypt( - ::openssl::crypto::symm::Type::AES_128_ECB, +fn decrypt_aes_128_ecb_nopad(bytes: &[u8], key: &[u8]) -> Vec<u8> { + let t = openssl::symm::Cipher::aes_128_ecb(); + let mut c = openssl::symm::Crypter::new( + t, + openssl::symm::Mode::Decrypt, key, - vec![], - bytes - )); + None, + ) + .unwrap(); + c.pad(false); + let mut out = vec![0; bytes.len() + t.block_size()]; + let count = c.update(bytes, &mut out).unwrap(); + let rest = c.finalize(&mut out[count..]).unwrap(); + out.truncate(count + rest); + out +} + +pub fn decrypt_aes_128_ecb(bytes: &[u8], key: &[u8]) -> Vec<u8> { + return openssl::symm::decrypt( + openssl::symm::Cipher::aes_128_ecb(), + key, + None, + bytes, + ) + .unwrap(); } -pub fn decrypt_aes_128_cbc (bytes: &[u8], key: &[u8], iv: &[u8]) -> Option<Vec<u8>> { +pub fn decrypt_aes_128_cbc( + bytes: &[u8], + key: &[u8], + iv: &[u8], +) -> Option<Vec<u8>> { let mut prev = iv.clone(); let mut plaintext = vec![]; for block in bytes.chunks(16) { - let plaintext_block = fixed_xor( - &decrypt_aes_128_ecb(&pad_pkcs7(block, 16)[..], key).unwrap()[..], - prev - ); + let plaintext_block = + fixed_xor(&decrypt_aes_128_ecb_nopad(&block, key)[..], prev); for c in plaintext_block { plaintext.push(c); } @@ -27,21 +45,23 @@ pub fn decrypt_aes_128_cbc (bytes: &[u8], key: &[u8], iv: &[u8]) -> Option<Vec<u return unpad_pkcs7(&plaintext[..]).map(|v| v.to_vec()); } -pub fn encrypt_aes_128_ecb (bytes: &[u8], key: &[u8]) -> Vec<u8> { - return ::openssl::crypto::symm::encrypt( - ::openssl::crypto::symm::Type::AES_128_ECB, +pub fn encrypt_aes_128_ecb(bytes: &[u8], key: &[u8]) -> Vec<u8> { + return openssl::symm::encrypt( + openssl::symm::Cipher::aes_128_ecb(), key, - vec![], - bytes + None, + bytes, ) + .unwrap(); } -pub fn encrypt_aes_128_cbc (bytes: &[u8], key: &[u8], iv: &[u8]) -> Vec<u8> { +pub fn encrypt_aes_128_cbc(bytes: &[u8], key: &[u8], iv: &[u8]) -> Vec<u8> { let mut prev = iv.to_vec(); let mut ciphertext = vec![]; for block in pad_pkcs7(bytes, 16).chunks(16) { let plaintext_block = fixed_xor(&block[..], &prev[..]); - let mut ciphertext_block = encrypt_aes_128_ecb(&plaintext_block[..], key); + let mut ciphertext_block = + encrypt_aes_128_ecb(&plaintext_block[..], key); ciphertext_block.truncate(16); for &c in ciphertext_block.iter() { ciphertext.push(c); @@ -51,20 +71,22 @@ 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> { +pub fn aes_128_ctr(bytes: &[u8], key: &[u8], nonce: u64) -> Vec<u8> { aes_128_ctr_with_counter(bytes, key, nonce, 0) } -pub fn aes_128_ctr_with_counter (bytes: &[u8], key: &[u8], nonce: u64, counter_start: u64) -> Vec<u8> { - let nonce_array: [u8; 8] = unsafe { - ::std::mem::transmute(nonce.to_le()) - }; +pub fn aes_128_ctr_with_counter( + bytes: &[u8], + key: &[u8], + nonce: u64, + counter_start: u64, +) -> Vec<u8> { + let nonce_array: [u8; 8] = unsafe { std::mem::transmute(nonce.to_le()) }; let mut counter = counter_start; let mut ret = vec![]; for block in bytes.chunks(16) { - let counter_array: [u8; 8] = unsafe { - ::std::mem::transmute(counter.to_le()) - }; + let counter_array: [u8; 8] = + unsafe { std::mem::transmute(counter.to_le()) }; let keystream = encrypt_aes_128_ecb( &pad_pkcs7( &nonce_array @@ -72,9 +94,9 @@ pub fn aes_128_ctr_with_counter (bytes: &[u8], key: &[u8], nonce: u64, counter_s .chain(counter_array.iter()) .map(|x| *x) .collect::<Vec<u8>>()[..], - 16 + 16, )[..], - key + key, ); for c in fixed_xor(block, &keystream[..]) { ret.push(c); @@ -85,7 +107,7 @@ pub fn aes_128_ctr_with_counter (bytes: &[u8], key: &[u8], nonce: u64, counter_s } #[test] -fn test_encrypt_decrypt () { +fn test_encrypt_decrypt() { let plaintext = b"Summertime and the wind is blowing outside in lower \ Chelsea and I don't know what I'm doing in the city, the \ sun is always in my eyes"; @@ -93,13 +115,16 @@ fn test_encrypt_decrypt () { let iv = [0; 16]; let ciphertext_ecb = encrypt_aes_128_ecb(&plaintext[..], &key[..]); - let ciphertext_cbc = encrypt_aes_128_cbc(&plaintext[..], &key[..], &iv[..]); + let ciphertext_cbc = + encrypt_aes_128_cbc(&plaintext[..], &key[..], &iv[..]); - let plaintext2_ecb = decrypt_aes_128_ecb(&ciphertext_ecb[..], &key[..]).unwrap(); - let plaintext2_cbc = decrypt_aes_128_cbc(&ciphertext_cbc[..], &key[..], &iv[..]).unwrap(); + let plaintext2_ecb = decrypt_aes_128_ecb(&ciphertext_ecb[..], &key[..]); + let plaintext2_cbc = + decrypt_aes_128_cbc(&ciphertext_cbc[..], &key[..], &iv[..]).unwrap(); let ciphertext2_ecb = encrypt_aes_128_ecb(&plaintext2_ecb[..], &key[..]); - let ciphertext2_cbc = encrypt_aes_128_cbc(&plaintext2_cbc[..], &key[..], &iv[..]); + let ciphertext2_cbc = + encrypt_aes_128_cbc(&plaintext2_cbc[..], &key[..], &iv[..]); assert_eq!(&plaintext[..], &plaintext2_ecb[..]); assert_eq!(&plaintext[..], &plaintext2_cbc[..]); |