Revert of Completed the functionalities of SrtpTransport. (patchset 7 id:320001 of https://codereview.webrtc.org/2997983002/ )

Reason for revert:
This seems to be causing some video freezes. See https://bugs.chromium.org/p/webrtc/issues/detail?id=8251

Original issue's description:
> Completed the functionalities of SrtpTransport.
>
> The SrtpTransport takes the SRTP responsibilities from the BaseChannel
> and SrtpFilter. SrtpTransport is now responsible for setting the crypto
> keys, protecting and unprotecting the packets. SrtpTransport doesn't know
> if the keys are from SDES or DTLS handshake.
>
> BaseChannel is now only responsible setting the offer/answer for SDES
> or extracting the key from DtlsTransport and configuring the
> SrtpTransport.
>
> SrtpFilter is used by BaseChannel as a helper for SDES negotiation.
>
> BUG=webrtc:7013
>
> Review-Url: https://codereview.webrtc.org/2997983002
> Cr-Commit-Position: refs/heads/master@{#19636}
> Committed: https://chromium.googlesource.com/external/webrtc/+/e683c6871fef24d3ff64f085d6bc0e965f17fcf7

TBR=deadbeef@webrtc.org,pthatcher@google.com,zhihuang@webrtc.org
Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:7013

Review-Url: https://codereview.webrtc.org/3018513002
Cr-Commit-Position: refs/heads/master@{#19895}
diff --git a/p2p/base/fakepackettransport.h b/p2p/base/fakepackettransport.h
index 2af14c1..654d05b 100644
--- a/p2p/base/fakepackettransport.h
+++ b/p2p/base/fakepackettransport.h
@@ -86,8 +86,6 @@
   bool GetOption(Socket::Option opt, int* value) override { return true; }
   int GetError() override { return 0; }
 
-  const CopyOnWriteBuffer* last_sent_packet() { return &last_sent_packet_; }
-
  private:
   void set_writable(bool writable) {
     if (writable_ == writable) {
@@ -109,14 +107,12 @@
   }
 
   void SendPacketInternal(const CopyOnWriteBuffer& packet) {
-    last_sent_packet_ = packet;
     if (dest_) {
       dest_->SignalReadPacket(dest_, packet.data<char>(), packet.size(),
                               CreatePacketTime(0), 0);
     }
   }
 
-  CopyOnWriteBuffer last_sent_packet_;
   AsyncInvoker invoker_;
   std::string debug_name_;
   FakePacketTransport* dest_ = nullptr;
diff --git a/pc/channel.cc b/pc/channel.cc
index 7ddf5de..3ab8ca0 100644
--- a/pc/channel.cc
+++ b/pc/channel.cc
@@ -151,22 +151,18 @@
       signaling_thread_(signaling_thread),
       content_name_(content_name),
       rtcp_mux_required_(rtcp_mux_required),
+      rtp_transport_(
+          srtp_required
+              ? rtc::WrapUnique<webrtc::RtpTransportInternal>(
+                    new webrtc::SrtpTransport(rtcp_mux_required, content_name))
+              : rtc::MakeUnique<webrtc::RtpTransport>(rtcp_mux_required)),
       srtp_required_(srtp_required),
       media_channel_(media_channel),
       selected_candidate_pair_(nullptr) {
   RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
-  if (srtp_required) {
-    auto transport =
-        rtc::MakeUnique<webrtc::SrtpTransport>(rtcp_mux_required, content_name);
-    srtp_transport_ = transport.get();
-    rtp_transport_ = std::move(transport);
 #if defined(ENABLE_EXTERNAL_AUTH)
-    srtp_transport_->EnableExternalAuth();
+  srtp_filter_.EnableExternalAuth();
 #endif
-  } else {
-    rtp_transport_ = rtc::MakeUnique<webrtc::RtpTransport>(rtcp_mux_required);
-    srtp_transport_ = nullptr;
-  }
   rtp_transport_->SignalReadyToSend.connect(
       this, &BaseChannel::OnTransportReadyToSend);
   // TODO(zstein):  RtpTransport::SignalPacketReceived will probably be replaced
@@ -311,17 +307,14 @@
     return;
   }
 
-  // When using DTLS-SRTP, we must reset the SrtpTransport every time the
-  // DtlsTransport changes and wait until the DTLS handshake is complete to set
-  // the newly negotiated parameters.
+  // When using DTLS-SRTP, we must reset the SrtpFilter every time the transport
+  // changes and wait until the DTLS handshake is complete to set the newly
+  // negotiated parameters.
   if (ShouldSetupDtlsSrtp_n()) {
     // Set |writable_| to false such that UpdateWritableState_w can set up
     // DTLS-SRTP when |writable_| becomes true again.
     writable_ = false;
-    dtls_active_ = false;
-    if (srtp_transport_) {
-      srtp_transport_->ResetParams();
-    }
+    srtp_filter_.ResetParams();
   }
 
   // If this BaseChannel doesn't require RTCP mux and we haven't fully
@@ -377,8 +370,8 @@
   }
 
   if (rtcp && new_dtls_transport) {
-    RTC_CHECK(!(ShouldSetupDtlsSrtp_n() && srtp_active()))
-        << "Setting RTCP for DTLS/SRTP after the DTLS is active "
+    RTC_CHECK(!(ShouldSetupDtlsSrtp_n() && srtp_filter_.IsActive()))
+        << "Setting RTCP for DTLS/SRTP after SrtpFilter is active "
         << "should never happen.";
   }
 
@@ -529,7 +522,8 @@
   // and we have had some form of connectivity.
   return enabled() && IsReceiveContentDirection(remote_content_direction_) &&
          IsSendContentDirection(local_content_direction_) &&
-         was_ever_writable() && (srtp_active() || !ShouldSetupDtlsSrtp_n());
+         was_ever_writable() &&
+         (srtp_filter_.IsActive() || !ShouldSetupDtlsSrtp_n());
 }
 
 bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet,
@@ -581,16 +575,13 @@
     return;
   }
 
-  // Reset the SrtpTransport if it's not the CONNECTED state. For the CONNECTED
+  // Reset the srtp filter if it's not the CONNECTED state. For the CONNECTED
   // state, setting up DTLS-SRTP context is deferred to ChannelWritable_w to
   // cover other scenarios like the whole transport is writable (not just this
   // TransportChannel) or when TransportChannel is attached after DTLS is
   // negotiated.
   if (state != DTLS_TRANSPORT_CONNECTED) {
-    dtls_active_ = false;
-    if (srtp_transport_) {
-      srtp_transport_->ResetParams();
-    }
+    srtp_filter_.ResetParams();
   }
 }
 
@@ -664,30 +655,90 @@
     return false;
   }
 
