1 /*
2 * libjingle
3 * Copyright 2009 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #undef HAVE_CONFIG_H
29
30 #include "talk/session/media/srtpfilter.h"
31
32 #include <string.h>
33
34 #include <algorithm>
35
36 #include "talk/media/base/rtputils.h"
37 #include "webrtc/base/base64.h"
38 #include "webrtc/base/logging.h"
39 #include "webrtc/base/stringencode.h"
40 #include "webrtc/base/timeutils.h"
41
42 // Enable this line to turn on SRTP debugging
43 // #define SRTP_DEBUG
44
45 #ifdef HAVE_SRTP
46 #ifdef SRTP_RELATIVE_PATH
47 #include "srtp.h" // NOLINT
48 extern "C" srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
49 #include "srtp_priv.h" // NOLINT
50 #else
51 #include "third_party/libsrtp/include/srtp.h"
52 extern "C" srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
53 #include "third_party/libsrtp/include/srtp_priv.h"
54 #endif // SRTP_RELATIVE_PATH
55 #ifdef ENABLE_EXTERNAL_AUTH
56 #include "talk/session/media/externalhmac.h"
57 #endif // ENABLE_EXTERNAL_AUTH
58 #ifdef _DEBUG
59 extern "C" debug_module_t mod_srtp;
60 extern "C" debug_module_t mod_auth;
61 extern "C" debug_module_t mod_cipher;
62 extern "C" debug_module_t mod_stat;
63 extern "C" debug_module_t mod_alloc;
64 extern "C" debug_module_t mod_aes_icm;
65 extern "C" debug_module_t mod_aes_hmac;
66 #endif
67 #else
68 // SrtpFilter needs that constant.
69 #define SRTP_MASTER_KEY_LEN 30
70 #endif // HAVE_SRTP
71
72 namespace cricket {
73
74 const char CS_AES_CM_128_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80";
75 const char CS_AES_CM_128_HMAC_SHA1_32[] = "AES_CM_128_HMAC_SHA1_32";
76 const int SRTP_MASTER_KEY_BASE64_LEN = SRTP_MASTER_KEY_LEN * 4 / 3;
77 const int SRTP_MASTER_KEY_KEY_LEN = 16;
78 const int SRTP_MASTER_KEY_SALT_LEN = 14;
79
80 #ifndef HAVE_SRTP
81
82 // This helper function is used on systems that don't (yet) have SRTP,
83 // to log that the functions that require it won't do anything.
84 namespace {
SrtpNotAvailable(const char * func)85 bool SrtpNotAvailable(const char *func) {
86 LOG(LS_ERROR) << func << ": SRTP is not available on your system.";
87 return false;
88 }
89 } // anonymous namespace
90
91 #endif // !HAVE_SRTP
92
EnableSrtpDebugging()93 void EnableSrtpDebugging() {
94 #ifdef HAVE_SRTP
95 #ifdef _DEBUG
96 debug_on(mod_srtp);
97 debug_on(mod_auth);
98 debug_on(mod_cipher);
99 debug_on(mod_stat);
100 debug_on(mod_alloc);
101 debug_on(mod_aes_icm);
102 // debug_on(mod_aes_cbc);
103 // debug_on(mod_hmac);
104 #endif
105 #endif // HAVE_SRTP
106 }
107
108 // NOTE: This is called from ChannelManager D'tor.
ShutdownSrtp()109 void ShutdownSrtp() {
110 #ifdef HAVE_SRTP
111 // If srtp_dealloc is not executed then this will clear all existing sessions.
112 // This should be called when application is shutting down.
113 SrtpSession::Terminate();
114 #endif
115 }
116
SrtpFilter()117 SrtpFilter::SrtpFilter()
118 : state_(ST_INIT),
119 signal_silent_time_in_ms_(0) {
120 }
121
~SrtpFilter()122 SrtpFilter::~SrtpFilter() {
123 }
124
IsActive() const125 bool SrtpFilter::IsActive() const {
126 return state_ >= ST_ACTIVE;
127 }
128
SetOffer(const std::vector<CryptoParams> & offer_params,ContentSource source)129 bool SrtpFilter::SetOffer(const std::vector<CryptoParams>& offer_params,
130 ContentSource source) {
131 if (!ExpectOffer(source)) {
132 LOG(LS_ERROR) << "Wrong state to update SRTP offer";
133 return false;
134 }
135 return StoreParams(offer_params, source);
136 }
137
SetAnswer(const std::vector<CryptoParams> & answer_params,ContentSource source)138 bool SrtpFilter::SetAnswer(const std::vector<CryptoParams>& answer_params,
139 ContentSource source) {
140 return DoSetAnswer(answer_params, source, true);
141 }
142
SetProvisionalAnswer(const std::vector<CryptoParams> & answer_params,ContentSource source)143 bool SrtpFilter::SetProvisionalAnswer(
144 const std::vector<CryptoParams>& answer_params,
145 ContentSource source) {
146 return DoSetAnswer(answer_params, source, false);
147 }
148
SetRtpParams(const std::string & send_cs,const uint8 * send_key,int send_key_len,const std::string & recv_cs,const uint8 * recv_key,int recv_key_len)149 bool SrtpFilter::SetRtpParams(const std::string& send_cs,
150 const uint8* send_key, int send_key_len,
151 const std::string& recv_cs,
152 const uint8* recv_key, int recv_key_len) {
153 if (state_ == ST_ACTIVE) {
154 LOG(LS_ERROR) << "Tried to set SRTP Params when filter already active";
155 return false;
156 }
157 CreateSrtpSessions();
158 if (!send_session_->SetSend(send_cs, send_key, send_key_len))
159 return false;
160
161 if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len))
162 return false;
163
164 state_ = ST_ACTIVE;
165
166 LOG(LS_INFO) << "SRTP activated with negotiated parameters:"
167 << " send cipher_suite " << send_cs
168 << " recv cipher_suite " << recv_cs;
169 return true;
170 }
171
172 // This function is provided separately because DTLS-SRTP behaves
173 // differently in RTP/RTCP mux and non-mux modes.
174 //
175 // - In the non-muxed case, RTP and RTCP are keyed with different
176 // keys (from different DTLS handshakes), and so we need a new
177 // SrtpSession.
178 // - In the muxed case, they are keyed with the same keys, so
179 // this function is not needed
SetRtcpParams(const std::string & send_cs,const uint8 * send_key,int send_key_len,const std::string & recv_cs,const uint8 * recv_key,int recv_key_len)180 bool SrtpFilter::SetRtcpParams(const std::string& send_cs,
181 const uint8* send_key, int send_key_len,
182 const std::string& recv_cs,
183 const uint8* recv_key, int recv_key_len) {
184 // This can only be called once, but can be safely called after
185 // SetRtpParams
186 if (send_rtcp_session_ || recv_rtcp_session_) {
187 LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active";
188 return false;
189 }
190
191 send_rtcp_session_.reset(new SrtpSession());
192 SignalSrtpError.repeat(send_rtcp_session_->SignalSrtpError);
193 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_);
194 if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len))
195 return false;
196
197 recv_rtcp_session_.reset(new SrtpSession());
198 SignalSrtpError.repeat(recv_rtcp_session_->SignalSrtpError);
199 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_);
200 if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len))
201 return false;
202
203 LOG(LS_INFO) << "SRTCP activated with negotiated parameters:"
204 << " send cipher_suite " << send_cs
205 << " recv cipher_suite " << recv_cs;
206
207 return true;
208 }
209
ProtectRtp(void * p,int in_len,int max_len,int * out_len)210 bool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) {
211 if (!IsActive()) {
212 LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active";
213 return false;
214 }
215 return send_session_->ProtectRtp(p, in_len, max_len, out_len);
216 }
217
ProtectRtp(void * p,int in_len,int max_len,int * out_len,int64 * index)218 bool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len,
219 int64* index) {
220 if (!IsActive()) {
221 LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active";
222 return false;
223 }
224
225 return send_session_->ProtectRtp(p, in_len, max_len, out_len, index);
226 }
227
ProtectRtcp(void * p,int in_len,int max_len,int * out_len)228 bool SrtpFilter::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) {
229 if (!IsActive()) {
230 LOG(LS_WARNING) << "Failed to ProtectRtcp: SRTP not active";
231 return false;
232 }
233 if (send_rtcp_session_) {
234 return send_rtcp_session_->ProtectRtcp(p, in_len, max_len, out_len);
235 } else {
236 return send_session_->ProtectRtcp(p, in_len, max_len, out_len);
237 }
238 }
239
UnprotectRtp(void * p,int in_len,int * out_len)240 bool SrtpFilter::UnprotectRtp(void* p, int in_len, int* out_len) {
241 if (!IsActive()) {
242 LOG(LS_WARNING) << "Failed to UnprotectRtp: SRTP not active";
243 return false;
244 }
245 return recv_session_->UnprotectRtp(p, in_len, out_len);
246 }
247
UnprotectRtcp(void * p,int in_len,int * out_len)248 bool SrtpFilter::UnprotectRtcp(void* p, int in_len, int* out_len) {
249 if (!IsActive()) {
250 LOG(LS_WARNING) << "Failed to UnprotectRtcp: SRTP not active";
251 return false;
252 }
253 if (recv_rtcp_session_) {
254 return recv_rtcp_session_->UnprotectRtcp(p, in_len, out_len);
255 } else {
256 return recv_session_->UnprotectRtcp(p, in_len, out_len);
257 }
258 }
259
GetRtpAuthParams(uint8 ** key,int * key_len,int * tag_len)260 bool SrtpFilter::GetRtpAuthParams(uint8** key, int* key_len, int* tag_len) {
261 if (!IsActive()) {
262 LOG(LS_WARNING) << "Failed to GetRtpAuthParams: SRTP not active";
263 return false;
264 }
265
266 return send_session_->GetRtpAuthParams(key, key_len, tag_len);
267 }
268
set_signal_silent_time(uint32 signal_silent_time_in_ms)269 void SrtpFilter::set_signal_silent_time(uint32 signal_silent_time_in_ms) {
270 signal_silent_time_in_ms_ = signal_silent_time_in_ms;
271 if (state_ == ST_ACTIVE) {
272 send_session_->set_signal_silent_time(signal_silent_time_in_ms);
273 recv_session_->set_signal_silent_time(signal_silent_time_in_ms);
274 if (send_rtcp_session_)
275 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms);
276 if (recv_rtcp_session_)
277 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms);
278 }
279 }
280
ExpectOffer(ContentSource source)281 bool SrtpFilter::ExpectOffer(ContentSource source) {
282 return ((state_ == ST_INIT) ||
283 (state_ == ST_ACTIVE) ||
284 (state_ == ST_SENTOFFER && source == CS_LOCAL) ||
285 (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) ||
286 (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) ||
287 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE));
288 }
289
StoreParams(const std::vector<CryptoParams> & params,ContentSource source)290 bool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params,
291 ContentSource source) {
292 offer_params_ = params;
293 if (state_ == ST_INIT) {
294 state_ = (source == CS_LOCAL) ? ST_SENTOFFER : ST_RECEIVEDOFFER;
295 } else { // state >= ST_ACTIVE
296 state_ =
297 (source == CS_LOCAL) ? ST_SENTUPDATEDOFFER : ST_RECEIVEDUPDATEDOFFER;
298 }
299 return true;
300 }
301
ExpectAnswer(ContentSource source)302 bool SrtpFilter::ExpectAnswer(ContentSource source) {
303 return ((state_ == ST_SENTOFFER && source == CS_REMOTE) ||
304 (state_ == ST_RECEIVEDOFFER && source == CS_LOCAL) ||
305 (state_ == ST_SENTUPDATEDOFFER && source == CS_REMOTE) ||
306 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_LOCAL) ||
307 (state_ == ST_SENTPRANSWER_NO_CRYPTO && source == CS_LOCAL) ||
308 (state_ == ST_SENTPRANSWER && source == CS_LOCAL) ||
309 (state_ == ST_RECEIVEDPRANSWER_NO_CRYPTO && source == CS_REMOTE) ||
310 (state_ == ST_RECEIVEDPRANSWER && source == CS_REMOTE));
311 }
312
DoSetAnswer(const std::vector<CryptoParams> & answer_params,ContentSource source,bool final)313 bool SrtpFilter::DoSetAnswer(const std::vector<CryptoParams>& answer_params,
314 ContentSource source,
315 bool final) {
316 if (!ExpectAnswer(source)) {
317 LOG(LS_ERROR) << "Invalid state for SRTP answer";
318 return false;
319 }
320
321 // If the answer doesn't requests crypto complete the negotiation of an
322 // unencrypted session.
323 // Otherwise, finalize the parameters and apply them.
324 if (answer_params.empty()) {
325 if (final) {
326 return ResetParams();
327 } else {
328 // Need to wait for the final answer to decide if
329 // we should go to Active state.
330 state_ = (source == CS_LOCAL) ? ST_SENTPRANSWER_NO_CRYPTO :
331 ST_RECEIVEDPRANSWER_NO_CRYPTO;
332 return true;
333 }
334 }
335 CryptoParams selected_params;
336 if (!NegotiateParams(answer_params, &selected_params))
337 return false;
338 const CryptoParams& send_params =
339 (source == CS_REMOTE) ? selected_params : answer_params[0];
340 const CryptoParams& recv_params =
341 (source == CS_REMOTE) ? answer_params[0] : selected_params;
342 if (!ApplyParams(send_params, recv_params)) {
343 return false;
344 }
345
346 if (final) {
347 offer_params_.clear();
348 state_ = ST_ACTIVE;
349 } else {
350 state_ =
351 (source == CS_LOCAL) ? ST_SENTPRANSWER : ST_RECEIVEDPRANSWER;
352 }
353 return true;
354 }
355
CreateSrtpSessions()356 void SrtpFilter::CreateSrtpSessions() {
357 send_session_.reset(new SrtpSession());
358 applied_send_params_ = CryptoParams();
359 recv_session_.reset(new SrtpSession());
360 applied_recv_params_ = CryptoParams();
361
362 SignalSrtpError.repeat(send_session_->SignalSrtpError);
363 SignalSrtpError.repeat(recv_session_->SignalSrtpError);
364
365 send_session_->set_signal_silent_time(signal_silent_time_in_ms_);
366 recv_session_->set_signal_silent_time(signal_silent_time_in_ms_);
367 }
368
NegotiateParams(const std::vector<CryptoParams> & answer_params,CryptoParams * selected_params)369 bool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params,
370 CryptoParams* selected_params) {
371 // We're processing an accept. We should have exactly one set of params,
372 // unless the offer didn't mention crypto, in which case we shouldn't be here.
373 bool ret = (answer_params.size() == 1U && !offer_params_.empty());
374 if (ret) {
375 // We should find a match between the answer params and the offered params.
376 std::vector<CryptoParams>::const_iterator it;
377 for (it = offer_params_.begin(); it != offer_params_.end(); ++it) {
378 if (answer_params[0].Matches(*it)) {
379 break;
380 }
381 }
382
383 if (it != offer_params_.end()) {
384 *selected_params = *it;
385 } else {
386 ret = false;
387 }
388 }
389
390 if (!ret) {
391 LOG(LS_WARNING) << "Invalid parameters in SRTP answer";
392 }
393 return ret;
394 }
395
ApplyParams(const CryptoParams & send_params,const CryptoParams & recv_params)396 bool SrtpFilter::ApplyParams(const CryptoParams& send_params,
397 const CryptoParams& recv_params) {
398 // TODO(jiayl): Split this method to apply send and receive CryptoParams
399 // independently, so that we can skip one method when either send or receive
400 // CryptoParams is unchanged.
401 if (applied_send_params_.cipher_suite == send_params.cipher_suite &&
402 applied_send_params_.key_params == send_params.key_params &&
403 applied_recv_params_.cipher_suite == recv_params.cipher_suite &&
404 applied_recv_params_.key_params == recv_params.key_params) {
405 LOG(LS_INFO) << "Applying the same SRTP parameters again. No-op.";
406
407 // We do not want to reset the ROC if the keys are the same. So just return.
408 return true;
409 }
410 // TODO(juberti): Zero these buffers after use.
411 bool ret;
412 uint8 send_key[SRTP_MASTER_KEY_LEN], recv_key[SRTP_MASTER_KEY_LEN];
413 ret = (ParseKeyParams(send_params.key_params, send_key, sizeof(send_key)) &&
414 ParseKeyParams(recv_params.key_params, recv_key, sizeof(recv_key)));
415 if (ret) {
416 CreateSrtpSessions();
417 ret = (send_session_->SetSend(send_params.cipher_suite,
418 send_key, sizeof(send_key)) &&
419 recv_session_->SetRecv(recv_params.cipher_suite,
420 recv_key, sizeof(recv_key)));
421 }
422 if (ret) {
423 LOG(LS_INFO) << "SRTP activated with negotiated parameters:"
424 << " send cipher_suite " << send_params.cipher_suite
425 << " recv cipher_suite " << recv_params.cipher_suite;
426 applied_send_params_ = send_params;
427 applied_recv_params_ = recv_params;
428 } else {
429 LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters";
430 }
431 return ret;
432 }
433
ResetParams()434 bool SrtpFilter::ResetParams() {
435 offer_params_.clear();
436 state_ = ST_INIT;
437 LOG(LS_INFO) << "SRTP reset to init state";
438 return true;
439 }
440
ParseKeyParams(const std::string & key_params,uint8 * key,int len)441 bool SrtpFilter::ParseKeyParams(const std::string& key_params,
442 uint8* key, int len) {
443 // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2"
444
445 // Fail if key-method is wrong.
446 if (key_params.find("inline:") != 0) {
447 return false;
448 }
449
450 // Fail if base64 decode fails, or the key is the wrong size.
451 std::string key_b64(key_params.substr(7)), key_str;
452 if (!rtc::Base64::Decode(key_b64, rtc::Base64::DO_STRICT,
453 &key_str, NULL) ||
454 static_cast<int>(key_str.size()) != len) {
455 return false;
456 }
457
458 memcpy(key, key_str.c_str(), len);
459 return true;
460 }
461
462 ///////////////////////////////////////////////////////////////////////////////
463 // SrtpSession
464
465 #ifdef HAVE_SRTP
466
467 bool SrtpSession::inited_ = false;
468
SrtpSession()469 SrtpSession::SrtpSession()
470 : session_(NULL),
471 rtp_auth_tag_len_(0),
472 rtcp_auth_tag_len_(0),
473 srtp_stat_(new SrtpStat()),
474 last_send_seq_num_(-1) {
475 sessions()->push_back(this);
476 SignalSrtpError.repeat(srtp_stat_->SignalSrtpError);
477 }
478
~SrtpSession()479 SrtpSession::~SrtpSession() {
480 sessions()->erase(std::find(sessions()->begin(), sessions()->end(), this));
481 if (session_) {
482 srtp_dealloc(session_);
483 }
484 }
485
SetSend(const std::string & cs,const uint8 * key,int len)486 bool SrtpSession::SetSend(const std::string& cs, const uint8* key, int len) {
487 return SetKey(ssrc_any_outbound, cs, key, len);
488 }
489
SetRecv(const std::string & cs,const uint8 * key,int len)490 bool SrtpSession::SetRecv(const std::string& cs, const uint8* key, int len) {
491 return SetKey(ssrc_any_inbound, cs, key, len);
492 }
493
ProtectRtp(void * p,int in_len,int max_len,int * out_len)494 bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) {
495 if (!session_) {
496 LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session";
497 return false;
498 }
499
500 int need_len = in_len + rtp_auth_tag_len_; // NOLINT
501 if (max_len < need_len) {
502 LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length "
503 << max_len << " is less than the needed " << need_len;
504 return false;
505 }
506
507 *out_len = in_len;
508 int err = srtp_protect(session_, p, out_len);
509 uint32 ssrc;
510 if (GetRtpSsrc(p, in_len, &ssrc)) {
511 srtp_stat_->AddProtectRtpResult(ssrc, err);
512 }
513 int seq_num;
514 GetRtpSeqNum(p, in_len, &seq_num);
515 if (err != err_status_ok) {
516 LOG(LS_WARNING) << "Failed to protect SRTP packet, seqnum="
517 << seq_num << ", err=" << err << ", last seqnum="
518 << last_send_seq_num_;
519 return false;
520 }
521 last_send_seq_num_ = seq_num;
522 return true;
523 }
524
ProtectRtp(void * p,int in_len,int max_len,int * out_len,int64 * index)525 bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len,
526 int64* index) {
527 if (!ProtectRtp(p, in_len, max_len, out_len)) {
528 return false;
529 }
530 return (index) ? GetSendStreamPacketIndex(p, in_len, index) : true;
531 }
532
ProtectRtcp(void * p,int in_len,int max_len,int * out_len)533 bool SrtpSession::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) {
534 if (!session_) {
535 LOG(LS_WARNING) << "Failed to protect SRTCP packet: no SRTP Session";
536 return false;
537 }
538
539 int need_len = in_len + sizeof(uint32) + rtcp_auth_tag_len_; // NOLINT
540 if (max_len < need_len) {
541 LOG(LS_WARNING) << "Failed to protect SRTCP packet: The buffer length "
542 << max_len << " is less than the needed " << need_len;
543 return false;
544 }
545
546 *out_len = in_len;
547 int err = srtp_protect_rtcp(session_, p, out_len);
548 srtp_stat_->AddProtectRtcpResult(err);
549 if (err != err_status_ok) {
550 LOG(LS_WARNING) << "Failed to protect SRTCP packet, err=" << err;
551 return false;
552 }
553 return true;
554 }
555
UnprotectRtp(void * p,int in_len,int * out_len)556 bool SrtpSession::UnprotectRtp(void* p, int in_len, int* out_len) {
557 if (!session_) {
558 LOG(LS_WARNING) << "Failed to unprotect SRTP packet: no SRTP Session";
559 return false;
560 }
561
562 *out_len = in_len;
563 int err = srtp_unprotect(session_, p, out_len);
564 uint32 ssrc;
565 if (GetRtpSsrc(p, in_len, &ssrc)) {
566 srtp_stat_->AddUnprotectRtpResult(ssrc, err);
567 }
568 if (err != err_status_ok) {
569 LOG(LS_WARNING) << "Failed to unprotect SRTP packet, err=" << err;
570 return false;
571 }
572 return true;
573 }
574
UnprotectRtcp(void * p,int in_len,int * out_len)575 bool SrtpSession::UnprotectRtcp(void* p, int in_len, int* out_len) {
576 if (!session_) {
577 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet: no SRTP Session";
578 return false;
579 }
580
581 *out_len = in_len;
582 int err = srtp_unprotect_rtcp(session_, p, out_len);
583 srtp_stat_->AddUnprotectRtcpResult(err);
584 if (err != err_status_ok) {
585 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet, err=" << err;
586 return false;
587 }
588 return true;
589 }
590
GetRtpAuthParams(uint8 ** key,int * key_len,int * tag_len)591 bool SrtpSession::GetRtpAuthParams(uint8** key, int* key_len,
592 int* tag_len) {
593 #if defined(ENABLE_EXTERNAL_AUTH)
594 external_hmac_ctx_t* external_hmac = NULL;
595 // stream_template will be the reference context for other streams.
596 // Let's use it for getting the keys.
597 srtp_stream_ctx_t* srtp_context = session_->stream_template;
598 if (srtp_context && srtp_context->rtp_auth) {
599 external_hmac = reinterpret_cast<external_hmac_ctx_t*>(
600 srtp_context->rtp_auth->state);
601 }
602
603 if (!external_hmac) {
604 LOG(LS_ERROR) << "Failed to get auth keys from libsrtp!.";
605 return false;
606 }
607
608 *key = external_hmac->key;
609 *key_len = external_hmac->key_length;
610 *tag_len = rtp_auth_tag_len_;
611 return true;
612 #else
613 return false;
614 #endif
615 }
616
GetSendStreamPacketIndex(void * p,int in_len,int64 * index)617 bool SrtpSession::GetSendStreamPacketIndex(void* p, int in_len, int64* index) {
618 srtp_hdr_t* hdr = reinterpret_cast<srtp_hdr_t*>(p);
619 srtp_stream_ctx_t* stream = srtp_get_stream(session_, hdr->ssrc);
620 if (stream == NULL)
621 return false;
622
623 // Shift packet index, put into network byte order
624 *index = be64_to_cpu(rdbx_get_packet_index(&stream->rtp_rdbx) << 16);
625 return true;
626 }
627
set_signal_silent_time(uint32 signal_silent_time_in_ms)628 void SrtpSession::set_signal_silent_time(uint32 signal_silent_time_in_ms) {
629 srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms);
630 }
631
SetKey(int type,const std::string & cs,const uint8 * key,int len)632 bool SrtpSession::SetKey(int type, const std::string& cs,
633 const uint8* key, int len) {
634 if (session_) {
635 LOG(LS_ERROR) << "Failed to create SRTP session: "
636 << "SRTP session already created";
637 return false;
638 }
639
640 if (!Init()) {
641 return false;
642 }
643
644 srtp_policy_t policy;
645 memset(&policy, 0, sizeof(policy));
646
647 if (cs == CS_AES_CM_128_HMAC_SHA1_80) {
648 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
649 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
650 } else if (cs == CS_AES_CM_128_HMAC_SHA1_32) {
651 crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); // rtp is 32,
652 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); // rtcp still 80
653 } else {
654 LOG(LS_WARNING) << "Failed to create SRTP session: unsupported"
655 << " cipher_suite " << cs.c_str();
656 return false;
657 }
658
659 if (!key || len != SRTP_MASTER_KEY_LEN) {
660 LOG(LS_WARNING) << "Failed to create SRTP session: invalid key";
661 return false;
662 }
663
664 policy.ssrc.type = static_cast<ssrc_type_t>(type);
665 policy.ssrc.value = 0;
666 policy.key = const_cast<uint8*>(key);
667 // TODO(astor) parse window size from WSH session-param
668 policy.window_size = 1024;
669 policy.allow_repeat_tx = 1;
670 // If external authentication option is enabled, supply custom auth module
671 // id EXTERNAL_HMAC_SHA1 in the policy structure.
672 // We want to set this option only for rtp packets.
673 // By default policy structure is initialized to HMAC_SHA1.
674 #if defined(ENABLE_EXTERNAL_AUTH)
675 // Enable external HMAC authentication only for outgoing streams.
676 if (type == ssrc_any_outbound) {
677 policy.rtp.auth_type = EXTERNAL_HMAC_SHA1;
678 }
679 #endif
680 policy.next = NULL;
681
682 int err = srtp_create(&session_, &policy);
683 if (err != err_status_ok) {
684 LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err;
685 return false;
686 }
687
688
689 rtp_auth_tag_len_ = policy.rtp.auth_tag_len;
690 rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len;
691 return true;
692 }
693
Init()694 bool SrtpSession::Init() {
695 if (!inited_) {
696 int err;
697 err = srtp_init();
698 if (err != err_status_ok) {
699 LOG(LS_ERROR) << "Failed to init SRTP, err=" << err;
700 return false;
701 }
702
703 err = srtp_install_event_handler(&SrtpSession::HandleEventThunk);
704 if (err != err_status_ok) {
705 LOG(LS_ERROR) << "Failed to install SRTP event handler, err=" << err;
706 return false;
707 }
708 #if defined(ENABLE_EXTERNAL_AUTH)
709 err = external_crypto_init();
710 if (err != err_status_ok) {
711 LOG(LS_ERROR) << "Failed to initialize fake auth, err=" << err;
712 return false;
713 }
714 #endif
715 inited_ = true;
716 }
717
718 return true;
719 }
720
Terminate()721 void SrtpSession::Terminate() {
722 if (inited_) {
723 int err = srtp_shutdown();
724 if (err) {
725 LOG(LS_ERROR) << "srtp_shutdown failed. err=" << err;
726 return;
727 }
728 inited_ = false;
729 }
730 }
731
HandleEvent(const srtp_event_data_t * ev)732 void SrtpSession::HandleEvent(const srtp_event_data_t* ev) {
733 switch (ev->event) {
734 case event_ssrc_collision:
735 LOG(LS_INFO) << "SRTP event: SSRC collision";
736 break;
737 case event_key_soft_limit:
738 LOG(LS_INFO) << "SRTP event: reached soft key usage limit";
739 break;
740 case event_key_hard_limit:
741 LOG(LS_INFO) << "SRTP event: reached hard key usage limit";
742 break;
743 case event_packet_index_limit:
744 LOG(LS_INFO) << "SRTP event: reached hard packet limit (2^48 packets)";
745 break;
746 default:
747 LOG(LS_INFO) << "SRTP event: unknown " << ev->event;
748 break;
749 }
750 }
751
HandleEventThunk(srtp_event_data_t * ev)752 void SrtpSession::HandleEventThunk(srtp_event_data_t* ev) {
753 for (std::list<SrtpSession*>::iterator it = sessions()->begin();
754 it != sessions()->end(); ++it) {
755 if ((*it)->session_ == ev->session) {
756 (*it)->HandleEvent(ev);
757 break;
758 }
759 }
760 }
761
sessions()762 std::list<SrtpSession*>* SrtpSession::sessions() {
763 LIBJINGLE_DEFINE_STATIC_LOCAL(std::list<SrtpSession*>, sessions, ());
764 return &sessions;
765 }
766
767 #else // !HAVE_SRTP
768
769 // On some systems, SRTP is not (yet) available.
770
SrtpSession()771 SrtpSession::SrtpSession() {
772 LOG(WARNING) << "SRTP implementation is missing.";
773 }
774
~SrtpSession()775 SrtpSession::~SrtpSession() {
776 }
777
SetSend(const std::string & cs,const uint8 * key,int len)778 bool SrtpSession::SetSend(const std::string& cs, const uint8* key, int len) {
779 return SrtpNotAvailable(__FUNCTION__);
780 }
781
SetRecv(const std::string & cs,const uint8 * key,int len)782 bool SrtpSession::SetRecv(const std::string& cs, const uint8* key, int len) {
783 return SrtpNotAvailable(__FUNCTION__);
784 }
785
ProtectRtp(void * data,int in_len,int max_len,int * out_len)786 bool SrtpSession::ProtectRtp(void* data, int in_len, int max_len,
787 int* out_len) {
788 return SrtpNotAvailable(__FUNCTION__);
789 }
790
ProtectRtcp(void * data,int in_len,int max_len,int * out_len)791 bool SrtpSession::ProtectRtcp(void* data, int in_len, int max_len,
792 int* out_len) {
793 return SrtpNotAvailable(__FUNCTION__);
794 }
795
UnprotectRtp(void * data,int in_len,int * out_len)796 bool SrtpSession::UnprotectRtp(void* data, int in_len, int* out_len) {
797 return SrtpNotAvailable(__FUNCTION__);
798 }
799
UnprotectRtcp(void * data,int in_len,int * out_len)800 bool SrtpSession::UnprotectRtcp(void* data, int in_len, int* out_len) {
801 return SrtpNotAvailable(__FUNCTION__);
802 }
803
set_signal_silent_time(uint32 signal_silent_time)804 void SrtpSession::set_signal_silent_time(uint32 signal_silent_time) {
805 // Do nothing.
806 }
807
808 #endif // HAVE_SRTP
809
810 ///////////////////////////////////////////////////////////////////////////////
811 // SrtpStat
812
813 #ifdef HAVE_SRTP
814
SrtpStat()815 SrtpStat::SrtpStat()
816 : signal_silent_time_(1000) {
817 }
818
AddProtectRtpResult(uint32 ssrc,int result)819 void SrtpStat::AddProtectRtpResult(uint32 ssrc, int result) {
820 FailureKey key;
821 key.ssrc = ssrc;
822 key.mode = SrtpFilter::PROTECT;
823 switch (result) {
824 case err_status_ok:
825 key.error = SrtpFilter::ERROR_NONE;
826 break;
827 case err_status_auth_fail:
828 key.error = SrtpFilter::ERROR_AUTH;
829 break;
830 default:
831 key.error = SrtpFilter::ERROR_FAIL;
832 }
833 HandleSrtpResult(key);
834 }
835
AddUnprotectRtpResult(uint32 ssrc,int result)836 void SrtpStat::AddUnprotectRtpResult(uint32 ssrc, int result) {
837 FailureKey key;
838 key.ssrc = ssrc;
839 key.mode = SrtpFilter::UNPROTECT;
840 switch (result) {
841 case err_status_ok:
842 key.error = SrtpFilter::ERROR_NONE;
843 break;
844 case err_status_auth_fail:
845 key.error = SrtpFilter::ERROR_AUTH;
846 break;
847 case err_status_replay_fail:
848 case err_status_replay_old:
849 key.error = SrtpFilter::ERROR_REPLAY;
850 break;
851 default:
852 key.error = SrtpFilter::ERROR_FAIL;
853 }
854 HandleSrtpResult(key);
855 }
856
AddProtectRtcpResult(int result)857 void SrtpStat::AddProtectRtcpResult(int result) {
858 AddProtectRtpResult(0U, result);
859 }
860
AddUnprotectRtcpResult(int result)861 void SrtpStat::AddUnprotectRtcpResult(int result) {
862 AddUnprotectRtpResult(0U, result);
863 }
864
HandleSrtpResult(const SrtpStat::FailureKey & key)865 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) {
866 // Handle some cases where error should be signalled right away. For other
867 // errors, trigger error for the first time seeing it. After that, silent
868 // the same error for a certain amount of time (default 1 sec).
869 if (key.error != SrtpFilter::ERROR_NONE) {
870 // For errors, signal first time and wait for 1 sec.
871 FailureStat* stat = &(failures_[key]);
872 uint32 current_time = rtc::Time();
873 if (stat->last_signal_time == 0 ||
874 rtc::TimeDiff(current_time, stat->last_signal_time) >
875 static_cast<int>(signal_silent_time_)) {
876 SignalSrtpError(key.ssrc, key.mode, key.error);
877 stat->last_signal_time = current_time;
878 }
879 }
880 }
881
882 #else // !HAVE_SRTP
883
884 // On some systems, SRTP is not (yet) available.
885
SrtpStat()886 SrtpStat::SrtpStat()
887 : signal_silent_time_(1000) {
888 LOG(WARNING) << "SRTP implementation is missing.";
889 }
890
AddProtectRtpResult(uint32 ssrc,int result)891 void SrtpStat::AddProtectRtpResult(uint32 ssrc, int result) {
892 SrtpNotAvailable(__FUNCTION__);
893 }
894
AddUnprotectRtpResult(uint32 ssrc,int result)895 void SrtpStat::AddUnprotectRtpResult(uint32 ssrc, int result) {
896 SrtpNotAvailable(__FUNCTION__);
897 }
898
AddProtectRtcpResult(int result)899 void SrtpStat::AddProtectRtcpResult(int result) {
900 SrtpNotAvailable(__FUNCTION__);
901 }
902
AddUnprotectRtcpResult(int result)903 void SrtpStat::AddUnprotectRtcpResult(int result) {
904 SrtpNotAvailable(__FUNCTION__);
905 }
906
HandleSrtpResult(const SrtpStat::FailureKey & key)907 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) {
908 SrtpNotAvailable(__FUNCTION__);
909 }
910
911 #endif // HAVE_SRTP
912
913 } // namespace cricket
914