cryptopals

Matasano's cryptopals challenges (cryptopals.com).
Log | Files | Refs | README | LICENSE

commit a53dbd17117ef5b36f91c09f776a7b2e01222d4c
parent 8ef598d54a7b3b9ae04886f1676f4267975c7238
Author: Jared Tobin <jared@jtobin.ca>
Date:   Mon,  4 Sep 2017 22:35:36 +1200

Updates.

Diffstat:
Msrc/s2c11.rs | 2+-
Msrc/s2c12.rs | 116++++++++++++++++++++++++++++++++++++++++++-------------------------------------
2 files changed, 62 insertions(+), 56 deletions(-)

diff --git a/src/s2c11.rs b/src/s2c11.rs @@ -77,7 +77,7 @@ pub fn ecb_oracle<F>(f: F, size: usize) -> bool let mut buffer = Vec::with_capacity(size * blocks); for _ in 0..blocks { - buffer.extend_from_slice(b"ABRACADABRABRA!!"); + buffer.extend_from_slice(b"AAAAAAAAAAAAAAAA"); } let ciphertext = f(&buffer); diff --git a/src/s2c12.rs b/src/s2c12.rs @@ -8,7 +8,8 @@ use s2c09::pad_pkcs7; use s2c11; use self::openssl::symm::Mode; use self::rand::{Rng, SeedableRng, StdRng}; -use std::collections::HashMap; +use std::ops::Range; +use std::iter::{FromIterator, repeat}; const BLOCK_SIZE: usize = 16; @@ -33,25 +34,6 @@ pub fn gen_bytes_from_seed(size: usize, seed: &[usize]) -> Vec<u8> { buffer } -pub fn encryption_oracle(injected: &[u8]) -> Vec<u8> { - let message = base64::decode( - "Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg\ - aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq\ - dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg\ - YnkK").unwrap(); - - let m_size = injected.len() + message.len(); - - let mut augmented_message = Vec::with_capacity(m_size); - - augmented_message.extend_from_slice(injected); - augmented_message.extend_from_slice(&message); - - let key = gen_bytes_from_seed(BLOCK_SIZE, &[1, 1, 2, 3, 5, 8, 13]); - - aes_128_ecb_crypt(Mode::Encrypt, &augmented_message, &key) -} - pub fn block_size_oracle<F>(f: F) -> usize where F: Fn(&[u8]) -> Vec<u8> { @@ -84,51 +66,75 @@ pub fn padding_oracle<F>(f: F) -> usize let new_ciphertext = f(&input); - if new_ciphertext.len() > c_size { return input.len(); } } } -// pub fn single_byte_ecb_decrypt<F>(f: F) -> Vec<u8> -// where f: Fn(&[u8]) -> Vec<u8> { -// -// let b_size = block_size_oracle(f); -// let is_ecb = s2c11:ecb_oracle(f, b_size); -// -// if !is_ecb { -// panic!("block cipher doesn't use ECB mode."); -// } -// -// let message = vec!['A' as u8; b_size - 1]; -// -// let ciphertext = encryption_oracle(&message); -// -// let temp = ciphertext.take(b_size); -// -// let mut index = HashMap::new(); -// -// let foo = for byte in 0..256 { -// let mut input = message.clone(); -// input.push(byte); -// -// let encrypted = encryption_oracle(&input); -// index.insert(byte, encrypted); -// }; -// } +pub fn encryption_oracle(injected: &[u8]) -> Vec<u8> { + let message = base64::decode( + "Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg\ + aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq\ + dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg\ + YnkK").unwrap(); -pub fn s2c12() -> String { - let tester = b"hurbitty gurbitty"; - let key = b"YELLOW SUBMARINE"; + let m_size = injected.len() + message.len(); + + let mut augmented_message = Vec::with_capacity(m_size); + + augmented_message.extend_from_slice(injected); + augmented_message.extend_from_slice(&message); + + let key = gen_bytes_from_seed(BLOCK_SIZE, &[1, 1, 2, 3, 5, 8, 13]); + + aes_128_ecb_crypt(Mode::Encrypt, &augmented_message, &key) +} - let black_box = |msg: &[u8]| aes_128_ecb_crypt(Mode::Encrypt, msg, key); +// lifted this just about verbatim from ttaubert/rust-cryptopals +// his looping method is pretty smahhhhhhhhhht +pub fn single_byte_ecb_decrypt<F>(f: F) -> Vec<u8> + where F: Fn(&[u8]) -> Vec<u8> { + + let b_size = block_size_oracle(&f); + let is_ecb = s2c11::ecb_oracle(&f, b_size); // FIXME + let padding = padding_oracle(&f); + + let ciphertext = f(&[]); + let c_size = ciphertext.len(); - let bsize = block_size_oracle(&black_box); - let padding = padding_oracle(&black_box); - let ecb = s2c11::ecb_oracle(black_box, bsize); + let mut input = Vec::from_iter(repeat(b'A').take(c_size)); + let guess = Range { start: c_size - b_size, end: c_size }; + + for index in 0..c_size - padding { + if index % b_size == 0 { + let block = input[guess.clone()].to_vec(); + input.extend(block); + } + + input.remove(0); + + let start = c_size + index - index % b_size; + let target = Range { start: start, end: start + b_size }; + + for byte in 0..256 { + input[c_size - 1] = byte as u8; + let probe = f(&input); + + if probe[guess.clone()] == probe[target.clone()] { + break; + } + } + + } + + input[padding..c_size].to_vec() +} + +pub fn s2c12() -> String { + let message = single_byte_ecb_decrypt(encryption_oracle); - String::from("foo") + String::from_utf8(message).unwrap() }