Home | History | Annotate | Download | only in media
      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/byteorder.h"
     39 #include "webrtc/base/common.h"
     40 #include "webrtc/base/logging.h"
     41 #include "webrtc/base/stringencode.h"
     42 #include "webrtc/base/timeutils.h"
     43 
     44 // Enable this line to turn on SRTP debugging
     45 // #define SRTP_DEBUG
     46 
     47 #ifdef HAVE_SRTP
     48 extern "C" {
     49 #ifdef SRTP_RELATIVE_PATH
     50 #include "srtp.h"  // NOLINT
     51 #include "srtp_priv.h"  // NOLINT
     52 #else
     53 #include "third_party/libsrtp/srtp/include/srtp.h"
     54 #include "third_party/libsrtp/srtp/include/srtp_priv.h"
     55 #endif  // SRTP_RELATIVE_PATH
     56 }
     57 #ifdef  ENABLE_EXTERNAL_AUTH
     58 #include "talk/session/media/externalhmac.h"
     59 #endif  // ENABLE_EXTERNAL_AUTH
     60 #if !defined(NDEBUG)
     61 extern "C" debug_module_t mod_srtp;
     62 extern "C" debug_module_t mod_auth;
     63 extern "C" debug_module_t mod_cipher;
     64 extern "C" debug_module_t mod_stat;
     65 extern "C" debug_module_t mod_alloc;
     66 extern "C" debug_module_t mod_aes_icm;
     67 extern "C" debug_module_t mod_aes_hmac;
     68 #endif
     69 #else
     70 // SrtpFilter needs that constant.
     71 #define SRTP_MASTER_KEY_LEN 30
     72 #endif  // HAVE_SRTP
     73 
     74 namespace cricket {
     75 
     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 #if !defined(NDEBUG)
     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(int send_cs,
    150                               const uint8_t* send_key,
    151                               int send_key_len,
    152                               int recv_cs,
    153                               const uint8_t* recv_key,
    154                               int recv_key_len) {
    155   if (IsActive()) {
    156     LOG(LS_ERROR) << "Tried to set SRTP Params when filter already active";
    157     return false;
    158   }
    159   CreateSrtpSessions();
    160   if (!send_session_->SetSend(send_cs, send_key, send_key_len))
    161     return false;
    162 
    163   if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len))
    164     return false;
    165 
    166   state_ = ST_ACTIVE;
    167 
    168   LOG(LS_INFO) << "SRTP activated with negotiated parameters:"
    169                << " send cipher_suite " << send_cs
    170                << " recv cipher_suite " << recv_cs;
    171   return true;
    172 }
    173 
    174 // This function is provided separately because DTLS-SRTP behaves
    175 // differently in RTP/RTCP mux and non-mux modes.
    176 //
    177 // - In the non-muxed case, RTP and RTCP are keyed with different
    178 //   keys (from different DTLS handshakes), and so we need a new
    179 //   SrtpSession.
    180 // - In the muxed case, they are keyed with the same keys, so
    181 //   this function is not needed
    182 bool SrtpFilter::SetRtcpParams(int send_cs,
    183                                const uint8_t* send_key,
    184                                int send_key_len,
    185                                int recv_cs,
    186                                const uint8_t* recv_key,
    187                                int recv_key_len) {
    188   // This can only be called once, but can be safely called after
    189   // SetRtpParams
    190   if (send_rtcp_session_ || recv_rtcp_session_) {
    191     LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active";
    192     return false;
    193   }
    194 
    195   send_rtcp_session_.reset(new SrtpSession());
    196   SignalSrtpError.repeat(send_rtcp_session_->SignalSrtpError);
    197   send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_);
    198   if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len))
    199     return false;
    200 
    201   recv_rtcp_session_.reset(new SrtpSession());
    202   SignalSrtpError.repeat(recv_rtcp_session_->SignalSrtpError);
    203   recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_);
    204   if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len))
    205     return false;
    206 
    207   LOG(LS_INFO) << "SRTCP activated with negotiated parameters:"
    208                << " send cipher_suite " << send_cs
    209                << " recv cipher_suite " << recv_cs;
    210 
    211   return true;
    212 }
    213 
    214 bool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) {
    215   if (!IsActive()) {
    216     LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active";
    217     return false;
    218   }
    219   ASSERT(send_session_ != NULL);
    220   return send_session_->ProtectRtp(p, in_len, max_len, out_len);
    221 }
    222 
    223 bool SrtpFilter::ProtectRtp(void* p,
    224                             int in_len,
    225                             int max_len,
    226                             int* out_len,
    227                             int64_t* index) {
    228   if (!IsActive()) {
    229     LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active";
    230     return false;
    231   }
    232   ASSERT(send_session_ != NULL);
    233   return send_session_->ProtectRtp(p, in_len, max_len, out_len, index);
    234 }
    235 
    236 bool SrtpFilter::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) {
    237   if (!IsActive()) {
    238     LOG(LS_WARNING) << "Failed to ProtectRtcp: SRTP not active";
    239     return false;
    240   }
    241   if (send_rtcp_session_) {
    242     return send_rtcp_session_->ProtectRtcp(p, in_len, max_len, out_len);
    243   } else {
    244     ASSERT(send_session_ != NULL);
    245     return send_session_->ProtectRtcp(p, in_len, max_len, out_len);
    246   }
    247 }
    248 
    249 bool SrtpFilter::UnprotectRtp(void* p, int in_len, int* out_len) {
    250   if (!IsActive()) {
    251     LOG(LS_WARNING) << "Failed to UnprotectRtp: SRTP not active";
    252     return false;
    253   }
    254   ASSERT(recv_session_ != NULL);
    255   return recv_session_->UnprotectRtp(p, in_len, out_len);
    256 }
    257 
    258 bool SrtpFilter::UnprotectRtcp(void* p, int in_len, int* out_len) {
    259   if (!IsActive()) {
    260     LOG(LS_WARNING) << "Failed to UnprotectRtcp: SRTP not active";
    261     return false;
    262   }
    263   if (recv_rtcp_session_) {
    264     return recv_rtcp_session_->UnprotectRtcp(p, in_len, out_len);
    265   } else {
    266     ASSERT(recv_session_ != NULL);
    267     return recv_session_->UnprotectRtcp(p, in_len, out_len);
    268   }
    269 }
    270 
    271 bool SrtpFilter::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) {
    272   if (!IsActive()) {
    273     LOG(LS_WARNING) << "Failed to GetRtpAuthParams: SRTP not active";
    274     return false;
    275   }
    276 
    277   ASSERT(send_session_ != NULL);
    278   return send_session_->GetRtpAuthParams(key, key_len, tag_len);
    279 }
    280 
    281 void SrtpFilter::set_signal_silent_time(uint32_t signal_silent_time_in_ms) {
    282   signal_silent_time_in_ms_ = signal_silent_time_in_ms;
    283   if (IsActive()) {
    284     ASSERT(send_session_ != NULL);
    285     send_session_->set_signal_silent_time(signal_silent_time_in_ms);
    286     ASSERT(recv_session_ != NULL);
    287     recv_session_->set_signal_silent_time(signal_silent_time_in_ms);
    288     if (send_rtcp_session_)
    289       send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms);
    290     if (recv_rtcp_session_)
    291       recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms);
    292   }
    293 }
    294 
    295 bool SrtpFilter::ExpectOffer(ContentSource source) {
    296   return ((state_ == ST_INIT) ||
    297           (state_ == ST_ACTIVE) ||
    298           (state_  == ST_SENTOFFER && source == CS_LOCAL) ||
    299           (state_  == ST_SENTUPDATEDOFFER && source == CS_LOCAL) ||
    300           (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) ||
    301           (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE));
    302 }
    303 
    304 bool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params,
    305                              ContentSource source) {
    306   offer_params_ = params;
    307   if (state_ == ST_INIT) {
    308     state_ = (source == CS_LOCAL) ? ST_SENTOFFER : ST_RECEIVEDOFFER;
    309   } else if (state_ == ST_ACTIVE) {
    310     state_ =
    311         (source == CS_LOCAL) ? ST_SENTUPDATEDOFFER : ST_RECEIVEDUPDATEDOFFER;
    312   }
    313   return true;
    314 }
    315 
    316 bool SrtpFilter::ExpectAnswer(ContentSource source) {
    317   return ((state_ == ST_SENTOFFER && source == CS_REMOTE) ||
    318           (state_ == ST_RECEIVEDOFFER && source == CS_LOCAL) ||
    319           (state_ == ST_SENTUPDATEDOFFER && source == CS_REMOTE) ||
    320           (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_LOCAL) ||
    321           (state_ == ST_SENTPRANSWER_NO_CRYPTO && source == CS_LOCAL) ||
    322           (state_ == ST_SENTPRANSWER && source == CS_LOCAL) ||
    323           (state_ == ST_RECEIVEDPRANSWER_NO_CRYPTO && source == CS_REMOTE) ||
    324           (state_ == ST_RECEIVEDPRANSWER && source == CS_REMOTE));
    325 }
    326 
    327 bool SrtpFilter::DoSetAnswer(const std::vector<CryptoParams>& answer_params,
    328                              ContentSource source,
    329                              bool final) {
    330   if (!ExpectAnswer(source)) {
    331     LOG(LS_ERROR) << "Invalid state for SRTP answer";
    332     return false;
    333   }
    334 
    335   // If the answer doesn't requests crypto complete the negotiation of an
    336   // unencrypted session.
    337   // Otherwise, finalize the parameters and apply them.
    338   if (answer_params.empty()) {
    339     if (final) {
    340       return ResetParams();
    341     } else {
    342       // Need to wait for the final answer to decide if
    343       // we should go to Active state.
    344       state_ = (source == CS_LOCAL) ? ST_SENTPRANSWER_NO_CRYPTO :
    345                                       ST_RECEIVEDPRANSWER_NO_CRYPTO;
    346       return true;
    347     }
    348   }
    349   CryptoParams selected_params;
    350   if (!NegotiateParams(answer_params, &selected_params))
    351     return false;
    352   const CryptoParams& send_params =
    353       (source == CS_REMOTE) ? selected_params : answer_params[0];
    354   const CryptoParams& recv_params =
    355       (source == CS_REMOTE) ? answer_params[0] : selected_params;
    356   if (!ApplyParams(send_params, recv_params)) {
    357     return false;
    358   }
    359 
    360   if (final) {
    361     offer_params_.clear();
    362     state_ = ST_ACTIVE;
    363   } else {
    364     state_ =
    365         (source == CS_LOCAL) ? ST_SENTPRANSWER : ST_RECEIVEDPRANSWER;
    366   }
    367   return true;
    368 }
    369 
    370 void SrtpFilter::CreateSrtpSessions() {
    371   send_session_.reset(new SrtpSession());
    372   applied_send_params_ = CryptoParams();
    373   recv_session_.reset(new SrtpSession());
    374   applied_recv_params_ = CryptoParams();
    375 
    376   SignalSrtpError.repeat(send_session_->SignalSrtpError);
    377   SignalSrtpError.repeat(recv_session_->SignalSrtpError);
    378 
    379   send_session_->set_signal_silent_time(signal_silent_time_in_ms_);
    380   recv_session_->set_signal_silent_time(signal_silent_time_in_ms_);
    381 }
    382 
    383 bool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params,
    384                                  CryptoParams* selected_params) {
    385   // We're processing an accept. We should have exactly one set of params,
    386   // unless the offer didn't mention crypto, in which case we shouldn't be here.
    387   bool ret = (answer_params.size() == 1U && !offer_params_.empty());
    388   if (ret) {
    389     // We should find a match between the answer params and the offered params.
    390     std::vector<CryptoParams>::const_iterator it;
    391     for (it = offer_params_.begin(); it != offer_params_.end(); ++it) {
    392       if (answer_params[0].Matches(*it)) {
    393         break;
    394       }
    395     }
    396 
    397     if (it != offer_params_.end()) {
    398       *selected_params = *it;
    399     } else {
    400       ret = false;
    401     }
    402   }
    403 
    404   if (!ret) {
    405     LOG(LS_WARNING) << "Invalid parameters in SRTP answer";
    406   }
    407   return ret;
    408 }
    409 
    410 bool SrtpFilter::ApplyParams(const CryptoParams& send_params,
    411                              const CryptoParams& recv_params) {
    412   // TODO(jiayl): Split this method to apply send and receive CryptoParams
    413   // independently, so that we can skip one method when either send or receive
    414   // CryptoParams is unchanged.
    415   if (applied_send_params_.cipher_suite == send_params.cipher_suite &&
    416       applied_send_params_.key_params == send_params.key_params &&
    417       applied_recv_params_.cipher_suite == recv_params.cipher_suite &&
    418       applied_recv_params_.key_params == recv_params.key_params) {
    419     LOG(LS_INFO) << "Applying the same SRTP parameters again. No-op.";
    420 
    421     // We do not want to reset the ROC if the keys are the same. So just return.
    422     return true;
    423   }
    424   // TODO(juberti): Zero these buffers after use.
    425   bool ret;
    426   uint8_t send_key[SRTP_MASTER_KEY_LEN], recv_key[SRTP_MASTER_KEY_LEN];
    427   ret = (ParseKeyParams(send_params.key_params, send_key, sizeof(send_key)) &&
    428          ParseKeyParams(recv_params.key_params, recv_key, sizeof(recv_key)));
    429   if (ret) {
    430     CreateSrtpSessions();
    431     ret = (send_session_->SetSend(
    432                rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite), send_key,
    433                sizeof(send_key)) &&
    434            recv_session_->SetRecv(
    435                rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite), recv_key,
    436                sizeof(recv_key)));
    437   }
    438   if (ret) {
    439     LOG(LS_INFO) << "SRTP activated with negotiated parameters:"
    440                  << " send cipher_suite " << send_params.cipher_suite
    441                  << " recv cipher_suite " << recv_params.cipher_suite;
    442     applied_send_params_ = send_params;
    443     applied_recv_params_ = recv_params;
    444   } else {
    445     LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters";
    446   }
    447   return ret;
    448 }
    449 
    450 bool SrtpFilter::ResetParams() {
    451   offer_params_.clear();
    452   state_ = ST_INIT;
    453   send_session_ = nullptr;
    454   recv_session_ = nullptr;
    455   send_rtcp_session_ = nullptr;
    456   recv_rtcp_session_ = nullptr;
    457   LOG(LS_INFO) << "SRTP reset to init state";
    458   return true;
    459 }
    460 
    461 bool SrtpFilter::ParseKeyParams(const std::string& key_params,
    462                                 uint8_t* key,
    463                                 int len) {
    464   // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2"
    465 
    466   // Fail if key-method is wrong.
    467   if (key_params.find("inline:") != 0) {
    468     return false;
    469   }
    470 
    471   // Fail if base64 decode fails, or the key is the wrong size.
    472   std::string key_b64(key_params.substr(7)), key_str;
    473   if (!rtc::Base64::Decode(key_b64, rtc::Base64::DO_STRICT,
    474                                  &key_str, NULL) ||
    475       static_cast<int>(key_str.size()) != len) {
    476     return false;
    477   }
    478 
    479   memcpy(key, key_str.c_str(), len);
    480   return true;
    481 }
    482 
    483 ///////////////////////////////////////////////////////////////////////////////
    484 // SrtpSession
    485 
    486 #ifdef HAVE_SRTP
    487 
    488 bool SrtpSession::inited_ = false;
    489 
    490 // This lock protects SrtpSession::inited_ and SrtpSession::sessions_.
    491 rtc::GlobalLockPod SrtpSession::lock_;
    492 
    493 SrtpSession::SrtpSession()
    494     : session_(NULL),
    495       rtp_auth_tag_len_(0),
    496       rtcp_auth_tag_len_(0),
    497       srtp_stat_(new SrtpStat()),
    498       last_send_seq_num_(-1) {
    499   {
    500     rtc::GlobalLockScope ls(&lock_);
    501     sessions()->push_back(this);
    502   }
    503   SignalSrtpError.repeat(srtp_stat_->SignalSrtpError);
    504 }
    505 
    506 SrtpSession::~SrtpSession() {
    507   {
    508     rtc::GlobalLockScope ls(&lock_);
    509     sessions()->erase(std::find(sessions()->begin(), sessions()->end(), this));
    510   }
    511   if (session_) {
    512     srtp_dealloc(session_);
    513   }
    514 }
    515 
    516 bool SrtpSession::SetSend(int cs, const uint8_t* key, int len) {
    517   return SetKey(ssrc_any_outbound, cs, key, len);
    518 }
    519 
    520 bool SrtpSession::SetRecv(int cs, const uint8_t* key, int len) {
    521   return SetKey(ssrc_any_inbound, cs, key, len);
    522 }
    523 
    524 bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) {
    525   if (!session_) {
    526     LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session";
    527     return false;
    528   }
    529 
    530   int need_len = in_len + rtp_auth_tag_len_;  // NOLINT
    531   if (max_len < need_len) {
    532     LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length "
    533                     << max_len << " is less than the needed " << need_len;
    534     return false;
    535   }
    536 
    537   *out_len = in_len;
    538   int err = srtp_protect(session_, p, out_len);
    539   uint32_t ssrc;
    540   if (GetRtpSsrc(p, in_len, &ssrc)) {
    541     srtp_stat_->AddProtectRtpResult(ssrc, err);
    542   }
    543   int seq_num;
    544   GetRtpSeqNum(p, in_len, &seq_num);
    545   if (err != err_status_ok) {
    546     LOG(LS_WARNING) << "Failed to protect SRTP packet, seqnum="
    547                     << seq_num << ", err=" << err << ", last seqnum="
    548                     << last_send_seq_num_;
    549     return false;
    550   }
    551   last_send_seq_num_ = seq_num;
    552   return true;
    553 }
    554 
    555 bool SrtpSession::ProtectRtp(void* p,
    556                              int in_len,
    557                              int max_len,
    558                              int* out_len,
    559                              int64_t* index) {
    560   if (!ProtectRtp(p, in_len, max_len, out_len)) {
    561     return false;
    562   }
    563   return (index) ? GetSendStreamPacketIndex(p, in_len, index) : true;
    564 }
    565 
    566 bool SrtpSession::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) {
    567   if (!session_) {
    568     LOG(LS_WARNING) << "Failed to protect SRTCP packet: no SRTP Session";
    569     return false;
    570   }
    571 
    572   int need_len = in_len + sizeof(uint32_t) + rtcp_auth_tag_len_;  // NOLINT
    573   if (max_len < need_len) {
    574     LOG(LS_WARNING) << "Failed to protect SRTCP packet: The buffer length "
    575                     << max_len << " is less than the needed " << need_len;
    576     return false;
    577   }
    578 
    579   *out_len = in_len;
    580   int err = srtp_protect_rtcp(session_, p, out_len);
    581   srtp_stat_->AddProtectRtcpResult(err);
    582   if (err != err_status_ok) {
    583     LOG(LS_WARNING) << "Failed to protect SRTCP packet, err=" << err;
    584     return false;
    585   }
    586   return true;
    587 }
    588 
    589 bool SrtpSession::UnprotectRtp(void* p, int in_len, int* out_len) {
    590   if (!session_) {
    591     LOG(LS_WARNING) << "Failed to unprotect SRTP packet: no SRTP Session";
    592     return false;
    593   }
    594 
    595   *out_len = in_len;
    596   int err = srtp_unprotect(session_, p, out_len);
    597   uint32_t ssrc;
    598   if (GetRtpSsrc(p, in_len, &ssrc)) {
    599     srtp_stat_->AddUnprotectRtpResult(ssrc, err);
    600   }
    601   if (err != err_status_ok) {
    602     LOG(LS_WARNING) << "Failed to unprotect SRTP packet, err=" << err;
    603     return false;
    604   }
    605   return true;
    606 }
    607 
    608 bool SrtpSession::UnprotectRtcp(void* p, int in_len, int* out_len) {
    609   if (!session_) {
    610     LOG(LS_WARNING) << "Failed to unprotect SRTCP packet: no SRTP Session";
    611     return false;
    612   }
    613 
    614   *out_len = in_len;
    615   int err = srtp_unprotect_rtcp(session_, p, out_len);
    616   srtp_stat_->AddUnprotectRtcpResult(err);
    617   if (err != err_status_ok) {
    618     LOG(LS_WARNING) << "Failed to unprotect SRTCP packet, err=" << err;
    619     return false;
    620   }
    621   return true;
    622 }
    623 
    624 bool SrtpSession::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) {
    625 #if defined(ENABLE_EXTERNAL_AUTH)
    626   ExternalHmacContext* external_hmac = NULL;
    627   // stream_template will be the reference context for other streams.
    628   // Let's use it for getting the keys.
    629   srtp_stream_ctx_t* srtp_context = session_->stream_template;
    630   if (srtp_context && srtp_context->rtp_auth) {
    631     external_hmac = reinterpret_cast<ExternalHmacContext*>(
    632         srtp_context->rtp_auth->state);
    633   }
    634 
    635   if (!external_hmac) {
    636     LOG(LS_ERROR) << "Failed to get auth keys from libsrtp!.";
    637     return false;
    638   }
    639 
    640   *key = external_hmac->key;
    641   *key_len = external_hmac->key_length;
    642   *tag_len = rtp_auth_tag_len_;
    643   return true;
    644 #else
    645   return false;
    646 #endif
    647 }
    648 
    649 bool SrtpSession::GetSendStreamPacketIndex(void* p,
    650                                            int in_len,
    651                                            int64_t* index) {
    652   srtp_hdr_t* hdr = reinterpret_cast<srtp_hdr_t*>(p);
    653   srtp_stream_ctx_t* stream = srtp_get_stream(session_, hdr->ssrc);
    654   if (stream == NULL)
    655     return false;
    656 
    657   // Shift packet index, put into network byte order
    658   *index = static_cast<int64_t>(
    659       rtc::NetworkToHost64(rdbx_get_packet_index(&stream->rtp_rdbx) << 16));
    660   return true;
    661 }
    662 
    663 void SrtpSession::set_signal_silent_time(uint32_t signal_silent_time_in_ms) {
    664   srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms);
    665 }
    666 
    667 bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, int len) {
    668   if (session_) {
    669     LOG(LS_ERROR) << "Failed to create SRTP session: "
    670                   << "SRTP session already created";
    671     return false;
    672   }
    673 
    674   if (!Init()) {
    675     return false;
    676   }
    677 
    678   srtp_policy_t policy;
    679   memset(&policy, 0, sizeof(policy));
    680 
    681   if (cs == rtc::SRTP_AES128_CM_SHA1_80) {
    682     crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
    683     crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
    684   } else if (cs == rtc::SRTP_AES128_CM_SHA1_32) {
    685     crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);   // rtp is 32,
    686     crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);  // rtcp still 80
    687   } else {
    688     LOG(LS_WARNING) << "Failed to create SRTP session: unsupported"
    689                     << " cipher_suite " << cs;
    690     return false;
    691   }
    692 
    693   if (!key || len != SRTP_MASTER_KEY_LEN) {
    694     LOG(LS_WARNING) << "Failed to create SRTP session: invalid key";
    695     return false;
    696   }
    697 
    698   policy.ssrc.type = static_cast<ssrc_type_t>(type);
    699   policy.ssrc.value = 0;
    700   policy.key = const_cast<uint8_t*>(key);
    701   // TODO(astor) parse window size from WSH session-param
    702   policy.window_size = 1024;
    703   policy.allow_repeat_tx = 1;
    704   // If external authentication option is enabled, supply custom auth module
    705   // id EXTERNAL_HMAC_SHA1 in the policy structure.
    706   // We want to set this option only for rtp packets.
    707   // By default policy structure is initialized to HMAC_SHA1.
    708 #if defined(ENABLE_EXTERNAL_AUTH)
    709   // Enable external HMAC authentication only for outgoing streams.
    710   if (type == ssrc_any_outbound) {
    711     policy.rtp.auth_type = EXTERNAL_HMAC_SHA1;
    712   }
    713 #endif
    714   policy.next = NULL;
    715 
    716   int err = srtp_create(&session_, &policy);
    717   if (err != err_status_ok) {
    718     session_ = NULL;
    719     LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err;
    720     return false;
    721   }
    722 
    723 
    724   rtp_auth_tag_len_ = policy.rtp.auth_tag_len;
    725   rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len;
    726   return true;
    727 }
    728 
    729 bool SrtpSession::Init() {
    730   rtc::GlobalLockScope ls(&lock_);
    731 
    732   if (!inited_) {
    733     int err;
    734     err = srtp_init();
    735     if (err != err_status_ok) {
    736       LOG(LS_ERROR) << "Failed to init SRTP, err=" << err;
    737       return false;
    738     }
    739 
    740     err = srtp_install_event_handler(&SrtpSession::HandleEventThunk);
    741     if (err != err_status_ok) {
    742       LOG(LS_ERROR) << "Failed to install SRTP event handler, err=" << err;
    743       return false;
    744     }
    745 #if defined(ENABLE_EXTERNAL_AUTH)
    746     err = external_crypto_init();
    747     if (err != err_status_ok) {
    748       LOG(LS_ERROR) << "Failed to initialize fake auth, err=" << err;
    749       return false;
    750     }
    751 #endif
    752     inited_ = true;
    753   }
    754 
    755   return true;
    756 }
    757 
    758 void SrtpSession::Terminate() {
    759   rtc::GlobalLockScope ls(&lock_);
    760 
    761   if (inited_) {
    762     int err = srtp_shutdown();
    763     if (err) {
    764       LOG(LS_ERROR) << "srtp_shutdown failed. err=" << err;
    765       return;
    766     }
    767     inited_ = false;
    768   }
    769 }
    770 
    771 void SrtpSession::HandleEvent(const srtp_event_data_t* ev) {
    772   switch (ev->event) {
    773     case event_ssrc_collision:
    774       LOG(LS_INFO) << "SRTP event: SSRC collision";
    775       break;
    776     case event_key_soft_limit:
    777       LOG(LS_INFO) << "SRTP event: reached soft key usage limit";
    778       break;
    779     case event_key_hard_limit:
    780       LOG(LS_INFO) << "SRTP event: reached hard key usage limit";
    781       break;
    782     case event_packet_index_limit:
    783       LOG(LS_INFO) << "SRTP event: reached hard packet limit (2^48 packets)";
    784       break;
    785     default:
    786       LOG(LS_INFO) << "SRTP event: unknown " << ev->event;
    787       break;
    788   }
    789 }
    790 
    791 void SrtpSession::HandleEventThunk(srtp_event_data_t* ev) {
    792   rtc::GlobalLockScope ls(&lock_);
    793 
    794   for (std::list<SrtpSession*>::iterator it = sessions()->begin();
    795        it != sessions()->end(); ++it) {
    796     if ((*it)->session_ == ev->session) {
    797       (*it)->HandleEvent(ev);
    798       break;
    799     }
    800   }
    801 }
    802 
    803 std::list<SrtpSession*>* SrtpSession::sessions() {
    804   RTC_DEFINE_STATIC_LOCAL(std::list<SrtpSession*>, sessions, ());
    805   return &sessions;
    806 }
    807 
    808 #else   // !HAVE_SRTP
    809 
    810 // On some systems, SRTP is not (yet) available.
    811 
    812 SrtpSession::SrtpSession() {
    813   LOG(WARNING) << "SRTP implementation is missing.";
    814 }
    815 
    816 SrtpSession::~SrtpSession() {
    817 }
    818 
    819 bool SrtpSession::SetSend(const std::string& cs, const uint8_t* key, int len) {
    820   return SrtpNotAvailable(__FUNCTION__);
    821 }
    822 
    823 bool SrtpSession::SetRecv(const std::string& cs, const uint8_t* key, int len) {
    824   return SrtpNotAvailable(__FUNCTION__);
    825 }
    826 
    827 bool SrtpSession::ProtectRtp(void* data, int in_len, int max_len,
    828                              int* out_len) {
    829   return SrtpNotAvailable(__FUNCTION__);
    830 }
    831 
    832 bool SrtpSession::ProtectRtcp(void* data, int in_len, int max_len,
    833                               int* out_len) {
    834   return SrtpNotAvailable(__FUNCTION__);
    835 }
    836 
    837 bool SrtpSession::UnprotectRtp(void* data, int in_len, int* out_len) {
    838   return SrtpNotAvailable(__FUNCTION__);
    839 }
    840 
    841 bool SrtpSession::UnprotectRtcp(void* data, int in_len, int* out_len) {
    842   return SrtpNotAvailable(__FUNCTION__);
    843 }
    844 
    845 void SrtpSession::set_signal_silent_time(uint32_t signal_silent_time) {
    846   // Do nothing.
    847 }
    848 
    849 #endif  // HAVE_SRTP
    850 
    851 ///////////////////////////////////////////////////////////////////////////////
    852 // SrtpStat
    853 
    854 #ifdef HAVE_SRTP
    855 
    856 SrtpStat::SrtpStat()
    857     : signal_silent_time_(1000) {
    858 }
    859 
    860 void SrtpStat::AddProtectRtpResult(uint32_t ssrc, int result) {
    861   FailureKey key;
    862   key.ssrc = ssrc;
    863   key.mode = SrtpFilter::PROTECT;
    864   switch (result) {
    865     case err_status_ok:
    866       key.error = SrtpFilter::ERROR_NONE;
    867       break;
    868     case err_status_auth_fail:
    869       key.error = SrtpFilter::ERROR_AUTH;
    870       break;
    871     default:
    872       key.error = SrtpFilter::ERROR_FAIL;
    873   }
    874   HandleSrtpResult(key);
    875 }
    876 
    877 void SrtpStat::AddUnprotectRtpResult(uint32_t ssrc, int result) {
    878   FailureKey key;
    879   key.ssrc = ssrc;
    880   key.mode = SrtpFilter::UNPROTECT;
    881   switch (result) {
    882     case err_status_ok:
    883       key.error = SrtpFilter::ERROR_NONE;
    884       break;
    885     case err_status_auth_fail:
    886       key.error = SrtpFilter::ERROR_AUTH;
    887       break;
    888     case err_status_replay_fail:
    889     case err_status_replay_old:
    890       key.error = SrtpFilter::ERROR_REPLAY;
    891       break;
    892     default:
    893       key.error = SrtpFilter::ERROR_FAIL;
    894   }
    895   HandleSrtpResult(key);
    896 }
    897 
    898 void SrtpStat::AddProtectRtcpResult(int result) {
    899   AddProtectRtpResult(0U, result);
    900 }
    901 
    902 void SrtpStat::AddUnprotectRtcpResult(int result) {
    903   AddUnprotectRtpResult(0U, result);
    904 }
    905 
    906 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) {
    907   // Handle some cases where error should be signalled right away. For other
    908   // errors, trigger error for the first time seeing it.  After that, silent
    909   // the same error for a certain amount of time (default 1 sec).
    910   if (key.error != SrtpFilter::ERROR_NONE) {
    911     // For errors, signal first time and wait for 1 sec.
    912     FailureStat* stat = &(failures_[key]);
    913     uint32_t current_time = rtc::Time();
    914     if (stat->last_signal_time == 0 ||
    915         rtc::TimeDiff(current_time, stat->last_signal_time) >
    916         static_cast<int>(signal_silent_time_)) {
    917       SignalSrtpError(key.ssrc, key.mode, key.error);
    918       stat->last_signal_time = current_time;
    919     }
    920   }
    921 }
    922 
    923 #else   // !HAVE_SRTP
    924 
    925 // On some systems, SRTP is not (yet) available.
    926 
    927 SrtpStat::SrtpStat()
    928     : signal_silent_time_(1000) {
    929   LOG(WARNING) << "SRTP implementation is missing.";
    930 }
    931 
    932 void SrtpStat::AddProtectRtpResult(uint32_t ssrc, int result) {
    933   SrtpNotAvailable(__FUNCTION__);
    934 }
    935 
    936 void SrtpStat::AddUnprotectRtpResult(uint32_t ssrc, int result) {
    937   SrtpNotAvailable(__FUNCTION__);
    938 }
    939 
    940 void SrtpStat::AddProtectRtcpResult(int result) {
    941   SrtpNotAvailable(__FUNCTION__);
    942 }
    943 
    944 void SrtpStat::AddUnprotectRtcpResult(int result) {
    945   SrtpNotAvailable(__FUNCTION__);
    946 }
    947 
    948 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) {
    949   SrtpNotAvailable(__FUNCTION__);
    950 }
    951 
    952 #endif  // HAVE_SRTP
    953 
    954 }  // namespace cricket
    955