1 use super::*; 2 use util::marshal::*; 3 4 use bytes::Bytes; 5 use lazy_static::lazy_static; 6 7 struct RTPTestCase { 8 sequence_number: u16, 9 encrypted: Bytes, 10 } 11 12 lazy_static! { 13 static ref RTP_TEST_CASE_DECRYPTED: Bytes = Bytes::from_static(&[0x00, 0x01, 0x02, 0x03, 0x04, 0x05]); 14 static ref RTP_TEST_CASES: Vec<RTPTestCase> = vec![ 15 RTPTestCase { 16 sequence_number: 5000, 17 encrypted: Bytes::from_static(&[ 18 0x6d, 0xd3, 0x7e, 0xd5, 0x99, 0xb7, 0x2d, 0x28, 0xb1, 0xf3, 0xa1, 0xf0, 0xc, 0xfb, 19 0xfd, 0x8 20 ]), 21 }, 22 RTPTestCase { 23 sequence_number: 5001, 24 encrypted: Bytes::from_static(&[ 25 0xda, 0x47, 0xb, 0x2a, 0x74, 0x53, 0x65, 0xbd, 0x2f, 0xeb, 0xdc, 0x4b, 0x6d, 0x23, 26 0xf3, 0xde 27 ]), 28 }, 29 RTPTestCase { 30 sequence_number: 5002, 31 encrypted: Bytes::from_static(&[ 32 0x6e, 0xa7, 0x69, 0x8d, 0x24, 0x6d, 0xdc, 0xbf, 0xec, 0x2, 0x1c, 0xd1, 0x60, 0x76, 33 0xc1, 0x0e 34 ]), 35 }, 36 RTPTestCase { 37 sequence_number: 5003, 38 encrypted: Bytes::from_static(&[ 39 0x24, 0x7e, 0x96, 0xc8, 0x7d, 0x33, 0xa2, 0x92, 0x8d, 0x13, 0x8d, 0xe0, 0x76, 0x9f, 40 0x08, 0xdc 41 ]), 42 }, 43 RTPTestCase { 44 sequence_number: 5004, 45 encrypted: Bytes::from_static(&[ 46 0x75, 0x43, 0x28, 0xe4, 0x3a, 0x77, 0x59, 0x9b, 0x2e, 0xdf, 0x7b, 0x12, 0x68, 0x0b, 47 0x57, 0x49 48 ]), 49 }, 50 RTPTestCase{ 51 sequence_number: 65535, // upper boundary 52 encrypted: Bytes::from_static(&[ 53 0xaf, 0xf7, 0xc2, 0x70, 0x37, 0x20, 0x83, 0x9c, 0x2c, 0x63, 0x85, 0x15, 0x0e, 0x44, 54 0xca, 0x36 55 ]), 56 }, 57 ]; 58 } 59 60 fn build_test_context() -> Result<Context> { 61 let master_key = Bytes::from_static(&[ 62 0x0d, 0xcd, 0x21, 0x3e, 0x4c, 0xbc, 0xf2, 0x8f, 0x01, 0x7f, 0x69, 0x94, 0x40, 0x1e, 0x28, 63 0x89, 64 ]); 65 let master_salt = Bytes::from_static(&[ 66 0x62, 0x77, 0x60, 0x38, 0xc0, 0x6d, 0xc9, 0x41, 0x9f, 0x6d, 0xd9, 0x43, 0x3e, 0x7c, 67 ]); 68 69 Context::new( 70 &master_key, 71 &master_salt, 72 ProtectionProfile::Aes128CmHmacSha1_80, 73 None, 74 None, 75 ) 76 } 77 78 #[test] 79 fn test_rtp_invalid_auth() -> Result<()> { 80 let master_key = Bytes::from_static(&[ 81 0x0d, 0xcd, 0x21, 0x3e, 0x4c, 0xbc, 0xf2, 0x8f, 0x01, 0x7f, 0x69, 0x94, 0x40, 0x1e, 0x28, 82 0x89, 83 ]); 84 let invalid_salt = Bytes::from_static(&[ 85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 86 ]); 87 88 let mut encrypt_context = build_test_context()?; 89 let mut invalid_context = Context::new( 90 &master_key, 91 &invalid_salt, 92 ProtectionProfile::Aes128CmHmacSha1_80, 93 None, 94 None, 95 )?; 96 97 for test_case in &*RTP_TEST_CASES { 98 let pkt = rtp::packet::Packet { 99 header: rtp::header::Header { 100 sequence_number: test_case.sequence_number, 101 ..Default::default() 102 }, 103 payload: RTP_TEST_CASE_DECRYPTED.clone(), 104 }; 105 106 let pkt_raw = pkt.marshal()?; 107 let out = encrypt_context.encrypt_rtp(&pkt_raw)?; 108 109 let result = invalid_context.decrypt_rtp(&out); 110 assert!( 111 result.is_err(), 112 "Managed to decrypt with incorrect salt for packet with SeqNum: {}", 113 test_case.sequence_number 114 ); 115 } 116 117 Ok(()) 118 } 119 120 #[test] 121 fn test_rtp_lifecyle() -> Result<()> { 122 let mut encrypt_context = build_test_context()?; 123 let mut decrypt_context = build_test_context()?; 124 let auth_tag_len = ProtectionProfile::Aes128CmHmacSha1_80.auth_tag_len(); 125 126 for test_case in RTP_TEST_CASES.iter() { 127 let decrypted_pkt = rtp::packet::Packet { 128 header: rtp::header::Header { 129 sequence_number: test_case.sequence_number, 130 ..Default::default() 131 }, 132 payload: RTP_TEST_CASE_DECRYPTED.clone(), 133 }; 134 135 let decrypted_raw = decrypted_pkt.marshal()?; 136 137 let encrypted_pkt = rtp::packet::Packet { 138 header: rtp::header::Header { 139 sequence_number: test_case.sequence_number, 140 ..Default::default() 141 }, 142 payload: test_case.encrypted.clone(), 143 }; 144 145 let encrypted_raw = encrypted_pkt.marshal()?; 146 let actual_encrypted = encrypt_context.encrypt_rtp(&decrypted_raw)?; 147 assert_eq!( 148 actual_encrypted, encrypted_raw, 149 "RTP packet with SeqNum invalid encryption: {}", 150 test_case.sequence_number 151 ); 152 153 let actual_decrypted = decrypt_context.decrypt_rtp(&encrypted_raw)?; 154 assert_ne!( 155 encrypted_raw[..encrypted_raw.len() - auth_tag_len].to_vec(), 156 actual_decrypted, 157 "DecryptRTP improperly encrypted in place" 158 ); 159 160 assert_eq!( 161 actual_decrypted, decrypted_raw, 162 "RTP packet with SeqNum invalid decryption: {}", 163 test_case.sequence_number, 164 ) 165 } 166 167 Ok(()) 168 } 169 170 //TODO: BenchmarkEncryptRTP 171 //TODO: BenchmarkEncryptRTPInPlace 172 //TODO: BenchmarkDecryptRTP 173