-  if (!srtp_active()) {
-    if (srtp_required_) {
-      // The audio/video engines may attempt to send RTCP packets as soon as the
-      // streams are created, so don't treat this as an error for RTCP.
-      // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
-      if (rtcp) {
+  rtc::PacketOptions updated_options;
+  updated_options = options;
+  // Protect if needed.
+  if (srtp_filter_.IsActive()) {
+    TRACE_EVENT0("webrtc", "SRTP Encode");
+    bool res;
+    uint8_t* data = packet->data();
+    int len = static_cast<int>(packet->size());
+    if (!rtcp) {
+// If ENABLE_EXTERNAL_AUTH flag is on then packet authentication is not done
+// inside libsrtp for a RTP packet. A external HMAC module will be writing
+// a fake HMAC value. This is ONLY done for a RTP packet.
+// Socket layer will update rtp sendtime extension header if present in
+// packet with current time before updating the HMAC.
+#if !defined(ENABLE_EXTERNAL_AUTH)
+      res = srtp_filter_.ProtectRtp(data, len,
+                                    static_cast<int>(packet->capacity()), &len);
+#else
+      if (!srtp_filter_.IsExternalAuthActive()) {
+        res = srtp_filter_.ProtectRtp(
+            data, len, static_cast<int>(packet->capacity()), &len);
+      } else {
+        updated_options.packet_time_params.rtp_sendtime_extension_id =
+            rtp_abs_sendtime_extn_id_;
+        res = srtp_filter_.ProtectRtp(
+            data, len, static_cast<int>(packet->capacity()), &len,
+            &updated_options.packet_time_params.srtp_packet_index);
+        // If protection succeeds, let's get auth params from srtp.
+        if (res) {
+          uint8_t* auth_key = NULL;
+          int key_len;
+          res = srtp_filter_.GetRtpAuthParams(
+              &auth_key, &key_len,
+              &updated_options.packet_time_params.srtp_auth_tag_len);
+          if (res) {
+            updated_options.packet_time_params.srtp_auth_key.resize(key_len);
+            updated_options.packet_time_params.srtp_auth_key.assign(
+                auth_key, auth_key + key_len);
+          }
+        }
+      }
+#endif
+      if (!res) {
+        int seq_num = -1;
+        uint32_t ssrc = 0;
+        GetRtpSeqNum(data, len, &seq_num);
+        GetRtpSsrc(data, len, &ssrc);
+        LOG(LS_ERROR) << "Failed to protect " << content_name_
+                      << " RTP packet: size=" << len << ", seqnum=" << seq_num
+                      << ", SSRC=" << ssrc;
         return false;
       }
-      // However, there shouldn't be any RTP packets sent before SRTP is set up
-      // (and SetSend(true) is called).
-      LOG(LS_ERROR) << "Can't send outgoing RTP packet when SRTP is inactive"
-                    << " and crypto is required";
-      RTC_NOTREACHED();
+    } else {
+      res = srtp_filter_.ProtectRtcp(
+          data, len, static_cast<int>(packet->capacity()), &len);
+      if (!res) {
+        int type = -1;
+        GetRtcpType(data, len, &type);
+        LOG(LS_ERROR) << "Failed to protect " << content_name_
+                      << " RTCP packet: size=" << len << ", type=" << type;
+        return false;
+      }
+    }
+
+    // Update the length of the packet now that we've added the auth tag.
+    packet->SetSize(len);
+  } else if (srtp_required_) {
+    // The audio/video engines may attempt to send RTCP packets as soon as the
+    // streams are created, so don't treat this as an error for RTCP.
+    // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=6809
+    if (rtcp) {
       return false;
     }
-    // Bon voyage.
-    return rtcp ? rtp_transport_->SendRtcpPacket(packet, options, PF_NORMAL)
-                : rtp_transport_->SendRtpPacket(packet, options, PF_NORMAL);
+    // However, there shouldn't be any RTP packets sent before SRTP is set up
+    // (and SetSend(true) is called).
+    LOG(LS_ERROR) << "Can't send outgoing RTP packet when SRTP is inactive"
+                  << " and crypto is required";
+    RTC_NOTREACHED();
+    return false;
   }
-  RTC_DCHECK(srtp_transport_);
-  RTC_DCHECK(srtp_transport_->IsActive());
+
   // Bon voyage.
-  return rtcp ? srtp_transport_->SendRtcpPacket(packet, options, PF_SRTP_BYPASS)
-              : srtp_transport_->SendRtpPacket(packet, options, PF_SRTP_BYPASS);
+  int flags = (secure() && secure_dtls()) ? PF_SRTP_BYPASS : PF_NORMAL;
+  return rtp_transport_->SendPacket(rtcp, packet, updated_options, flags);
 }
 
 bool BaseChannel::HandlesPayloadType(int packet_type) const {
@@ -702,7 +753,37 @@
     signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FIRSTPACKETRECEIVED);
   }
 
-  if (!srtp_active() && srtp_required_) {
+  // Unprotect the packet, if needed.
+  if (srtp_filter_.IsActive()) {
+    TRACE_EVENT0("webrtc", "SRTP Decode");
+    char* data = packet->data<char>();
+    int len = static_cast<int>(packet->size());
+    bool res;
+    if (!rtcp) {
+      res = srtp_filter_.UnprotectRtp(data, len, &len);
+      if (!res) {
+        int seq_num = -1;
+        uint32_t ssrc = 0;
+        GetRtpSeqNum(data, len, &seq_num);
+        GetRtpSsrc(data, len, &ssrc);
+        LOG(LS_ERROR) << "Failed to unprotect " << content_name_
+                      << " RTP packet: size=" << len << ", seqnum=" << seq_num
+                      << ", SSRC=" << ssrc;
+        return;
+      }
+    } else {
+      res = srtp_filter_.UnprotectRtcp(data, len, &len);
+      if (!res) {
+        int type = -1;
+        GetRtcpType(data, len, &type);
+        LOG(LS_ERROR) << "Failed to unprotect " << content_name_
+                      << " RTCP packet: size=" << len << ", type=" << type;
+        return;
+      }
+    }
+
+    packet->SetSize(len);
+  } else if (srtp_required_) {
     // Our session description indicates that SRTP is required, but we got a
     // packet before our SRTP filter is active. This means either that
     // a) we got SRTP packets before we received the SDES keys, in which case
@@ -878,37 +959,42 @@
     recv_key = &server_write_key;
   }
 
-  if (rtcp) {
-    if (!dtls_active()) {
-      RTC_DCHECK(srtp_transport_);
-      ret = srtp_transport_->SetRtcpParams(
-          selected_crypto_suite, &(*send_key)[0],
-          static_cast<int>(send_key->size()), selected_crypto_suite,
-          &(*recv_key)[0], static_cast<int>(recv_key->size()));
+  if (!srtp_filter_.IsActive()) {
+    if (rtcp) {
+      ret = srtp_filter_.SetRtcpParams(selected_crypto_suite, &(*send_key)[0],
+                                       static_cast<int>(send_key->size()),
+                                       selected_crypto_suite, &(*recv_key)[0],
+                                       static_cast<int>(recv_key->size()));
     } else {
-      // RTCP doesn't need to call SetRtpParam because it is only used
-      // to make the updated encrypted RTP header extension IDs take effect.
-      ret = true;
+      ret = srtp_filter_.SetRtpParams(selected_crypto_suite, &(*send_key)[0],
+                                      static_cast<int>(send_key->size()),
+                                      selected_crypto_suite, &(*recv_key)[0],
+                                      static_cast<int>(recv_key->size()));
     }
   } else {
-    RTC_DCHECK(srtp_transport_);
-    ret = srtp_transport_->SetRtpParams(selected_crypto_suite, &(*send_key)[0],
-                                        static_cast<int>(send_key->size()),
-                                        selected_crypto_suite, &(*recv_key)[0],
-                                        static_cast<int>(recv_key->size()));
-    dtls_active_ = ret;
+    if (rtcp) {
+      // RTCP doesn't need to be updated because UpdateRtpParams is only used
+      // to update the set of encrypted RTP header extension IDs.
+      ret = true;
+    } else {
+      ret = srtp_filter_.UpdateRtpParams(selected_crypto_suite, &(*send_key)[0],
+                                         static_cast<int>(send_key->size()),
+                                         selected_crypto_suite, &(*recv_key)[0],
+                                         static_cast<int>(recv_key->size()));
+    }
   }
 
   if (!ret) {
     LOG(LS_WARNING) << "DTLS-SRTP key installation failed";
   } else {
+    dtls_keyed_ = true;
     UpdateTransportOverhead();
   }
   return ret;
 }
 
 void BaseChannel::MaybeSetupDtlsSrtp_n() {
-  if (dtls_active()) {
+  if (srtp_filter_.IsActive()) {
     return;
   }
 
@@ -916,10 +1002,6 @@
     return;
   }
 
-  if (!srtp_transport_) {
-    EnableSrtpTransport_n();
-  }
-
   if (!SetupDtlsSrtp_n(false)) {
     SignalDtlsSrtpSetupFailure_n(false);
     return;
@@ -1003,24 +1085,6 @@
   return true;
 }
 
-void BaseChannel::EnableSrtpTransport_n() {
-  if (srtp_transport_ == nullptr) {
-    rtp_transport_->SignalReadyToSend.disconnect(this);
-    rtp_transport_->SignalPacketReceived.disconnect(this);
-
-    auto transport = rtc::MakeUnique<webrtc::SrtpTransport>(
-        std::move(rtp_transport_), content_name_);
-    srtp_transport_ = transport.get();
-    rtp_transport_ = std::move(transport);
-
-    rtp_transport_->SignalReadyToSend.connect(
-        this, &BaseChannel::OnTransportReadyToSend);
-    rtp_transport_->SignalPacketReceived.connect(
-        this, &BaseChannel::OnPacketReceived);
-    LOG(LS_INFO) << "Wrapping RtpTransport in SrtpTransport.";
-  }
-}
-
 bool BaseChannel::SetSrtp_n(const std::vector<CryptoParams>& cryptos,
                             ContentAction action,
                             ContentSource src,
@@ -1037,69 +1101,36 @@
   if (!ret) {
     return false;
   }
-
-  // If SRTP was not required, but we're setting a description that uses SDES,
-  // we need to upgrade to an SrtpTransport.
-  if (!srtp_transport_ && !dtls && !cryptos.empty()) {
-    EnableSrtpTransport_n();
-  }
-  if (srtp_transport_) {
-    srtp_transport_->SetEncryptedHeaderExtensionIds(src,
-                                                    encrypted_extension_ids);
-  }
+  srtp_filter_.SetEncryptedHeaderExtensionIds(src, encrypted_extension_ids);
   switch (action) {
     case CA_OFFER:
       // If DTLS is already active on the channel, we could be renegotiating
       // here. We don't update the srtp filter.
       if (!dtls) {
-        ret = sdes_negotiator_.SetOffer(cryptos, src);
+        ret = srtp_filter_.SetOffer(cryptos, src);
       }
       break;
     case CA_PRANSWER:
       // If we're doing DTLS-SRTP, we don't want to update the filter
       // with an answer, because we already have SRTP parameters.
       if (!dtls) {
-        ret = sdes_negotiator_.SetProvisionalAnswer(cryptos, src);
+        ret = srtp_filter_.SetProvisionalAnswer(cryptos, src);
       }
       break;
     case CA_ANSWER:
       // If we're doing DTLS-SRTP, we don't want to update the filter
       // with an answer, because we already have SRTP parameters.
       if (!dtls) {
-        ret = sdes_negotiator_.SetAnswer(cryptos, src);
+        ret = srtp_filter_.SetAnswer(cryptos, src);
       }
       break;
     default:
       break;
   }
-
-  // If setting an SDES answer succeeded, apply the negotiated parameters
-  // to the SRTP transport.
-  if ((action == CA_PRANSWER || action == CA_ANSWER) && !dtls && ret) {
-    if (sdes_negotiator_.send_cipher_suite() &&
-        sdes_negotiator_.recv_cipher_suite()) {
-      ret = srtp_transport_->SetRtpParams(
-          *(sdes_negotiator_.send_cipher_suite()),
-          sdes_negotiator_.send_key().data(),
-          static_cast<int>(sdes_negotiator_.send_key().size()),
-          *(sdes_negotiator_.recv_cipher_suite()),
-          sdes_negotiator_.recv_key().data(),
-          static_cast<int>(sdes_negotiator_.recv_key().size()));
-    } else {
-      LOG(LS_INFO) << "No crypto keys are provided for SDES.";
-      if (action == CA_ANSWER && srtp_transport_) {
-        // Explicitly reset the |srtp_transport_| if no crypto param is
-        // provided in the answer. No need to call |ResetParams()| for
-        // |sdes_negotiator_| because it resets the params inside |SetAnswer|.
-        srtp_transport_->ResetParams();
-      }
-    }
-  }
-
   // Only update SRTP filter if using DTLS. SDES is handled internally
   // by the SRTP filter.
   // TODO(jbauch): Only update if encrypted extension ids have changed.
-  if (ret && dtls_active() && rtp_dtls_transport_ &&
+  if (ret && dtls_keyed_ && rtp_dtls_transport_ &&
       rtp_dtls_transport_->dtls_state() == DTLS_TRANSPORT_CONNECTED) {
     bool rtcp = false;
     ret = SetupDtlsSrtp_n(rtcp);
@@ -1143,6 +1174,7 @@
             transport_name_.empty()
                 ? rtp_transport_->rtp_packet_transport()->debug_name()
                 : transport_name_;
+        ;
         LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name()
                      << "; no longer need RTCP transport for " << debug_name;
         if (rtp_transport_->rtcp_packet_transport()) {
@@ -1371,13 +1403,7 @@
 
 void BaseChannel::CacheRtpAbsSendTimeHeaderExtension_n(
     int rtp_abs_sendtime_extn_id) {
-  if (srtp_transport_) {
-    srtp_transport_->CacheRtpAbsSendTimeHeaderExtension(
-        rtp_abs_sendtime_extn_id);
-  } else {
-    LOG(LS_WARNING) << "Trying to cache the Absolute Send Time extension id "
-                       "but the SRTP is not active.";
-  }
+  rtp_abs_sendtime_extn_id_ = rtp_abs_sendtime_extn_id;
 }
 
 void BaseChannel::OnMessage(rtc::Message *pmsg) {
@@ -1661,9 +1687,9 @@
           ? kTcpOverhaed
           : kUdpOverhaed;
 
-  if (sdes_active()) {
+  if (secure()) {
     int srtp_overhead = 0;
-    if (srtp_transport_->GetSrtpOverhead(&srtp_overhead))
+    if (srtp_filter_.GetSrtpOverhead(&srtp_overhead))
       transport_overhead_per_packet += srtp_overhead;
   }
 
diff --git a/pc/channel.h b/pc/channel.h
index 613597b..e7871f9 100644
--- a/pc/channel.h
+++ b/pc/channel.h
@@ -33,6 +33,7 @@
 #include "pc/mediamonitor.h"
 #include "pc/mediasession.h"
 #include "pc/rtcpmuxfilter.h"
+#include "pc/rtptransportinternal.h"
 #include "pc/srtpfilter.h"
 #include "rtc_base/asyncinvoker.h"
 #include "rtc_base/asyncudpsocket.h"
@@ -43,8 +44,6 @@
 
 namespace webrtc {
 class AudioSinkInterface;
-class RtpTransportInternal;
-class SrtpTransport;
 }  // namespace webrtc
 
 namespace cricket {
@@ -100,12 +99,12 @@
   const std::string& transport_name() const { return transport_name_; }
   bool enabled() const { return enabled_; }
 
-  // This function returns true if we are using SDES.
-  bool sdes_active() const { return sdes_negotiator_.IsActive(); }
-  // The following function returns true if we are using DTLS-based keying.
-  bool dtls_active() const { return dtls_active_; }
-  // This function returns true if using SRTP (DTLS-based keying or SDES).
-  bool srtp_active() const { return sdes_active() || dtls_active(); }
+  // This function returns true if we are using SRTP.
+  bool secure() const { return srtp_filter_.IsActive(); }
+  // The following function returns true if we are using
+  // DTLS-based keying. If you turned off SRTP later, however
+  // you could have secure() == false and dtls_secure() == true.
+  bool secure_dtls() const { return dtls_keyed_; }
 
   bool writable() const { return writable_; }
 
@@ -183,6 +182,8 @@
       override;
   int SetOption_n(SocketType type, rtc::Socket::Option o, int val);
 
+  SrtpFilter* srtp_filter() { return &srtp_filter_; }
+
   virtual cricket::MediaType media_type() = 0;
 
   // This function returns true if we require SRTP for call setup.
@@ -368,8 +369,6 @@
   void CacheRtpAbsSendTimeHeaderExtension_n(int rtp_abs_sendtime_extn_id);
   int GetTransportOverheadPerPacket() const;
   void UpdateTransportOverhead();
-  // Wraps the existing RtpTransport in an SrtpTransport.
-  void EnableSrtpTransport_n();
 
   rtc::Thread* const worker_thread_;
   rtc::Thread* const network_thread_;
@@ -390,16 +389,16 @@
   DtlsTransportInternal* rtp_dtls_transport_ = nullptr;
   DtlsTransportInternal* rtcp_dtls_transport_ = nullptr;
   std::unique_ptr<webrtc::RtpTransportInternal> rtp_transport_;
-  webrtc::SrtpTransport* srtp_transport_ = nullptr;
   std::vector<std::pair<rtc::Socket::Option, int> > socket_options_;
   std::vector<std::pair<rtc::Socket::Option, int> > rtcp_socket_options_;
-  SrtpFilter sdes_negotiator_;
+  SrtpFilter srtp_filter_;
   RtcpMuxFilter rtcp_mux_filter_;
   bool writable_ = false;
   bool was_ever_writable_ = false;
   bool has_received_packet_ = false;
-  bool dtls_active_ = false;
+  bool dtls_keyed_ = false;
   const bool srtp_required_ = true;
+  int rtp_abs_sendtime_extn_id_ = -1;
 
   // MediaChannel related members that should be accessed from the worker
   // thread.
diff --git a/pc/channel_unittest.cc b/pc/channel_unittest.cc
index b5517da..26da453 100644
--- a/pc/channel_unittest.cc
+++ b/pc/channel_unittest.cc
@@ -577,7 +577,7 @@
   // Basic sanity check.
   void TestInit() {
     CreateChannels(0, 0);
-    EXPECT_FALSE(channel1_->srtp_active());
+    EXPECT_FALSE(channel1_->secure());
     EXPECT_FALSE(media_channel1_->sending());
     if (verify_playout_) {
       EXPECT_FALSE(media_channel1_->playout());
@@ -892,8 +892,8 @@
     EXPECT_TRUE(channel2_->SetRemoteContent(&content4, CA_ANSWER, NULL));
     EXPECT_EQ(0u, media_channel2_->recv_streams().size());
 
-    EXPECT_TRUE(channel1_->srtp_active());
-    EXPECT_TRUE(channel2_->srtp_active());
+    EXPECT_TRUE(channel1_->secure());
+    EXPECT_TRUE(channel2_->secure());
     SendCustomRtp2(kSsrc2, 0);
     WaitForThreads();
     EXPECT_TRUE(CheckCustomRtp1(kSsrc2, 0));
@@ -1249,14 +1249,14 @@
   // Test setting up a call.
   void TestCallSetup() {
     CreateChannels(0, 0);
-    EXPECT_FALSE(channel1_->srtp_active());
+    EXPECT_FALSE(channel1_->secure());
     EXPECT_TRUE(SendInitiate());
     if (verify_playout_) {
       EXPECT_TRUE(media_channel1_->playout());
     }
     EXPECT_FALSE(media_channel1_->sending());
     EXPECT_TRUE(SendAccept());
-    EXPECT_FALSE(channel1_->srtp_active());
+    EXPECT_FALSE(channel1_->secure());
     EXPECT_TRUE(media_channel1_->sending());
     EXPECT_EQ(1U, media_channel1_->codecs().size());
     if (verify_playout_) {
@@ -1531,17 +1531,17 @@
     bool dtls1 = !!(flags1_in & DTLS);
     bool dtls2 = !!(flags2_in & DTLS);
     CreateChannels(flags1, flags2);
-    EXPECT_FALSE(channel1_->srtp_active());
-    EXPECT_FALSE(channel2_->srtp_active());
+    EXPECT_FALSE(channel1_->secure());
+    EXPECT_FALSE(channel2_->secure());
     EXPECT_TRUE(SendInitiate());
     WaitForThreads();
     EXPECT_TRUE(channel1_->writable());
     EXPECT_TRUE(channel2_->writable());
     EXPECT_TRUE(SendAccept());
-    EXPECT_TRUE(channel1_->srtp_active());
-    EXPECT_TRUE(channel2_->srtp_active());
-    EXPECT_EQ(dtls1 && dtls2, channel1_->dtls_active());
-    EXPECT_EQ(dtls1 && dtls2, channel2_->dtls_active());
+    EXPECT_TRUE(channel1_->secure());
+    EXPECT_TRUE(channel2_->secure());
+    EXPECT_EQ(dtls1 && dtls2, channel1_->secure_dtls());
+    EXPECT_EQ(dtls1 && dtls2, channel2_->secure_dtls());
     SendRtp1();
     SendRtp2();
     SendRtcp1();
@@ -1560,12 +1560,12 @@
   // Test that we properly handling SRTP negotiating down to RTP.
   void SendSrtpToRtp() {
     CreateChannels(SECURE, 0);
-    EXPECT_FALSE(channel1_->srtp_active());
-    EXPECT_FALSE(channel2_->srtp_active());
+    EXPECT_FALSE(channel1_->secure());
+    EXPECT_FALSE(channel2_->secure());
     EXPECT_TRUE(SendInitiate());
     EXPECT_TRUE(SendAccept());
-    EXPECT_FALSE(channel1_->srtp_active());
-    EXPECT_FALSE(channel2_->srtp_active());
+    EXPECT_FALSE(channel1_->secure());
+    EXPECT_FALSE(channel2_->secure());
     SendRtp1();
     SendRtp2();
     SendRtcp1();
@@ -1590,8 +1590,8 @@
                      SSRC_MUX | RTCP_MUX | SECURE);
       EXPECT_TRUE(SendOffer());
       EXPECT_TRUE(SendProvisionalAnswer());
-      EXPECT_TRUE(channel1_->srtp_active());
-      EXPECT_TRUE(channel2_->srtp_active());
+      EXPECT_TRUE(channel1_->secure());
+      EXPECT_TRUE(channel2_->secure());
       EXPECT_TRUE(channel1_->NeedsRtcpTransport());
       EXPECT_TRUE(channel2_->NeedsRtcpTransport());
       WaitForThreads();  // Wait for 'sending' flag go through network thread.
@@ -1616,8 +1616,8 @@
       EXPECT_FALSE(channel2_->NeedsRtcpTransport());
       EXPECT_EQ(1, rtcp_mux_activated_callbacks1_);
       EXPECT_EQ(1, rtcp_mux_activated_callbacks2_);
-      EXPECT_TRUE(channel1_->srtp_active());
-      EXPECT_TRUE(channel2_->srtp_active());
+      EXPECT_TRUE(channel1_->secure());
+      EXPECT_TRUE(channel2_->secure());
       SendCustomRtcp1(kSsrc1);
       SendCustomRtp1(kSsrc1, ++sequence_number1_1);
       SendCustomRtcp2(kSsrc2);
diff --git a/pc/rtptransport.cc b/pc/rtptransport.cc
index 78a2af5..2917911 100644
--- a/pc/rtptransport.cc
+++ b/pc/rtptransport.cc
@@ -76,18 +76,6 @@
   return transport && transport->writable();
 }
 
-bool RtpTransport::SendRtpPacket(rtc::CopyOnWriteBuffer* packet,
-                                 const rtc::PacketOptions& options,
-                                 int flags) {
-  return SendPacket(false, packet, options, flags);
-}
-
-bool RtpTransport::SendRtcpPacket(rtc::CopyOnWriteBuffer* packet,
-                                  const rtc::PacketOptions& options,
-                                  int flags) {
-  return SendPacket(true, packet, options, flags);
-}
-
 bool RtpTransport::SendPacket(bool rtcp,
                               rtc::CopyOnWriteBuffer* packet,
                               const rtc::PacketOptions& options,
diff --git a/pc/rtptransport.h b/pc/rtptransport.h
index 5e1aa20..373eaa7 100644
--- a/pc/rtptransport.h
+++ b/pc/rtptransport.h
@@ -56,13 +56,10 @@
 
   bool IsWritable(bool rtcp) const override;
 
-  bool SendRtpPacket(rtc::CopyOnWriteBuffer* packet,
-                     const rtc::PacketOptions& options,
-                     int flags) override;
-
-  bool SendRtcpPacket(rtc::CopyOnWriteBuffer* packet,
-                      const rtc::PacketOptions& options,
-                      int flags) override;
+  bool SendPacket(bool rtcp,
+                  rtc::CopyOnWriteBuffer* packet,
+                  const rtc::PacketOptions& options,
+                  int flags) override;
 
   bool HandlesPayloadType(int payload_type) const override;
 
@@ -83,11 +80,6 @@
 
   void MaybeSignalReadyToSend();
 
-  bool SendPacket(bool rtcp,
-                  rtc::CopyOnWriteBuffer* packet,
-                  const rtc::PacketOptions& options,
-                  int flags);
-
   void OnReadPacket(rtc::PacketTransportInternal* transport,
                     const char* data,
                     size_t len,
diff --git a/pc/rtptransportinternal.h b/pc/rtptransportinternal.h
index e589619..cd88b97 100644
--- a/pc/rtptransportinternal.h
+++ b/pc/rtptransportinternal.h
@@ -54,13 +54,10 @@
 
   virtual bool IsWritable(bool rtcp) const = 0;
 
-  virtual bool SendRtpPacket(rtc::CopyOnWriteBuffer* packet,
-                             const rtc::PacketOptions& options,
-                             int flags) = 0;
-
-  virtual bool SendRtcpPacket(rtc::CopyOnWriteBuffer* packet,
-                              const rtc::PacketOptions& options,
-                              int flags) = 0;
+  virtual bool SendPacket(bool rtcp,
+                          rtc::CopyOnWriteBuffer* packet,
+                          const rtc::PacketOptions& options,
+                          int flags) = 0;
 
   virtual bool HandlesPayloadType(int payload_type) const = 0;
 
diff --git a/pc/srtpfilter.cc b/pc/srtpfilter.cc
index fbea08f..c01f29b 100644
--- a/pc/srtpfilter.cc
+++ b/pc/srtpfilter.cc
@@ -17,6 +17,7 @@
 #include "media/base/rtputils.h"
 #include "pc/srtpsession.h"
 #include "rtc_base/base64.h"
+#include "rtc_base/buffer.h"
 #include "rtc_base/byteorder.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/logging.h"
@@ -62,6 +63,210 @@
   return DoSetAnswer(answer_params, source, false);
 }
 
+bool SrtpFilter::SetRtpParams(int send_cs,
+                              const uint8_t* send_key,
+                              int send_key_len,
+                              int recv_cs,
+                              const uint8_t* recv_key,
+                              int recv_key_len) {
+  if (IsActive()) {
+    LOG(LS_ERROR) << "Tried to set SRTP Params when filter already active";
+    return false;
+  }
+  CreateSrtpSessions();
+  send_session_->SetEncryptedHeaderExtensionIds(
+      send_encrypted_header_extension_ids_);
+  if (!send_session_->SetSend(send_cs, send_key, send_key_len)) {
+    return false;
+  }
+
+  recv_session_->SetEncryptedHeaderExtensionIds(
+      recv_encrypted_header_extension_ids_);
+  if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len)) {
+    return false;
+  }
+
+  state_ = ST_ACTIVE;
+
+  LOG(LS_INFO) << "SRTP activated with negotiated parameters:"
+               << " send cipher_suite " << send_cs << " recv cipher_suite "
+               << recv_cs;
+  return true;
+}
+
+bool SrtpFilter::UpdateRtpParams(int send_cs,
+                                 const uint8_t* send_key,
+                                 int send_key_len,
+                                 int recv_cs,
+                                 const uint8_t* recv_key,
+                                 int recv_key_len) {
+  if (!IsActive()) {
+    LOG(LS_ERROR) << "Tried to update SRTP Params when filter is not active";
+    return false;
+  }
+  send_session_->SetEncryptedHeaderExtensionIds(
+      send_encrypted_header_extension_ids_);
+  if (!send_session_->UpdateSend(send_cs, send_key, send_key_len)) {
+    return false;
+  }
+
+  recv_session_->SetEncryptedHeaderExtensionIds(
+      recv_encrypted_header_extension_ids_);
+  if (!recv_session_->UpdateRecv(recv_cs, recv_key, recv_key_len)) {
+    return false;
+  }
+
+  LOG(LS_INFO) << "SRTP updated with negotiated parameters:"
+               << " send cipher_suite " << send_cs << " recv cipher_suite "
+               << recv_cs;
+  return true;
+}
+
+// This function is provided separately because DTLS-SRTP behaves
+// differently in RTP/RTCP mux and non-mux modes.
+//
+// - In the non-muxed case, RTP and RTCP are keyed with different
+//   keys (from different DTLS handshakes), and so we need a new
+//   SrtpSession.
+// - In the muxed case, they are keyed with the same keys, so
+//   this function is not needed
+bool SrtpFilter::SetRtcpParams(int send_cs,
+                               const uint8_t* send_key,
+                               int send_key_len,
+                               int recv_cs,
+                               const uint8_t* recv_key,
+                               int recv_key_len) {
+  // This can only be called once, but can be safely called after
+  // SetRtpParams
+  if (send_rtcp_session_ || recv_rtcp_session_) {
+    LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active";
+    return false;
+  }
+
+  send_rtcp_session_.reset(new SrtpSession());
+  if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len)) {
+    return false;
+  }
+
+  recv_rtcp_session_.reset(new SrtpSession());
+  if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len)) {
+    return false;
+  }
+
+  LOG(LS_INFO) << "SRTCP activated with negotiated parameters:"
+               << " send cipher_suite " << send_cs << " recv cipher_suite "
+               << recv_cs;
+
+  return true;
+}
+
+bool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) {
+  if (!IsActive()) {
+    LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active";
+    return false;
+  }
+  RTC_CHECK(send_session_);
+  return send_session_->ProtectRtp(p, in_len, max_len, out_len);
+}
+
+bool SrtpFilter::ProtectRtp(void* p,
+                            int in_len,
+                            int max_len,
+                            int* out_len,
+                            int64_t* index) {
+  if (!IsActive()) {
+    LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active";
+    return false;
+  }
+  RTC_CHECK(send_session_);
+  return send_session_->ProtectRtp(p, in_len, max_len, out_len, index);
+}
+
+bool SrtpFilter::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) {
+  if (!IsActive()) {
+    LOG(LS_WARNING) << "Failed to ProtectRtcp: SRTP not active";
+    return false;
+  }
+  if (send_rtcp_session_) {
+    return send_rtcp_session_->ProtectRtcp(p, in_len, max_len, out_len);
+  } else {
+    RTC_CHECK(send_session_);
+    return send_session_->ProtectRtcp(p, in_len, max_len, out_len);
+  }
+}
+
+bool SrtpFilter::UnprotectRtp(void* p, int in_len, int* out_len) {
+  if (!IsActive()) {
+    LOG(LS_WARNING) << "Failed to UnprotectRtp: SRTP not active";
+    return false;
+  }
+  RTC_CHECK(recv_session_);
+  return recv_session_->UnprotectRtp(p, in_len, out_len);
+}
+
+bool SrtpFilter::UnprotectRtcp(void* p, int in_len, int* out_len) {
+  if (!IsActive()) {
+    LOG(LS_WARNING) << "Failed to UnprotectRtcp: SRTP not active";
+    return false;
+  }
+  if (recv_rtcp_session_) {
+    return recv_rtcp_session_->UnprotectRtcp(p, in_len, out_len);
+  } else {
+    RTC_CHECK(recv_session_);
+    return recv_session_->UnprotectRtcp(p, in_len, out_len);
+  }
+}
+
+bool SrtpFilter::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) {
+  if (!IsActive()) {
+    LOG(LS_WARNING) << "Failed to GetRtpAuthParams: SRTP not active";
+    return false;
+  }
+
+  RTC_CHECK(send_session_);
+  return send_session_->GetRtpAuthParams(key, key_len, tag_len);
+}
+
+bool SrtpFilter::GetSrtpOverhead(int* srtp_overhead) const {
+  if (!IsActive()) {
+    LOG(LS_WARNING) << "Failed to GetSrtpOverhead: SRTP not active";
+    return false;
+  }
+
+  RTC_CHECK(send_session_);
+  *srtp_overhead = send_session_->GetSrtpOverhead();
+  return true;
+}
+
+void SrtpFilter::EnableExternalAuth() {
+  RTC_DCHECK(!IsActive());
+  external_auth_enabled_ = true;
+}
+
+bool SrtpFilter::IsExternalAuthEnabled() const {
+  return external_auth_enabled_;
+}
+
+bool SrtpFilter::IsExternalAuthActive() const {
+  if (!IsActive()) {
+    LOG(LS_WARNING) << "Failed to check IsExternalAuthActive: SRTP not active";
+    return false;
+  }
+
+  RTC_CHECK(send_session_);
+  return send_session_->IsExternalAuthActive();
+}
+
+void SrtpFilter::SetEncryptedHeaderExtensionIds(
+    ContentSource source,
+    const std::vector<int>& extension_ids) {
+  if (source == CS_LOCAL) {
+    recv_encrypted_header_extension_ids_ = extension_ids;
+  } else {
+    send_encrypted_header_extension_ids_ = extension_ids;
+  }
+}
+
 bool SrtpFilter::ExpectOffer(ContentSource source) {
   return ((state_ == ST_INIT) ||
           (state_ == ST_ACTIVE) ||
@@ -119,16 +324,13 @@
   CryptoParams selected_params;
   if (!NegotiateParams(answer_params, &selected_params))
     return false;
-
-  const CryptoParams& new_send_params =
+  const CryptoParams& send_params =
       (source == CS_REMOTE) ? selected_params : answer_params[0];
-  const CryptoParams& new_recv_params =
+  const CryptoParams& recv_params =
       (source == CS_REMOTE) ? answer_params[0] : selected_params;
-  if (!ApplySendParams(new_send_params) || !ApplyRecvParams(new_recv_params)) {
+  if (!ApplyParams(send_params, recv_params)) {
     return false;
   }
-  applied_send_params_ = new_send_params;
-  applied_recv_params_ = new_recv_params;
 
   if (final) {
     offer_params_.clear();
@@ -140,6 +342,17 @@
   return true;
 }
 
+void SrtpFilter::CreateSrtpSessions() {
+  send_session_.reset(new SrtpSession());
+  applied_send_params_ = CryptoParams();
+  recv_session_.reset(new SrtpSession());
+  applied_recv_params_ = CryptoParams();
+
+  if (external_auth_enabled_) {
+    send_session_->EnableExternalAuth();
+  }
+}
+
 bool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params,
                                  CryptoParams* selected_params) {
   // We're processing an accept. We should have exactly one set of params,
@@ -167,76 +380,85 @@
   return ret;
 }
 
-bool SrtpFilter::ResetParams() {
-  offer_params_.clear();
-  applied_send_params_ = CryptoParams();
-  applied_recv_params_ = CryptoParams();
-  send_cipher_suite_ = rtc::Optional<int>();
-  recv_cipher_suite_ = rtc::Optional<int>();
-  send_key_.Clear();
-  recv_key_.Clear();
-  state_ = ST_INIT;
-  return true;
-}
-
-bool SrtpFilter::ApplySendParams(const CryptoParams& send_params) {
+bool SrtpFilter::ApplyParams(const CryptoParams& send_params,
+                             const CryptoParams& recv_params) {
+  // TODO(jiayl): Split this method to apply send and receive CryptoParams
+  // independently, so that we can skip one method when either send or receive
+  // CryptoParams is unchanged.
   if (applied_send_params_.cipher_suite == send_params.cipher_suite &&
-      applied_send_params_.key_params == send_params.key_params) {
-    LOG(LS_INFO) << "Applying the same SRTP send parameters again. No-op.";
+      applied_send_params_.key_params == send_params.key_params &&
+      applied_recv_params_.cipher_suite == recv_params.cipher_suite &&
+      applied_recv_params_.key_params == recv_params.key_params) {
+    LOG(LS_INFO) << "Applying the same SRTP parameters again. No-op.";
 
     // We do not want to reset the ROC if the keys are the same. So just return.
     return true;
   }
 
-  send_cipher_suite_ = rtc::Optional<int>(
-      rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite));
-  if (send_cipher_suite_ == rtc::SRTP_INVALID_CRYPTO_SUITE) {
+  int send_suite = rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite);
+  int recv_suite = rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite);
+  if (send_suite == rtc::SRTP_INVALID_CRYPTO_SUITE ||
+      recv_suite == rtc::SRTP_INVALID_CRYPTO_SUITE) {
     LOG(LS_WARNING) << "Unknown crypto suite(s) received:"
-                    << " send cipher_suite " << send_params.cipher_suite;
+                    << " send cipher_suite " << send_params.cipher_suite
+                    << " recv cipher_suite " << recv_params.cipher_suite;
     return false;
   }
 
   int send_key_len, send_salt_len;
-  if (!rtc::GetSrtpKeyAndSaltLengths(*send_cipher_suite_, &send_key_len,
-                                     &send_salt_len)) {
-    LOG(LS_WARNING) << "Could not get lengths for crypto suite(s):"
-                    << " send cipher_suite " << send_params.cipher_suite;
-    return false;
-  }
-
-  send_key_ = rtc::Buffer(send_key_len + send_salt_len);
-  return ParseKeyParams(send_params.key_params, send_key_.data(),
-                        send_key_.size());
-}
-
-bool SrtpFilter::ApplyRecvParams(const CryptoParams& recv_params) {
-  if (applied_recv_params_.cipher_suite == recv_params.cipher_suite &&
-      applied_recv_params_.key_params == recv_params.key_params) {
-    LOG(LS_INFO) << "Applying the same SRTP recv parameters again. No-op.";
-
-    // We do not want to reset the ROC if the keys are the same. So just return.
-    return true;
-  }
-
-  recv_cipher_suite_ = rtc::Optional<int>(
-      rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite));
-  if (recv_cipher_suite_ == rtc::SRTP_INVALID_CRYPTO_SUITE) {
-    LOG(LS_WARNING) << "Unknown crypto suite(s) received:"
-                    << " recv cipher_suite " << recv_params.cipher_suite;
-    return false;
-  }
-
   int recv_key_len, recv_salt_len;
-  if (!rtc::GetSrtpKeyAndSaltLengths(*recv_cipher_suite_, &recv_key_len,
+  if (!rtc::GetSrtpKeyAndSaltLengths(send_suite, &send_key_len,
+                                     &send_salt_len) ||
+      !rtc::GetSrtpKeyAndSaltLengths(recv_suite, &recv_key_len,
                                      &recv_salt_len)) {
     LOG(LS_WARNING) << "Could not get lengths for crypto suite(s):"
+                    << " send cipher_suite " << send_params.cipher_suite
                     << " recv cipher_suite " << recv_params.cipher_suite;
     return false;
   }
 
-  recv_key_ = rtc::Buffer(recv_key_len + recv_salt_len);
-  return ParseKeyParams(recv_params.key_params, recv_key_.data(),
-                        recv_key_.size());
+  // TODO(juberti): Zero these buffers after use.
+  bool ret;
+  rtc::Buffer send_key(send_key_len + send_salt_len);
+  rtc::Buffer recv_key(recv_key_len + recv_salt_len);
+  ret = (ParseKeyParams(send_params.key_params, send_key.data(),
+                        send_key.size()) &&
+         ParseKeyParams(recv_params.key_params, recv_key.data(),
+                        recv_key.size()));
+  if (ret) {
+    CreateSrtpSessions();
+    send_session_->SetEncryptedHeaderExtensionIds(
+        send_encrypted_header_extension_ids_);
+    recv_session_->SetEncryptedHeaderExtensionIds(
+        recv_encrypted_header_extension_ids_);
+    ret = (send_session_->SetSend(
+               rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite),
+               send_key.data(), send_key.size()) &&
+           recv_session_->SetRecv(
+               rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite),
+               recv_key.data(), recv_key.size()));
+  }
+  if (ret) {
+    LOG(LS_INFO) << "SRTP activated with negotiated parameters:"
+                 << " send cipher_suite " << send_params.cipher_suite
+                 << " recv cipher_suite " << recv_params.cipher_suite;
+    applied_send_params_ = send_params;
+    applied_recv_params_ = recv_params;
+  } else {
+    LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters";
+  }
+  return ret;
+}
+
+bool SrtpFilter::ResetParams() {
+  offer_params_.clear();
+  state_ = ST_INIT;
+  send_session_ = nullptr;
+  recv_session_ = nullptr;
+  send_rtcp_session_ = nullptr;
+  recv_rtcp_session_ = nullptr;
+  LOG(LS_INFO) << "SRTP reset to init state";
+  return true;
 }
 
 bool SrtpFilter::ParseKeyParams(const std::string& key_params,
diff --git a/pc/srtpfilter.h b/pc/srtpfilter.h
index ffdf637..7b1127e 100644
--- a/pc/srtpfilter.h
+++ b/pc/srtpfilter.h
@@ -17,11 +17,9 @@
 #include <string>
 #include <vector>
 
-#include "api/optional.h"
 #include "media/base/cryptoparams.h"
 #include "p2p/base/sessiondescription.h"
 #include "rtc_base/basictypes.h"
-#include "rtc_base/buffer.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/criticalsection.h"
 #include "rtc_base/sslstreamadapter.h"
@@ -33,10 +31,16 @@
 
 namespace cricket {
 
+class SrtpSession;
+
 void ShutdownSrtp();
 
-// A helper class used to negotiate SDES crypto params.
-// TODO(zhihuang): Find a better name for this class, like "SdesNegotiator".
+// Class to transform SRTP to/from RTP.
+// Initialize by calling SetSend with the local security params, then
+// call
+// SetRecv once the remote security params are received. At that point
+// Protect/UnprotectRt(c)p can be called to encrypt/decrypt data.
+// TODO: Figure out concurrency policy for SrtpFilter.
 class SrtpFilter {
  public:
   enum Mode {
@@ -73,14 +77,66 @@
   bool SetAnswer(const std::vector<CryptoParams>& answer_params,
                  ContentSource source);
 
+  // Set the header extension ids that should be encrypted for the given
+  // source.
+  void SetEncryptedHeaderExtensionIds(ContentSource source,
+                                      const std::vector<int>& extension_ids);
+  // Just set up both sets of keys directly.
+  // Used with DTLS-SRTP.
+  bool SetRtpParams(int send_cs,
+                    const uint8_t* send_key,
+                    int send_key_len,
+                    int recv_cs,
+                    const uint8_t* recv_key,
+                    int recv_key_len);
+  bool UpdateRtpParams(int send_cs,
+                       const uint8_t* send_key,
+                       int send_key_len,
+                       int recv_cs,
+                       const uint8_t* recv_key,
+                       int recv_key_len);
+  bool SetRtcpParams(int send_cs,
+                     const uint8_t* send_key,
+                     int send_key_len,
+                     int recv_cs,
+                     const uint8_t* recv_key,
+                     int recv_key_len);
+  // Encrypts/signs an individual RTP/RTCP packet, in-place.
+  // If an HMAC is used, this will increase the packet size.
+  bool ProtectRtp(void* data, int in_len, int max_len, int* out_len);
+  // Overloaded version, outputs packet index.
+  bool ProtectRtp(void* data,
+                  int in_len,
+                  int max_len,
+                  int* out_len,
+                  int64_t* index);
+  bool ProtectRtcp(void* data, int in_len, int max_len, int* out_len);
+  // Decrypts/verifies an invidiual RTP/RTCP packet.
+  // If an HMAC is used, this will decrease the packet size.
+  bool UnprotectRtp(void* data, int in_len, int* out_len);
+  bool UnprotectRtcp(void* data, int in_len, int* out_len);
+  // Returns rtp auth params from srtp context.
+  bool GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len);
+  // Returns srtp overhead for rtp packets.
+  bool GetSrtpOverhead(int* srtp_overhead) const;
+  // If external auth is enabled, SRTP will write a dummy auth tag that
+  // then
+  // later must get replaced before the packet is sent out. Only
+  // supported for
+  // non-GCM cipher suites and can be checked through
+  // "IsExternalAuthActive"
+  // if it is actually used. This method is only valid before the RTP
+  // params
+  // have been set.
+  void EnableExternalAuth();
+  bool IsExternalAuthEnabled() const;
+  // A SRTP filter supports external creation of the auth tag if a non-GCM
+  // cipher is used. This method is only valid after the RTP params have
+  // been set.
+  bool IsExternalAuthActive() const;
+
   bool ResetParams();
 
-  rtc::Optional<int> send_cipher_suite() { return send_cipher_suite_; }
-  rtc::Optional<int> recv_cipher_suite() { return recv_cipher_suite_; }
-
-  const rtc::Buffer& send_key() { return send_key_; }
-  const rtc::Buffer& recv_key() { return recv_key_; }
-
  protected:
   bool ExpectOffer(ContentSource source);
 
@@ -93,18 +149,17 @@
                    ContentSource source,
                    bool final);
 
+  void CreateSrtpSessions();
   bool NegotiateParams(const std::vector<CryptoParams>& answer_params,
                        CryptoParams* selected_params);
 
- private:
-  bool ApplySendParams(const CryptoParams& send_params);
-
-  bool ApplyRecvParams(const CryptoParams& recv_params);
-
+  bool ApplyParams(const CryptoParams& send_params,
+                   const CryptoParams& recv_params);
   static bool ParseKeyParams(const std::string& params,
                              uint8_t* key,
                              size_t len);
 
+ private:
   enum State {
     ST_INIT,           // SRTP filter unused.
     ST_SENTOFFER,      // Offer with SRTP parameters sent.
@@ -129,13 +184,16 @@
     ST_RECEIVEDPRANSWER
   };
   State state_ = ST_INIT;
+  bool external_auth_enabled_ = false;
   std::vector<CryptoParams> offer_params_;
+  std::unique_ptr<SrtpSession> send_session_;
+  std::unique_ptr<SrtpSession> recv_session_;
+  std::unique_ptr<SrtpSession> send_rtcp_session_;
+  std::unique_ptr<SrtpSession> recv_rtcp_session_;
   CryptoParams applied_send_params_;
   CryptoParams applied_recv_params_;
-  rtc::Optional<int> send_cipher_suite_;
-  rtc::Optional<int> recv_cipher_suite_;
-  rtc::Buffer send_key_;
-  rtc::Buffer recv_key_;
+  std::vector<int> send_encrypted_header_extension_ids_;
+  std::vector<int> recv_encrypted_header_extension_ids_;
 };
 
 }  // namespace cricket
diff --git a/pc/srtpfilter_unittest.cc b/pc/srtpfilter_unittest.cc
index a71762c..75a4e39 100644
--- a/pc/srtpfilter_unittest.cc
+++ b/pc/srtpfilter_unittest.cc
@@ -13,7 +13,14 @@
 #include "pc/srtpfilter.h"
 
 #include "media/base/cryptoparams.h"
+#include "media/base/fakertp.h"
+#include "p2p/base/sessiondescription.h"
+#include "pc/srtptestutil.h"
+#include "rtc_base/buffer.h"
+#include "rtc_base/byteorder.h"
+#include "rtc_base/constructormagic.h"
 #include "rtc_base/gunit.h"
+#include "rtc_base/thread.h"
 
 using cricket::CryptoParams;
 using cricket::CS_LOCAL;
@@ -21,6 +28,14 @@
 
 namespace rtc {
 
+static const uint8_t kTestKeyGcm128_1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ12";
+static const uint8_t kTestKeyGcm128_2[] = "21ZYXWVUTSRQPONMLKJIHGFEDCBA";
+static const int kTestKeyGcm128Len = 28;  // 128 bits key + 96 bits salt.
+static const uint8_t kTestKeyGcm256_1[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr";
+static const uint8_t kTestKeyGcm256_2[] =
+    "rqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA";
+static const int kTestKeyGcm256Len = 44;  // 256 bits key + 96 bits salt.
 static const std::string kTestKeyParams1 =
     "inline:WVNfX19zZW1jdGwgKCkgewkyMjA7fQp9CnVubGVz";
 static const std::string kTestKeyParams2 =
@@ -52,13 +67,14 @@
 
 class SrtpFilterTest : public testing::Test {
  protected:
-  SrtpFilterTest() {}
+  SrtpFilterTest()
+      // Need to initialize |sequence_number_|, the value does not matter.
+      : sequence_number_(1) {}
   static std::vector<CryptoParams> MakeVector(const CryptoParams& params) {
     std::vector<CryptoParams> vec;
     vec.push_back(params);
     return vec;
   }
-
   void TestSetParams(const std::vector<CryptoParams>& params1,
                      const std::vector<CryptoParams>& params2) {
     EXPECT_TRUE(f1_.SetOffer(params1, CS_LOCAL));
@@ -70,16 +86,186 @@
     EXPECT_TRUE(f1_.IsActive());
     EXPECT_TRUE(f2_.IsActive());
   }
+  void TestRtpAuthParams(cricket::SrtpFilter* filter, const std::string& cs) {
+    int overhead;
+    EXPECT_TRUE(filter->GetSrtpOverhead(&overhead));
+    switch (SrtpCryptoSuiteFromName(cs)) {
+      case SRTP_AES128_CM_SHA1_32:
+        EXPECT_EQ(32 / 8, overhead);  // 32-bit tag.
+        break;
+      case SRTP_AES128_CM_SHA1_80:
+        EXPECT_EQ(80 / 8, overhead);  // 80-bit tag.
+        break;
+      default:
+        RTC_NOTREACHED();
+        break;
+    }
 
-  void VerifyCryptoParamsMatch(const std::string& cs1, const std::string& cs2) {
-    EXPECT_EQ(rtc::SrtpCryptoSuiteFromName(cs1), f1_.send_cipher_suite());
-    EXPECT_EQ(rtc::SrtpCryptoSuiteFromName(cs2), f2_.send_cipher_suite());
-    EXPECT_TRUE(f1_.send_key() == f2_.recv_key());
-    EXPECT_TRUE(f2_.send_key() == f1_.recv_key());
+    uint8_t* auth_key = nullptr;
+    int key_len = 0;
+    int tag_len = 0;
+    EXPECT_TRUE(filter->GetRtpAuthParams(&auth_key, &key_len, &tag_len));
+    EXPECT_NE(nullptr, auth_key);
+    EXPECT_EQ(160 / 8, key_len);  // Length of SHA-1 is 160 bits.
+    EXPECT_EQ(overhead, tag_len);
   }
+  void TestProtectUnprotect(const std::string& cs1, const std::string& cs2) {
+    Buffer rtp_buffer(sizeof(kPcmuFrame) + rtp_auth_tag_len(cs1));
+    char* rtp_packet = rtp_buffer.data<char>();
+    char original_rtp_packet[sizeof(kPcmuFrame)];
+    Buffer rtcp_buffer(sizeof(kRtcpReport) + 4 + rtcp_auth_tag_len(cs2));
+    char* rtcp_packet = rtcp_buffer.data<char>();
+    int rtp_len = sizeof(kPcmuFrame), rtcp_len = sizeof(kRtcpReport), out_len;
+    memcpy(rtp_packet, kPcmuFrame, rtp_len);
+    // In order to be able to run this test function multiple times we can not
+    // use the same sequence number twice. Increase the sequence number by one.
+    SetBE16(reinterpret_cast<uint8_t*>(rtp_packet) + 2, ++sequence_number_);
+    memcpy(original_rtp_packet, rtp_packet, rtp_len);
+    memcpy(rtcp_packet, kRtcpReport, rtcp_len);
 
+    EXPECT_TRUE(f1_.ProtectRtp(rtp_packet, rtp_len,
+                               static_cast<int>(rtp_buffer.size()), &out_len));
+    EXPECT_EQ(out_len, rtp_len + rtp_auth_tag_len(cs1));
+    EXPECT_NE(0, memcmp(rtp_packet, original_rtp_packet, rtp_len));
+    if (!f1_.IsExternalAuthActive()) {
+      EXPECT_TRUE(f2_.UnprotectRtp(rtp_packet, out_len, &out_len));
+      EXPECT_EQ(rtp_len, out_len);
+      EXPECT_EQ(0, memcmp(rtp_packet, original_rtp_packet, rtp_len));
+    } else {
+      // With external auth enabled, SRTP doesn't write the auth tag and
+      // unprotect would fail. Check accessing the information about the
+      // tag instead, similar to what the actual code would do that relies
+      // on external auth.
+      TestRtpAuthParams(&f1_, cs1);
+    }
+
+    EXPECT_TRUE(f2_.ProtectRtp(rtp_packet, rtp_len,
+                               static_cast<int>(rtp_buffer.size()), &out_len));
+    EXPECT_EQ(out_len, rtp_len + rtp_auth_tag_len(cs2));
+    EXPECT_NE(0, memcmp(rtp_packet, original_rtp_packet, rtp_len));
+    if (!f2_.IsExternalAuthActive()) {
+      EXPECT_TRUE(f1_.UnprotectRtp(rtp_packet, out_len, &out_len));
+      EXPECT_EQ(rtp_len, out_len);
+      EXPECT_EQ(0, memcmp(rtp_packet, original_rtp_packet, rtp_len));
+    } else {
+      TestRtpAuthParams(&f2_, cs2);
+    }
+
+    EXPECT_TRUE(f1_.ProtectRtcp(
+        rtcp_packet, rtcp_len, static_cast<int>(rtcp_buffer.size()), &out_len));
+    EXPECT_EQ(out_len, rtcp_len + 4 + rtcp_auth_tag_len(cs1));  // NOLINT
+    EXPECT_NE(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len));
+    EXPECT_TRUE(f2_.UnprotectRtcp(rtcp_packet, out_len, &out_len));
+    EXPECT_EQ(rtcp_len, out_len);
+    EXPECT_EQ(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len));
+
+    EXPECT_TRUE(f2_.ProtectRtcp(
+        rtcp_packet, rtcp_len, static_cast<int>(rtcp_buffer.size()), &out_len));
+    EXPECT_EQ(out_len, rtcp_len + 4 + rtcp_auth_tag_len(cs2));  // NOLINT
+    EXPECT_NE(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len));
+    EXPECT_TRUE(f1_.UnprotectRtcp(rtcp_packet, out_len, &out_len));
+    EXPECT_EQ(rtcp_len, out_len);
+    EXPECT_EQ(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len));
+  }
+  void TestProtectUnprotectHeaderEncryption(
+      const std::string& cs1,
+      const std::string& cs2,
+      const std::vector<int>& encrypted_header_ids) {
+    Buffer rtp_buffer(sizeof(kPcmuFrameWithExtensions) + rtp_auth_tag_len(cs1));
+    char* rtp_packet = rtp_buffer.data<char>();
+    size_t rtp_packet_size = rtp_buffer.size();
+    char original_rtp_packet[sizeof(kPcmuFrameWithExtensions)];
+    size_t original_rtp_packet_size = sizeof(original_rtp_packet);
+    int rtp_len = sizeof(kPcmuFrameWithExtensions), out_len;
+    memcpy(rtp_packet, kPcmuFrameWithExtensions, rtp_len);
+    // In order to be able to run this test function multiple times we can not
+    // use the same sequence number twice. Increase the sequence number by one.
+    SetBE16(reinterpret_cast<uint8_t*>(rtp_packet) + 2, ++sequence_number_);
+    memcpy(original_rtp_packet, rtp_packet, rtp_len);
+
+    EXPECT_TRUE(f1_.ProtectRtp(rtp_packet, rtp_len,
+                               static_cast<int>(rtp_buffer.size()), &out_len));
+    EXPECT_EQ(out_len, rtp_len + rtp_auth_tag_len(cs1));
+    EXPECT_NE(0, memcmp(rtp_packet, original_rtp_packet, rtp_len));
+    CompareHeaderExtensions(rtp_packet, rtp_packet_size, original_rtp_packet,
+                            original_rtp_packet_size, encrypted_header_ids,
+                            false);
+    EXPECT_TRUE(f2_.UnprotectRtp(rtp_packet, out_len, &out_len));
+    EXPECT_EQ(rtp_len, out_len);
+    EXPECT_EQ(0, memcmp(rtp_packet, original_rtp_packet, rtp_len));
+    CompareHeaderExtensions(rtp_packet, rtp_packet_size, original_rtp_packet,
+                            original_rtp_packet_size, encrypted_header_ids,
+                            true);
+
+    EXPECT_TRUE(f2_.ProtectRtp(rtp_packet, rtp_len,
+                               static_cast<int>(rtp_buffer.size()), &out_len));
+    EXPECT_EQ(out_len, rtp_len + rtp_auth_tag_len(cs2));
+    EXPECT_NE(0, memcmp(rtp_packet, original_rtp_packet, rtp_len));
+    CompareHeaderExtensions(rtp_packet, rtp_packet_size, original_rtp_packet,
+                            original_rtp_packet_size, encrypted_header_ids,
+                            false);
+    EXPECT_TRUE(f1_.UnprotectRtp(rtp_packet, out_len, &out_len));
+    EXPECT_EQ(rtp_len, out_len);
+    EXPECT_EQ(0, memcmp(rtp_packet, original_rtp_packet, rtp_len));
+    CompareHeaderExtensions(rtp_packet, rtp_packet_size, original_rtp_packet,
+                            original_rtp_packet_size, encrypted_header_ids,
+                            true);
+  }
+  void TestProtectSetParamsDirect(bool enable_external_auth,
+                                  int cs,
+                                  const uint8_t* key1,
+                                  int key1_len,
+                                  const uint8_t* key2,
+                                  int key2_len,
+                                  const std::string& cs_name) {
+    EXPECT_EQ(key1_len, key2_len);
+    EXPECT_EQ(cs_name, SrtpCryptoSuiteToName(cs));
+    if (enable_external_auth) {
+      f1_.EnableExternalAuth();
+      f2_.EnableExternalAuth();
+    }
+    EXPECT_TRUE(f1_.SetRtpParams(cs, key1, key1_len, cs, key2, key2_len));
+    EXPECT_TRUE(f2_.SetRtpParams(cs, key2, key2_len, cs, key1, key1_len));
+    EXPECT_TRUE(f1_.SetRtcpParams(cs, key1, key1_len, cs, key2, key2_len));
+    EXPECT_TRUE(f2_.SetRtcpParams(cs, key2, key2_len, cs, key1, key1_len));
+    EXPECT_TRUE(f1_.IsActive());
+    EXPECT_TRUE(f2_.IsActive());
+    if (IsGcmCryptoSuite(cs)) {
+      EXPECT_FALSE(f1_.IsExternalAuthActive());
+      EXPECT_FALSE(f2_.IsExternalAuthActive());
+    } else if (enable_external_auth) {
+      EXPECT_TRUE(f1_.IsExternalAuthActive());
+      EXPECT_TRUE(f2_.IsExternalAuthActive());
+    }
+    TestProtectUnprotect(cs_name, cs_name);
+  }
+  void TestProtectSetParamsDirectHeaderEncryption(int cs,
+                                                  const uint8_t* key1,
+                                                  int key1_len,
+                                                  const uint8_t* key2,
+                                                  int key2_len,
+                                                  const std::string& cs_name) {
+    std::vector<int> encrypted_headers;
+    encrypted_headers.push_back(1);
+    // Don't encrypt header ids 2 and 3.
+    encrypted_headers.push_back(4);
+    EXPECT_EQ(key1_len, key2_len);
+    EXPECT_EQ(cs_name, SrtpCryptoSuiteToName(cs));
+    f1_.SetEncryptedHeaderExtensionIds(CS_LOCAL, encrypted_headers);
+    f1_.SetEncryptedHeaderExtensionIds(CS_REMOTE, encrypted_headers);
+    f2_.SetEncryptedHeaderExtensionIds(CS_LOCAL, encrypted_headers);
+    f2_.SetEncryptedHeaderExtensionIds(CS_REMOTE, encrypted_headers);
+    EXPECT_TRUE(f1_.SetRtpParams(cs, key1, key1_len, cs, key2, key2_len));
+    EXPECT_TRUE(f2_.SetRtpParams(cs, key2, key2_len, cs, key1, key1_len));
+    EXPECT_TRUE(f1_.IsActive());
+    EXPECT_TRUE(f2_.IsActive());
+    EXPECT_FALSE(f1_.IsExternalAuthActive());
+    EXPECT_FALSE(f2_.IsExternalAuthActive());
+    TestProtectUnprotectHeaderEncryption(cs_name, cs_name, encrypted_headers);
+  }
   cricket::SrtpFilter f1_;
   cricket::SrtpFilter f2_;
+  int sequence_number_;
 };
 
 // Test that we can set up the session and keys properly.
@@ -293,6 +479,21 @@
   EXPECT_FALSE(f1_.IsActive());
 }
 
+// Test that we can encrypt/decrypt after setting the same CryptoParams again on
+// one side.
+TEST_F(SrtpFilterTest, TestSettingSameKeyOnOneSide) {
+  std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
+  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
+  TestSetParams(offer, answer);
+
+  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_80, CS_AES_CM_128_HMAC_SHA1_80);
+
+  // Re-applying the same keys on one end and it should not reset the ROC.
+  EXPECT_TRUE(f2_.SetOffer(offer, CS_REMOTE));
+  EXPECT_TRUE(f2_.SetAnswer(answer, CS_LOCAL));
+  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_80, CS_AES_CM_128_HMAC_SHA1_80);
+}
+
 // Test that we can encrypt/decrypt after negotiating AES_CM_128_HMAC_SHA1_80.
 TEST_F(SrtpFilterTest, TestProtect_AES_CM_128_HMAC_SHA1_80) {
   std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
@@ -301,8 +502,7 @@
   offer[1].tag = 2;
   offer[1].cipher_suite = CS_AES_CM_128_HMAC_SHA1_32;
   TestSetParams(offer, answer);
-  VerifyCryptoParamsMatch(CS_AES_CM_128_HMAC_SHA1_80,
-                          CS_AES_CM_128_HMAC_SHA1_80);
+  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_80, CS_AES_CM_128_HMAC_SHA1_80);
 }
 
 // Test that we can encrypt/decrypt after negotiating AES_CM_128_HMAC_SHA1_32.
@@ -315,8 +515,7 @@
   answer[0].tag = 2;
   answer[0].cipher_suite = CS_AES_CM_128_HMAC_SHA1_32;
   TestSetParams(offer, answer);
-  VerifyCryptoParamsMatch(CS_AES_CM_128_HMAC_SHA1_32,
-                          CS_AES_CM_128_HMAC_SHA1_32);
+  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_32, CS_AES_CM_128_HMAC_SHA1_32);
 }
 
 // Test that we can change encryption parameters.
