cryptopals/src/cbc.rs

54 lines
2.1 KiB
Rust

use crate::bytes::Bytes;
use openssl::symm;
pub fn enrypt_aes_128_ecb_block(key: &[u8], data: &[u8]) -> Vec<u8> {
let cipher_type = symm::Cipher::aes_128_ecb();
let block_size = cipher_type.block_size();
let mut encrypter = symm::Crypter::new(cipher_type, symm::Mode::Encrypt, key, None).unwrap();
if data.len() == block_size {
encrypter.pad(false);
}
let mut cipher = vec![0; data.len() + block_size];
let mut count = encrypter.update(data, &mut cipher).unwrap();
count += encrypter.finalize(&mut cipher).unwrap();
cipher[0..count].to_vec()
}
pub fn decrypt_aes_128_ecb_block(key: &[u8], data: &[u8]) -> Vec<u8> {
let cipher_type = symm::Cipher::aes_128_ecb();
let block_size = cipher_type.block_size();
let mut encrypter = symm::Crypter::new(cipher_type, symm::Mode::Decrypt, key, None).unwrap();
encrypter.pad(false);
let mut cipher = vec![0; data.len() + block_size];
encrypter.update(data, &mut cipher).unwrap();
cipher[0..block_size].to_vec()
}
pub fn encrypt(Bytes(key): &Bytes, Bytes(iv): &Bytes, Bytes(data): &Bytes) -> Bytes {
let block_size = 16;
let mut result: Vec<u8> = vec![];
let mut prev_cipher: Vec<u8> = iv.clone(); // first xor input is IV
for data in data.chunks(block_size) {
let xored = crate::utils::xor(&prev_cipher, data);
let mut cipher = enrypt_aes_128_ecb_block(key, &xored);
prev_cipher = cipher.clone(); // cipher is input for next xor
result.append(&mut cipher);
}
Bytes(result)
}
pub fn decrypt(Bytes(key): &Bytes, Bytes(iv): &Bytes, Bytes(data): &Bytes) -> Bytes {
// XXX: does not handle padding for last block
let cipher_type = symm::Cipher::aes_128_ecb();
let block_size = cipher_type.block_size();
let mut result: Vec<u8> = vec![];
let mut prev_cipher: Vec<u8> = iv.clone(); // first xor input is IV
for cipher in data.chunks(block_size) {
let xored = decrypt_aes_128_ecb_block(key, cipher);
let data = crate::utils::xor(&xored, &prev_cipher);
result.extend(data.clone());
prev_cipher = cipher.to_vec();
}
Bytes(result)
}