Improve testing of SRTP external auth code paths.

Previously code behind ENABLE_EXTERNAL_AUTH was only compiled with Chromium
but developed in WebRTC, which made testing rather complicated. This caused
some trouble in the past (e.g. https://crbug.com/628400#c1)

This CL helps in that the external auth code is now compiled with WebRTC
and the srtpfilter integration gets tested.

BUG=chromium:628400

Review-Url: https://codereview.webrtc.org/2722423003
Cr-Commit-Position: refs/heads/master@{#17030}
diff --git a/webrtc/pc/BUILD.gn b/webrtc/pc/BUILD.gn
index eed2ee9..f84622b 100644
--- a/webrtc/pc/BUILD.gn
+++ b/webrtc/pc/BUILD.gn
@@ -38,6 +38,8 @@
     "channelmanager.h",
     "currentspeakermonitor.cc",
     "currentspeakermonitor.h",
+    "externalhmac.cc",
+    "externalhmac.h",
     "mediamonitor.cc",
     "mediamonitor.h",
     "mediasession.cc",
@@ -55,12 +57,6 @@
     "../media",
   ]
 
-  if (rtc_enable_external_auth) {
-    sources += [
-      "externalhmac.cc",
-      "externalhmac.h",
-    ]
-  }
   if (rtc_build_libsrtp) {
     deps += [ "//third_party/libsrtp" ]
   }
diff --git a/webrtc/pc/channel.cc b/webrtc/pc/channel.cc
index 68fdabb..8a17f8f 100644
--- a/webrtc/pc/channel.cc
+++ b/webrtc/pc/channel.cc
@@ -172,6 +172,9 @@
       media_channel_(media_channel),
       selected_candidate_pair_(nullptr) {
   RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
+#if defined(ENABLE_EXTERNAL_AUTH)
+  srtp_filter_->EnableExternalAuth();
+#endif
   LOG(LS_INFO) << "Created channel for " << content_name;
 }
 
diff --git a/webrtc/pc/externalhmac.cc b/webrtc/pc/externalhmac.cc
index ec71833..2d3ff5f 100644
--- a/webrtc/pc/externalhmac.cc
+++ b/webrtc/pc/externalhmac.cc
@@ -19,7 +19,7 @@
 #include "third_party/libsrtp/include/srtp.h"
 #endif // HAVE_SRTP
 
-#if defined(HAVE_SRTP) && defined(ENABLE_EXTERNAL_AUTH)
+#if defined(HAVE_SRTP)
 
 // Begin test case 0 */
 static const uint8_t kExternalHmacTestCase0Key[20] = {
@@ -151,4 +151,4 @@
   return srtp_err_status_ok;
 }
 
-#endif  // defined(HAVE_SRTP) && defined(ENABLE_EXTERNAL_AUTH)
+#endif  // defined(HAVE_SRTP)
diff --git a/webrtc/pc/externalhmac.h b/webrtc/pc/externalhmac.h
index 2666d90..c0f2ce1 100644
--- a/webrtc/pc/externalhmac.h
+++ b/webrtc/pc/externalhmac.h
@@ -34,7 +34,7 @@
 #include "third_party/libsrtp/crypto/include/auth.h"
 #endif  // HAVE_SRTP
 
-#if defined(HAVE_SRTP) && defined(ENABLE_EXTERNAL_AUTH)
+#if defined(HAVE_SRTP)
 
 #define EXTERNAL_HMAC_SHA1 SRTP_HMAC_SHA1 + 1
 #define HMAC_KEY_LENGTH 20
@@ -71,5 +71,5 @@
 
 srtp_err_status_t external_crypto_init();
 
-#endif  // defined(HAVE_SRTP) && defined(ENABLE_EXTERNAL_AUTH)
+#endif  // defined(HAVE_SRTP)
 #endif  // WEBRTC_PC_EXTERNALHMAC_H_
diff --git a/webrtc/pc/srtpfilter.cc b/webrtc/pc/srtpfilter.cc
index 5094987..82ab4e1 100644
--- a/webrtc/pc/srtpfilter.cc
+++ b/webrtc/pc/srtpfilter.cc
@@ -51,9 +51,7 @@
 #endif
 }
 
