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/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