Implement challenge 10.

This commit is contained in:
2022-04-17 21:36:14 -04:00
parent 766a36e790
commit 9f3eb1356c
4 changed files with 159 additions and 10 deletions

59
src/cbs.rs Normal file
View File

@@ -0,0 +1,59 @@
use crate::bytes::Bytes;
use openssl::symm;
fn xor(a: &[u8], b: &[u8]) -> Vec<u8> {
Iterator::zip(a.iter(), b.iter())
.map(|z| *(z.0) ^ *(z.1))
.collect()
}
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()
}
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.to_vec(); // first xor input is IV
for data in data.chunks(block_size) {
let xored = xor(&prev_cipher, data);
let mut cipher = enrypt_aes_128_ecb_block(key, &xored);
prev_cipher = cipher.to_vec(); // 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.to_vec(); // first xor input is IV
for cipher in data.chunks(block_size) {
let xored = decrypt_aes_128_ecb_block(key, &cipher);
let data = xor(&xored, &prev_cipher);
result.extend(data.to_vec());
prev_cipher = cipher.to_vec();
}
Bytes(result)
}

View File

@@ -1,17 +1,19 @@
mod bytes;
mod bytes_base64;
mod cbs;
mod set1;
mod set2;
fn main() {
set1::challenge1();
set1::challenge2();
set1::challenge3();
set1::challenge4();
set1::challenge5();
set1::challenge6();
set1::challenge7();
set1::challenge8();
set2::challenge9();
// set1::challenge1();
// set1::challenge2();
// set1::challenge3();
// set1::challenge4();
// set1::challenge5();
// set1::challenge6();
// set1::challenge7();
// set1::challenge8();
// set2::challenge9();
set2::challenge10();
set2::challenge11();
}

View File

@@ -1,4 +1,7 @@
#![allow(dead_code)]
use crate::bytes::Bytes;
use crate::bytes_base64::BytesBase64;
use crate::cbs;
pub fn challenge9() {
let mut bytes = Bytes::from_utf8("YELLOW SUBMARINE");
@@ -7,5 +10,26 @@ pub fn challenge9() {
}
pub fn challenge10() {
println!("[TBD] Challenge 10: TBD");
fn read(path: &str) -> Bytes {
let s = std::fs::read_to_string(path).unwrap();
BytesBase64::from_base64(&s).to_bytes()
}
let iv = Bytes(vec![0; 16]);
let key = Bytes::from_utf8("YELLOW SUBMARINE");
let text = Bytes::from_utf8("aaaabbbbccccddddeeeeffffgggghhhh");
let ciphertext = cbs::encrypt(&key, &iv, &text);
let roundtrip = cbs::decrypt(&key, &iv, &ciphertext);
if text == roundtrip {
let ciphertext = read("data/10.txt");
let cleartext = cbs::decrypt(&key, &iv, &ciphertext);
let output = cleartext.to_utf8()[..10].to_string();
println!("[okay] Challenge 10: {}", output);
} else {
println!("[fail] Challenge 10: rountrip failed");
}
}
pub fn challenge11() {
println!("[tbd] Challenge 11: TBD!");
}