@@ -325,8 +524,7 @@
   std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
 
   TestSetParams(offer, answer);
-  VerifyCryptoParamsMatch(CS_AES_CM_128_HMAC_SHA1_80,
-                          CS_AES_CM_128_HMAC_SHA1_80);
+  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_80, CS_AES_CM_128_HMAC_SHA1_80);
 
   // Change the key parameters and cipher_suite.
   offer[0].key_params = kTestKeyParams3;
@@ -340,15 +538,13 @@
   EXPECT_TRUE(f1_.IsActive());
 
   // Test that the old keys are valid until the negotiation is complete.
-  VerifyCryptoParamsMatch(CS_AES_CM_128_HMAC_SHA1_80,
-                          CS_AES_CM_128_HMAC_SHA1_80);
+  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_80, CS_AES_CM_128_HMAC_SHA1_80);
 
   // Complete the negotiation and test that we can still understand each other.
   EXPECT_TRUE(f2_.SetAnswer(answer, CS_LOCAL));
   EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE));
 
-  VerifyCryptoParamsMatch(CS_AES_CM_128_HMAC_SHA1_32,
-                          CS_AES_CM_128_HMAC_SHA1_32);
+  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_32, CS_AES_CM_128_HMAC_SHA1_32);
 }
 
 // Test that we can send and receive provisional answers with crypto enabled.
