X-Git-Url: http://git.euphorik.ch/?p=crypto_lab1.git;a=blobdiff_plain;f=lab1_rust%2Fsrc%2Fpacket.rs;h=c9f111a77098dccf97dfafd0477795921548edb8;hp=4016ccb845ce9cea5513eae64c8ffe8d43de113a;hb=d7f0bb987b21e93a5798403d294f7905151682f7;hpb=ffb9351a121dff754127787c80dff9e0bcd49848 diff --git a/lab1_rust/src/packet.rs b/lab1_rust/src/packet.rs index 4016ccb..c9f111a 100644 --- a/lab1_rust/src/packet.rs +++ b/lab1_rust/src/packet.rs @@ -5,14 +5,16 @@ use std::rand::distributions::IndependentSample; use serialize::hex::{ ToHex }; use self::PacketType::{ Command, Answer, Error }; use crypto; +use utils::from_elem; +#[derive(Show, Copy)] pub enum Variant { Weak, // The MAC is computed on data without padding. Fixed // The MAC is computed on data and padding. } // There are all the errors that may occur when reading an encrypted and authenticated packet. -#[deriving(Show)] +#[derive(Show)] pub enum ReadingError { IO(io::IoError), UnknownPacketType, // If the first byte is unknown. @@ -28,10 +30,10 @@ pub enum ReadingError { // A macro to return a 'Err(ReadingError::IO(..))' in case of error. macro_rules! try_read_io( ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(ReadingError::IO(e)) }) -) +); // There are all the errors that may occur when encrypting, authenticating and writing a packet. -#[deriving(Show)] +#[derive(Show)] pub enum WritingError { IO(io::IoError), Encrypt, @@ -40,7 +42,7 @@ pub enum WritingError { // A macro to return a 'Err(WritingError::IO(..))' in case of error. macro_rules! try_write_io( ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(WritingError::IO(e)) }) -) +); pub type ReadingResult = Result; pub type WritingResult = Result<(), WritingError>; @@ -49,19 +51,19 @@ static MIN_PAYLOAD_SIZE: uint = 7; static MAX_PAYLOAD_SIZE: uint = 39; static FIXED_PACKET_SIZE: uint = 1 + 8 + 10; // Packet type + timestamp + MAC. -#[deriving(Show, Clone)] +#[derive(Show, Clone)] pub struct PacketData { id: u8, payload: Vec // The size can vary from 'MIN_PAYLOAD_SIZE' to 'MAX_PAYLOAD_SIZE' bytes. } -#[deriving(Show, Clone)] +#[derive(Show, Clone)] pub enum ErrorType { Crypt, Auth } -#[deriving(Clone)] +#[derive(Clone)] pub enum PacketType { Command(PacketData), Answer(PacketData), @@ -77,22 +79,22 @@ pub enum PacketType { /// 0x0A: Decrypt error /// 0x0B: Authentication error /// TTTTTTTT: Timestamp (64 bits) -/// D...D: Encrypted data (AES-256 CBC mode) of: -/// |I|C...C|P...P| for command and answer packet: -/// I: Command ID -/// C: Command payload (from 7 to 39 bytes) -/// P: Padding from 1 to 16, |I|C...C|P...P| size must be a multiple of 16 -/// |0000000000000000| for error packet (16 bytes length) +/// D...D: Encrypted data (AES-256 CBC mode) of: +/// |I|C...C|P...P| for command and answer packet: +/// I: Command ID +/// C: Command payload (from 7 to 39 bytes) +/// P: Padding from 1 to 16, |I|C...C|P...P| size must be a multiple of 16 +/// |0000000000000000| for error packet (16 bytes length) /// MMMMMMMMMM: first 10 bytes (most significant) of the HMAC-SHA256 of: /// for command and answer packet: /// |I|C...C| for weak variant /// |I|C...C|P...P|for fixed variant /// |0000000000000000| for error packet -#[deriving(Show)] +#[derive(Show)] pub struct Packet { pub t: PacketType, pub timestamp: u64 -} +} impl fmt::Show for PacketType { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -102,7 +104,7 @@ impl fmt::Show for PacketType { match self { &Command(ref data) => write!(formatter, "Command {{ {} }}", data_to_str(data)), &Answer(ref data) => write!(formatter, "Answer {{ {} }}", data_to_str(data)), - &Error(error_type) => write!(formatter, "Error {{ errorType: {} }}", error_type) + &Error(ref error_type) => write!(formatter, "Error {{ errorType: {} }}", error_type) } } } @@ -110,8 +112,8 @@ impl fmt::Show for PacketType { impl Packet { pub fn random_packet_data(seed: &[uint]) -> PacketData { let mut rng = if seed.is_empty() { StdRng::new().unwrap() } else { SeedableRng::from_seed(seed) }; - let mut payload = Vec::from_elem(distributions::Range::new(MIN_PAYLOAD_SIZE, MAX_PAYLOAD_SIZE + 1).ind_sample(&mut rng), 0u8); - rng.fill_bytes(payload.as_mut_slice_()); + let mut payload = from_elem(distributions::Range::new(MIN_PAYLOAD_SIZE, MAX_PAYLOAD_SIZE + 1).ind_sample(&mut rng), 0u8); + rng.fill_bytes(payload.as_mut_slice()); PacketData { id: rng.gen::(), payload: payload @@ -142,7 +144,7 @@ impl Packet { let mut data = match self.t { Command(ref p) | Answer(ref p) => packet_data(p), - Error(_) => Vec::from_elem(16, 0) // Padding as data: 16 * 0. + Error(_) => from_elem(16, 0) // Padding as data: 16 * 0. }; let data_size = data.len(); @@ -209,8 +211,8 @@ impl Packet { let timestamp = try_read_io!(input.read_be_u64()); - let mut encrypted_data = Vec::from_elem(data_size as uint - FIXED_PACKET_SIZE, 0u8); - if try_read_io!(input.read(encrypted_data.as_mut_slice_())) != encrypted_data.len() { + let mut encrypted_data = from_elem(data_size as uint - FIXED_PACKET_SIZE, 0u8); + if try_read_io!(input.read(encrypted_data.as_mut_slice())) != encrypted_data.len() { return Err(ReadingError::UnconsistentEncryptedSize) } let mut data = match crypto::decrypt(encrypted_data.as_slice(), iv_from_timestamp(timestamp).as_slice()) { @@ -219,7 +221,7 @@ impl Packet { }; // Reads the MAC. - let mut mac_read = [0u8, ..10]; + let mut mac_read = [0u8; 10]; if try_read_io!(input.read(&mut mac_read)) != mac_read.len() { return Err(ReadingError::UnconsistentMACSize) } @@ -257,7 +259,7 @@ impl Packet { _ => { if data.len() != 16 { return Err(ReadingError::UnconsistentDataSize) - } else if data != Vec::from_elem(16, 0) { + } else if data != from_elem(16, 0) { return Err(ReadingError::Data) } match packet_type { 0x0A => Error(ErrorType::Crypt), _ => Error(ErrorType::Auth) }