X-Git-Url: http://git.euphorik.ch/?p=crypto_lab1.git;a=blobdiff_plain;f=lab1_rust%2Fsrc%2Foracle_machine.rs;h=71cee8af3b09543cc482b1080088bacf16b40e1c;hp=a5be2d758b5c6a9003f4728332d8608358e4eba0;hb=d7f0bb987b21e93a5798403d294f7905151682f7;hpb=307b73948c18f26a4ff12fc29f9055397a999f44 diff --git a/lab1_rust/src/oracle_machine.rs b/lab1_rust/src/oracle_machine.rs index a5be2d7..71cee8a 100644 --- a/lab1_rust/src/oracle_machine.rs +++ b/lab1_rust/src/oracle_machine.rs @@ -1,16 +1,17 @@ use std::io; -use std::io::{ TcpStream }; -use std::iter::{ range_inclusive }; +use std::io::TcpStream; +use std::iter::range_inclusive; use std::slice::bytes::copy_memory; use packet; -use packet::{ Packet, Error }; +use packet::Packet; +use packet::PacketType::Error; use end_point::EndPoint; -/// Try to decipher a ciphered data block by using the previous xor operand and an oracle on the provided address and port. -/// May prints some message on the stdout. -pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cipherblock: &[u8, ..16], variant: packet::Variant) -> Option> { +/// Tries to decipher a ciphered data block by using the previous XOR operand and an oracle on the provided address and port. +/// May print some messages on stdout. +pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8; 16], cipher_block: &[u8; 16], variant: packet::Variant) -> Option> { let mut end_point = EndPoint::new( - match TcpStream::connect(address, port) { + match TcpStream::connect((address, port)) { Ok(s) => s, _ => { println!("Unable to connect to the oracle on [{}]:{}", address, port); @@ -20,12 +21,13 @@ pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cip variant, ); - let mut final_packet = [0u8, ..2 + 1 + 8 + 32 + 10]; - final_packet[1] = 1 + 8 + 32 + 10; // Data length. - copy_memory(final_packet.slice_mut(2 + 1 + 8 + 16, 2 + 1 + 8 + 32), cipherblock); + // Sees 'packet::Packet' documentation for a complete description about the binary packet structure. + let mut final_packet = [0u8; 2 + 1 + 8 + 32 + 10]; + final_packet[1] = (final_packet.len() as u8) - 2; // Data length. + copy_memory(final_packet.slice_mut(2 + 1 + 8 + 16, 2 + 1 + 8 + 32), cipher_block); - let mut decipher_block = [0u8, ..16]; // The result. - let mut x_prime_block = [0u8, ..16]; // The cipher block ('cipherblock') after AES and before XOR. + let mut decipher_block = [0u8; 16]; // The result. + let mut x_prime_block = [0u8; 16]; // The cipher block ('cipher_block') after AES and before XOR. let mut current_timestamp = 0u64; let mut first_byte = 0u8; // Used to save the first byte for the first iteration. @@ -39,7 +41,7 @@ pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cip for v in range_inclusive(0u8, 255) { // For each values of the current byte. - // Compute and write timestamp. + // Computes and writes timestamp. current_timestamp += 2; { let mut timestamp_writer = io::BufWriter::new(final_packet.slice_mut(2 + 1, 2 + 1 + 8)); @@ -48,11 +50,12 @@ pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cip forged_xor_operand(&mut final_packet)[byte] = v; - match end_point.send_raw_with_result(final_packet) { - Ok(Ok(p @ Packet { t: Error(packet::AuthError), .. })) => { + match end_point.send_raw_with_result(&final_packet) { + Ok(Ok(p @ Packet { t: Error(packet::ErrorType::Auth), .. })) => { println!("We received a MAC Error: {}", p); - // If we already got a MAC mismatch for the first byte then the second byte is incremented and the loop is replayed. + // If we already got a MAC mismatch for the first byte then + // the second byte is incremented and the main loop is replayed for the first byte. if byte == 15 && get_mac_mismatch_error { forged_xor_operand(&mut final_packet)[14] += 1; continue 'main_loop; @@ -64,19 +67,20 @@ pub fn decipher(address: &str, port: u16, original_xor_operand: &[u8, ..16], cip x_prime_block[byte] = v ^ (padding_value as u8); decipher_block[byte] = x_prime_block[byte] ^ original_xor_operand[byte]; - // We set the processed bytes of the forged XOR operand to have the next padding value. + // We set the processed bytes of the forged XOR operand to have the next padding value (2, 3, 4, etc..). for i in range(16 - padding_value, 16) { forged_xor_operand(&mut final_packet)[i] = x_prime_block[i] ^ ((padding_value as u8) + 1); } - // Special case for the first byte: we have to test all the values. + // Special case for the first byte: we have to test all the values to avoid a valid padding + // which is not [.., 0x01], for instance [.., 0x02, 0x02]. It's a very rare case but not impossible. if byte == 15 { first_byte = forged_xor_operand(&mut final_packet)[15]; } else { break; } }, - Ok(Ok(Packet { t: Error(packet::CryptError), .. })) => (), // Ignored case: the padding is wrong. + Ok(Ok(Packet { t: Error(packet::ErrorType::Crypt), .. })) => (), // Ignored case: the padding is wrong. other => { println!("Unexcepted response, aborting. {}", other); return None