@@ -368,8 +564,7 @@
   EXPECT_TRUE(f1_.SetProvisionalAnswer(answer, CS_REMOTE));
   EXPECT_TRUE(f1_.IsActive());
   EXPECT_TRUE(f2_.IsActive());
-  VerifyCryptoParamsMatch(CS_AES_CM_128_HMAC_SHA1_80,
-                          CS_AES_CM_128_HMAC_SHA1_80);
+  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_80, CS_AES_CM_128_HMAC_SHA1_80);
 
   answer[0].key_params = kTestKeyParams4;
   answer[0].tag = 2;
@@ -378,8 +573,7 @@
   EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE));
   EXPECT_TRUE(f1_.IsActive());
   EXPECT_TRUE(f2_.IsActive());
-  VerifyCryptoParamsMatch(CS_AES_CM_128_HMAC_SHA1_32,
-                          CS_AES_CM_128_HMAC_SHA1_32);
+  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_32, CS_AES_CM_128_HMAC_SHA1_32);
 }
 
 // Test that a provisional answer doesn't need to contain a crypto.
@@ -401,8 +595,7 @@
   EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE));
   EXPECT_TRUE(f1_.IsActive());
   EXPECT_TRUE(f2_.IsActive());
-  VerifyCryptoParamsMatch(CS_AES_CM_128_HMAC_SHA1_80,
-                          CS_AES_CM_128_HMAC_SHA1_80);
+  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_80, CS_AES_CM_128_HMAC_SHA1_80);
 }
 
 // Test that if we get a new local offer after a provisional answer
