cryptopals

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

commit 0bac88e3bb33c388147e3446c4b6a186e3fef9dc
parent f5e296b7aff44a16e70dd68588e4204b169ca2c6
Author: Jared Tobin <jared@jtobin.ca>
Date:   Sun, 28 May 2017 23:11:27 +1200

WIP.

Diffstat:
Alib/aes_cbc/Cargo.lock | 197+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alib/aes_cbc/Cargo.toml | 10++++++++++
Alib/aes_cbc/src/main.rs | 152+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 359 insertions(+), 0 deletions(-)

diff --git a/lib/aes_cbc/Cargo.lock b/lib/aes_cbc/Cargo.lock @@ -0,0 +1,197 @@ +[root] +name = "aes_cbc" +version = "0.1.0" +dependencies = [ + "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ansi_term" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "atty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "base64" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byteorder" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "clap" +version = "2.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "foreign-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "gcc" +version = "0.3.49" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "gdi32-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "openssl" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "openssl-sys" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", + "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pkg-config" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "strsim" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "term_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-segmentation" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-width" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "user32-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "vec_map" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" +"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159" +"checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557" +"checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4" +"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8" +"checksum clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b8f69e518f967224e628896b54e41ff6acfb4dcfefc5076325c36525dac900f" +"checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d" +"checksum gcc 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)" = "9be730064c122681712957ba1a9abaf082150be8aaf94526a805d900015b65b9" +"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" +"checksum libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)" = "e7eb6b826bfc1fdea7935d46556250d1799b7fe2d9f7951071f4291710665e3e" +"checksum openssl 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bb5d1663b73d10c6a3eda53e2e9d0346f822394e7b858d7257718f65f61dfbe2" +"checksum openssl-sys 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)" = "3a5886d87d3e2a0d890bf62dc8944f5e3769a405f7e1e9ef6e517e47fd7a0897" +"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" +"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" +"checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209" +"checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946" +"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" +"checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47" +"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/lib/aes_cbc/Cargo.toml b/lib/aes_cbc/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "aes_cbc" +version = "0.1.0" +authors = ["Jared Tobin <jared@jtobin.ca>"] + +[dependencies] + +base64 = "~0.5.0" +clap = "2.24.2" +openssl = "0.9.11" diff --git a/lib/aes_cbc/src/main.rs b/lib/aes_cbc/src/main.rs @@ -0,0 +1,152 @@ + +// hat tip to ttaubert/rust-cryptopals for lots of help here + +extern crate base64; +extern crate clap; +extern crate openssl; + +use openssl::symm::{Cipher, Crypter, Mode}; +use std::io::{self, Read}; +use clap::{App, Arg}; + +fn fixed_xor(target: Vec<u8>, partner: Vec<u8>) -> Vec<u8> { + assert_eq!(target.len(), partner.len()); + + target + .iter() + .zip(partner) + .map(|(&l, r)| l ^ r) + .collect() +} + +fn new_crypter_unpadded( + cipher: Cipher, + mode: Mode, + key: &[u8], + iv: Option<&[u8]> + ) -> Crypter { + + let mut crypter = match Crypter::new(cipher, mode, key, iv) { + Ok(val) => val, + Err(err) => panic!("{}", err) + }; + + crypter.pad(false); + + crypter +} + +fn ecb_128_crypt(mode: Mode, key: &[u8], text: &[u8]) -> Vec<u8> { + let cipher = Cipher::aes_128_ecb(); + let iv = None; + + let mut crypter = new_crypter_unpadded(cipher, mode, key, iv); + let mut result = vec![0; text.len() + cipher.key_len()]; + + let decrypted_len = match crypter.update(&text, result.as_mut_slice()) { + Ok(val) => val, + Err(err) => panic!("{}", err) + }; + + (&result[0..decrypted_len]).to_vec() +} + +fn ecb_128_encrypt(key: &[u8], text: &[u8]) -> Vec<u8> { + ecb_128_crypt(Mode::Encrypt, key, text) +} + +fn ecb_128_decrypt(key: &[u8], text: &[u8]) -> Vec<u8> { + ecb_128_crypt(Mode::Decrypt, key, text) +} + +fn cbc_128_encrypt(key: &[u8], text: &[u8], iv: Vec<u8>) -> Vec<u8> { + let mut iv = iv; + let mut ciphertext = Vec::with_capacity(text.len()); + + for block in text.chunks(16) { + let xored = fixed_xor(iv, block.to_vec()); + let encrypted = ecb_128_encrypt(key, xored.as_slice()); + + ciphertext.extend(encrypted.clone()); + iv = encrypted; + } + + ciphertext +} + +fn cbc_128_decrypt(key: &[u8], text: &[u8], iv: Vec<u8>) -> Vec<u8> { + let mut iv = iv; + let mut plain = Vec::with_capacity(text.len()); + + for block in text.chunks(16) { + let decrypted = ecb_128_decrypt(key, block); + plain.extend(fixed_xor(decrypted, iv)); + + iv = block.to_vec(); + } + + plain +} + +fn main() { + let args = App::new("aes_cbc") + .version("0.1") + .about("AES ECB/CBC tools") + .arg(Arg::with_name("key") + .short("k") + .long("key") + .value_name("KEY") + .takes_value(true) + .required(true)) + .arg(Arg::with_name("mode") + .short("e") + .long("encrypt") + .help("encrypt (instead of decrypt)")) + .arg(Arg::with_name("iv") + .short("i") + .long("iv") + .value_name("INIT") + .takes_value(true) + .help("initial value")) + .get_matches(); + + let mut buffer = String::new(); + + io::stdin().read_to_string(&mut buffer).expect("aes_cbc"); + + let decoded = match base64::decode(&buffer) { + Ok(val) => val, + Err(err) => panic!("{}", err) + }; + + let mode = match args.occurrences_of("mode") { + 0 => Mode::Decrypt, + _ => Mode::Encrypt, + }; + + let key = match args.value_of("key") { + Some(text) => + if text.len() == 16 { + text.as_bytes() + } else { + panic!("invalid key length!"); + }, + None => panic!("no key provided.") + }; + + let iv = match args.value_of("iv") { + Some(text) => text.as_bytes().to_vec(), + None => (&[0u8; 16]).to_vec(), + }; + + let output = match mode { + Mode::Decrypt => cbc_128_decrypt(&decoded[..], key, iv), + Mode::Encrypt => cbc_128_encrypt(&decoded[..], key, iv), + }; + + match mode { + Mode::Decrypt => println!("{}", String::from_utf8_lossy(&output)), + Mode::Encrypt => println!("{}", base64::encode(&output)), + }; +} +