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/base/base64.h" 37 #include "talk/base/logging.h" 38 #include "talk/base/stringencode.h" 39 #include "talk/base/timeutils.h" 40 #include "talk/media/base/rtputils.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 { 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 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. 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 117 SrtpFilter::SrtpFilter() 118 : state_(ST_INIT), 119 signal_silent_time_in_ms_(0) { 120 } 121 122 SrtpFilter::~SrtpFilter() { 123 } 124 125 bool SrtpFilter::IsActive() const { 126 return state_ >= ST_ACTIVE; 127 } 128 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 138 bool SrtpFilter::SetAnswer(const std::vector<CryptoParams>& answer_params, 139 ContentSource source) { 140 return DoSetAnswer(answer_params, source, true); 141 } 142 143 bool SrtpFilter::SetProvisionalAnswer( 144 const std::vector<CryptoParams>& answer_params, 145 ContentSource source) { 146 return DoSetAnswer(answer_params, source, false); 147 } 148 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 (!talk_base::Base64::Decode(key_b64, talk_base::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 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 479 SrtpSession::~SrtpSession() { 480 sessions()->erase(std::find(sessions()->begin(), sessions()->end(), this)); 481 if (session_) { 482 srtp_dealloc(session_); 483 } 484 } 485 486 bool SrtpSession::SetSend(const std::string& cs, const uint8* key, int len) { 487 return SetKey(ssrc_any_outbound, cs, key, len); 488 } 489 490 bool SrtpSession::SetRecv(const std::string& cs, const uint8* key, int len) { 491 return SetKey(ssrc_any_inbound, cs, key, len); 492 } 493 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 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 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 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 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 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 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 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 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 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 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 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 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 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 771 SrtpSession::SrtpSession() { 772 LOG(WARNING) << "SRTP implementation is missing."; 773 } 774 775 SrtpSession::~SrtpSession() { 776 } 777 778 bool SrtpSession::SetSend(const std::string& cs, const uint8* key, int len) { 779 return SrtpNotAvailable(__FUNCTION__); 780 } 781 782 bool SrtpSession::SetRecv(const std::string& cs, const uint8* key, int len) { 783 return SrtpNotAvailable(__FUNCTION__); 784 } 785 786 bool SrtpSession::ProtectRtp(void* data, int in_len, int max_len, 787 int* out_len) { 788 return SrtpNotAvailable(__FUNCTION__); 789 } 790 791 bool SrtpSession::ProtectRtcp(void* data, int in_len, int max_len, 792 int* out_len) { 793 return SrtpNotAvailable(__FUNCTION__); 794 } 795 796 bool SrtpSession::UnprotectRtp(void* data, int in_len, int* out_len) { 797 return SrtpNotAvailable(__FUNCTION__); 798 } 799 800 bool SrtpSession::UnprotectRtcp(void* data, int in_len, int* out_len) { 801 return SrtpNotAvailable(__FUNCTION__); 802 } 803 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 815 SrtpStat::SrtpStat() 816 : signal_silent_time_(1000) { 817 } 818 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 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 857 void SrtpStat::AddProtectRtcpResult(int result) { 858 AddProtectRtpResult(0U, result); 859 } 860 861 void SrtpStat::AddUnprotectRtcpResult(int result) { 862 AddUnprotectRtpResult(0U, result); 863 } 864 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 = talk_base::Time(); 873 if (stat->last_signal_time == 0 || 874 talk_base::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 886 SrtpStat::SrtpStat() 887 : signal_silent_time_(1000) { 888 LOG(WARNING) << "SRTP implementation is missing."; 889 } 890 891 void SrtpStat::AddProtectRtpResult(uint32 ssrc, int result) { 892 SrtpNotAvailable(__FUNCTION__); 893 } 894 895 void SrtpStat::AddUnprotectRtpResult(uint32 ssrc, int result) { 896 SrtpNotAvailable(__FUNCTION__); 897 } 898 899 void SrtpStat::AddProtectRtcpResult(int result) { 900 SrtpNotAvailable(__FUNCTION__); 901 } 902 903 void SrtpStat::AddUnprotectRtcpResult(int result) { 904 SrtpNotAvailable(__FUNCTION__); 905 } 906 907 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { 908 SrtpNotAvailable(__FUNCTION__); 909 } 910 911 #endif // HAVE_SRTP 912 913 } // namespace cricket 914