@@ -429,8 +622,7 @@
   EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE));
   EXPECT_TRUE(f1_.IsActive());
   EXPECT_TRUE(f2_.IsActive());
-  VerifyCryptoParamsMatch(CS_AES_CM_128_HMAC_SHA1_80,
-                          CS_AES_CM_128_HMAC_SHA1_80);
+  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_80, CS_AES_CM_128_HMAC_SHA1_80);
 }
 
 // Test that we can disable encryption.
@@ -439,8 +631,7 @@
   std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
 
   TestSetParams(offer, answer);
-  VerifyCryptoParamsMatch(CS_AES_CM_128_HMAC_SHA1_80,
-                          CS_AES_CM_128_HMAC_SHA1_80);
+  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_80, CS_AES_CM_128_HMAC_SHA1_80);
 
   offer.clear();
   answer.clear();
@@ -450,8 +641,7 @@
   EXPECT_TRUE(f2_.IsActive());
 
   // Test that the old keys are valid until the negotiation is complete.
-  VerifyCryptoParamsMatch(CS_AES_CM_128_HMAC_SHA1_80,
-                          CS_AES_CM_128_HMAC_SHA1_80);
+  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_80, CS_AES_CM_128_HMAC_SHA1_80);
 
   // Complete the negotiation.
   EXPECT_TRUE(f2_.SetAnswer(answer, CS_LOCAL));
@@ -461,4 +651,85 @@
   EXPECT_FALSE(f2_.IsActive());
 }
 
