blob: d0f6ea6c847efa71884efb707124514397a7cdab [file] [log] [blame]
zstein4dde3df2017-07-07 14:26:25 -07001/*
2 * Copyright 2004 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Steve Anton10542f22019-01-11 09:11:00 -080011#include "pc/srtp_session.h"
zstein4dde3df2017-07-07 14:26:25 -070012
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <string.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020014
zstein4dde3df2017-07-07 14:26:25 -070015#include <string>
16
Steve Anton10542f22019-01-11 09:11:00 -080017#include "media/base/fake_rtp.h"
18#include "pc/test/srtp_test_util.h"
19#include "rtc_base/byte_order.h"
20#include "rtc_base/ssl_stream_adapter.h" // For rtc::SRTP_*
Mirko Bonadei17f48782018-09-28 08:51:10 +020021#include "system_wrappers/include/metrics.h"
Steve Antonb443dfe2019-03-05 14:09:49 -080022#include "test/gmock.h"
Yves Gerey3e707812018-11-28 16:47:49 +010023#include "test/gtest.h"
Steve Antondb67ba12018-03-19 17:41:42 -070024#include "third_party/libsrtp/include/srtp.h"
zstein4dde3df2017-07-07 14:26:25 -070025
Steve Antonb443dfe2019-03-05 14:09:49 -080026using ::testing::ElementsAre;
27using ::testing::Pair;
28
zstein4dde3df2017-07-07 14:26:25 -070029namespace rtc {
30
Zhi Huangc99b6c72017-11-10 16:44:46 -080031std::vector<int> kEncryptedHeaderExtensionIds;
32
Mirko Bonadei6a489f22019-04-09 15:11:12 +020033class SrtpSessionTest : public ::testing::Test {
Qingsi Wang7fc821d2018-07-12 12:54:53 -070034 public:
35 SrtpSessionTest() { webrtc::metrics::Reset(); }
36
zstein4dde3df2017-07-07 14:26:25 -070037 protected:
38 virtual void SetUp() {
39 rtp_len_ = sizeof(kPcmuFrame);
40 rtcp_len_ = sizeof(kRtcpReport);
41 memcpy(rtp_packet_, kPcmuFrame, rtp_len_);
42 memcpy(rtcp_packet_, kRtcpReport, rtcp_len_);
43 }
44 void TestProtectRtp(const std::string& cs) {
45 int out_len = 0;
46 EXPECT_TRUE(
47 s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_), &out_len));
48 EXPECT_EQ(out_len, rtp_len_ + rtp_auth_tag_len(cs));
49 EXPECT_NE(0, memcmp(rtp_packet_, kPcmuFrame, rtp_len_));
50 rtp_len_ = out_len;
51 }
52 void TestProtectRtcp(const std::string& cs) {
53 int out_len = 0;
54 EXPECT_TRUE(s1_.ProtectRtcp(rtcp_packet_, rtcp_len_, sizeof(rtcp_packet_),
55 &out_len));
56 EXPECT_EQ(out_len, rtcp_len_ + 4 + rtcp_auth_tag_len(cs)); // NOLINT
57 EXPECT_NE(0, memcmp(rtcp_packet_, kRtcpReport, rtcp_len_));
58 rtcp_len_ = out_len;
59 }
60 void TestUnprotectRtp(const std::string& cs) {
61 int out_len = 0, expected_len = sizeof(kPcmuFrame);
62 EXPECT_TRUE(s2_.UnprotectRtp(rtp_packet_, rtp_len_, &out_len));
63 EXPECT_EQ(expected_len, out_len);
64 EXPECT_EQ(0, memcmp(rtp_packet_, kPcmuFrame, out_len));
65 }
66 void TestUnprotectRtcp(const std::string& cs) {
67 int out_len = 0, expected_len = sizeof(kRtcpReport);
68 EXPECT_TRUE(s2_.UnprotectRtcp(rtcp_packet_, rtcp_len_, &out_len));
69 EXPECT_EQ(expected_len, out_len);
70 EXPECT_EQ(0, memcmp(rtcp_packet_, kRtcpReport, out_len));
71 }
72 cricket::SrtpSession s1_;
73 cricket::SrtpSession s2_;
74 char rtp_packet_[sizeof(kPcmuFrame) + 10];
75 char rtcp_packet_[sizeof(kRtcpReport) + 4 + 10];
76 int rtp_len_;
77 int rtcp_len_;
78};
79
80// Test that we can set up the session and keys properly.
81TEST_F(SrtpSessionTest, TestGoodSetup) {
Zhi Huangc99b6c72017-11-10 16:44:46 -080082 EXPECT_TRUE(s1_.SetSend(SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
83 kEncryptedHeaderExtensionIds));
84 EXPECT_TRUE(s2_.SetRecv(SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
85 kEncryptedHeaderExtensionIds));
zstein4dde3df2017-07-07 14:26:25 -070086}
87
88// Test that we can't change the keys once set.
89TEST_F(SrtpSessionTest, TestBadSetup) {
Zhi Huangc99b6c72017-11-10 16:44:46 -080090 EXPECT_TRUE(s1_.SetSend(SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
91 kEncryptedHeaderExtensionIds));
92 EXPECT_TRUE(s2_.SetRecv(SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
93 kEncryptedHeaderExtensionIds));
94 EXPECT_FALSE(s1_.SetSend(SRTP_AES128_CM_SHA1_80, kTestKey2, kTestKeyLen,
95 kEncryptedHeaderExtensionIds));
96 EXPECT_FALSE(s2_.SetRecv(SRTP_AES128_CM_SHA1_80, kTestKey2, kTestKeyLen,
97 kEncryptedHeaderExtensionIds));
zstein4dde3df2017-07-07 14:26:25 -070098}
99
100// Test that we fail keys of the wrong length.
101TEST_F(SrtpSessionTest, TestKeysTooShort) {
Zhi Huangc99b6c72017-11-10 16:44:46 -0800102 EXPECT_FALSE(s1_.SetSend(SRTP_AES128_CM_SHA1_80, kTestKey1, 1,
103 kEncryptedHeaderExtensionIds));
104 EXPECT_FALSE(s2_.SetRecv(SRTP_AES128_CM_SHA1_80, kTestKey1, 1,
105 kEncryptedHeaderExtensionIds));
zstein4dde3df2017-07-07 14:26:25 -0700106}
107
108// Test that we can encrypt and decrypt RTP/RTCP using AES_CM_128_HMAC_SHA1_80.
109TEST_F(SrtpSessionTest, TestProtect_AES_CM_128_HMAC_SHA1_80) {
Zhi Huangc99b6c72017-11-10 16:44:46 -0800110 EXPECT_TRUE(s1_.SetSend(SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
111 kEncryptedHeaderExtensionIds));
112 EXPECT_TRUE(s2_.SetRecv(SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
113 kEncryptedHeaderExtensionIds));
zstein4dde3df2017-07-07 14:26:25 -0700114 TestProtectRtp(CS_AES_CM_128_HMAC_SHA1_80);
115 TestProtectRtcp(CS_AES_CM_128_HMAC_SHA1_80);
116 TestUnprotectRtp(CS_AES_CM_128_HMAC_SHA1_80);
117 TestUnprotectRtcp(CS_AES_CM_128_HMAC_SHA1_80);
118}
119
120// Test that we can encrypt and decrypt RTP/RTCP using AES_CM_128_HMAC_SHA1_32.
121TEST_F(SrtpSessionTest, TestProtect_AES_CM_128_HMAC_SHA1_32) {
Zhi Huangc99b6c72017-11-10 16:44:46 -0800122 EXPECT_TRUE(s1_.SetSend(SRTP_AES128_CM_SHA1_32, kTestKey1, kTestKeyLen,
123 kEncryptedHeaderExtensionIds));
124 EXPECT_TRUE(s2_.SetRecv(SRTP_AES128_CM_SHA1_32, kTestKey1, kTestKeyLen,
125 kEncryptedHeaderExtensionIds));
zstein4dde3df2017-07-07 14:26:25 -0700126 TestProtectRtp(CS_AES_CM_128_HMAC_SHA1_32);
127 TestProtectRtcp(CS_AES_CM_128_HMAC_SHA1_32);
128 TestUnprotectRtp(CS_AES_CM_128_HMAC_SHA1_32);
129 TestUnprotectRtcp(CS_AES_CM_128_HMAC_SHA1_32);
130}
131
132TEST_F(SrtpSessionTest, TestGetSendStreamPacketIndex) {
Zhi Huangc99b6c72017-11-10 16:44:46 -0800133 EXPECT_TRUE(s1_.SetSend(SRTP_AES128_CM_SHA1_32, kTestKey1, kTestKeyLen,
134 kEncryptedHeaderExtensionIds));
zstein4dde3df2017-07-07 14:26:25 -0700135 int64_t index;
136 int out_len = 0;
137 EXPECT_TRUE(s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_),
138 &out_len, &index));
139 // |index| will be shifted by 16.
140 int64_t be64_index = static_cast<int64_t>(NetworkToHost64(1 << 16));
141 EXPECT_EQ(be64_index, index);
142}
143
144// Test that we fail to unprotect if someone tampers with the RTP/RTCP paylaods.
145TEST_F(SrtpSessionTest, TestTamperReject) {
146 int out_len;
Zhi Huangc99b6c72017-11-10 16:44:46 -0800147 EXPECT_TRUE(s1_.SetSend(SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
148 kEncryptedHeaderExtensionIds));
149 EXPECT_TRUE(s2_.SetRecv(SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
150 kEncryptedHeaderExtensionIds));
zstein4dde3df2017-07-07 14:26:25 -0700151 TestProtectRtp(CS_AES_CM_128_HMAC_SHA1_80);
152 TestProtectRtcp(CS_AES_CM_128_HMAC_SHA1_80);
153 rtp_packet_[0] = 0x12;
154 rtcp_packet_[1] = 0x34;
155 EXPECT_FALSE(s2_.UnprotectRtp(rtp_packet_, rtp_len_, &out_len));
Ying Wangef3998f2019-12-09 13:06:53 +0100156 EXPECT_METRIC_THAT(
Steve Antonb443dfe2019-03-05 14:09:49 -0800157 webrtc::metrics::Samples("WebRTC.PeerConnection.SrtpUnprotectError"),
158 ElementsAre(Pair(srtp_err_status_bad_param, 1)));
zstein4dde3df2017-07-07 14:26:25 -0700159 EXPECT_FALSE(s2_.UnprotectRtcp(rtcp_packet_, rtcp_len_, &out_len));
Ying Wangef3998f2019-12-09 13:06:53 +0100160 EXPECT_METRIC_THAT(
Steve Antonb443dfe2019-03-05 14:09:49 -0800161 webrtc::metrics::Samples("WebRTC.PeerConnection.SrtcpUnprotectError"),
162 ElementsAre(Pair(srtp_err_status_auth_fail, 1)));
zstein4dde3df2017-07-07 14:26:25 -0700163}
164
165// Test that we fail to unprotect if the payloads are not authenticated.
166TEST_F(SrtpSessionTest, TestUnencryptReject) {
167 int out_len;
Zhi Huangc99b6c72017-11-10 16:44:46 -0800168 EXPECT_TRUE(s1_.SetSend(SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
169 kEncryptedHeaderExtensionIds));
170 EXPECT_TRUE(s2_.SetRecv(SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
171 kEncryptedHeaderExtensionIds));
zstein4dde3df2017-07-07 14:26:25 -0700172 EXPECT_FALSE(s2_.UnprotectRtp(rtp_packet_, rtp_len_, &out_len));
Ying Wangef3998f2019-12-09 13:06:53 +0100173 EXPECT_METRIC_THAT(
Steve Antonb443dfe2019-03-05 14:09:49 -0800174 webrtc::metrics::Samples("WebRTC.PeerConnection.SrtpUnprotectError"),
175 ElementsAre(Pair(srtp_err_status_auth_fail, 1)));
zstein4dde3df2017-07-07 14:26:25 -0700176 EXPECT_FALSE(s2_.UnprotectRtcp(rtcp_packet_, rtcp_len_, &out_len));
Ying Wangef3998f2019-12-09 13:06:53 +0100177 EXPECT_METRIC_THAT(
Steve Antonb443dfe2019-03-05 14:09:49 -0800178 webrtc::metrics::Samples("WebRTC.PeerConnection.SrtcpUnprotectError"),
179 ElementsAre(Pair(srtp_err_status_cant_check, 1)));
zstein4dde3df2017-07-07 14:26:25 -0700180}
181
182// Test that we fail when using buffers that are too small.
183TEST_F(SrtpSessionTest, TestBuffersTooSmall) {
184 int out_len;
Zhi Huangc99b6c72017-11-10 16:44:46 -0800185 EXPECT_TRUE(s1_.SetSend(SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
186 kEncryptedHeaderExtensionIds));
zstein4dde3df2017-07-07 14:26:25 -0700187 EXPECT_FALSE(s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_) - 10,
188 &out_len));
189 EXPECT_FALSE(s1_.ProtectRtcp(rtcp_packet_, rtcp_len_,
190 sizeof(rtcp_packet_) - 14, &out_len));
191}
192
193TEST_F(SrtpSessionTest, TestReplay) {
194 static const uint16_t kMaxSeqnum = static_cast<uint16_t>(-1);
195 static const uint16_t seqnum_big = 62275;
196 static const uint16_t seqnum_small = 10;
197 static const uint16_t replay_window = 1024;
198 int out_len;
199
Zhi Huangc99b6c72017-11-10 16:44:46 -0800200 EXPECT_TRUE(s1_.SetSend(SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
201 kEncryptedHeaderExtensionIds));
202 EXPECT_TRUE(s2_.SetRecv(SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen,
203 kEncryptedHeaderExtensionIds));
zstein4dde3df2017-07-07 14:26:25 -0700204
205 // Initial sequence number.
206 SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_) + 2, seqnum_big);
207 EXPECT_TRUE(
208 s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_), &out_len));
209
210 // Replay within the 1024 window should succeed.
211 SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_) + 2,
212 seqnum_big - replay_window + 1);
213 EXPECT_TRUE(
214 s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_), &out_len));
215
216 // Replay out side of the 1024 window should fail.
217 SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_) + 2,
218 seqnum_big - replay_window - 1);
219 EXPECT_FALSE(
220 s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_), &out_len));
221
222 // Increment sequence number to a small number.
223 SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_) + 2, seqnum_small);
224 EXPECT_TRUE(
225 s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_), &out_len));
226
227 // Replay around 0 but out side of the 1024 window should fail.
228 SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_) + 2,
229 kMaxSeqnum + seqnum_small - replay_window - 1);
230 EXPECT_FALSE(
231 s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_), &out_len));
232
233 // Replay around 0 but within the 1024 window should succeed.
234 for (uint16_t seqnum = 65000; seqnum < 65003; ++seqnum) {
235 SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_) + 2, seqnum);
236 EXPECT_TRUE(
237 s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_), &out_len));
238 }
239
240 // Go back to normal sequence nubmer.
241 // NOTE: without the fix in libsrtp, this would fail. This is because
242 // without the fix, the loop above would keep incrementing local sequence
243 // number in libsrtp, eventually the new sequence number would go out side
244 // of the window.
245 SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_) + 2, seqnum_small + 1);
246 EXPECT_TRUE(
247 s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_), &out_len));
248}
249
250} // namespace rtc