Implement challenge 10.
This commit is contained in:
59
src/cbs.rs
Normal file
59
src/cbs.rs
Normal 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)
|
||||
}
|
||||
20
src/main.rs
20
src/main.rs
@@ -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();
|
||||
}
|
||||
|
||||
26
src/set2.rs
26
src/set2.rs
@@ -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!");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user