+class SrtpFilterProtectSetParamsDirectTest
+    : public SrtpFilterTest,
+      public testing::WithParamInterface<bool> {};
+
+// Test directly setting the params with AES_CM_128_HMAC_SHA1_80.
+TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_AES_CM_128_HMAC_SHA1_80) {
+  bool enable_external_auth = GetParam();
+  TestProtectSetParamsDirect(enable_external_auth, SRTP_AES128_CM_SHA1_80,
+                             kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen,
+                             CS_AES_CM_128_HMAC_SHA1_80);
+}
+
+TEST_F(SrtpFilterTest,
+       TestProtectSetParamsDirectHeaderEncryption_AES_CM_128_HMAC_SHA1_80) {
+  TestProtectSetParamsDirectHeaderEncryption(
+      SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen,
+      CS_AES_CM_128_HMAC_SHA1_80);
+}
+
+// Test directly setting the params with AES_CM_128_HMAC_SHA1_32.
+TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_AES_CM_128_HMAC_SHA1_32) {
+  bool enable_external_auth = GetParam();
+  TestProtectSetParamsDirect(enable_external_auth, SRTP_AES128_CM_SHA1_32,
+                             kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen,
+                             CS_AES_CM_128_HMAC_SHA1_32);
+}
+
+TEST_F(SrtpFilterTest,
+       TestProtectSetParamsDirectHeaderEncryption_AES_CM_128_HMAC_SHA1_32) {
+  TestProtectSetParamsDirectHeaderEncryption(
+      SRTP_AES128_CM_SHA1_32, kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen,
+      CS_AES_CM_128_HMAC_SHA1_32);
+}
+
+// Test directly setting the params with SRTP_AEAD_AES_128_GCM.
+TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_128_GCM) {
+  bool enable_external_auth = GetParam();
+  TestProtectSetParamsDirect(enable_external_auth, SRTP_AEAD_AES_128_GCM,
+                             kTestKeyGcm128_1, kTestKeyGcm128Len,
+                             kTestKeyGcm128_2, kTestKeyGcm128Len,
+                             CS_AEAD_AES_128_GCM);
+}
+
+TEST_F(SrtpFilterTest,
+       TestProtectSetParamsDirectHeaderEncryption_SRTP_AEAD_AES_128_GCM) {
+  TestProtectSetParamsDirectHeaderEncryption(
+      SRTP_AEAD_AES_128_GCM, kTestKeyGcm128_1, kTestKeyGcm128Len,
+      kTestKeyGcm128_2, kTestKeyGcm128Len, CS_AEAD_AES_128_GCM);
+}
+
+// Test directly setting the params with SRTP_AEAD_AES_256_GCM.
+TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_256_GCM) {
+  bool enable_external_auth = GetParam();
+  TestProtectSetParamsDirect(enable_external_auth, SRTP_AEAD_AES_256_GCM,
+                             kTestKeyGcm256_1, kTestKeyGcm256Len,
+                             kTestKeyGcm256_2, kTestKeyGcm256Len,
+                             CS_AEAD_AES_256_GCM);
+}
+
+TEST_F(SrtpFilterTest,
+       TestProtectSetParamsDirectHeaderEncryption_SRTP_AEAD_AES_256_GCM) {
+  TestProtectSetParamsDirectHeaderEncryption(
+      SRTP_AEAD_AES_256_GCM, kTestKeyGcm256_1, kTestKeyGcm256Len,
+      kTestKeyGcm256_2, kTestKeyGcm256Len, CS_AEAD_AES_256_GCM);
+}
+
+// Run all tests both with and without external auth enabled.
+INSTANTIATE_TEST_CASE_P(ExternalAuth,
+                        SrtpFilterProtectSetParamsDirectTest,
+                        ::testing::Values(true, false));
+
+// Test directly setting the params with bogus keys.
+TEST_F(SrtpFilterTest, TestSetParamsKeyTooShort) {
+  EXPECT_FALSE(f1_.SetRtpParams(SRTP_AES128_CM_SHA1_80, kTestKey1,
+                                kTestKeyLen - 1, SRTP_AES128_CM_SHA1_80,
+                                kTestKey1, kTestKeyLen - 1));
+  EXPECT_FALSE(f1_.SetRtcpParams(SRTP_AES128_CM_SHA1_80, kTestKey1,
+                                 kTestKeyLen - 1, SRTP_AES128_CM_SHA1_80,
+                                 kTestKey1, kTestKeyLen - 1));
+}
+
 }  // namespace rtc
diff --git a/pc/srtptransport.cc b/pc/srtptransport.cc
index f3b5309..3dd3ce7 100644
--- a/pc/srtptransport.cc
+++ b/pc/srtptransport.cc
@@ -16,7 +16,6 @@
 #include "pc/rtptransport.h"
 #include "pc/srtpsession.h"
 #include "rtc_base/asyncpacketsocket.h"
-#include "rtc_base/base64.h"
 #include "rtc_base/copyonwritebuffer.h"
 #include "rtc_base/ptr_util.h"
 #include "rtc_base/trace_event.h"
@@ -43,322 +42,21 @@
                                             &SrtpTransport::OnReadyToSend);
 }
 
-bool SrtpTransport::SendRtpPacket(rtc::CopyOnWriteBuffer* packet,
-                                  const rtc::PacketOptions& options,
-                                  int flags) {
-  return SendPacket(false, packet, options, flags);
-}
-
-bool SrtpTransport::SendRtcpPacket(rtc::CopyOnWriteBuffer* packet,
-                                   const rtc::PacketOptions& options,
-                                   int flags) {
-  return SendPacket(true, packet, options, flags);
-}
-
 bool SrtpTransport::SendPacket(bool rtcp,
                                rtc::CopyOnWriteBuffer* packet,
                                const rtc::PacketOptions& options,
                                int flags) {
-  if (!IsActive()) {
-    LOG(LS_ERROR)
-        << "Failed to send the packet because SRTP transport is inactive.";
-    return false;
-  }
+  // TODO(zstein): Protect packet.
 
-  rtc::PacketOptions updated_options = options;
-  rtc::CopyOnWriteBuffer cp = *packet;
-  TRACE_EVENT0("webrtc", "SRTP Encode");
-  bool res;
-  uint8_t* data = packet->data();
-  int len = static_cast<int>(packet->size());
-  if (!rtcp) {
-// If ENABLE_EXTERNAL_AUTH flag is on then packet authentication is not done
-// inside libsrtp for a RTP packet. A external HMAC module will be writing
-// a fake HMAC value. This is ONLY done for a RTP packet.
-// Socket layer will update rtp sendtime extension header if present in
-// packet with current time before updating the HMAC.
-#if !defined(ENABLE_EXTERNAL_AUTH)
-    res = ProtectRtp(data, len, static_cast<int>(packet->capacity()), &len);
-#else
-    if (!IsExternalAuthActive()) {
-      res = ProtectRtp(data, len, static_cast<int>(packet->capacity()), &len);
-    } else {
-      updated_options.packet_time_params.rtp_sendtime_extension_id =
-          rtp_abs_sendtime_extn_id_;
-      res = ProtectRtp(data, len, static_cast<int>(packet->capacity()), &len,
-                       &updated_options.packet_time_params.srtp_packet_index);
-      // If protection succeeds, let's get auth params from srtp.
-      if (res) {
-        uint8_t* auth_key = NULL;
-        int key_len;
-        res = GetRtpAuthParams(
-            &auth_key, &key_len,
-            &updated_options.packet_time_params.srtp_auth_tag_len);
-        if (res) {
-          updated_options.packet_time_params.srtp_auth_key.resize(key_len);
-          updated_options.packet_time_params.srtp_auth_key.assign(
-              auth_key, auth_key + key_len);
-        }
-      }
-    }
-#endif
-    if (!res) {
-      int seq_num = -1;
-      uint32_t ssrc = 0;
-      cricket::GetRtpSeqNum(data, len, &seq_num);
-      cricket::GetRtpSsrc(data, len, &ssrc);
-      LOG(LS_ERROR) << "Failed to protect " << content_name_
-                    << " RTP packet: size=" << len << ", seqnum=" << seq_num
-                    << ", SSRC=" << ssrc;
-      return false;
-    }
-  } else {
-    res = ProtectRtcp(data, len, static_cast<int>(packet->capacity()), &len);
-    if (!res) {
-      int type = -1;
-      cricket::GetRtcpType(data, len, &type);
-      LOG(LS_ERROR) << "Failed to protect " << content_name_
-                    << " RTCP packet: size=" << len << ", type=" << type;
-      return false;
-    }
-  }
-
-  // Update the length of the packet now that we've added the auth tag.
-  packet->SetSize(len);
-  return rtcp ? rtp_transport_->SendRtcpPacket(packet, updated_options, flags)
-              : rtp_transport_->SendRtpPacket(packet, updated_options, flags);
+  return rtp_transport_->SendPacket(rtcp, packet, options, flags);
 }
 
 void SrtpTransport::OnPacketReceived(bool rtcp,
                                      rtc::CopyOnWriteBuffer* packet,
                                      const rtc::PacketTime& packet_time) {
-  if (!IsActive()) {
-    LOG(LS_WARNING) << "Inactive SRTP transport received a packet. Drop it.";
-    return;
-  }
+  // TODO(zstein): Unprotect packet.
 
-  TRACE_EVENT0("webrtc", "SRTP Decode");
-  char* data = packet->data<char>();
-  int len = static_cast<int>(packet->size());
-  bool res;
-  if (!rtcp) {
-    res = UnprotectRtp(data, len, &len);
-    if (!res) {
-      int seq_num = -1;
-      uint32_t ssrc = 0;
-      cricket::GetRtpSeqNum(data, len, &seq_num);
-      cricket::GetRtpSsrc(data, len, &ssrc);
-      LOG(LS_ERROR) << "Failed to unprotect " << content_name_
-                    << " RTP packet: size=" << len << ", seqnum=" << seq_num
-                    << ", SSRC=" << ssrc;
-      return;
-    }
-  } else {
-    res = UnprotectRtcp(data, len, &len);
-    if (!res) {
-      int type = -1;
-      cricket::GetRtcpType(data, len, &type);
-      LOG(LS_ERROR) << "Failed to unprotect " << content_name_
-                    << " RTCP packet: size=" << len << ", type=" << type;
-      return;
-    }
-  }
-
-  packet->SetSize(len);
   SignalPacketReceived(rtcp, packet, packet_time);
 }
 
-bool SrtpTransport::SetRtpParams(int send_cs,
-                                 const uint8_t* send_key,
-                                 int send_key_len,
-                                 int recv_cs,
-                                 const uint8_t* recv_key,
-                                 int recv_key_len) {
-  CreateSrtpSessions();
-  send_session_->SetEncryptedHeaderExtensionIds(
-      send_encrypted_header_extension_ids_);
-  if (external_auth_enabled_) {
-    send_session_->EnableExternalAuth();
-  }
-  if (!send_session_->SetSend(send_cs, send_key, send_key_len)) {
-    ResetParams();
-    return false;
-  }
-
-  recv_session_->SetEncryptedHeaderExtensionIds(
-      recv_encrypted_header_extension_ids_);
-  if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len)) {
-    ResetParams();
-    return false;
-  }
-
-  LOG(LS_INFO) << "SRTP activated with negotiated parameters:"
-               << " send cipher_suite " << send_cs << " recv cipher_suite "
-               << recv_cs;
-  return true;
-}
-
-bool SrtpTransport::SetRtcpParams(int send_cs,
-                                  const uint8_t* send_key,
-                                  int send_key_len,
-                                  int recv_cs,
-                                  const uint8_t* recv_key,
-                                  int recv_key_len) {
-  // This can only be called once, but can be safely called after
-  // SetRtpParams
-  if (send_rtcp_session_ || recv_rtcp_session_) {
-    LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active";
-    return false;
-  }
-
-  send_rtcp_session_.reset(new cricket::SrtpSession());
-  if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len)) {
-    return false;
-  }
-
-  recv_rtcp_session_.reset(new cricket::SrtpSession());
-  if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len)) {
-    return false;
-  }
-
-  LOG(LS_INFO) << "SRTCP activated with negotiated parameters:"
-               << " send cipher_suite " << send_cs << " recv cipher_suite "
-               << recv_cs;
-
-  return true;
-}
-
-bool SrtpTransport::IsActive() const {
-  return send_session_ && recv_session_;
-}
-
-void SrtpTransport::ResetParams() {
-  send_session_ = nullptr;
-  recv_session_ = nullptr;
-  send_rtcp_session_ = nullptr;
-  recv_rtcp_session_ = nullptr;
-  LOG(LS_INFO) << "The params in SRTP transport are reset.";
-}
-
-void SrtpTransport::SetEncryptedHeaderExtensionIds(
-    cricket::ContentSource source,
-    const std::vector<int>& extension_ids) {
-  if (source == cricket::CS_LOCAL) {
-    recv_encrypted_header_extension_ids_ = extension_ids;
-  } else {
-    send_encrypted_header_extension_ids_ = extension_ids;
-  }
-}
-
-void SrtpTransport::CreateSrtpSessions() {
-  send_session_.reset(new cricket::SrtpSession());
-  recv_session_.reset(new cricket::SrtpSession());
-
-  if (external_auth_enabled_) {
-    send_session_->EnableExternalAuth();
-  }
-}
-
-bool SrtpTransport::ProtectRtp(void* p, int in_len, int max_len, int* out_len) {
-  if (!IsActive()) {
-    LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active";
-    return false;
-  }
-  RTC_CHECK(send_session_);
-  return send_session_->ProtectRtp(p, in_len, max_len, out_len);
-}
-
-bool SrtpTransport::ProtectRtp(void* p,
-                               int in_len,
-                               int max_len,
-                               int* out_len,
-                               int64_t* index) {
-  if (!IsActive()) {
-    LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active";
-    return false;
-  }
-  RTC_CHECK(send_session_);
-  return send_session_->ProtectRtp(p, in_len, max_len, out_len, index);
-}
-
-bool SrtpTransport::ProtectRtcp(void* p,
-                                int in_len,
-                                int max_len,
-                                int* out_len) {
-  if (!IsActive()) {
-    LOG(LS_WARNING) << "Failed to ProtectRtcp: SRTP not active";
-    return false;
-  }
-  if (send_rtcp_session_) {
-    return send_rtcp_session_->ProtectRtcp(p, in_len, max_len, out_len);
-  } else {
-    RTC_CHECK(send_session_);
-    return send_session_->ProtectRtcp(p, in_len, max_len, out_len);
-  }
-}
-
-bool SrtpTransport::UnprotectRtp(void* p, int in_len, int* out_len) {
-  if (!IsActive()) {
-    LOG(LS_WARNING) << "Failed to UnprotectRtp: SRTP not active";
-    return false;
-  }
-  RTC_CHECK(recv_session_);
-  return recv_session_->UnprotectRtp(p, in_len, out_len);
-}
-
-bool SrtpTransport::UnprotectRtcp(void* p, int in_len, int* out_len) {
-  if (!IsActive()) {
-    LOG(LS_WARNING) << "Failed to UnprotectRtcp: SRTP not active";
-    return false;
-  }
-  if (recv_rtcp_session_) {
-    return recv_rtcp_session_->UnprotectRtcp(p, in_len, out_len);
-  } else {
-    RTC_CHECK(recv_session_);
-    return recv_session_->UnprotectRtcp(p, in_len, out_len);
-  }
-}
-
-bool SrtpTransport::GetRtpAuthParams(uint8_t** key,
-                                     int* key_len,
-                                     int* tag_len) {
-  if (!IsActive()) {
-    LOG(LS_WARNING) << "Failed to GetRtpAuthParams: SRTP not active";
-    return false;
-  }
-
-  RTC_CHECK(send_session_);
-  return send_session_->GetRtpAuthParams(key, key_len, tag_len);
-}
-
-bool SrtpTransport::GetSrtpOverhead(int* srtp_overhead) const {
-  if (!IsActive()) {
-    LOG(LS_WARNING) << "Failed to GetSrtpOverhead: SRTP not active";
-    return false;
-  }
-
-  RTC_CHECK(send_session_);
-  *srtp_overhead = send_session_->GetSrtpOverhead();
-  return true;
-}
-
-void SrtpTransport::EnableExternalAuth() {
-  RTC_DCHECK(!IsActive());
-  external_auth_enabled_ = true;
-}
-
-bool SrtpTransport::IsExternalAuthEnabled() const {
-  return external_auth_enabled_;
-}
-
-bool SrtpTransport::IsExternalAuthActive() const {
-  if (!IsActive()) {
-    LOG(LS_WARNING) << "Failed to check IsExternalAuthActive: SRTP not active";
-    return false;
-  }
-
-  RTC_CHECK(send_session_);
-  return send_session_->IsExternalAuthActive();
-}
-
 }  // namespace webrtc
diff --git a/pc/srtptransport.h b/pc/srtptransport.h
index 9f20e1d..4d2ecb8 100644
--- a/pc/srtptransport.h
+++ b/pc/srtptransport.h
@@ -17,17 +17,20 @@
 
 #include "pc/rtptransportinternal.h"
 #include "pc/srtpfilter.h"
