Disable automatic padding.
authorUmmon <greg.burri@gmail.com>
Mon, 3 Nov 2014 12:25:23 +0000 (13:25 +0100)
committerUmmon <greg.burri@gmail.com>
Mon, 3 Nov 2014 12:25:23 +0000 (13:25 +0100)
src/crypto.rs
src/packet.rs

index 39e8696..35c7b48 100644 (file)
@@ -16,16 +16,34 @@ pub fn compute_mac(data: &[u8]) -> [u8, ..10] {
    result
 }
 
-pub fn encrypt(plaindata: &[u8], iv: &[u8]) -> Vec<u8> {
-   symm::encrypt(symm::AES_256_CBC, KEY_C, iv.to_vec(), plaindata)
+pub fn encrypt(plaindata: &[u8], iv: &[u8]) -> Option<Vec<u8>> {
+   let c = symm::Crypter::new(symm::AES_256_CBC);
+   c.init(symm::Encrypt, KEY_C, iv.to_vec());
+   c.pad(false); // Padding disabled!
+   let mut r = c.update(plaindata);
+   let rest = c.finalize();
+   if rest.is_empty() {
+      Some(r)
+   } else {
+      None
+   }
 }
 
-pub fn decrypt(cypherdata: &[u8], iv: &[u8]) -> Vec<u8> {
-   symm::decrypt(symm::AES_256_CBC, KEY_C, iv.to_vec(), cypherdata)
+pub fn decrypt(cypherdata: &[u8], iv: &[u8]) -> Option<Vec<u8>> {
+   let c = symm::Crypter::new(symm::AES_256_CBC);
+   c.init(symm::Decrypt, KEY_C, iv.to_vec());
+   c.pad(false); // Padding disabled!
+   let mut r = c.update(cypherdata);
+   let rest = c.finalize();
+   if rest.is_empty() {
+      Some(r)
+   } else {
+      None
+   }
 }
 
 pub fn generate_key(size_byte: uint) -> IoResult<Vec<u8>>  {
-   let mut bytes = Vec::      from_elem(size_byte, 0u8);
+   let mut bytes = Vec::from_elem(size_byte, 0u8);
    let mut generator = try!(OsRng::new()); // Uses '/dev/urandom' on Unix-like systems.
    generator.fill_bytes(bytes.as_mut_slice_());
    Ok(bytes)
index 632d298..73eecea 100644 (file)
@@ -27,8 +27,8 @@ macro_rules! try_read_io(
 // There are all the errors that may occur when encrypting, authenticating and writing a packet.
 #[deriving(Show)]
 pub enum WritingError {
-   WriteIOError(io::IoError)
-   // TODO...
+   WriteIOError(io::IoError),
+   EncryptError,
 }
 
 // A macro to return a 'IOWritingError' in case of error.
@@ -64,7 +64,7 @@ pub enum PacketType {
 
 /// Serialized packet format : |LL|P|TTTTTTTT|D...D|MMMMMMMMMM|
 /// Where:
-///   LL: Size on the following data
+///   LL: Size of the following data
 ///   P: Packet type:
 ///      0x00: Command
 ///      OxFF: Answer
@@ -78,7 +78,7 @@ pub enum PacketType {
 ///            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:
-///      |I|C...C| for command ans answer packet
+///      |I|C...C| for command and answer packet
 ///      |0000000000000000| for error packet
 #[deriving(Show)]
 pub struct Packet {
@@ -115,12 +115,12 @@ impl Packet {
    }
 
    pub fn write(&self, output: &mut io::Writer) -> WritingResult {
-      self.write_with_padding_fun(output, |_: uint, padding_length: uint| -> u8 {
+      self.write_with_padding_fun(output, |_, padding_length: uint| -> u8 {
          padding_length as u8
       })
    }
 
-   /// 'padd_fun' is function to fill the padding. The first argument is the index of the current byte, starting at 0.
+   /// 'padd_fun' is function defining the padding. The first argument is the index of the current byte, starting at 0.
    /// The second argument is the padding length.
    pub fn write_with_padding_fun(&self, output: &mut io::Writer, padd_fun: |uint, uint| -> u8) -> WritingResult {
       fn packet_data(p: &PacketData) -> Vec<u8> {
@@ -143,7 +143,7 @@ impl Packet {
       // Padding.
       match self.t {
          Command(_) | Answer(_) => {
-            let padding_size = if data.len() % 16 == 0 { 16 } else { data.len() % 16 } ;
+            let padding_size = if data.len() % 16 == 0 { 16 } else { 16 - data.len() % 16 } ;
             data.reserve_additional(padding_size);
             for i in range(0, padding_size) {
                data.push(padd_fun(i, padding_size));
@@ -152,12 +152,11 @@ impl Packet {
          _ => ()
       }
 
-      println!("data not crypted: {}", data);
-
       // Encrypt.
-      let encrypted_data = crypto::encrypt(data.as_slice(), iv_from_timestamp(self.timestamp).as_slice());
-
-      println!("data crypted: {}", encrypted_data);
+      let encrypted_data = match crypto::encrypt(data.as_slice(), iv_from_timestamp(self.timestamp).as_slice()) {
+         Some(d) => d,
+         _ => return Err(EncryptError)
+      };
 
       // Write packet length.
       try_write_io!(output.write_be_u16((encrypted_data.len() + FIXED_PACKET_SIZE) as u16));
@@ -204,7 +203,10 @@ impl Packet {
       if try_read_io!(input.read(encrypted_data.as_mut_slice_())) != encrypted_data.len() {
          return Err(UnconsistentEncryptedSizeError)
       }
-      let mut data = crypto::decrypt(encrypted_data.as_slice(), iv_from_timestamp(timestamp).as_slice());
+      let mut data = match crypto::decrypt(encrypted_data.as_slice(), iv_from_timestamp(timestamp).as_slice()) {
+         Some(d) => d,
+         _ => return Err(UnconsistentEncryptedSizeError)
+      };
 
       // Control the size and the content of the padding then remove it.
       if packet_type == 0x00 || packet_type == 0xFF {