xref: /aosp_15_r20/external/webrtc/pc/srtp_transport_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2017 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "pc/srtp_transport.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <string.h>
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #include <vector>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include "call/rtp_demuxer.h"
18*d9f75844SAndroid Build Coastguard Worker #include "media/base/fake_rtp.h"
19*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/dtls_transport_internal.h"
20*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/fake_packet_transport.h"
21*d9f75844SAndroid Build Coastguard Worker #include "pc/test/rtp_transport_test_util.h"
22*d9f75844SAndroid Build Coastguard Worker #include "pc/test/srtp_test_util.h"
23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/async_packet_socket.h"
24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/byte_order.h"
25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
26*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/containers/flat_set.h"
27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_stream_adapter.h"
28*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/third_party/sigslot/sigslot.h"
29*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
30*d9f75844SAndroid Build Coastguard Worker #include "test/scoped_key_value_config.h"
31*d9f75844SAndroid Build Coastguard Worker 
32*d9f75844SAndroid Build Coastguard Worker using rtc::kSrtpAeadAes128Gcm;
33*d9f75844SAndroid Build Coastguard Worker using rtc::kTestKey1;
34*d9f75844SAndroid Build Coastguard Worker using rtc::kTestKey2;
35*d9f75844SAndroid Build Coastguard Worker using rtc::kTestKeyLen;
36*d9f75844SAndroid Build Coastguard Worker 
37*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
38*d9f75844SAndroid Build Coastguard Worker static const uint8_t kTestKeyGcm128_1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ12";
39*d9f75844SAndroid Build Coastguard Worker static const uint8_t kTestKeyGcm128_2[] = "21ZYXWVUTSRQPONMLKJIHGFEDCBA";
40*d9f75844SAndroid Build Coastguard Worker static const int kTestKeyGcm128Len = 28;  // 128 bits key + 96 bits salt.
41*d9f75844SAndroid Build Coastguard Worker static const uint8_t kTestKeyGcm256_1[] =
42*d9f75844SAndroid Build Coastguard Worker     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr";
43*d9f75844SAndroid Build Coastguard Worker static const uint8_t kTestKeyGcm256_2[] =
44*d9f75844SAndroid Build Coastguard Worker     "rqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA";
45*d9f75844SAndroid Build Coastguard Worker static const int kTestKeyGcm256Len = 44;  // 256 bits key + 96 bits salt.
46*d9f75844SAndroid Build Coastguard Worker 
47*d9f75844SAndroid Build Coastguard Worker class SrtpTransportTest : public ::testing::Test, public sigslot::has_slots<> {
48*d9f75844SAndroid Build Coastguard Worker  protected:
SrtpTransportTest()49*d9f75844SAndroid Build Coastguard Worker   SrtpTransportTest() {
50*d9f75844SAndroid Build Coastguard Worker     bool rtcp_mux_enabled = true;
51*d9f75844SAndroid Build Coastguard Worker 
52*d9f75844SAndroid Build Coastguard Worker     rtp_packet_transport1_ =
53*d9f75844SAndroid Build Coastguard Worker         std::make_unique<rtc::FakePacketTransport>("fake_packet_transport1");
54*d9f75844SAndroid Build Coastguard Worker     rtp_packet_transport2_ =
55*d9f75844SAndroid Build Coastguard Worker         std::make_unique<rtc::FakePacketTransport>("fake_packet_transport2");
56*d9f75844SAndroid Build Coastguard Worker 
57*d9f75844SAndroid Build Coastguard Worker     bool asymmetric = false;
58*d9f75844SAndroid Build Coastguard Worker     rtp_packet_transport1_->SetDestination(rtp_packet_transport2_.get(),
59*d9f75844SAndroid Build Coastguard Worker                                            asymmetric);
60*d9f75844SAndroid Build Coastguard Worker 
61*d9f75844SAndroid Build Coastguard Worker     srtp_transport1_ =
62*d9f75844SAndroid Build Coastguard Worker         std::make_unique<SrtpTransport>(rtcp_mux_enabled, field_trials_);
63*d9f75844SAndroid Build Coastguard Worker     srtp_transport2_ =
64*d9f75844SAndroid Build Coastguard Worker         std::make_unique<SrtpTransport>(rtcp_mux_enabled, field_trials_);
65*d9f75844SAndroid Build Coastguard Worker 
66*d9f75844SAndroid Build Coastguard Worker     srtp_transport1_->SetRtpPacketTransport(rtp_packet_transport1_.get());
67*d9f75844SAndroid Build Coastguard Worker     srtp_transport2_->SetRtpPacketTransport(rtp_packet_transport2_.get());
68*d9f75844SAndroid Build Coastguard Worker 
69*d9f75844SAndroid Build Coastguard Worker     srtp_transport1_->SignalRtcpPacketReceived.connect(
70*d9f75844SAndroid Build Coastguard Worker         &rtp_sink1_, &TransportObserver::OnRtcpPacketReceived);
71*d9f75844SAndroid Build Coastguard Worker     srtp_transport2_->SignalRtcpPacketReceived.connect(
72*d9f75844SAndroid Build Coastguard Worker         &rtp_sink2_, &TransportObserver::OnRtcpPacketReceived);
73*d9f75844SAndroid Build Coastguard Worker 
74*d9f75844SAndroid Build Coastguard Worker     RtpDemuxerCriteria demuxer_criteria;
75*d9f75844SAndroid Build Coastguard Worker     // 0x00 is the payload type used in kPcmuFrame.
76*d9f75844SAndroid Build Coastguard Worker     demuxer_criteria.payload_types().insert(0x00);
77*d9f75844SAndroid Build Coastguard Worker 
78*d9f75844SAndroid Build Coastguard Worker     srtp_transport1_->RegisterRtpDemuxerSink(demuxer_criteria, &rtp_sink1_);
79*d9f75844SAndroid Build Coastguard Worker     srtp_transport2_->RegisterRtpDemuxerSink(demuxer_criteria, &rtp_sink2_);
80*d9f75844SAndroid Build Coastguard Worker   }
81*d9f75844SAndroid Build Coastguard Worker 
~SrtpTransportTest()82*d9f75844SAndroid Build Coastguard Worker   ~SrtpTransportTest() {
83*d9f75844SAndroid Build Coastguard Worker     if (srtp_transport1_) {
84*d9f75844SAndroid Build Coastguard Worker       srtp_transport1_->UnregisterRtpDemuxerSink(&rtp_sink1_);
85*d9f75844SAndroid Build Coastguard Worker     }
86*d9f75844SAndroid Build Coastguard Worker     if (srtp_transport2_) {
87*d9f75844SAndroid Build Coastguard Worker       srtp_transport2_->UnregisterRtpDemuxerSink(&rtp_sink2_);
88*d9f75844SAndroid Build Coastguard Worker     }
89*d9f75844SAndroid Build Coastguard Worker   }
90*d9f75844SAndroid Build Coastguard Worker 
91*d9f75844SAndroid Build Coastguard Worker   // With external auth enabled, SRTP doesn't write the auth tag and
92*d9f75844SAndroid Build Coastguard Worker   // unprotect would fail. Check accessing the information about the
93*d9f75844SAndroid Build Coastguard Worker   // tag instead, similar to what the actual code would do that relies
94*d9f75844SAndroid Build Coastguard Worker   // on external auth.
TestRtpAuthParams(SrtpTransport * transport,const std::string & cs)95*d9f75844SAndroid Build Coastguard Worker   void TestRtpAuthParams(SrtpTransport* transport, const std::string& cs) {
96*d9f75844SAndroid Build Coastguard Worker     int overhead;
97*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(transport->GetSrtpOverhead(&overhead));
98*d9f75844SAndroid Build Coastguard Worker     switch (rtc::SrtpCryptoSuiteFromName(cs)) {
99*d9f75844SAndroid Build Coastguard Worker       case rtc::kSrtpAes128CmSha1_32:
100*d9f75844SAndroid Build Coastguard Worker         EXPECT_EQ(32 / 8, overhead);  // 32-bit tag.
101*d9f75844SAndroid Build Coastguard Worker         break;
102*d9f75844SAndroid Build Coastguard Worker       case rtc::kSrtpAes128CmSha1_80:
103*d9f75844SAndroid Build Coastguard Worker         EXPECT_EQ(80 / 8, overhead);  // 80-bit tag.
104*d9f75844SAndroid Build Coastguard Worker         break;
105*d9f75844SAndroid Build Coastguard Worker       default:
106*d9f75844SAndroid Build Coastguard Worker         RTC_DCHECK_NOTREACHED();
107*d9f75844SAndroid Build Coastguard Worker         break;
108*d9f75844SAndroid Build Coastguard Worker     }
109*d9f75844SAndroid Build Coastguard Worker 
110*d9f75844SAndroid Build Coastguard Worker     uint8_t* auth_key = nullptr;
111*d9f75844SAndroid Build Coastguard Worker     int key_len = 0;
112*d9f75844SAndroid Build Coastguard Worker     int tag_len = 0;
113*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(transport->GetRtpAuthParams(&auth_key, &key_len, &tag_len));
114*d9f75844SAndroid Build Coastguard Worker     EXPECT_NE(nullptr, auth_key);
115*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(160 / 8, key_len);  // Length of SHA-1 is 160 bits.
116*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(overhead, tag_len);
117*d9f75844SAndroid Build Coastguard Worker   }
118*d9f75844SAndroid Build Coastguard Worker 
TestSendRecvRtpPacket(const std::string & cipher_suite_name)119*d9f75844SAndroid Build Coastguard Worker   void TestSendRecvRtpPacket(const std::string& cipher_suite_name) {
120*d9f75844SAndroid Build Coastguard Worker     size_t rtp_len = sizeof(kPcmuFrame);
121*d9f75844SAndroid Build Coastguard Worker     size_t packet_size = rtp_len + rtc::rtp_auth_tag_len(cipher_suite_name);
122*d9f75844SAndroid Build Coastguard Worker     rtc::Buffer rtp_packet_buffer(packet_size);
123*d9f75844SAndroid Build Coastguard Worker     char* rtp_packet_data = rtp_packet_buffer.data<char>();
124*d9f75844SAndroid Build Coastguard Worker     memcpy(rtp_packet_data, kPcmuFrame, rtp_len);
125*d9f75844SAndroid Build Coastguard Worker     // In order to be able to run this test function multiple times we can not
126*d9f75844SAndroid Build Coastguard Worker     // use the same sequence number twice. Increase the sequence number by one.
127*d9f75844SAndroid Build Coastguard Worker     rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_data) + 2,
128*d9f75844SAndroid Build Coastguard Worker                  ++sequence_number_);
129*d9f75844SAndroid Build Coastguard Worker     rtc::CopyOnWriteBuffer rtp_packet1to2(rtp_packet_data, rtp_len,
130*d9f75844SAndroid Build Coastguard Worker                                           packet_size);
131*d9f75844SAndroid Build Coastguard Worker     rtc::CopyOnWriteBuffer rtp_packet2to1(rtp_packet_data, rtp_len,
132*d9f75844SAndroid Build Coastguard Worker                                           packet_size);
133*d9f75844SAndroid Build Coastguard Worker 
134*d9f75844SAndroid Build Coastguard Worker     char original_rtp_data[sizeof(kPcmuFrame)];
135*d9f75844SAndroid Build Coastguard Worker     memcpy(original_rtp_data, rtp_packet_data, rtp_len);
136*d9f75844SAndroid Build Coastguard Worker 
137*d9f75844SAndroid Build Coastguard Worker     rtc::PacketOptions options;
138*d9f75844SAndroid Build Coastguard Worker     // Send a packet from `srtp_transport1_` to `srtp_transport2_` and verify
139*d9f75844SAndroid Build Coastguard Worker     // that the packet can be successfully received and decrypted.
140*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(srtp_transport1_->SendRtpPacket(&rtp_packet1to2, options,
141*d9f75844SAndroid Build Coastguard Worker                                                 cricket::PF_SRTP_BYPASS));
142*d9f75844SAndroid Build Coastguard Worker     if (srtp_transport1_->IsExternalAuthActive()) {
143*d9f75844SAndroid Build Coastguard Worker       TestRtpAuthParams(srtp_transport1_.get(), cipher_suite_name);
144*d9f75844SAndroid Build Coastguard Worker     } else {
145*d9f75844SAndroid Build Coastguard Worker       ASSERT_TRUE(rtp_sink2_.last_recv_rtp_packet().data());
146*d9f75844SAndroid Build Coastguard Worker       EXPECT_EQ(0, memcmp(rtp_sink2_.last_recv_rtp_packet().data(),
147*d9f75844SAndroid Build Coastguard Worker                           original_rtp_data, rtp_len));
148*d9f75844SAndroid Build Coastguard Worker       // Get the encrypted packet from underneath packet transport and verify
149*d9f75844SAndroid Build Coastguard Worker       // the data is actually encrypted.
150*d9f75844SAndroid Build Coastguard Worker       auto fake_rtp_packet_transport = static_cast<rtc::FakePacketTransport*>(
151*d9f75844SAndroid Build Coastguard Worker           srtp_transport1_->rtp_packet_transport());
152*d9f75844SAndroid Build Coastguard Worker       EXPECT_NE(0, memcmp(fake_rtp_packet_transport->last_sent_packet()->data(),
153*d9f75844SAndroid Build Coastguard Worker                           original_rtp_data, rtp_len));
154*d9f75844SAndroid Build Coastguard Worker     }
155*d9f75844SAndroid Build Coastguard Worker 
156*d9f75844SAndroid Build Coastguard Worker     // Do the same thing in the opposite direction;
157*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(srtp_transport2_->SendRtpPacket(&rtp_packet2to1, options,
158*d9f75844SAndroid Build Coastguard Worker                                                 cricket::PF_SRTP_BYPASS));
159*d9f75844SAndroid Build Coastguard Worker     if (srtp_transport2_->IsExternalAuthActive()) {
160*d9f75844SAndroid Build Coastguard Worker       TestRtpAuthParams(srtp_transport2_.get(), cipher_suite_name);
161*d9f75844SAndroid Build Coastguard Worker     } else {
162*d9f75844SAndroid Build Coastguard Worker       ASSERT_TRUE(rtp_sink1_.last_recv_rtp_packet().data());
163*d9f75844SAndroid Build Coastguard Worker       EXPECT_EQ(0, memcmp(rtp_sink1_.last_recv_rtp_packet().data(),
164*d9f75844SAndroid Build Coastguard Worker                           original_rtp_data, rtp_len));
165*d9f75844SAndroid Build Coastguard Worker       auto fake_rtp_packet_transport = static_cast<rtc::FakePacketTransport*>(
166*d9f75844SAndroid Build Coastguard Worker           srtp_transport2_->rtp_packet_transport());
167*d9f75844SAndroid Build Coastguard Worker       EXPECT_NE(0, memcmp(fake_rtp_packet_transport->last_sent_packet()->data(),
168*d9f75844SAndroid Build Coastguard Worker                           original_rtp_data, rtp_len));
169*d9f75844SAndroid Build Coastguard Worker     }
170*d9f75844SAndroid Build Coastguard Worker   }
171*d9f75844SAndroid Build Coastguard Worker 
TestSendRecvRtcpPacket(const std::string & cipher_suite_name)172*d9f75844SAndroid Build Coastguard Worker   void TestSendRecvRtcpPacket(const std::string& cipher_suite_name) {
173*d9f75844SAndroid Build Coastguard Worker     size_t rtcp_len = sizeof(::kRtcpReport);
174*d9f75844SAndroid Build Coastguard Worker     size_t packet_size =
175*d9f75844SAndroid Build Coastguard Worker         rtcp_len + 4 + rtc::rtcp_auth_tag_len(cipher_suite_name);
176*d9f75844SAndroid Build Coastguard Worker     rtc::Buffer rtcp_packet_buffer(packet_size);
177*d9f75844SAndroid Build Coastguard Worker     char* rtcp_packet_data = rtcp_packet_buffer.data<char>();
178*d9f75844SAndroid Build Coastguard Worker     memcpy(rtcp_packet_data, ::kRtcpReport, rtcp_len);
179*d9f75844SAndroid Build Coastguard Worker 
180*d9f75844SAndroid Build Coastguard Worker     rtc::CopyOnWriteBuffer rtcp_packet1to2(rtcp_packet_data, rtcp_len,
181*d9f75844SAndroid Build Coastguard Worker                                            packet_size);
182*d9f75844SAndroid Build Coastguard Worker     rtc::CopyOnWriteBuffer rtcp_packet2to1(rtcp_packet_data, rtcp_len,
183*d9f75844SAndroid Build Coastguard Worker                                            packet_size);
184*d9f75844SAndroid Build Coastguard Worker 
185*d9f75844SAndroid Build Coastguard Worker     rtc::PacketOptions options;
186*d9f75844SAndroid Build Coastguard Worker     // Send a packet from `srtp_transport1_` to `srtp_transport2_` and verify
187*d9f75844SAndroid Build Coastguard Worker     // that the packet can be successfully received and decrypted.
188*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(srtp_transport1_->SendRtcpPacket(&rtcp_packet1to2, options,
189*d9f75844SAndroid Build Coastguard Worker                                                  cricket::PF_SRTP_BYPASS));
190*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(rtp_sink2_.last_recv_rtcp_packet().data());
191*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(rtp_sink2_.last_recv_rtcp_packet().data(),
192*d9f75844SAndroid Build Coastguard Worker                         rtcp_packet_data, rtcp_len));
193*d9f75844SAndroid Build Coastguard Worker     // Get the encrypted packet from underneath packet transport and verify the
194*d9f75844SAndroid Build Coastguard Worker     // data is actually encrypted.
195*d9f75844SAndroid Build Coastguard Worker     auto fake_rtp_packet_transport = static_cast<rtc::FakePacketTransport*>(
196*d9f75844SAndroid Build Coastguard Worker         srtp_transport1_->rtp_packet_transport());
197*d9f75844SAndroid Build Coastguard Worker     EXPECT_NE(0, memcmp(fake_rtp_packet_transport->last_sent_packet()->data(),
198*d9f75844SAndroid Build Coastguard Worker                         rtcp_packet_data, rtcp_len));
199*d9f75844SAndroid Build Coastguard Worker 
200*d9f75844SAndroid Build Coastguard Worker     // Do the same thing in the opposite direction;
201*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(srtp_transport2_->SendRtcpPacket(&rtcp_packet2to1, options,
202*d9f75844SAndroid Build Coastguard Worker                                                  cricket::PF_SRTP_BYPASS));
203*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(rtp_sink1_.last_recv_rtcp_packet().data());
204*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(rtp_sink1_.last_recv_rtcp_packet().data(),
205*d9f75844SAndroid Build Coastguard Worker                         rtcp_packet_data, rtcp_len));
206*d9f75844SAndroid Build Coastguard Worker     fake_rtp_packet_transport = static_cast<rtc::FakePacketTransport*>(
207*d9f75844SAndroid Build Coastguard Worker         srtp_transport2_->rtp_packet_transport());
208*d9f75844SAndroid Build Coastguard Worker     EXPECT_NE(0, memcmp(fake_rtp_packet_transport->last_sent_packet()->data(),
209*d9f75844SAndroid Build Coastguard Worker                         rtcp_packet_data, rtcp_len));
210*d9f75844SAndroid Build Coastguard Worker   }
211*d9f75844SAndroid Build Coastguard Worker 
TestSendRecvPacket(bool enable_external_auth,int cs,const uint8_t * key1,int key1_len,const uint8_t * key2,int key2_len,const std::string & cipher_suite_name)212*d9f75844SAndroid Build Coastguard Worker   void TestSendRecvPacket(bool enable_external_auth,
213*d9f75844SAndroid Build Coastguard Worker                           int cs,
214*d9f75844SAndroid Build Coastguard Worker                           const uint8_t* key1,
215*d9f75844SAndroid Build Coastguard Worker                           int key1_len,
216*d9f75844SAndroid Build Coastguard Worker                           const uint8_t* key2,
217*d9f75844SAndroid Build Coastguard Worker                           int key2_len,
218*d9f75844SAndroid Build Coastguard Worker                           const std::string& cipher_suite_name) {
219*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(key1_len, key2_len);
220*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(cipher_suite_name, rtc::SrtpCryptoSuiteToName(cs));
221*d9f75844SAndroid Build Coastguard Worker     if (enable_external_auth) {
222*d9f75844SAndroid Build Coastguard Worker       srtp_transport1_->EnableExternalAuth();
223*d9f75844SAndroid Build Coastguard Worker       srtp_transport2_->EnableExternalAuth();
224*d9f75844SAndroid Build Coastguard Worker     }
225*d9f75844SAndroid Build Coastguard Worker     std::vector<int> extension_ids;
226*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(srtp_transport1_->SetRtpParams(
227*d9f75844SAndroid Build Coastguard Worker         cs, key1, key1_len, extension_ids, cs, key2, key2_len, extension_ids));
228*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(srtp_transport2_->SetRtpParams(
229*d9f75844SAndroid Build Coastguard Worker         cs, key2, key2_len, extension_ids, cs, key1, key1_len, extension_ids));
230*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(srtp_transport1_->SetRtcpParams(
231*d9f75844SAndroid Build Coastguard Worker         cs, key1, key1_len, extension_ids, cs, key2, key2_len, extension_ids));
232*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(srtp_transport2_->SetRtcpParams(
233*d9f75844SAndroid Build Coastguard Worker         cs, key2, key2_len, extension_ids, cs, key1, key1_len, extension_ids));
234*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(srtp_transport1_->IsSrtpActive());
235*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(srtp_transport2_->IsSrtpActive());
236*d9f75844SAndroid Build Coastguard Worker     if (rtc::IsGcmCryptoSuite(cs)) {
237*d9f75844SAndroid Build Coastguard Worker       EXPECT_FALSE(srtp_transport1_->IsExternalAuthActive());
238*d9f75844SAndroid Build Coastguard Worker       EXPECT_FALSE(srtp_transport2_->IsExternalAuthActive());
239*d9f75844SAndroid Build Coastguard Worker     } else if (enable_external_auth) {
240*d9f75844SAndroid Build Coastguard Worker       EXPECT_TRUE(srtp_transport1_->IsExternalAuthActive());
241*d9f75844SAndroid Build Coastguard Worker       EXPECT_TRUE(srtp_transport2_->IsExternalAuthActive());
242*d9f75844SAndroid Build Coastguard Worker     }
243*d9f75844SAndroid Build Coastguard Worker     TestSendRecvRtpPacket(cipher_suite_name);
244*d9f75844SAndroid Build Coastguard Worker     TestSendRecvRtcpPacket(cipher_suite_name);
245*d9f75844SAndroid Build Coastguard Worker   }
246*d9f75844SAndroid Build Coastguard Worker 
TestSendRecvPacketWithEncryptedHeaderExtension(const std::string & cs,const std::vector<int> & encrypted_header_ids)247*d9f75844SAndroid Build Coastguard Worker   void TestSendRecvPacketWithEncryptedHeaderExtension(
248*d9f75844SAndroid Build Coastguard Worker       const std::string& cs,
249*d9f75844SAndroid Build Coastguard Worker       const std::vector<int>& encrypted_header_ids) {
250*d9f75844SAndroid Build Coastguard Worker     size_t rtp_len = sizeof(kPcmuFrameWithExtensions);
251*d9f75844SAndroid Build Coastguard Worker     size_t packet_size = rtp_len + rtc::rtp_auth_tag_len(cs);
252*d9f75844SAndroid Build Coastguard Worker     rtc::Buffer rtp_packet_buffer(packet_size);
253*d9f75844SAndroid Build Coastguard Worker     char* rtp_packet_data = rtp_packet_buffer.data<char>();
254*d9f75844SAndroid Build Coastguard Worker     memcpy(rtp_packet_data, kPcmuFrameWithExtensions, rtp_len);
255*d9f75844SAndroid Build Coastguard Worker     // In order to be able to run this test function multiple times we can not
256*d9f75844SAndroid Build Coastguard Worker     // use the same sequence number twice. Increase the sequence number by one.
257*d9f75844SAndroid Build Coastguard Worker     rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_data) + 2,
258*d9f75844SAndroid Build Coastguard Worker                  ++sequence_number_);
259*d9f75844SAndroid Build Coastguard Worker     rtc::CopyOnWriteBuffer rtp_packet1to2(rtp_packet_data, rtp_len,
260*d9f75844SAndroid Build Coastguard Worker                                           packet_size);
261*d9f75844SAndroid Build Coastguard Worker     rtc::CopyOnWriteBuffer rtp_packet2to1(rtp_packet_data, rtp_len,
262*d9f75844SAndroid Build Coastguard Worker                                           packet_size);
263*d9f75844SAndroid Build Coastguard Worker 
264*d9f75844SAndroid Build Coastguard Worker     char original_rtp_data[sizeof(kPcmuFrameWithExtensions)];
265*d9f75844SAndroid Build Coastguard Worker     memcpy(original_rtp_data, rtp_packet_data, rtp_len);
266*d9f75844SAndroid Build Coastguard Worker 
267*d9f75844SAndroid Build Coastguard Worker     rtc::PacketOptions options;
268*d9f75844SAndroid Build Coastguard Worker     // Send a packet from `srtp_transport1_` to `srtp_transport2_` and verify
269*d9f75844SAndroid Build Coastguard Worker     // that the packet can be successfully received and decrypted.
270*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(srtp_transport1_->SendRtpPacket(&rtp_packet1to2, options,
271*d9f75844SAndroid Build Coastguard Worker                                                 cricket::PF_SRTP_BYPASS));
272*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(rtp_sink2_.last_recv_rtp_packet().data());
273*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(rtp_sink2_.last_recv_rtp_packet().data(),
274*d9f75844SAndroid Build Coastguard Worker                         original_rtp_data, rtp_len));
275*d9f75844SAndroid Build Coastguard Worker     // Get the encrypted packet from underneath packet transport and verify the
276*d9f75844SAndroid Build Coastguard Worker     // data and header extension are actually encrypted.
277*d9f75844SAndroid Build Coastguard Worker     auto fake_rtp_packet_transport = static_cast<rtc::FakePacketTransport*>(
278*d9f75844SAndroid Build Coastguard Worker         srtp_transport1_->rtp_packet_transport());
279*d9f75844SAndroid Build Coastguard Worker     EXPECT_NE(0, memcmp(fake_rtp_packet_transport->last_sent_packet()->data(),
280*d9f75844SAndroid Build Coastguard Worker                         original_rtp_data, rtp_len));
281*d9f75844SAndroid Build Coastguard Worker     CompareHeaderExtensions(
282*d9f75844SAndroid Build Coastguard Worker         reinterpret_cast<const char*>(
283*d9f75844SAndroid Build Coastguard Worker             fake_rtp_packet_transport->last_sent_packet()->data()),
284*d9f75844SAndroid Build Coastguard Worker         fake_rtp_packet_transport->last_sent_packet()->size(),
285*d9f75844SAndroid Build Coastguard Worker         original_rtp_data, rtp_len, encrypted_header_ids, false);
286*d9f75844SAndroid Build Coastguard Worker 
287*d9f75844SAndroid Build Coastguard Worker     // Do the same thing in the opposite direction;
288*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(srtp_transport2_->SendRtpPacket(&rtp_packet2to1, options,
289*d9f75844SAndroid Build Coastguard Worker                                                 cricket::PF_SRTP_BYPASS));
290*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE(rtp_sink1_.last_recv_rtp_packet().data());
291*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(rtp_sink1_.last_recv_rtp_packet().data(),
292*d9f75844SAndroid Build Coastguard Worker                         original_rtp_data, rtp_len));
293*d9f75844SAndroid Build Coastguard Worker     fake_rtp_packet_transport = static_cast<rtc::FakePacketTransport*>(
294*d9f75844SAndroid Build Coastguard Worker         srtp_transport2_->rtp_packet_transport());
295*d9f75844SAndroid Build Coastguard Worker     EXPECT_NE(0, memcmp(fake_rtp_packet_transport->last_sent_packet()->data(),
296*d9f75844SAndroid Build Coastguard Worker                         original_rtp_data, rtp_len));
297*d9f75844SAndroid Build Coastguard Worker     CompareHeaderExtensions(
298*d9f75844SAndroid Build Coastguard Worker         reinterpret_cast<const char*>(
299*d9f75844SAndroid Build Coastguard Worker             fake_rtp_packet_transport->last_sent_packet()->data()),
300*d9f75844SAndroid Build Coastguard Worker         fake_rtp_packet_transport->last_sent_packet()->size(),
301*d9f75844SAndroid Build Coastguard Worker         original_rtp_data, rtp_len, encrypted_header_ids, false);
302*d9f75844SAndroid Build Coastguard Worker   }
303*d9f75844SAndroid Build Coastguard Worker 
TestSendRecvEncryptedHeaderExtension(int cs,const uint8_t * key1,int key1_len,const uint8_t * key2,int key2_len,const std::string & cs_name)304*d9f75844SAndroid Build Coastguard Worker   void TestSendRecvEncryptedHeaderExtension(int cs,
305*d9f75844SAndroid Build Coastguard Worker                                             const uint8_t* key1,
306*d9f75844SAndroid Build Coastguard Worker                                             int key1_len,
307*d9f75844SAndroid Build Coastguard Worker                                             const uint8_t* key2,
308*d9f75844SAndroid Build Coastguard Worker                                             int key2_len,
309*d9f75844SAndroid Build Coastguard Worker                                             const std::string& cs_name) {
310*d9f75844SAndroid Build Coastguard Worker     std::vector<int> encrypted_headers;
311*d9f75844SAndroid Build Coastguard Worker     encrypted_headers.push_back(kHeaderExtensionIDs[0]);
312*d9f75844SAndroid Build Coastguard Worker     // Don't encrypt header ids 2 and 3.
313*d9f75844SAndroid Build Coastguard Worker     encrypted_headers.push_back(kHeaderExtensionIDs[1]);
314*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(key1_len, key2_len);
315*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(cs_name, rtc::SrtpCryptoSuiteToName(cs));
316*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(srtp_transport1_->SetRtpParams(cs, key1, key1_len,
317*d9f75844SAndroid Build Coastguard Worker                                                encrypted_headers, cs, key2,
318*d9f75844SAndroid Build Coastguard Worker                                                key2_len, encrypted_headers));
319*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(srtp_transport2_->SetRtpParams(cs, key2, key2_len,
320*d9f75844SAndroid Build Coastguard Worker                                                encrypted_headers, cs, key1,
321*d9f75844SAndroid Build Coastguard Worker                                                key1_len, encrypted_headers));
322*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(srtp_transport1_->IsSrtpActive());
323*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(srtp_transport2_->IsSrtpActive());
324*d9f75844SAndroid Build Coastguard Worker     EXPECT_FALSE(srtp_transport1_->IsExternalAuthActive());
325*d9f75844SAndroid Build Coastguard Worker     EXPECT_FALSE(srtp_transport2_->IsExternalAuthActive());
326*d9f75844SAndroid Build Coastguard Worker     TestSendRecvPacketWithEncryptedHeaderExtension(cs_name, encrypted_headers);
327*d9f75844SAndroid Build Coastguard Worker   }
328*d9f75844SAndroid Build Coastguard Worker 
329*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<SrtpTransport> srtp_transport1_;
330*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<SrtpTransport> srtp_transport2_;
331*d9f75844SAndroid Build Coastguard Worker 
332*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::FakePacketTransport> rtp_packet_transport1_;
333*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::FakePacketTransport> rtp_packet_transport2_;
334*d9f75844SAndroid Build Coastguard Worker 
335*d9f75844SAndroid Build Coastguard Worker   TransportObserver rtp_sink1_;
336*d9f75844SAndroid Build Coastguard Worker   TransportObserver rtp_sink2_;
337*d9f75844SAndroid Build Coastguard Worker 
338*d9f75844SAndroid Build Coastguard Worker   int sequence_number_ = 0;
339*d9f75844SAndroid Build Coastguard Worker   webrtc::test::ScopedKeyValueConfig field_trials_;
340*d9f75844SAndroid Build Coastguard Worker };
341*d9f75844SAndroid Build Coastguard Worker 
342*d9f75844SAndroid Build Coastguard Worker class SrtpTransportTestWithExternalAuth
343*d9f75844SAndroid Build Coastguard Worker     : public SrtpTransportTest,
344*d9f75844SAndroid Build Coastguard Worker       public ::testing::WithParamInterface<bool> {};
345*d9f75844SAndroid Build Coastguard Worker 
TEST_P(SrtpTransportTestWithExternalAuth,SendAndRecvPacket_AES_CM_128_HMAC_SHA1_80)346*d9f75844SAndroid Build Coastguard Worker TEST_P(SrtpTransportTestWithExternalAuth,
347*d9f75844SAndroid Build Coastguard Worker        SendAndRecvPacket_AES_CM_128_HMAC_SHA1_80) {
348*d9f75844SAndroid Build Coastguard Worker   bool enable_external_auth = GetParam();
349*d9f75844SAndroid Build Coastguard Worker   TestSendRecvPacket(enable_external_auth, rtc::kSrtpAes128CmSha1_80, kTestKey1,
350*d9f75844SAndroid Build Coastguard Worker                      kTestKeyLen, kTestKey2, kTestKeyLen,
351*d9f75844SAndroid Build Coastguard Worker                      rtc::kCsAesCm128HmacSha1_80);
352*d9f75844SAndroid Build Coastguard Worker }
353*d9f75844SAndroid Build Coastguard Worker 
TEST_F(SrtpTransportTest,SendAndRecvPacketWithHeaderExtension_AES_CM_128_HMAC_SHA1_80)354*d9f75844SAndroid Build Coastguard Worker TEST_F(SrtpTransportTest,
355*d9f75844SAndroid Build Coastguard Worker        SendAndRecvPacketWithHeaderExtension_AES_CM_128_HMAC_SHA1_80) {
356*d9f75844SAndroid Build Coastguard Worker   TestSendRecvEncryptedHeaderExtension(rtc::kSrtpAes128CmSha1_80, kTestKey1,
357*d9f75844SAndroid Build Coastguard Worker                                        kTestKeyLen, kTestKey2, kTestKeyLen,
358*d9f75844SAndroid Build Coastguard Worker                                        rtc::kCsAesCm128HmacSha1_80);
359*d9f75844SAndroid Build Coastguard Worker }
360*d9f75844SAndroid Build Coastguard Worker 
TEST_P(SrtpTransportTestWithExternalAuth,SendAndRecvPacket_AES_CM_128_HMAC_SHA1_32)361*d9f75844SAndroid Build Coastguard Worker TEST_P(SrtpTransportTestWithExternalAuth,
362*d9f75844SAndroid Build Coastguard Worker        SendAndRecvPacket_AES_CM_128_HMAC_SHA1_32) {
363*d9f75844SAndroid Build Coastguard Worker   bool enable_external_auth = GetParam();
364*d9f75844SAndroid Build Coastguard Worker   TestSendRecvPacket(enable_external_auth, rtc::kSrtpAes128CmSha1_32, kTestKey1,
365*d9f75844SAndroid Build Coastguard Worker                      kTestKeyLen, kTestKey2, kTestKeyLen,
366*d9f75844SAndroid Build Coastguard Worker                      rtc::kCsAesCm128HmacSha1_32);
367*d9f75844SAndroid Build Coastguard Worker }
368*d9f75844SAndroid Build Coastguard Worker 
TEST_F(SrtpTransportTest,SendAndRecvPacketWithHeaderExtension_AES_CM_128_HMAC_SHA1_32)369*d9f75844SAndroid Build Coastguard Worker TEST_F(SrtpTransportTest,
370*d9f75844SAndroid Build Coastguard Worker        SendAndRecvPacketWithHeaderExtension_AES_CM_128_HMAC_SHA1_32) {
371*d9f75844SAndroid Build Coastguard Worker   TestSendRecvEncryptedHeaderExtension(rtc::kSrtpAes128CmSha1_32, kTestKey1,
372*d9f75844SAndroid Build Coastguard Worker                                        kTestKeyLen, kTestKey2, kTestKeyLen,
373*d9f75844SAndroid Build Coastguard Worker                                        rtc::kCsAesCm128HmacSha1_32);
374*d9f75844SAndroid Build Coastguard Worker }
375*d9f75844SAndroid Build Coastguard Worker 
TEST_P(SrtpTransportTestWithExternalAuth,SendAndRecvPacket_kSrtpAeadAes128Gcm)376*d9f75844SAndroid Build Coastguard Worker TEST_P(SrtpTransportTestWithExternalAuth,
377*d9f75844SAndroid Build Coastguard Worker        SendAndRecvPacket_kSrtpAeadAes128Gcm) {
378*d9f75844SAndroid Build Coastguard Worker   bool enable_external_auth = GetParam();
379*d9f75844SAndroid Build Coastguard Worker   TestSendRecvPacket(enable_external_auth, rtc::kSrtpAeadAes128Gcm,
380*d9f75844SAndroid Build Coastguard Worker                      kTestKeyGcm128_1, kTestKeyGcm128Len, kTestKeyGcm128_2,
381*d9f75844SAndroid Build Coastguard Worker                      kTestKeyGcm128Len, rtc::kCsAeadAes128Gcm);
382*d9f75844SAndroid Build Coastguard Worker }
383*d9f75844SAndroid Build Coastguard Worker 
TEST_F(SrtpTransportTest,SendAndRecvPacketWithHeaderExtension_kSrtpAeadAes128Gcm)384*d9f75844SAndroid Build Coastguard Worker TEST_F(SrtpTransportTest,
385*d9f75844SAndroid Build Coastguard Worker        SendAndRecvPacketWithHeaderExtension_kSrtpAeadAes128Gcm) {
386*d9f75844SAndroid Build Coastguard Worker   TestSendRecvEncryptedHeaderExtension(
387*d9f75844SAndroid Build Coastguard Worker       rtc::kSrtpAeadAes128Gcm, kTestKeyGcm128_1, kTestKeyGcm128Len,
388*d9f75844SAndroid Build Coastguard Worker       kTestKeyGcm128_2, kTestKeyGcm128Len, rtc::kCsAeadAes128Gcm);
389*d9f75844SAndroid Build Coastguard Worker }
390*d9f75844SAndroid Build Coastguard Worker 
TEST_P(SrtpTransportTestWithExternalAuth,SendAndRecvPacket_kSrtpAeadAes256Gcm)391*d9f75844SAndroid Build Coastguard Worker TEST_P(SrtpTransportTestWithExternalAuth,
392*d9f75844SAndroid Build Coastguard Worker        SendAndRecvPacket_kSrtpAeadAes256Gcm) {
393*d9f75844SAndroid Build Coastguard Worker   bool enable_external_auth = GetParam();
394*d9f75844SAndroid Build Coastguard Worker   TestSendRecvPacket(enable_external_auth, rtc::kSrtpAeadAes256Gcm,
395*d9f75844SAndroid Build Coastguard Worker                      kTestKeyGcm256_1, kTestKeyGcm256Len, kTestKeyGcm256_2,
396*d9f75844SAndroid Build Coastguard Worker                      kTestKeyGcm256Len, rtc::kCsAeadAes256Gcm);
397*d9f75844SAndroid Build Coastguard Worker }
398*d9f75844SAndroid Build Coastguard Worker 
TEST_F(SrtpTransportTest,SendAndRecvPacketWithHeaderExtension_kSrtpAeadAes256Gcm)399*d9f75844SAndroid Build Coastguard Worker TEST_F(SrtpTransportTest,
400*d9f75844SAndroid Build Coastguard Worker        SendAndRecvPacketWithHeaderExtension_kSrtpAeadAes256Gcm) {
401*d9f75844SAndroid Build Coastguard Worker   TestSendRecvEncryptedHeaderExtension(
402*d9f75844SAndroid Build Coastguard Worker       rtc::kSrtpAeadAes256Gcm, kTestKeyGcm256_1, kTestKeyGcm256Len,
403*d9f75844SAndroid Build Coastguard Worker       kTestKeyGcm256_2, kTestKeyGcm256Len, rtc::kCsAeadAes256Gcm);
404*d9f75844SAndroid Build Coastguard Worker }
405*d9f75844SAndroid Build Coastguard Worker 
406*d9f75844SAndroid Build Coastguard Worker // Run all tests both with and without external auth enabled.
407*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(ExternalAuth,
408*d9f75844SAndroid Build Coastguard Worker                          SrtpTransportTestWithExternalAuth,
409*d9f75844SAndroid Build Coastguard Worker                          ::testing::Values(true, false));
410*d9f75844SAndroid Build Coastguard Worker 
411*d9f75844SAndroid Build Coastguard Worker // Test directly setting the params with bogus keys.
TEST_F(SrtpTransportTest,TestSetParamsKeyTooShort)412*d9f75844SAndroid Build Coastguard Worker TEST_F(SrtpTransportTest, TestSetParamsKeyTooShort) {
413*d9f75844SAndroid Build Coastguard Worker   std::vector<int> extension_ids;
414*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(srtp_transport1_->SetRtpParams(
415*d9f75844SAndroid Build Coastguard Worker       rtc::kSrtpAes128CmSha1_80, kTestKey1, kTestKeyLen - 1, extension_ids,
416*d9f75844SAndroid Build Coastguard Worker       rtc::kSrtpAes128CmSha1_80, kTestKey1, kTestKeyLen - 1, extension_ids));
417*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(srtp_transport1_->SetRtcpParams(
418*d9f75844SAndroid Build Coastguard Worker       rtc::kSrtpAes128CmSha1_80, kTestKey1, kTestKeyLen - 1, extension_ids,
419*d9f75844SAndroid Build Coastguard Worker       rtc::kSrtpAes128CmSha1_80, kTestKey1, kTestKeyLen - 1, extension_ids));
420*d9f75844SAndroid Build Coastguard Worker }
421*d9f75844SAndroid Build Coastguard Worker 
422*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
423