xref: /webrtc/srtp/src/context/context_test.rs (revision 04f0bd9e)
1 use super::*;
2 use crate::key_derivation::*;
3 
4 use bytes::Bytes;
5 use lazy_static::lazy_static;
6 
7 const CIPHER_CONTEXT_ALGO: ProtectionProfile = ProtectionProfile::Aes128CmHmacSha1_80;
8 const DEFAULT_SSRC: u32 = 0;
9 
10 #[test]
11 fn test_context_roc() -> Result<()> {
12     let key_len = CIPHER_CONTEXT_ALGO.key_len();
13     let salt_len = CIPHER_CONTEXT_ALGO.salt_len();
14 
15     let mut c = Context::new(
16         &vec![0; key_len],
17         &vec![0; salt_len],
18         CIPHER_CONTEXT_ALGO,
19         None,
20         None,
21     )?;
22 
23     let roc = c.get_roc(123);
24     assert!(roc.is_none(), "ROC must return None for unused SSRC");
25 
26     c.set_roc(123, 100);
27     let roc = c.get_roc(123);
28     if let Some(r) = roc {
29         assert_eq!(r, 100, "ROC is set to 100, but returned {}", r)
30     } else {
31         assert!(false, "ROC must return value for used SSRC");
32     }
33 
34     Ok(())
35 }
36 
37 #[test]
38 fn test_context_index() -> Result<()> {
39     let key_len = CIPHER_CONTEXT_ALGO.key_len();
40     let salt_len = CIPHER_CONTEXT_ALGO.salt_len();
41 
42     let mut c = Context::new(
43         &vec![0; key_len],
44         &vec![0; salt_len],
45         CIPHER_CONTEXT_ALGO,
46         None,
47         None,
48     )?;
49 
50     let index = c.get_index(123);
51     assert!(index.is_none(), "Index must return None for unused SSRC");
52 
53     c.set_index(123, 100);
54     let index = c.get_index(123);
55     if let Some(i) = index {
56         assert_eq!(i, 100, "Index is set to 100, but returned {}", i);
57     } else {
58         assert!(false, "Index must return true for used SSRC")
59     }
60 
61     Ok(())
62 }
63 
64 #[test]
65 fn test_key_len() -> Result<()> {
66     let key_len = CIPHER_CONTEXT_ALGO.key_len();
67     let salt_len = CIPHER_CONTEXT_ALGO.salt_len();
68 
69     let result = Context::new(&[], &vec![0; salt_len], CIPHER_CONTEXT_ALGO, None, None);
70     assert!(result.is_err(), "CreateContext accepted a 0 length key");
71 
72     let result = Context::new(&vec![0; key_len], &[], CIPHER_CONTEXT_ALGO, None, None);
73     assert!(result.is_err(), "CreateContext accepted a 0 length salt");
74 
75     let result = Context::new(
76         &vec![0; key_len],
77         &vec![0; salt_len],
78         CIPHER_CONTEXT_ALGO,
79         None,
80         None,
81     );
82     assert!(
83         result.is_ok(),
84         "CreateContext failed with a valid length key and salt"
85     );
86 
87     Ok(())
88 }
89 
90 #[test]
91 fn test_valid_packet_counter() -> Result<()> {
92     let master_key = vec![
93         0x0d, 0xcd, 0x21, 0x3e, 0x4c, 0xbc, 0xf2, 0x8f, 0x01, 0x7f, 0x69, 0x94, 0x40, 0x1e, 0x28,
94         0x89,
95     ];
96     let master_salt = vec![
97         0x62, 0x77, 0x60, 0x38, 0xc0, 0x6d, 0xc9, 0x41, 0x9f, 0x6d, 0xd9, 0x43, 0x3e, 0x7c,
98     ];
99 
100     let srtp_session_salt = aes_cm_key_derivation(
101         LABEL_SRTP_SALT,
102         &master_key,
103         &master_salt,
104         0,
105         master_salt.len(),
106     )?;
107 
108     let s = SrtpSsrcState {
109         ssrc: 4160032510,
110         ..Default::default()
111     };
112     let expected_counter = vec![
113         0xcf, 0x90, 0x1e, 0xa5, 0xda, 0xd3, 0x2c, 0x15, 0x00, 0xa2, 0x24, 0xae, 0xae, 0xaf, 0x00,
114         0x00,
115     ];
116     let counter = generate_counter(32846, s.rollover_counter, s.ssrc, &srtp_session_salt)?;
117     assert_eq!(
118         counter, expected_counter,
119         "Session Key {:?} does not match expected {:?}",
120         counter, expected_counter,
121     );
122 
123     Ok(())
124 }
125 
126 #[test]
127 fn test_rollover_count() -> Result<()> {
128     let mut s = SrtpSsrcState {
129         ssrc: DEFAULT_SSRC,
130         ..Default::default()
131     };
132 
133     // Set initial seqnum
134     let roc = s.next_rollover_count(65530);
135     assert_eq!(roc, 0, "Initial rolloverCounter must be 0");
136     s.update_rollover_count(65530);
137 
138     // Invalid packets never update ROC
139     s.next_rollover_count(0);
140     s.next_rollover_count(0x4000);
141     s.next_rollover_count(0x8000);
142     s.next_rollover_count(0xFFFF);
143     s.next_rollover_count(0);
144 
145     // We rolled over to 0
146     let roc = s.next_rollover_count(0);
147     assert_eq!(roc, 1, "rolloverCounter was not updated after it crossed 0");
148     s.update_rollover_count(0);
149 
150     let roc = s.next_rollover_count(65530);
151     assert_eq!(
152         roc, 0,
153         "rolloverCounter was not updated when it rolled back, failed to handle out of order"
154     );
155     s.update_rollover_count(65530);
156 
157     let roc = s.next_rollover_count(5);
158     assert_eq!(
159         roc, 1,
160         "rolloverCounter was not updated when it rolled over initial, to handle out of order"
161     );
162     s.update_rollover_count(5);
163 
164     s.next_rollover_count(6);
165     s.update_rollover_count(6);
166 
167     s.next_rollover_count(7);
168     s.update_rollover_count(7);
169 
170     let roc = s.next_rollover_count(8);
171     assert_eq!(
172         roc, 1,
173         "rolloverCounter was improperly updated for non-significant packets"
174     );
175     s.update_rollover_count(8);
176 
177     // valid packets never update ROC
178     let roc = s.next_rollover_count(0x4000);
179     assert_eq!(
180         roc, 1,
181         "rolloverCounter was improperly updated for non-significant packets"
182     );
183     s.update_rollover_count(0x4000);
184 
185     let roc = s.next_rollover_count(0x8000);
186     assert_eq!(
187         roc, 1,
188         "rolloverCounter was improperly updated for non-significant packets"
189     );
190     s.update_rollover_count(0x8000);
191 
192     let roc = s.next_rollover_count(0xFFFF);
193     assert_eq!(
194         roc, 1,
195         "rolloverCounter was improperly updated for non-significant packets"
196     );
197     s.update_rollover_count(0xFFFF);
198 
199     let roc = s.next_rollover_count(0);
200     assert_eq!(
201         roc, 2,
202         "rolloverCounter must be incremented after wrapping, got {}",
203         roc
204     );
205 
206     Ok(())
207 }
208 
209 lazy_static! {
210     static ref MASTER_KEY: Bytes = Bytes::from_static(&[
211         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
212         0x0f,
213     ]);
214     static ref MASTER_SALT: Bytes = Bytes::from_static(&[
215         0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab,
216     ]);
217     static ref DECRYPTED_RTP_PACKET: Bytes = Bytes::from_static(&[
218         0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab,
219         0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
220     ]);
221     static ref ENCRYPTED_RTP_PACKET: Bytes = Bytes::from_static(&[
222         0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad, 0xca, 0xfe, 0xba, 0xbe, 0xc5, 0x00, 0x2e,
223         0xde, 0x04, 0xcf, 0xdd, 0x2e, 0xb9, 0x11, 0x59, 0xe0, 0x88, 0x0a, 0xa0, 0x6e, 0xd2, 0x97,
224         0x68, 0x26, 0xf7, 0x96, 0xb2, 0x01, 0xdf, 0x31, 0x31, 0xa1, 0x27, 0xe8, 0xa3, 0x92,
225     ]);
226     static ref DECRYPTED_RTCP_PACKET: Bytes = Bytes::from_static(&[
227         0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
228         0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
229     ]);
230     static ref ENCRYPTED_RTCP_PACKET: Bytes = Bytes::from_static(&[
231         0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe, 0xc9, 0x8b, 0x8b, 0x5d, 0xf0, 0x39, 0x2a,
232         0x55, 0x85, 0x2b, 0x6c, 0x21, 0xac, 0x8e, 0x70, 0x25, 0xc5, 0x2c, 0x6f, 0xbe, 0xa2, 0xb3,
233         0xb4, 0x46, 0xea, 0x31, 0x12, 0x3b, 0xa8, 0x8c, 0xe6, 0x1e, 0x80, 0x00, 0x00, 0x01,
234     ]);
235 }
236 
237 #[test]
238 fn test_encrypt_rtp() {
239     let mut ctx = Context::new(
240         &MASTER_KEY,
241         &MASTER_SALT,
242         ProtectionProfile::AeadAes128Gcm,
243         None,
244         None,
245     )
246     .expect("Error creating srtp context");
247 
248     let gotten_encrypted_rtp_packet = ctx
249         .encrypt_rtp(&DECRYPTED_RTP_PACKET)
250         .expect("Error encrypting rtp payload");
251 
252     assert_eq!(gotten_encrypted_rtp_packet, *ENCRYPTED_RTP_PACKET)
253 }
254 
255 #[test]
256 fn test_decrypt_rtp() {
257     let mut ctx = Context::new(
258         &MASTER_KEY,
259         &MASTER_SALT,
260         ProtectionProfile::AeadAes128Gcm,
261         None,
262         None,
263     )
264     .expect("Error creating srtp context");
265 
266     let gotten_decrypted_rtp_packet = ctx
267         .decrypt_rtp(&ENCRYPTED_RTP_PACKET)
268         .expect("Error decrypting rtp payload");
269 
270     assert_eq!(gotten_decrypted_rtp_packet, *DECRYPTED_RTP_PACKET)
271 }
272 
273 #[test]
274 fn test_encrypt_rtcp() {
275     let mut ctx = Context::new(
276         &MASTER_KEY,
277         &MASTER_SALT,
278         ProtectionProfile::AeadAes128Gcm,
279         None,
280         None,
281     )
282     .expect("Error creating srtp context");
283 
284     let gotten_encrypted_rtcp_packet = ctx
285         .encrypt_rtcp(&DECRYPTED_RTCP_PACKET)
286         .expect("Error encrypting rtcp payload");
287 
288     assert_eq!(gotten_encrypted_rtcp_packet, *ENCRYPTED_RTCP_PACKET)
289 }
290 
291 #[test]
292 fn test_decrypt_rtcp() {
293     let mut ctx = Context::new(
294         &MASTER_KEY,
295         &MASTER_SALT,
296         ProtectionProfile::AeadAes128Gcm,
297         None,
298         None,
299     )
300     .expect("Error creating srtp context");
301 
302     let gotten_decrypted_rtcp_packet = ctx
303         .decrypt_rtcp(&ENCRYPTED_RTCP_PACKET)
304         .expect("Error decrypting rtcp payload");
305 
306     assert_eq!(gotten_decrypted_rtcp_packet, *DECRYPTED_RTCP_PACKET)
307 }
308