1 use super::Cipher;
2 use crate::error::Result;
3 use crate::{error::Error, key_derivation::*, protection_profile::*};
4 use util::marshal::*;
5 
6 use aes::cipher::generic_array::GenericArray;
7 use byteorder::{BigEndian, ByteOrder, WriteBytesExt};
8 use bytes::{BufMut, Bytes, BytesMut};
9 use ctr::cipher::{NewCipher, StreamCipher, StreamCipherSeek};
10 use hmac::{Hmac, Mac};
11 use sha1::Sha1;
12 use std::io::BufWriter;
13 use subtle::ConstantTimeEq;
14 
15 type HmacSha1 = Hmac<Sha1>;
16 type Aes128Ctr = ctr::Ctr128BE<aes::Aes128>;
17 
18 pub const CIPHER_AES_CM_HMAC_SHA1AUTH_TAG_LEN: usize = 10;
19 
20 pub(crate) struct CipherAesCmHmacSha1 {
21     srtp_session_key: Vec<u8>,
22     srtp_session_salt: Vec<u8>,
23     srtp_session_auth: HmacSha1,
24     //srtp_session_auth_tag: Vec<u8>,
25     srtcp_session_key: Vec<u8>,
26     srtcp_session_salt: Vec<u8>,
27     srtcp_session_auth: HmacSha1,
28     //srtcp_session_auth_tag: Vec<u8>,
29 }
30 
31 impl CipherAesCmHmacSha1 {
new(master_key: &[u8], master_salt: &[u8]) -> Result<Self>32     pub fn new(master_key: &[u8], master_salt: &[u8]) -> Result<Self> {
33         let srtp_session_key = aes_cm_key_derivation(
34             LABEL_SRTP_ENCRYPTION,
35             master_key,
36             master_salt,
37             0,
38             master_key.len(),
39         )?;
40         let srtcp_session_key = aes_cm_key_derivation(
41             LABEL_SRTCP_ENCRYPTION,
42             master_key,
43             master_salt,
44             0,
45             master_key.len(),
46         )?;
47 
48         let srtp_session_salt = aes_cm_key_derivation(
49             LABEL_SRTP_SALT,
50             master_key,
51             master_salt,
52             0,
53             master_salt.len(),
54         )?;
55         let srtcp_session_salt = aes_cm_key_derivation(
56             LABEL_SRTCP_SALT,
57             master_key,
58             master_salt,
59             0,
60             master_salt.len(),
61         )?;
62 
63         let auth_key_len = ProtectionProfile::Aes128CmHmacSha1_80.auth_key_len();
64 
65         let srtp_session_auth_tag = aes_cm_key_derivation(
66             LABEL_SRTP_AUTHENTICATION_TAG,
67             master_key,
68             master_salt,
69             0,
70             auth_key_len,
71         )?;
72         let srtcp_session_auth_tag = aes_cm_key_derivation(
73             LABEL_SRTCP_AUTHENTICATION_TAG,
74             master_key,
75             master_salt,
76             0,
77             auth_key_len,
78         )?;
79 
80         let srtp_session_auth = HmacSha1::new_from_slice(&srtp_session_auth_tag)
81             .map_err(|e| Error::Other(e.to_string()))?;
82         let srtcp_session_auth = HmacSha1::new_from_slice(&srtcp_session_auth_tag)
83             .map_err(|e| Error::Other(e.to_string()))?;
84 
85         Ok(CipherAesCmHmacSha1 {
86             srtp_session_key,
87             srtp_session_salt,
88             srtp_session_auth,
89             //srtp_session_auth_tag,
90             srtcp_session_key,
91             srtcp_session_salt,
92             srtcp_session_auth,
93             //srtcp_session_auth_tag,
94         })
95     }
96 
97     /// https://tools.ietf.org/html/rfc3711#section-4.2
98     /// In the case of SRTP, M SHALL consist of the Authenticated
99     /// Portion of the packet (as specified in Figure 1) concatenated with
100     /// the roc, M = Authenticated Portion || roc;
101     ///
102     /// The pre-defined authentication transform for SRTP is HMAC-SHA1
103     /// [RFC2104].  With HMAC-SHA1, the SRTP_PREFIX_LENGTH (Figure 3) SHALL
104     /// be 0.  For SRTP (respectively SRTCP), the HMAC SHALL be applied to
105     /// the session authentication key and M as specified above, i.e.,
106     /// HMAC(k_a, M).  The HMAC output SHALL then be truncated to the n_tag
107     /// left-most bits.
108     /// - Authenticated portion of the packet is everything BEFORE MKI
109     /// - k_a is the session message authentication key
110     /// - n_tag is the bit-length of the output authentication tag
generate_srtp_auth_tag(&mut self, buf: &[u8], roc: u32) -> Result<Vec<u8>>111     fn generate_srtp_auth_tag(&mut self, buf: &[u8], roc: u32) -> Result<Vec<u8>> {
112         self.srtp_session_auth.reset();
113 
114         self.srtp_session_auth.update(buf);
115 
116         // For SRTP only, we need to hash the rollover counter as well.
117         let mut roc_buf: Vec<u8> = vec![];
118         {
119             let mut writer = BufWriter::<&mut Vec<u8>>::new(roc_buf.as_mut());
120             writer.write_u32::<BigEndian>(roc)?;
121         }
122 
123         self.srtp_session_auth.update(&roc_buf);
124 
125         let result = self.srtp_session_auth.clone().finalize();
126         let code_bytes = result.into_bytes();
127 
128         // Truncate the hash to the first AUTH_TAG_SIZE bytes.
129         Ok(code_bytes[0..self.auth_tag_len()].to_vec())
130     }
131 
132     /// https://tools.ietf.org/html/rfc3711#section-4.2
133     ///
134     /// The pre-defined authentication transform for SRTP is HMAC-SHA1
135     /// [RFC2104].  With HMAC-SHA1, the SRTP_PREFIX_LENGTH (Figure 3) SHALL
136     /// be 0.  For SRTP (respectively SRTCP), the HMAC SHALL be applied to
137     /// the session authentication key and M as specified above, i.e.,
138     /// HMAC(k_a, M).  The HMAC output SHALL then be truncated to the n_tag
139     /// left-most bits.
140     /// - Authenticated portion of the packet is everything BEFORE MKI
141     /// - k_a is the session message authentication key
142     /// - n_tag is the bit-length of the output authentication tag
generate_srtcp_auth_tag(&mut self, buf: &[u8]) -> Vec<u8>143     fn generate_srtcp_auth_tag(&mut self, buf: &[u8]) -> Vec<u8> {
144         self.srtcp_session_auth.reset();
145 
146         self.srtcp_session_auth.update(buf);
147 
148         let result = self.srtcp_session_auth.clone().finalize();
149         let code_bytes = result.into_bytes();
150 
151         // Truncate the hash to the first AUTH_TAG_SIZE bytes.
152         code_bytes[0..self.auth_tag_len()].to_vec()
153     }
154 }
155 
156 impl Cipher for CipherAesCmHmacSha1 {
auth_tag_len(&self) -> usize157     fn auth_tag_len(&self) -> usize {
158         CIPHER_AES_CM_HMAC_SHA1AUTH_TAG_LEN
159     }
160 
get_rtcp_index(&self, input: &[u8]) -> usize161     fn get_rtcp_index(&self, input: &[u8]) -> usize {
162         let tail_offset = input.len() - (self.auth_tag_len() + SRTCP_INDEX_SIZE);
163         (BigEndian::read_u32(&input[tail_offset..tail_offset + SRTCP_INDEX_SIZE]) & !(1 << 31))
164             as usize
165     }
166 
encrypt_rtp( &mut self, payload: &[u8], header: &rtp::header::Header, roc: u32, ) -> Result<Bytes>167     fn encrypt_rtp(
168         &mut self,
169         payload: &[u8],
170         header: &rtp::header::Header,
171         roc: u32,
172     ) -> Result<Bytes> {
173         let mut writer =
174             BytesMut::with_capacity(header.marshal_size() + payload.len() + self.auth_tag_len());
175 
176         // Copy the header unencrypted.
177         let data = header.marshal()?;
178         writer.extend(data);
179 
180         // Write the plaintext header to the destination buffer.
181         writer.extend_from_slice(payload);
182 
183         // Encrypt the payload
184         let counter = generate_counter(
185             header.sequence_number,
186             roc,
187             header.ssrc,
188             &self.srtp_session_salt,
189         )?;
190         let key = GenericArray::from_slice(&self.srtp_session_key);
191         let nonce = GenericArray::from_slice(&counter);
192         let mut stream = Aes128Ctr::new(key, nonce);
193         let payload_offset = header.marshal_size();
194         stream.apply_keystream(&mut writer[payload_offset..]);
195 
196         // Generate the auth tag.
197         let auth_tag = self.generate_srtp_auth_tag(&writer, roc)?;
198         writer.extend(auth_tag);
199 
200         Ok(writer.freeze())
201     }
202 
decrypt_rtp( &mut self, encrypted: &[u8], header: &rtp::header::Header, roc: u32, ) -> Result<Bytes>203     fn decrypt_rtp(
204         &mut self,
205         encrypted: &[u8],
206         header: &rtp::header::Header,
207         roc: u32,
208     ) -> Result<Bytes> {
209         if encrypted.len() < self.auth_tag_len() {
210             return Err(Error::SrtpTooSmall(encrypted.len(), self.auth_tag_len()));
211         }
212 
213         let mut writer = BytesMut::with_capacity(encrypted.len() - self.auth_tag_len());
214 
215         // Split the auth tag and the cipher text into two parts.
216         let actual_tag = &encrypted[encrypted.len() - self.auth_tag_len()..];
217         let cipher_text = &encrypted[..encrypted.len() - self.auth_tag_len()];
218 
219         // Generate the auth tag we expect to see from the ciphertext.
220         let expected_tag = self.generate_srtp_auth_tag(cipher_text, roc)?;
221 
222         // See if the auth tag actually matches.
223         // We use a constant time comparison to prevent timing attacks.
224         if actual_tag.ct_eq(&expected_tag).unwrap_u8() != 1 {
225             return Err(Error::RtpFailedToVerifyAuthTag);
226         }
227 
228         // Write cipher_text to the destination buffer.
229         writer.extend_from_slice(cipher_text);
230 
231         // Decrypt the ciphertext for the payload.
232         let counter = generate_counter(
233             header.sequence_number,
234             roc,
235             header.ssrc,
236             &self.srtp_session_salt,
237         )?;
238 
239         let key = GenericArray::from_slice(&self.srtp_session_key);
240         let nonce = GenericArray::from_slice(&counter);
241         let mut stream = Aes128Ctr::new(key, nonce);
242         let payload_offset = header.marshal_size();
243         stream.seek(0);
244         stream.apply_keystream(&mut writer[payload_offset..]);
245 
246         Ok(writer.freeze())
247     }
248 
encrypt_rtcp(&mut self, decrypted: &[u8], srtcp_index: usize, ssrc: u32) -> Result<Bytes>249     fn encrypt_rtcp(&mut self, decrypted: &[u8], srtcp_index: usize, ssrc: u32) -> Result<Bytes> {
250         let mut writer =
251             BytesMut::with_capacity(decrypted.len() + SRTCP_INDEX_SIZE + self.auth_tag_len());
252 
253         // Write the decrypted to the destination buffer.
254         writer.extend_from_slice(decrypted);
255 
256         // Encrypt everything after header
257         let counter = generate_counter(
258             (srtcp_index & 0xFFFF) as u16,
259             (srtcp_index >> 16) as u32,
260             ssrc,
261             &self.srtcp_session_salt,
262         )?;
263 
264         let key = GenericArray::from_slice(&self.srtcp_session_key);
265         let nonce = GenericArray::from_slice(&counter);
266         let mut stream = Aes128Ctr::new(key, nonce);
267 
268         stream.apply_keystream(
269             &mut writer[rtcp::header::HEADER_LENGTH + rtcp::header::SSRC_LENGTH..],
270         );
271 
272         // Add SRTCP index and set Encryption bit
273         writer.put_u32(srtcp_index as u32 | (1u32 << 31));
274 
275         // Generate the auth tag.
276         let auth_tag = self.generate_srtcp_auth_tag(&writer);
277         writer.extend(auth_tag);
278 
279         Ok(writer.freeze())
280     }
281 
decrypt_rtcp(&mut self, encrypted: &[u8], srtcp_index: usize, ssrc: u32) -> Result<Bytes>282     fn decrypt_rtcp(&mut self, encrypted: &[u8], srtcp_index: usize, ssrc: u32) -> Result<Bytes> {
283         if encrypted.len() < self.auth_tag_len() + SRTCP_INDEX_SIZE {
284             return Err(Error::SrtcpTooSmall(
285                 encrypted.len(),
286                 self.auth_tag_len() + SRTCP_INDEX_SIZE,
287             ));
288         }
289 
290         let tail_offset = encrypted.len() - (self.auth_tag_len() + SRTCP_INDEX_SIZE);
291 
292         let mut writer = BytesMut::with_capacity(tail_offset);
293 
294         writer.extend_from_slice(&encrypted[0..tail_offset]);
295 
296         let is_encrypted = encrypted[tail_offset] >> 7;
297         if is_encrypted == 0 {
298             return Ok(writer.freeze());
299         }
300 
301         // Split the auth tag and the cipher text into two parts.
302         let actual_tag = &encrypted[encrypted.len() - self.auth_tag_len()..];
303         let cipher_text = &encrypted[..encrypted.len() - self.auth_tag_len()];
304 
305         // Generate the auth tag we expect to see from the ciphertext.
306         let expected_tag = self.generate_srtcp_auth_tag(cipher_text);
307 
308         // See if the auth tag actually matches.
309         // We use a constant time comparison to prevent timing attacks.
310         if actual_tag.ct_eq(&expected_tag).unwrap_u8() != 1 {
311             return Err(Error::RtcpFailedToVerifyAuthTag);
312         }
313 
314         let counter = generate_counter(
315             (srtcp_index & 0xFFFF) as u16,
316             (srtcp_index >> 16) as u32,
317             ssrc,
318             &self.srtcp_session_salt,
319         )?;
320 
321         let key = GenericArray::from_slice(&self.srtcp_session_key);
322         let nonce = GenericArray::from_slice(&counter);
323         let mut stream = Aes128Ctr::new(key, nonce);
324 
325         stream.seek(0);
326         stream.apply_keystream(
327             &mut writer[rtcp::header::HEADER_LENGTH + rtcp::header::SSRC_LENGTH..],
328         );
329 
330         Ok(writer.freeze())
331     }
332 }
333