-#include "pc/srtpsession.h"
 #include "rtc_base/checks.h"
 
 namespace webrtc {
 
 // This class will eventually be a wrapper around RtpTransportInternal
-// that protects and unprotects sent and received RTP packets.
+// that protects and unprotects sent and received RTP packets. This
+// functionality is currently implemented by SrtpFilter and BaseChannel, but
+// will be moved here in the future.
 class SrtpTransport : public RtpTransportInternal {
  public:
   SrtpTransport(bool rtcp_mux_enabled, const std::string& content_name);
 
+  // TODO(zstein): Consider taking an RtpTransport instead of an
+  // RtpTransportInternal.
   SrtpTransport(std::unique_ptr<RtpTransportInternal> transport,
                 const std::string& content_name);
 
@@ -58,21 +61,14 @@
     return rtp_transport_->GetRtcpPacketTransport();
   }
 
-  bool SendRtpPacket(rtc::CopyOnWriteBuffer* packet,
-                     const rtc::PacketOptions& options,
-                     int flags) override;
-
-  bool SendRtcpPacket(rtc::CopyOnWriteBuffer* packet,
-                      const rtc::PacketOptions& options,
-                      int flags) override;
-
   bool IsWritable(bool rtcp) const override {
     return rtp_transport_->IsWritable(rtcp);
   }
 
-  // The transport becomes active if the send_session_ and recv_session_ are
-  // created.
-  bool IsActive() const;
+  bool SendPacket(bool rtcp,
+                  rtc::CopyOnWriteBuffer* packet,
+                  const rtc::PacketOptions& options,
+                  int flags) override;
 
   bool HandlesPayloadType(int payload_type) const override {
     return rtp_transport_->HandlesPayloadType(payload_type);
@@ -93,104 +89,18 @@
   // TODO(zstein): Remove this when we remove RtpTransportAdapter.
   RtpTransportAdapter* GetInternal() override { return nullptr; }
 
-  // Create new send/recv sessions and set the negotiated crypto keys for RTP
-  // packet encryption. The keys can either come from SDES negotiation or DTLS
-  // handshake.
-  bool SetRtpParams(int send_cs,
-                    const uint8_t* send_key,
-                    int send_key_len,
-                    int recv_cs,
-                    const uint8_t* recv_key,
-                    int recv_key_len);
-
-  // Create new send/recv sessions and set the negotiated crypto keys for RTCP
-  // packet encryption. The keys can either come from SDES negotiation or DTLS
-  // handshake.
-  bool SetRtcpParams(int send_cs,
-                     const uint8_t* send_key,
-                     int send_key_len,
-                     int recv_cs,
-                     const uint8_t* recv_key,
-                     int recv_key_len);
-
-  void ResetParams();
-
-  // Set the header extension ids that should be encrypted for the given source.
-  // This method doesn't immediately update the SRTP session with the new IDs,
-  // and you need to call SetRtpParams for that to happen.
-  void SetEncryptedHeaderExtensionIds(cricket::ContentSource source,
-                                      const std::vector<int>& extension_ids);
-
-  // If external auth is enabled, SRTP will write a dummy auth tag that then
-  // later must get replaced before the packet is sent out. Only supported for
-  // non-GCM cipher suites and can be checked through "IsExternalAuthActive"
-  // if it is actually used. This method is only valid before the RTP params
-  // have been set.
-  void EnableExternalAuth();
-  bool IsExternalAuthEnabled() const;
-
-  // A SrtpTransport supports external creation of the auth tag if a non-GCM
-  // cipher is used. This method is only valid after the RTP params have
-  // been set.
-  bool IsExternalAuthActive() const;
-
-  // Returns srtp overhead for rtp packets.
-  bool GetSrtpOverhead(int* srtp_overhead) const;
-
-  // Returns rtp auth params from srtp context.
-  bool GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len);
-
-  // Helper method to get RTP Absoulute SendTime extension header id if
-  // present in remote supported extensions list.
-  void CacheRtpAbsSendTimeHeaderExtension(int rtp_abs_sendtime_extn_id) {
-    rtp_abs_sendtime_extn_id_ = rtp_abs_sendtime_extn_id;
-  }
-
  private:
-  void CreateSrtpSessions();
-
   void ConnectToRtpTransport();
 
-  bool SendPacket(bool rtcp,
-                  rtc::CopyOnWriteBuffer* packet,
-                  const rtc::PacketOptions& options,
-                  int flags);
-
   void OnPacketReceived(bool rtcp,
                         rtc::CopyOnWriteBuffer* packet,
                         const rtc::PacketTime& packet_time);
 
   void OnReadyToSend(bool ready) { SignalReadyToSend(ready); }
 
-  bool ProtectRtp(void* data, int in_len, int max_len, int* out_len);
-
-  // Overloaded version, outputs packet index.
-  bool ProtectRtp(void* data,
-                  int in_len,
-                  int max_len,
-                  int* out_len,
-                  int64_t* index);
-  bool ProtectRtcp(void* data, int in_len, int max_len, int* out_len);
-
-  // Decrypts/verifies an invidiual RTP/RTCP packet.
-  // If an HMAC is used, this will decrease the packet size.
-  bool UnprotectRtp(void* data, int in_len, int* out_len);
-
-  bool UnprotectRtcp(void* data, int in_len, int* out_len);
-
   const std::string content_name_;
+
   std::unique_ptr<RtpTransportInternal> rtp_transport_;
-
-  std::unique_ptr<cricket::SrtpSession> send_session_;
-  std::unique_ptr<cricket::SrtpSession> recv_session_;
-  std::unique_ptr<cricket::SrtpSession> send_rtcp_session_;
-  std::unique_ptr<cricket::SrtpSession> recv_rtcp_session_;
-
-  std::vector<int> send_encrypted_header_extension_ids_;
-  std::vector<int> recv_encrypted_header_extension_ids_;
-  bool external_auth_enabled_ = false;
-
-  int rtp_abs_sendtime_extn_id_ = -1;
 };
 
 }  // namespace webrtc
diff --git a/pc/srtptransport_unittest.cc b/pc/srtptransport_unittest.cc
index d3bc259..6cc4ee7 100644
--- a/pc/srtptransport_unittest.cc
+++ b/pc/srtptransport_unittest.cc
@@ -10,413 +10,67 @@
 
 #include "pc/srtptransport.h"
 
-#include "media/base/fakertp.h"
-#include "p2p/base/dtlstransportinternal.h"
-#include "p2p/base/fakepackettransport.h"
 #include "pc/rtptransport.h"
 #include "pc/rtptransporttestutil.h"
-#include "pc/srtptestutil.h"
 #include "rtc_base/asyncpacketsocket.h"
 #include "rtc_base/gunit.h"
 #include "rtc_base/ptr_util.h"
