summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2019-04-18 04:24:54 -0400
committerJesse Luehrs <doy@tozt.net>2019-04-18 04:24:54 -0400
commit1c663ca4e0cf4584e941e18d967d38ee628c9e0d (patch)
treefd5ce6f2b874899bfac87bfd721afd1d7572cded
parentcaaf7016fcecd3a95df53e65150666d50bd0fbcf (diff)
downloadmatasano-1c663ca4e0cf4584e941e18d967d38ee628c9e0d.tar.gz
matasano-1c663ca4e0cf4584e941e18d967d38ee628c9e0d.zip
problem 35
-rw-r--r--src/crack.rs111
-rw-r--r--src/dh.rs4
-rw-r--r--tests/set5.rs127
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<F, G, H>(
+ 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<num_bigint::BigUint>,
+ {
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<u8> = ma_recver.recv().unwrap();
+ let p: num_bigint::BigUint =
+ serde_json::from_slice(&p_bytes).unwrap();
+ let g_bytes: Vec<u8> = 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<u8> = mb_recver.recv().unwrap();
+ let p: num_bigint::BigUint =
+ serde_json::from_slice(&p_bytes).unwrap();
+ let g_bytes: Vec<u8> = 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<u8> = 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<u8> = 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<num_bigint::BigUint>,
}
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(
&parameter_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(
+ &parameter_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(
+ &parameter_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(
+ &parameter_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<T>(
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<T>(
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<T>(
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);