From 1c663ca4e0cf4584e941e18d967d38ee628c9e0d Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Thu, 18 Apr 2019 04:24:54 -0400 Subject: problem 35 --- src/crack.rs | 111 +++++++++++++++++++++++++++++++++++++------------- src/dh.rs | 4 +- tests/set5.rs | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 196 insertions(+), 46 deletions(-) diff --git a/src/crack.rs b/src/crack.rs index a4e7005..e65ea35 100644 --- a/src/crack.rs +++ b/src/crack.rs @@ -785,29 +785,87 @@ pub struct ParameterInjectionDiffieHellmanMessageExchanger { } impl ParameterInjectionDiffieHellmanMessageExchanger { - pub fn new() -> ParameterInjectionDiffieHellmanMessageExchanger { + pub fn new( + inject_pg: F, + inject_pubkey: G, + generate_s: H, + ) -> ParameterInjectionDiffieHellmanMessageExchanger + where + F: 'static + + Send + + Fn( + num_bigint::BigUint, + num_bigint::BigUint, + ) -> (num_bigint::BigUint, num_bigint::BigUint), + G: 'static + + Send + + Fn( + num_bigint::BigUint, + num_bigint::BigUint, + num_bigint::BigUint, + ) -> num_bigint::BigUint, + H: 'static + + Send + + Fn( + num_bigint::BigUint, + num_bigint::BigUint, + ) -> Vec, + { let (a_sender, ma_recver) = crossbeam::channel::unbounded(); let (ma_sender, b_recver) = crossbeam::channel::unbounded(); let (b_sender, mb_recver) = crossbeam::channel::unbounded(); let (mb_sender, a_recver) = crossbeam::channel::unbounded(); let thread = std::thread::spawn(move || { + let p_bytes: Vec = ma_recver.recv().unwrap(); + let p: num_bigint::BigUint = + serde_json::from_slice(&p_bytes).unwrap(); + let g_bytes: Vec = ma_recver.recv().unwrap(); + let g: num_bigint::BigUint = + serde_json::from_slice(&g_bytes).unwrap(); + + let (modified_p, modified_g) = inject_pg(p.clone(), g.clone()); + ma_sender + .send(serde_json::to_vec(&modified_p).unwrap()) + .unwrap(); + ma_sender + .send(serde_json::to_vec(&modified_g).unwrap()) + .unwrap(); + + let p_bytes: Vec = mb_recver.recv().unwrap(); + let p: num_bigint::BigUint = + serde_json::from_slice(&p_bytes).unwrap(); + let g_bytes: Vec = mb_recver.recv().unwrap(); + let g: num_bigint::BigUint = + serde_json::from_slice(&g_bytes).unwrap(); + mb_sender + .send(serde_json::to_vec(&modified_p).unwrap()) + .unwrap(); + mb_sender + .send(serde_json::to_vec(&modified_g).unwrap()) + .unwrap(); + + let possible_s = + generate_s(modified_p.clone(), modified_g.clone()); + let a_bytes: Vec = ma_recver.recv().unwrap(); - let a: crate::dh::DHKeyPair = + let a_pubkey: num_bigint::BigUint = serde_json::from_slice(&a_bytes).unwrap(); - let mut modified_a = a.clone(); - modified_a.pubkey = modified_a.p.clone(); + + let modified_pubkey_a = + inject_pubkey(p.clone(), g.clone(), a_pubkey); ma_sender - .send(serde_json::to_vec(&modified_a).unwrap()) + .send(serde_json::to_vec(&modified_pubkey_a).unwrap()) .unwrap(); let b_bytes: Vec = mb_recver.recv().unwrap(); - let b: crate::dh::DHKeyPair = + let b_pubkey: num_bigint::BigUint = serde_json::from_slice(&b_bytes).unwrap(); - let mut modified_b = b.clone(); - modified_b.pubkey = modified_b.p.clone(); + + let modified_pubkey_b = + inject_pubkey(p.clone(), g.clone(), b_pubkey); mb_sender - .send(serde_json::to_vec(&modified_b).unwrap()) + .send(serde_json::to_vec(&modified_pubkey_b).unwrap()) .unwrap(); let a_ciphertext = ma_recver.recv().unwrap(); @@ -820,25 +878,22 @@ impl ParameterInjectionDiffieHellmanMessageExchanger { let b_iv = mb_recver.recv().unwrap(); mb_sender.send(b_iv.clone()).unwrap(); - let s = num_bigint::BigUint::from(0 as u8); - let mut aes_key = crate::sha1::sha1(&s.to_bytes_le()).to_vec(); - aes_key.truncate(16); - - let a_plaintext = crate::aes::decrypt_aes_128_cbc( - &a_ciphertext, - &aes_key, - &a_iv, - ) - .unwrap(); - let b_plaintext = crate::aes::decrypt_aes_128_cbc( - &b_ciphertext, - &aes_key, - &b_iv, - ) - .unwrap(); - assert_eq!(a_plaintext, b_plaintext); - - a_plaintext + for s in possible_s { + let mut aes_key = + crate::sha1::sha1(&s.to_bytes_le()).to_vec(); + aes_key.truncate(16); + + let a_plaintext = crate::aes::decrypt_aes_128_cbc( + &a_ciphertext, + &aes_key, + &a_iv, + ); + if let Some(a_plaintext) = a_plaintext { + return a_plaintext; + } + } + + unreachable!() }); ParameterInjectionDiffieHellmanMessageExchanger { diff --git a/src/dh.rs b/src/dh.rs index 0db0bb2..5e368d9 100644 --- a/src/dh.rs +++ b/src/dh.rs @@ -1,12 +1,10 @@ use num_bigint::RandBigInt; -use serde_derive::{Deserialize, Serialize}; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug)] pub struct DHKeyPair { pub p: num_bigint::BigUint, pub g: num_bigint::BigUint, pub pubkey: num_bigint::BigUint, - #[serde(skip)] privkey: Option, } diff --git a/tests/set5.rs b/tests/set5.rs index 594b420..8cab7df 100644 --- a/tests/set5.rs +++ b/tests/set5.rs @@ -35,22 +35,23 @@ fn problem_34() { let p = num_bigint::BigUint::parse_bytes(p_hex.as_bytes(), 16).unwrap(); let g = num_bigint::BigUint::from(2 as u8); - let a = matasano::DHKeyPair::new(p.clone(), g.clone()); - let b = matasano::DHKeyPair::new(p.clone(), g.clone()); - let plaintext = b"Summertime and the wind is blowing outside in \ lower Chelsea and I don't know what I'm doing \ in the city, the sun is always in my eyes"; let null_exchanger = matasano::NullDiffieHellmanMessageExchanger::new(); - run_dh_message_exchange(&null_exchanger, &a, &b, &plaintext[..]); + run_dh_message_exchange(&null_exchanger, &p, &g, &plaintext[..]); let parameter_injection_exchanger = - matasano::ParameterInjectionDiffieHellmanMessageExchanger::new(); + matasano::ParameterInjectionDiffieHellmanMessageExchanger::new( + |p, g| (p, g), + |p, _, _| p, + |_, _| vec![num_bigint::BigUint::from(0 as u8)], + ); run_dh_message_exchange( ¶meter_injection_exchanger, - &a, - &b, + &p, + &g, &plaintext[..], ); assert_eq!( @@ -59,10 +60,79 @@ fn problem_34() { ); } +#[test] +fn problem_35() { + let p_hex = "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024\ + e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd\ + 3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec\ + 6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f\ + 24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361\ + c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552\ + bb9ed529077096966d670c354e4abc9804f1746c08ca237327fff\ + fffffffffffff"; + let p = num_bigint::BigUint::parse_bytes(p_hex.as_bytes(), 16).unwrap(); + let g = num_bigint::BigUint::from(2 as u8); + + let plaintext = b"Summertime and the wind is blowing outside in \ + lower Chelsea and I don't know what I'm doing \ + in the city, the sun is always in my eyes"; + + let parameter_injection_exchanger_g_1 = + matasano::ParameterInjectionDiffieHellmanMessageExchanger::new( + |p, _| (p, num_bigint::BigUint::from(1 as u8)), + |_, _, pubkey| pubkey, + |_, _| vec![num_bigint::BigUint::from(1 as u8)], + ); + run_dh_message_exchange( + ¶meter_injection_exchanger_g_1, + &p, + &g, + &plaintext[..], + ); + assert_eq!( + parameter_injection_exchanger_g_1.retrieve_plaintext(), + plaintext.to_vec(), + ); + + let parameter_injection_exchanger_g_p = + matasano::ParameterInjectionDiffieHellmanMessageExchanger::new( + |p, _| (p.clone(), p), + |_, _, pubkey| pubkey, + |_, _| vec![num_bigint::BigUint::from(0 as u8)], + ); + run_dh_message_exchange( + ¶meter_injection_exchanger_g_p, + &p, + &g, + &plaintext[..], + ); + assert_eq!( + parameter_injection_exchanger_g_p.retrieve_plaintext(), + plaintext.to_vec(), + ); + + let parameter_injection_exchanger_g_p_minus_1 = + matasano::ParameterInjectionDiffieHellmanMessageExchanger::new( + |p, _| (p.clone(), p - 1u8), + |_, _, pubkey| pubkey, + |p, _| vec![num_bigint::BigUint::from(1 as u8), p - 1u8], + ); + run_dh_message_exchange( + ¶meter_injection_exchanger_g_p_minus_1, + &p, + &g, + &plaintext[..], + ); + assert_eq!( + parameter_injection_exchanger_g_p_minus_1.retrieve_plaintext(), + plaintext.to_vec(), + ); +} + fn run_dh_message_exchange( exchanger: &T, - a: &matasano::DHKeyPair, - b: &matasano::DHKeyPair, + p: &num_bigint::BigUint, + g: &num_bigint::BigUint, plaintext: &[u8], ) where T: matasano::DiffieHellmanMessageExchanger, @@ -76,11 +146,26 @@ fn run_dh_message_exchange( let key_compare_sender_b = key_compare_sender_a.clone(); let a_runner = s.spawn(move |_| { - a_sender.send(serde_json::to_vec(a).unwrap()).unwrap(); + a_sender.send(serde_json::to_vec(p).unwrap()).unwrap(); + a_sender.send(serde_json::to_vec(g).unwrap()).unwrap(); + let p_bytes = a_recver.recv().unwrap(); + let negotiated_p: num_bigint::BigUint = + serde_json::from_slice(&p_bytes).unwrap(); + let g_bytes = a_recver.recv().unwrap(); + let negotiated_g: num_bigint::BigUint = + serde_json::from_slice(&g_bytes).unwrap(); + let a = matasano::DHKeyPair::new( + negotiated_p.clone(), + negotiated_g.clone(), + ); + + a_sender + .send(serde_json::to_vec(&a.pubkey).unwrap()) + .unwrap(); let b_bytes = a_recver.recv().unwrap(); - let b: matasano::DHKeyPair = + let b_pubkey: num_bigint::BigUint = serde_json::from_slice(&b_bytes).unwrap(); - let s = a.key_exchange(&b.pubkey); + let s = a.key_exchange(&b_pubkey); let mut aes_key = matasano::sha1(&s.to_bytes_le()).to_vec(); aes_key.truncate(16); @@ -103,11 +188,23 @@ fn run_dh_message_exchange( assert_ne!(ciphertext, b_ciphertext); }); let b_runner = s.spawn(move |_| { - b_sender.send(serde_json::to_vec(b).unwrap()).unwrap(); + let p_bytes = b_recver.recv().unwrap(); + let p: num_bigint::BigUint = + serde_json::from_slice(&p_bytes).unwrap(); + let g_bytes = b_recver.recv().unwrap(); + let g: num_bigint::BigUint = + serde_json::from_slice(&g_bytes).unwrap(); + b_sender.send(serde_json::to_vec(&p).unwrap()).unwrap(); + b_sender.send(serde_json::to_vec(&g).unwrap()).unwrap(); + + let b = matasano::DHKeyPair::new(p.clone(), g.clone()); + b_sender + .send(serde_json::to_vec(&b.pubkey).unwrap()) + .unwrap(); let a_bytes = b_recver.recv().unwrap(); - let a: matasano::DHKeyPair = + let a_pubkey: num_bigint::BigUint = serde_json::from_slice(&a_bytes).unwrap(); - let s = b.key_exchange(&a.pubkey); + let s = b.key_exchange(&a_pubkey); let mut aes_key = matasano::sha1(&s.to_bytes_le()).to_vec(); aes_key.truncate(16); -- cgit v1.2.3-54-g00ecf