-#include "rtc_base/sslstreamadapter.h"
-
-using rtc::kTestKey1;
-using rtc::kTestKey2;
-using rtc::kTestKeyLen;
-using rtc::SRTP_AEAD_AES_128_GCM;
+#include "test/gmock.h"
 
 namespace webrtc {
-static const uint8_t kTestKeyGcm128_1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ12";
-static const uint8_t kTestKeyGcm128_2[] = "21ZYXWVUTSRQPONMLKJIHGFEDCBA";
-static const int kTestKeyGcm128Len = 28;  // 128 bits key + 96 bits salt.
-static const uint8_t kTestKeyGcm256_1[] =
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr";
-static const uint8_t kTestKeyGcm256_2[] =
-    "rqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA";
-static const int kTestKeyGcm256Len = 44;  // 256 bits key + 96 bits salt.
 
-class SrtpTransportTest : public testing::Test, public sigslot::has_slots<> {
- protected:
-  SrtpTransportTest() {
-    bool rtcp_mux_enabled = true;
-    auto rtp_transport1 = rtc::MakeUnique<RtpTransport>(rtcp_mux_enabled);
-    auto rtp_transport2 = rtc::MakeUnique<RtpTransport>(rtcp_mux_enabled);
+using testing::_;
+using testing::Return;
 
-    rtp_packet_transport1_ =
-        rtc::MakeUnique<rtc::FakePacketTransport>("fake_packet_transport1");
-    rtp_packet_transport2_ =
-        rtc::MakeUnique<rtc::FakePacketTransport>("fake_packet_transport2");
+class MockRtpTransport : public RtpTransport {
+ public:
+  MockRtpTransport() : RtpTransport(true) {}
 
-    bool asymmetric = false;
-    rtp_packet_transport1_->SetDestination(rtp_packet_transport2_.get(),
-                                           asymmetric);
+  MOCK_METHOD4(SendPacket,
+               bool(bool rtcp,
+                    rtc::CopyOnWriteBuffer* packet,
+                    const rtc::PacketOptions& options,
+                    int flags));
 
-    rtp_transport1->SetRtpPacketTransport(rtp_packet_transport1_.get());
-    rtp_transport2->SetRtpPacketTransport(rtp_packet_transport2_.get());
-
-    // Add payload type for RTP packet and RTCP packet.
-    rtp_transport1->AddHandledPayloadType(0x00);
-    rtp_transport2->AddHandledPayloadType(0x00);
-    rtp_transport1->AddHandledPayloadType(0xc9);
-    rtp_transport2->AddHandledPayloadType(0xc9);
-
-    srtp_transport1_ =
-        rtc::MakeUnique<SrtpTransport>(std::move(rtp_transport1), "content");
-    srtp_transport2_ =
-        rtc::MakeUnique<SrtpTransport>(std::move(rtp_transport2), "content");
-
-    srtp_transport1_->SignalPacketReceived.connect(
-        this, &SrtpTransportTest::OnPacketReceived1);
-    srtp_transport2_->SignalPacketReceived.connect(
-        this, &SrtpTransportTest::OnPacketReceived2);
+  void PretendReceivedPacket() {
+    bool rtcp = false;
+    rtc::CopyOnWriteBuffer buffer;
+    rtc::PacketTime time;
+    SignalPacketReceived(rtcp, &buffer, time);
   }
-
-  void OnPacketReceived1(bool rtcp,
-                         rtc::CopyOnWriteBuffer* packet,
-                         const rtc::PacketTime& packet_time) {
-    LOG(LS_INFO) << "SrtpTransport1 Received a packet.";
-    last_recv_packet1_ = *packet;
-  }
-
-  void OnPacketReceived2(bool rtcp,
-                         rtc::CopyOnWriteBuffer* packet,
-                         const rtc::PacketTime& packet_time) {
-    LOG(LS_INFO) << "SrtpTransport2 Received a packet.";
-    last_recv_packet2_ = *packet;
-  }
-
-  // With external auth enabled, SRTP doesn't write the auth tag and
-  // unprotect would fail. Check accessing the information about the
-  // tag instead, similar to what the actual code would do that relies
-  // on external auth.
-  void TestRtpAuthParams(SrtpTransport* transport, const std::string& cs) {
-    int overhead;
-    EXPECT_TRUE(transport->GetSrtpOverhead(&overhead));
-    switch (rtc::SrtpCryptoSuiteFromName(cs)) {
-      case rtc::SRTP_AES128_CM_SHA1_32:
-        EXPECT_EQ(32 / 8, overhead);  // 32-bit tag.
-        break;
-      case rtc::SRTP_AES128_CM_SHA1_80:
-        EXPECT_EQ(80 / 8, overhead);  // 80-bit tag.
-        break;
-      default:
-        RTC_NOTREACHED();
-        break;
-    }
-
-    uint8_t* auth_key = nullptr;
-    int key_len = 0;
-    int tag_len = 0;
-    EXPECT_TRUE(transport->GetRtpAuthParams(&auth_key, &key_len, &tag_len));
-    EXPECT_NE(nullptr, auth_key);
-    EXPECT_EQ(160 / 8, key_len);  // Length of SHA-1 is 160 bits.
-    EXPECT_EQ(overhead, tag_len);
-  }
-
-  void TestSendRecvRtpPacket(const std::string& cipher_suite_name) {
-    size_t rtp_len = sizeof(kPcmuFrame);
-    size_t packet_size = rtp_len + rtc::rtp_auth_tag_len(cipher_suite_name);
-    rtc::Buffer rtp_packet_buffer(packet_size);
-    char* rtp_packet_data = rtp_packet_buffer.data<char>();
-    memcpy(rtp_packet_data, kPcmuFrame, rtp_len);
-    // In order to be able to run this test function multiple times we can not
-    // use the same sequence number twice. Increase the sequence number by one.
-    rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_data) + 2,
-                 ++sequence_number_);
-    rtc::CopyOnWriteBuffer rtp_packet1to2(rtp_packet_data, rtp_len,
-                                          packet_size);
-    rtc::CopyOnWriteBuffer rtp_packet2to1(rtp_packet_data, rtp_len,
-                                          packet_size);
-
-    char original_rtp_data[sizeof(kPcmuFrame)];
-    memcpy(original_rtp_data, rtp_packet_data, rtp_len);
-
-    rtc::PacketOptions options;
-    // Send a packet from |srtp_transport1_| to |srtp_transport2_| and verify
-    // that the packet can be successfully received and decrypted.
-    ASSERT_TRUE(srtp_transport1_->SendRtpPacket(&rtp_packet1to2, options,
-                                                cricket::PF_SRTP_BYPASS));
-    if (srtp_transport1_->IsExternalAuthActive()) {
-      TestRtpAuthParams(srtp_transport1_.get(), cipher_suite_name);
-    } else {
-      ASSERT_TRUE(last_recv_packet2_.data());
-      EXPECT_TRUE(
-          memcmp(last_recv_packet2_.data(), original_rtp_data, rtp_len) == 0);
-      // Get the encrypted packet from underneath packet transport and verify
-      // the data is actually encrypted.
-      auto fake_rtp_packet_transport = static_cast<rtc::FakePacketTransport*>(
-          srtp_transport1_->rtp_packet_transport());
-      EXPECT_FALSE(memcmp(fake_rtp_packet_transport->last_sent_packet()->data(),
-                          original_rtp_data, rtp_len) == 0);
-    }
-
-    // Do the same thing in the opposite direction;
-    ASSERT_TRUE(srtp_transport2_->SendRtpPacket(&rtp_packet2to1, options,
-                                                cricket::PF_SRTP_BYPASS));
-    if (srtp_transport2_->IsExternalAuthActive()) {
-      TestRtpAuthParams(srtp_transport2_.get(), cipher_suite_name);
-    } else {
-      ASSERT_TRUE(last_recv_packet1_.data());
-      EXPECT_TRUE(
-          memcmp(last_recv_packet1_.data(), original_rtp_data, rtp_len) == 0);
-      auto fake_rtp_packet_transport = static_cast<rtc::FakePacketTransport*>(
-          srtp_transport2_->rtp_packet_transport());
-      EXPECT_FALSE(memcmp(fake_rtp_packet_transport->last_sent_packet()->data(),
-                          original_rtp_data, rtp_len) == 0);
-    }
-  }
-
-  void TestSendRecvRtcpPacket(const std::string& cipher_suite_name) {
-    size_t rtcp_len = sizeof(kRtcpReport);
-    size_t packet_size =
-        rtcp_len + 4 + rtc::rtcp_auth_tag_len(cipher_suite_name);
-    rtc::Buffer rtcp_packet_buffer(packet_size);
-    char* rtcp_packet_data = rtcp_packet_buffer.data<char>();
-    memcpy(rtcp_packet_data, kRtcpReport, rtcp_len);
-
-    rtc::CopyOnWriteBuffer rtcp_packet1to2(rtcp_packet_data, rtcp_len,
-                                           packet_size);
-    rtc::CopyOnWriteBuffer rtcp_packet2to1(rtcp_packet_data, rtcp_len,
-                                           packet_size);
-
-    rtc::PacketOptions options;
-    // Send a packet from |srtp_transport1_| to |srtp_transport2_| and verify
-    // that the packet can be successfully received and decrypted.
-    ASSERT_TRUE(srtp_transport1_->SendRtcpPacket(&rtcp_packet1to2, options,
-                                                 cricket::PF_SRTP_BYPASS));
-    ASSERT_TRUE(last_recv_packet2_.data());
-    EXPECT_TRUE(memcmp(last_recv_packet2_.data(), rtcp_packet_data, rtcp_len) ==
-                0);
-    // Get the encrypted packet from underneath packet transport and verify the
-    // data is actually encrypted.
-    auto fake_rtp_packet_transport = static_cast<rtc::FakePacketTransport*>(
-        srtp_transport1_->rtp_packet_transport());
-    EXPECT_FALSE(memcmp(fake_rtp_packet_transport->last_sent_packet()->data(),
-                        rtcp_packet_data, rtcp_len) == 0);
-
-    // Do the same thing in the opposite direction;
-    ASSERT_TRUE(srtp_transport2_->SendRtcpPacket(&rtcp_packet2to1, options,
-                                                 cricket::PF_SRTP_BYPASS));
-    ASSERT_TRUE(last_recv_packet1_.data());
-    EXPECT_TRUE(memcmp(last_recv_packet1_.data(), rtcp_packet_data, rtcp_len) ==
-                0);
-    fake_rtp_packet_transport = static_cast<rtc::FakePacketTransport*>(
-        srtp_transport2_->rtp_packet_transport());
-    EXPECT_FALSE(memcmp(fake_rtp_packet_transport->last_sent_packet()->data(),
-                        rtcp_packet_data, rtcp_len) == 0);
-  }
-
-  void TestSendRecvPacket(bool enable_external_auth,
-                          int cs,
-                          const uint8_t* key1,
-                          int key1_len,
-                          const uint8_t* key2,
-                          int key2_len,
-                          const std::string& cipher_suite_name) {
-    EXPECT_EQ(key1_len, key2_len);
-    EXPECT_EQ(cipher_suite_name, rtc::SrtpCryptoSuiteToName(cs));
-    if (enable_external_auth) {
-      srtp_transport1_->EnableExternalAuth();
-      srtp_transport2_->EnableExternalAuth();
-    }
-    EXPECT_TRUE(
-        srtp_transport1_->SetRtpParams(cs, key1, key1_len, cs, key2, key2_len));
-    EXPECT_TRUE(
-        srtp_transport2_->SetRtpParams(cs, key2, key2_len, cs, key1, key1_len));
-    EXPECT_TRUE(srtp_transport1_->SetRtcpParams(cs, key1, key1_len, cs, key2,
-                                                key2_len));
-    EXPECT_TRUE(srtp_transport2_->SetRtcpParams(cs, key2, key2_len, cs, key1,
-                                                key1_len));
-    EXPECT_TRUE(srtp_transport1_->IsActive());
-    EXPECT_TRUE(srtp_transport2_->IsActive());
-    if (rtc::IsGcmCryptoSuite(cs)) {
-      EXPECT_FALSE(srtp_transport1_->IsExternalAuthActive());
-      EXPECT_FALSE(srtp_transport2_->IsExternalAuthActive());
-    } else if (enable_external_auth) {
-      EXPECT_TRUE(srtp_transport1_->IsExternalAuthActive());
-      EXPECT_TRUE(srtp_transport2_->IsExternalAuthActive());
-    }
-    TestSendRecvRtpPacket(cipher_suite_name);
-    TestSendRecvRtcpPacket(cipher_suite_name);
-  }
-
-  void TestSendRecvPacketWithEncryptedHeaderExtension(
-      const std::string& cs,
-      const std::vector<int>& encrypted_header_ids) {
-    size_t rtp_len = sizeof(kPcmuFrameWithExtensions);
-    size_t packet_size = rtp_len + rtc::rtp_auth_tag_len(cs);
-    rtc::Buffer rtp_packet_buffer(packet_size);
-    char* rtp_packet_data = rtp_packet_buffer.data<char>();
-    memcpy(rtp_packet_data, kPcmuFrameWithExtensions, rtp_len);
-    // In order to be able to run this test function multiple times we can not
-    // use the same sequence number twice. Increase the sequence number by one.
-    rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_data) + 2,
-                 ++sequence_number_);
-    rtc::CopyOnWriteBuffer rtp_packet1to2(rtp_packet_data, rtp_len,
-                                          packet_size);
-    rtc::CopyOnWriteBuffer rtp_packet2to1(rtp_packet_data, rtp_len,
-                                          packet_size);
-
-    char original_rtp_data[sizeof(kPcmuFrameWithExtensions)];
-    memcpy(original_rtp_data, rtp_packet_data, rtp_len);
-
-    rtc::PacketOptions options;
-    // Send a packet from |srtp_transport1_| to |srtp_transport2_| and verify
-    // that the packet can be successfully received and decrypted.
-    ASSERT_TRUE(srtp_transport1_->SendRtpPacket(&rtp_packet1to2, options,
-                                                cricket::PF_SRTP_BYPASS));
-    ASSERT_TRUE(last_recv_packet2_.data());
-    EXPECT_TRUE(memcmp(last_recv_packet2_.data(), original_rtp_data, rtp_len) ==
-                0);
-    // Get the encrypted packet from underneath packet transport and verify the
-    // data and header extension are actually encrypted.
-    auto fake_rtp_packet_transport = static_cast<rtc::FakePacketTransport*>(
-        srtp_transport1_->rtp_packet_transport());
-    EXPECT_FALSE(memcmp(fake_rtp_packet_transport->last_sent_packet()->data(),
-                        original_rtp_data, rtp_len) == 0);
-    CompareHeaderExtensions(
-        reinterpret_cast<const char*>(
-            fake_rtp_packet_transport->last_sent_packet()->data()),
-        fake_rtp_packet_transport->last_sent_packet()->size(),
-        original_rtp_data, rtp_len, encrypted_header_ids, false);
-
-    // Do the same thing in the opposite direction;
-    ASSERT_TRUE(srtp_transport2_->SendRtpPacket(&rtp_packet2to1, options,
-                                                cricket::PF_SRTP_BYPASS));
-    ASSERT_TRUE(last_recv_packet1_.data());
-    EXPECT_TRUE(memcmp(last_recv_packet1_.data(), original_rtp_data, rtp_len) ==
-                0);
-    fake_rtp_packet_transport = static_cast<rtc::FakePacketTransport*>(
-        srtp_transport2_->rtp_packet_transport());
-    EXPECT_FALSE(memcmp(fake_rtp_packet_transport->last_sent_packet()->data(),
-                        original_rtp_data, rtp_len) == 0);
-    CompareHeaderExtensions(
-        reinterpret_cast<const char*>(
-            fake_rtp_packet_transport->last_sent_packet()->data()),
-        fake_rtp_packet_transport->last_sent_packet()->size(),
-        original_rtp_data, rtp_len, encrypted_header_ids, false);
-  }
-
-  void TestSendRecvEncryptedHeaderExtension(int cs,
-                                            const uint8_t* key1,
-                                            int key1_len,
-                                            const uint8_t* key2,
-                                            int key2_len,
-                                            const std::string& cs_name) {
-    std::vector<int> encrypted_headers;
-    encrypted_headers.push_back(1);
-    // Don't encrypt header ids 2 and 3.
-    encrypted_headers.push_back(4);
-    EXPECT_EQ(key1_len, key2_len);
-    EXPECT_EQ(cs_name, rtc::SrtpCryptoSuiteToName(cs));
-    srtp_transport1_->SetEncryptedHeaderExtensionIds(cricket::CS_LOCAL,
-                                                     encrypted_headers);
-    srtp_transport1_->SetEncryptedHeaderExtensionIds(cricket::CS_REMOTE,
-                                                     encrypted_headers);
-    srtp_transport2_->SetEncryptedHeaderExtensionIds(cricket::CS_LOCAL,
-                                                     encrypted_headers);
-    srtp_transport2_->SetEncryptedHeaderExtensionIds(cricket::CS_REMOTE,
-                                                     encrypted_headers);
-    EXPECT_TRUE(
-        srtp_transport1_->SetRtpParams(cs, key1, key1_len, cs, key2, key2_len));
-    EXPECT_TRUE(
-        srtp_transport2_->SetRtpParams(cs, key2, key2_len, cs, key1, key1_len));
-    EXPECT_TRUE(srtp_transport1_->IsActive());
-    EXPECT_TRUE(srtp_transport2_->IsActive());
-    EXPECT_FALSE(srtp_transport1_->IsExternalAuthActive());
-    EXPECT_FALSE(srtp_transport2_->IsExternalAuthActive());
-    TestSendRecvPacketWithEncryptedHeaderExtension(cs_name, encrypted_headers);
-  }
-
-  std::unique_ptr<SrtpTransport> srtp_transport1_;
-  std::unique_ptr<SrtpTransport> srtp_transport2_;
-
-  std::unique_ptr<rtc::FakePacketTransport> rtp_packet_transport1_;
-  std::unique_ptr<rtc::FakePacketTransport> rtp_packet_transport2_;
-
-  rtc::CopyOnWriteBuffer last_recv_packet1_;
-  rtc::CopyOnWriteBuffer last_recv_packet2_;
-  int sequence_number_ = 0;
 };
 
-class SrtpTransportTestWithExternalAuth
-    : public SrtpTransportTest,
-      public testing::WithParamInterface<bool> {};
+TEST(SrtpTransportTest, SendPacket) {
+  auto rtp_transport = rtc::MakeUnique<MockRtpTransport>();
+  EXPECT_CALL(*rtp_transport, SendPacket(_, _, _, _)).WillOnce(Return(true));
 
-TEST_P(SrtpTransportTestWithExternalAuth,
-       SendAndRecvPacket_AES_CM_128_HMAC_SHA1_80) {
-  bool enable_external_auth = GetParam();
-  TestSendRecvPacket(enable_external_auth, rtc::SRTP_AES128_CM_SHA1_80,
-                     kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen,
-                     rtc::CS_AES_CM_128_HMAC_SHA1_80);
+  SrtpTransport srtp_transport(std::move(rtp_transport), "a");
+
+  const bool rtcp = false;
+  rtc::CopyOnWriteBuffer packet;
+  rtc::PacketOptions options;
+  int flags = 0;
+  EXPECT_TRUE(srtp_transport.SendPacket(rtcp, &packet, options, flags));
+
+  // TODO(zstein): Also verify that the packet received by RtpTransport has been
+  // protected once SrtpTransport handles that.
 }
 
-TEST_F(SrtpTransportTest,
-       SendAndRecvPacketWithHeaderExtension_AES_CM_128_HMAC_SHA1_80) {
-  TestSendRecvEncryptedHeaderExtension(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1,
-                                       kTestKeyLen, kTestKey2, kTestKeyLen,
-                                       rtc::CS_AES_CM_128_HMAC_SHA1_80);
-}
+// Test that SrtpTransport fires SignalPacketReceived when the underlying
+// RtpTransport fires SignalPacketReceived.
+TEST(SrtpTransportTest, SignalPacketReceived) {
+  auto rtp_transport = rtc::MakeUnique<MockRtpTransport>();
+  MockRtpTransport* rtp_transport_raw = rtp_transport.get();
+  SrtpTransport srtp_transport(std::move(rtp_transport), "a");
 
-TEST_P(SrtpTransportTestWithExternalAuth,
-       SendAndRecvPacket_AES_CM_128_HMAC_SHA1_32) {
-  bool enable_external_auth = GetParam();
-  TestSendRecvPacket(enable_external_auth, rtc::SRTP_AES128_CM_SHA1_32,
-                     kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen,
-                     rtc::CS_AES_CM_128_HMAC_SHA1_32);
-}
+  SignalPacketReceivedCounter counter(&srtp_transport);
 
-TEST_F(SrtpTransportTest,
-       SendAndRecvPacketWithHeaderExtension_AES_CM_128_HMAC_SHA1_32) {
-  TestSendRecvEncryptedHeaderExtension(rtc::SRTP_AES128_CM_SHA1_32, kTestKey1,
-                                       kTestKeyLen, kTestKey2, kTestKeyLen,
-                                       rtc::CS_AES_CM_128_HMAC_SHA1_32);
-}
+  rtp_transport_raw->PretendReceivedPacket();
 
-TEST_P(SrtpTransportTestWithExternalAuth,
-       SendAndRecvPacket_SRTP_AEAD_AES_128_GCM) {
-  bool enable_external_auth = GetParam();
-  TestSendRecvPacket(enable_external_auth, rtc::SRTP_AEAD_AES_128_GCM,
-                     kTestKeyGcm128_1, kTestKeyGcm128Len, kTestKeyGcm128_2,
-                     kTestKeyGcm128Len, rtc::CS_AEAD_AES_128_GCM);
-}
+  EXPECT_EQ(1, counter.rtp_count());
 
-TEST_F(SrtpTransportTest,
-       SendAndRecvPacketWithHeaderExtension_SRTP_AEAD_AES_128_GCM) {
-  TestSendRecvEncryptedHeaderExtension(
-      rtc::SRTP_AEAD_AES_128_GCM, kTestKeyGcm128_1, kTestKeyGcm128Len,
-      kTestKeyGcm128_2, kTestKeyGcm128Len, rtc::CS_AEAD_AES_128_GCM);
-}
-
-TEST_P(SrtpTransportTestWithExternalAuth,
-       SendAndRecvPacket_SRTP_AEAD_AES_256_GCM) {
-  bool enable_external_auth = GetParam();
-  TestSendRecvPacket(enable_external_auth, rtc::SRTP_AEAD_AES_256_GCM,
-                     kTestKeyGcm256_1, kTestKeyGcm256Len, kTestKeyGcm256_2,
-                     kTestKeyGcm256Len, rtc::CS_AEAD_AES_256_GCM);
-}
-
-TEST_F(SrtpTransportTest,
-       SendAndRecvPacketWithHeaderExtension_SRTP_AEAD_AES_256_GCM) {
-  TestSendRecvEncryptedHeaderExtension(
-      rtc::SRTP_AEAD_AES_256_GCM, kTestKeyGcm256_1, kTestKeyGcm256Len,
-      kTestKeyGcm256_2, kTestKeyGcm256Len, rtc::CS_AEAD_AES_256_GCM);
-}
-
-// Run all tests both with and without external auth enabled.
-INSTANTIATE_TEST_CASE_P(ExternalAuth,
-                        SrtpTransportTestWithExternalAuth,
-                        ::testing::Values(true, false));
-
-// Test directly setting the params with bogus keys.
-TEST_F(SrtpTransportTest, TestSetParamsKeyTooShort) {
-  EXPECT_FALSE(srtp_transport1_->SetRtpParams(
-      rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen - 1,
-      rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen - 1));
-  EXPECT_FALSE(srtp_transport1_->SetRtcpParams(
-      rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen - 1,
-      rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, kTestKeyLen - 1));
+  // TODO(zstein): Also verify that the packet is unprotected once SrtpTransport
+  // handles that.
 }
 
 }  // namespace webrtc