1 // AES-CBC (Cipher Block Chaining) 2 // First historic block cipher for AES. 3 // CBC mode is insecure and must not be used. It’s been progressively deprecated and 4 // removed from SSL libraries. 5 // Introduced with TLS 1.0 year 2002. Superseded by GCM in TLS 1.2 year 2008. 6 // Removed in TLS 1.3 year 2018. 7 // RFC 3268 year 2002 https://tools.ietf.org/html/rfc3268 8 9 // https://github.com/RustCrypto/block-ciphers 10 11 use std::io::Cursor; 12 use std::ops::Not; 13 14 use crate::content::*; 15 use crate::error::*; 16 use crate::prf::*; 17 use crate::record_layer::record_layer_header::*; 18 19 use aes::Aes256; 20 use block_modes::BlockModeError; 21 use block_modes::{BlockMode, Cbc}; 22 use rand::Rng; 23 use subtle::ConstantTimeEq; 24 25 use super::padding::DtlsPadding; 26 type Aes256Cbc = Cbc<Aes256, DtlsPadding>; 27 28 // State needed to handle encrypted input/output 29 #[derive(Clone)] 30 pub struct CryptoCbc { 31 local_key: Vec<u8>, 32 remote_key: Vec<u8>, 33 write_mac: Vec<u8>, 34 read_mac: Vec<u8>, 35 } 36 37 impl CryptoCbc { 38 const BLOCK_SIZE: usize = 16; 39 const MAC_SIZE: usize = 20; 40 new( local_key: &[u8], local_mac: &[u8], remote_key: &[u8], remote_mac: &[u8], ) -> Result<Self>41 pub fn new( 42 local_key: &[u8], 43 local_mac: &[u8], 44 remote_key: &[u8], 45 remote_mac: &[u8], 46 ) -> Result<Self> { 47 Ok(CryptoCbc { 48 local_key: local_key.to_vec(), 49 write_mac: local_mac.to_vec(), 50 51 remote_key: remote_key.to_vec(), 52 read_mac: remote_mac.to_vec(), 53 }) 54 } 55 encrypt(&self, pkt_rlh: &RecordLayerHeader, raw: &[u8]) -> Result<Vec<u8>>56 pub fn encrypt(&self, pkt_rlh: &RecordLayerHeader, raw: &[u8]) -> Result<Vec<u8>> { 57 let mut payload = raw[RECORD_LAYER_HEADER_SIZE..].to_vec(); 58 let raw = &raw[..RECORD_LAYER_HEADER_SIZE]; 59 60 // Generate + Append MAC 61 let h = pkt_rlh; 62 63 let mac = prf_mac( 64 h.epoch, 65 h.sequence_number, 66 h.content_type, 67 h.protocol_version, 68 &payload, 69 &self.write_mac, 70 )?; 71 payload.extend_from_slice(&mac); 72 73 let mut iv: Vec<u8> = vec![0; Self::BLOCK_SIZE]; 74 rand::thread_rng().fill(iv.as_mut_slice()); 75 76 let write_cbc = Aes256Cbc::new_var(&self.local_key, &iv)?; 77 let encrypted = write_cbc.encrypt_vec(&payload); 78 79 // Prepend unencrypte header with encrypted payload 80 let mut r = vec![]; 81 r.extend_from_slice(raw); 82 r.extend_from_slice(&iv); 83 r.extend_from_slice(&encrypted); 84 85 let r_len = (r.len() - RECORD_LAYER_HEADER_SIZE) as u16; 86 r[RECORD_LAYER_HEADER_SIZE - 2..RECORD_LAYER_HEADER_SIZE] 87 .copy_from_slice(&r_len.to_be_bytes()); 88 89 Ok(r) 90 } 91 decrypt(&self, r: &[u8]) -> Result<Vec<u8>>92 pub fn decrypt(&self, r: &[u8]) -> Result<Vec<u8>> { 93 let mut reader = Cursor::new(r); 94 let h = RecordLayerHeader::unmarshal(&mut reader)?; 95 if h.content_type == ContentType::ChangeCipherSpec { 96 // Nothing to encrypt with ChangeCipherSpec 97 return Ok(r.to_vec()); 98 } 99 100 let body = &r[RECORD_LAYER_HEADER_SIZE..]; 101 let iv = &body[0..Self::BLOCK_SIZE]; 102 let body = &body[Self::BLOCK_SIZE..]; 103 //TODO: add body.len() check 104 105 let read_cbc = Aes256Cbc::new_var(&self.remote_key, iv)?; 106 107 let decrypted = read_cbc.decrypt_vec(body)?; 108 109 let recv_mac = &decrypted[decrypted.len() - Self::MAC_SIZE..]; 110 let decrypted = &decrypted[0..decrypted.len() - Self::MAC_SIZE]; 111 let mac = prf_mac( 112 h.epoch, 113 h.sequence_number, 114 h.content_type, 115 h.protocol_version, 116 decrypted, 117 &self.read_mac, 118 )?; 119 120 if recv_mac.ct_eq(&mac).not().into() { 121 return Err(BlockModeError.into()); 122 } 123 124 let mut d = Vec::with_capacity(RECORD_LAYER_HEADER_SIZE + decrypted.len()); 125 d.extend_from_slice(&r[..RECORD_LAYER_HEADER_SIZE]); 126 d.extend_from_slice(decrypted); 127 128 Ok(d) 129 } 130 } 131