-SrtpFilter::SrtpFilter()
-    : state_(ST_INIT),
-      signal_silent_time_in_ms_(0) {
+SrtpFilter::SrtpFilter() {
 }
 
 SrtpFilter::~SrtpFilter() {
@@ -226,7 +224,15 @@
   return true;
 }
 
-#if defined(ENABLE_EXTERNAL_AUTH)
+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";
@@ -236,7 +242,6 @@
   RTC_CHECK(send_session_);
   return send_session_->IsExternalAuthActive();
 }
-#endif
 
 void SrtpFilter::set_signal_silent_time(int signal_silent_time_in_ms) {
   signal_silent_time_in_ms_ = signal_silent_time_in_ms;
@@ -338,6 +343,9 @@
 
   send_session_->set_signal_silent_time(signal_silent_time_in_ms_);
   recv_session_->set_signal_silent_time(signal_silent_time_in_ms_);
+  if (external_auth_enabled_) {
+    send_session_->EnableExternalAuth();
+  }
 }
 
 bool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params,
@@ -599,7 +607,6 @@
 }
 
 bool SrtpSession::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) {
-#if defined(ENABLE_EXTERNAL_AUTH)
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
   RTC_DCHECK(IsExternalAuthActive());
   if (!IsExternalAuthActive()) {
@@ -624,20 +631,24 @@
   *key_len = external_hmac->key_length;
   *tag_len = rtp_auth_tag_len_;
   return true;
-#else
-  return false;
-#endif
 }
 
 int SrtpSession::GetSrtpOverhead() const {
   return rtp_auth_tag_len_;
 }
 
-#if defined(ENABLE_EXTERNAL_AUTH)
+void SrtpSession::EnableExternalAuth() {
+  RTC_DCHECK(!session_);
+  external_auth_enabled_ = true;
+}
+
+bool SrtpSession::IsExternalAuthEnabled() const {
+  return external_auth_enabled_;
+}
+
 bool SrtpSession::IsExternalAuthActive() const {
   return external_auth_active_;
 }
-#endif
 
 bool SrtpSession::GetSendStreamPacketIndex(void* p,
                                            int in_len,
@@ -719,13 +730,12 @@
   // id EXTERNAL_HMAC_SHA1 in the policy structure.
   // We want to set this option only for rtp packets.
   // By default policy structure is initialized to HMAC_SHA1.
-#if defined(ENABLE_EXTERNAL_AUTH)
   // Enable external HMAC authentication only for outgoing streams and only
   // for cipher suites that support it (i.e. only non-GCM cipher suites).
-  if (type == ssrc_any_outbound && !rtc::IsGcmCryptoSuite(cs)) {
+  if (type == ssrc_any_outbound && IsExternalAuthEnabled() &&
+      !rtc::IsGcmCryptoSuite(cs)) {
     policy.rtp.auth_type = EXTERNAL_HMAC_SHA1;
   }
-#endif
   policy.next = nullptr;
 
   int err = srtp_create(&session_, &policy);
@@ -738,9 +748,7 @@
   srtp_set_user_data(session_, this);
   rtp_auth_tag_len_ = policy.rtp.auth_tag_len;
   rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len;
-#if defined(ENABLE_EXTERNAL_AUTH)
   external_auth_active_ = (policy.rtp.auth_type == EXTERNAL_HMAC_SHA1);
-#endif
   return true;
 }
 
@@ -760,13 +768,12 @@
       LOG(LS_ERROR) << "Failed to install SRTP event handler, err=" << err;
       return false;
     }
-#if defined(ENABLE_EXTERNAL_AUTH)
+
     err = external_crypto_init();
     if (err != srtp_err_status_ok) {
       LOG(LS_ERROR) << "Failed to initialize fake auth, err=" << err;
       return false;
     }
-#endif
     inited_ = true;
   }
 
diff --git a/webrtc/pc/srtpfilter.h b/webrtc/pc/srtpfilter.h
index 46b9dea..3df7876 100644
--- a/webrtc/pc/srtpfilter.h
+++ b/webrtc/pc/srtpfilter.h
@@ -114,12 +114,18 @@
   // Returns srtp overhead for rtp packets.
   bool GetSrtpOverhead(int* srtp_overhead) const;
 
-#if defined(ENABLE_EXTERNAL_AUTH)
+  // 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;
-#endif
 
   // Update the silent threshold (in ms) for signaling errors.
   void set_signal_silent_time(int signal_silent_time_in_ms);
@@ -169,8 +175,9 @@
     // ST_INIT.
     ST_RECEIVEDPRANSWER
   };
-  State state_;
-  int signal_silent_time_in_ms_;
+  State state_ = ST_INIT;
+  int signal_silent_time_in_ms_ = 0;
+  bool external_auth_enabled_ = false;
   std::vector<CryptoParams> offer_params_;
   std::unique_ptr<SrtpSession> send_session_;
   std::unique_ptr<SrtpSession> recv_session_;
@@ -213,12 +220,18 @@
 
   int GetSrtpOverhead() const;
 
-#if defined(ENABLE_EXTERNAL_AUTH)
+  // 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 session 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;
-#endif
 
   // Update the silent threshold (in ms) for signaling errors.
   void set_signal_silent_time(int signal_silent_time_in_ms);
@@ -246,9 +259,8 @@
   static bool inited_;
   static rtc::GlobalLockPod lock_;
   int last_send_seq_num_ = -1;
-#if defined(ENABLE_EXTERNAL_AUTH)
   bool external_auth_active_ = false;
-#endif
+  bool external_auth_enabled_ = false;
   RTC_DISALLOW_COPY_AND_ASSIGN(SrtpSession);
 };
 
diff --git a/webrtc/pc/srtpfilter_unittest.cc b/webrtc/pc/srtpfilter_unittest.cc
index 9486dd6..af8b69f 100644
--- a/webrtc/pc/srtpfilter_unittest.cc
+++ b/webrtc/pc/srtpfilter_unittest.cc
@@ -107,6 +107,29 @@
     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 (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(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) {
     rtc::Buffer rtp_buffer(sizeof(kPcmuFrame) + rtp_auth_tag_len(cs1));
     char* rtp_packet = rtp_buffer.data<char>();
@@ -127,18 +150,30 @@
                                &out_len));
     EXPECT_EQ(out_len, rtp_len + rtp_auth_tag_len(cs1));
     EXPECT_NE(0, memcmp(rtp_packet, original_rtp_packet, rtp_len));
-    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));
+    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));
-    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));
+    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()),
@@ -158,6 +193,30 @@
     EXPECT_EQ(rtcp_len, out_len);
     EXPECT_EQ(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len));
   }
+  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, rtc::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 (rtc::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);
+  }
   cricket::SrtpFilter f1_;
   cricket::SrtpFilter f2_;
   int sequence_number_;
@@ -547,98 +606,48 @@
   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_F(SrtpFilterTest, TestProtect_SetParamsDirect_AES_CM_128_HMAC_SHA1_80) {
-  EXPECT_TRUE(f1_.SetRtpParams(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1,
-                               kTestKeyLen, rtc::SRTP_AES128_CM_SHA1_80,
-                               kTestKey2, kTestKeyLen));
-  EXPECT_TRUE(f2_.SetRtpParams(rtc::SRTP_AES128_CM_SHA1_80, kTestKey2,
-                               kTestKeyLen, rtc::SRTP_AES128_CM_SHA1_80,
-                               kTestKey1, kTestKeyLen));
-  EXPECT_TRUE(f1_.SetRtcpParams(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1,
-                                kTestKeyLen, rtc::SRTP_AES128_CM_SHA1_80,
-                                kTestKey2, kTestKeyLen));
-  EXPECT_TRUE(f2_.SetRtcpParams(rtc::SRTP_AES128_CM_SHA1_80, kTestKey2,
-                                kTestKeyLen, rtc::SRTP_AES128_CM_SHA1_80,
-                                kTestKey1, kTestKeyLen));
-  EXPECT_TRUE(f1_.IsActive());
-  EXPECT_TRUE(f2_.IsActive());
-#if defined(ENABLE_EXTERNAL_AUTH)
-  EXPECT_TRUE(f1_.IsExternalAuthActive());
-  EXPECT_TRUE(f2_.IsExternalAuthActive());
-#endif
-  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_80, CS_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, rtc::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_F(SrtpFilterTest, TestProtect_SetParamsDirect_AES_CM_128_HMAC_SHA1_32) {
-  EXPECT_TRUE(f1_.SetRtpParams(rtc::SRTP_AES128_CM_SHA1_32, kTestKey1,
-                               kTestKeyLen, rtc::SRTP_AES128_CM_SHA1_32,
-                               kTestKey2, kTestKeyLen));
-  EXPECT_TRUE(f2_.SetRtpParams(rtc::SRTP_AES128_CM_SHA1_32, kTestKey2,
-                               kTestKeyLen, rtc::SRTP_AES128_CM_SHA1_32,
-                               kTestKey1, kTestKeyLen));
-  EXPECT_TRUE(f1_.SetRtcpParams(rtc::SRTP_AES128_CM_SHA1_32, kTestKey1,
-                                kTestKeyLen, rtc::SRTP_AES128_CM_SHA1_32,
-                                kTestKey2, kTestKeyLen));
-  EXPECT_TRUE(f2_.SetRtcpParams(rtc::SRTP_AES128_CM_SHA1_32, kTestKey2,
-                                kTestKeyLen, rtc::SRTP_AES128_CM_SHA1_32,
-                                kTestKey1, kTestKeyLen));
-  EXPECT_TRUE(f1_.IsActive());
-  EXPECT_TRUE(f2_.IsActive());
-#if defined(ENABLE_EXTERNAL_AUTH)
-  EXPECT_TRUE(f1_.IsExternalAuthActive());
-  EXPECT_TRUE(f2_.IsExternalAuthActive());
-#endif
-  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_32, CS_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, rtc::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_F(SrtpFilterTest, TestProtect_SetParamsDirect_SRTP_AEAD_AES_128_GCM) {
-  EXPECT_TRUE(f1_.SetRtpParams(rtc::SRTP_AEAD_AES_128_GCM, kTestKeyGcm128_1,
-                               kTestKeyGcm128Len, rtc::SRTP_AEAD_AES_128_GCM,
-                               kTestKeyGcm128_2, kTestKeyGcm128Len));
-  EXPECT_TRUE(f2_.SetRtpParams(rtc::SRTP_AEAD_AES_128_GCM, kTestKeyGcm128_2,
-                               kTestKeyGcm128Len, rtc::SRTP_AEAD_AES_128_GCM,
-                               kTestKeyGcm128_1, kTestKeyGcm128Len));
-  EXPECT_TRUE(f1_.SetRtcpParams(rtc::SRTP_AEAD_AES_128_GCM, kTestKeyGcm128_1,
-                                kTestKeyGcm128Len, rtc::SRTP_AEAD_AES_128_GCM,
-                                kTestKeyGcm128_2, kTestKeyGcm128Len));
-  EXPECT_TRUE(f2_.SetRtcpParams(rtc::SRTP_AEAD_AES_128_GCM, kTestKeyGcm128_2,
-                                kTestKeyGcm128Len, rtc::SRTP_AEAD_AES_128_GCM,
-                                kTestKeyGcm128_1, kTestKeyGcm128Len));
-  EXPECT_TRUE(f1_.IsActive());
-  EXPECT_TRUE(f2_.IsActive());
-#if defined(ENABLE_EXTERNAL_AUTH)
-  EXPECT_FALSE(f1_.IsExternalAuthActive());
-  EXPECT_FALSE(f2_.IsExternalAuthActive());
-#endif
-  TestProtectUnprotect(CS_AEAD_AES_128_GCM, CS_AEAD_AES_128_GCM);
+TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_128_GCM) {
+  bool enable_external_auth = GetParam();
+  TestProtectSetParamsDirect(enable_external_auth, rtc::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_F(SrtpFilterTest, TestProtect_SetParamsDirect_SRTP_AEAD_AES_256_GCM) {
-  EXPECT_TRUE(f1_.SetRtpParams(rtc::SRTP_AEAD_AES_256_GCM, kTestKeyGcm256_1,
-                               kTestKeyGcm256Len, rtc::SRTP_AEAD_AES_256_GCM,
-                               kTestKeyGcm256_2, kTestKeyGcm256Len));
-  EXPECT_TRUE(f2_.SetRtpParams(rtc::SRTP_AEAD_AES_256_GCM, kTestKeyGcm256_2,
-                               kTestKeyGcm256Len, rtc::SRTP_AEAD_AES_256_GCM,
-                               kTestKeyGcm256_1, kTestKeyGcm256Len));
-  EXPECT_TRUE(f1_.SetRtcpParams(rtc::SRTP_AEAD_AES_256_GCM, kTestKeyGcm256_1,
-                                kTestKeyGcm256Len, rtc::SRTP_AEAD_AES_256_GCM,
-                                kTestKeyGcm256_2, kTestKeyGcm256Len));
-  EXPECT_TRUE(f2_.SetRtcpParams(rtc::SRTP_AEAD_AES_256_GCM, kTestKeyGcm256_2,
-                                kTestKeyGcm256Len, rtc::SRTP_AEAD_AES_256_GCM,
-                                kTestKeyGcm256_1, kTestKeyGcm256Len));
-  EXPECT_TRUE(f1_.IsActive());
-  EXPECT_TRUE(f2_.IsActive());
-#if defined(ENABLE_EXTERNAL_AUTH)
-  EXPECT_FALSE(f1_.IsExternalAuthActive());
-  EXPECT_FALSE(f2_.IsExternalAuthActive());
-#endif
-  TestProtectUnprotect(CS_AEAD_AES_256_GCM, CS_AEAD_AES_256_GCM);
+TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_256_GCM) {
+  bool enable_external_auth = GetParam();
+  TestProtectSetParamsDirect(enable_external_auth, rtc::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(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1,
@@ -649,25 +658,6 @@
                                  kTestKey1, kTestKeyLen - 1));
 }
 
-#if defined(ENABLE_EXTERNAL_AUTH)
-TEST_F(SrtpFilterTest, TestGetSendAuthParams) {
-  EXPECT_TRUE(f1_.SetRtpParams(rtc::SRTP_AES128_CM_SHA1_32, kTestKey1,
-                               kTestKeyLen, rtc::SRTP_AES128_CM_SHA1_32,
-                               kTestKey2, kTestKeyLen));
-  EXPECT_TRUE(f1_.SetRtcpParams(rtc::SRTP_AES128_CM_SHA1_32, kTestKey1,
-                                kTestKeyLen, rtc::SRTP_AES128_CM_SHA1_32,
-                                kTestKey2, kTestKeyLen));
-  // Non-GCM ciphers support external auth.
-  EXPECT_TRUE(f1_.IsExternalAuthActive());
-  uint8_t* auth_key = NULL;
-  int auth_key_len = 0, auth_tag_len = 0;
-  EXPECT_TRUE(f1_.GetRtpAuthParams(&auth_key, &auth_key_len, &auth_tag_len));
-  EXPECT_TRUE(auth_key != NULL);
-  EXPECT_EQ(20, auth_key_len);
-  EXPECT_EQ(4, auth_tag_len);
-}
-#endif
-
 class SrtpSessionTest : public testing::Test {
  protected:
   virtual void SetUp() {