From 51f29197e67817f3d4d77a2d1b3018c06368a2cc Mon Sep 17 00:00:00 2001 From: mattdr Date: Wed, 28 Sep 2016 14:08:46 -0700 Subject: [PATCH] Update WebRTC to build against libsrtp 2.0 BUG=webrtc:6376 Review-Url: https://codereview.webrtc.org/2345753002 Cr-Commit-Position: refs/heads/master@{#14424} --- webrtc/pc/externalhmac.cc | 10 +++-- webrtc/pc/externalhmac.h | 7 ++- webrtc/pc/srtpfilter.cc | 73 ++++++++++++++++---------------- webrtc/pc/srtpfilter.h | 10 +++-- webrtc/pc/srtpfilter_unittest.cc | 50 +++++++++++----------- 5 files changed, 80 insertions(+), 70 deletions(-) diff --git a/webrtc/pc/externalhmac.cc b/webrtc/pc/externalhmac.cc index d88cfdc7ec..f85e753e71 100644 --- a/webrtc/pc/externalhmac.cc +++ b/webrtc/pc/externalhmac.cc @@ -8,24 +8,26 @@ * be found in the AUTHORS file in the root of the source tree. */ -#if defined(HAVE_SRTP) && defined(ENABLE_EXTERNAL_AUTH) - #include "webrtc/pc/externalhmac.h" #include // For malloc/free. +#ifdef HAVE_SRTP extern "C" { #ifdef SRTP_RELATIVE_PATH #include "crypto_kernel.h" // NOLINT #include "srtp.h" // NOLINT #else -#include "third_party/libsrtp/srtp/crypto/include/crypto_kernel.h" -#include "third_party/libsrtp/srtp/include/srtp.h" +#include "third_party/libsrtp/crypto/include/crypto_kernel.h" +#include "third_party/libsrtp/include/srtp.h" #endif // SRTP_RELATIVE_PATH } +#endif // HAVE_SRTP #include "webrtc/base/logging.h" +#if defined(HAVE_SRTP) && defined(ENABLE_EXTERNAL_AUTH) + // Begin test case 0 */ static const uint8_t kExternalHmacTestCase0Key[20] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, diff --git a/webrtc/pc/externalhmac.h b/webrtc/pc/externalhmac.h index edca74d4d4..18d4681145 100644 --- a/webrtc/pc/externalhmac.h +++ b/webrtc/pc/externalhmac.h @@ -27,16 +27,19 @@ // the auth_type of srtp_policy_t. The application must first register auth // functions and the corresponding authentication id using // crypto_kernel_replace_auth_type function. -#if defined(HAVE_SRTP) && defined(ENABLE_EXTERNAL_AUTH) #include "webrtc/base/basictypes.h" +#ifdef HAVE_SRTP extern "C" { #ifdef SRTP_RELATIVE_PATH #include "auth.h" // NOLINT #else -#include "third_party/libsrtp/srtp/crypto/include/auth.h" +#include "third_party/libsrtp/crypto/include/auth.h" #endif // SRTP_RELATIVE_PATH } +#endif // HAVE_SRTP + +#if defined(HAVE_SRTP) && defined(ENABLE_EXTERNAL_AUTH) #define EXTERNAL_HMAC_SHA1 HMAC_SHA1 + 1 #define HMAC_KEY_LENGTH 20 diff --git a/webrtc/pc/srtpfilter.cc b/webrtc/pc/srtpfilter.cc index 9e7cc665f2..3f38d11a08 100644 --- a/webrtc/pc/srtpfilter.cc +++ b/webrtc/pc/srtpfilter.cc @@ -23,6 +23,7 @@ #include "webrtc/base/stringencode.h" #include "webrtc/base/timeutils.h" #include "webrtc/media/base/rtputils.h" +#include "webrtc/pc/externalhmac.h" // Enable this line to turn on SRTP debugging // #define SRTP_DEBUG @@ -33,21 +34,19 @@ extern "C" { #include "srtp.h" // NOLINT #include "srtp_priv.h" // NOLINT #else -#include "third_party/libsrtp/srtp/include/srtp.h" -#include "third_party/libsrtp/srtp/include/srtp_priv.h" +#include "third_party/libsrtp/include/srtp.h" +#include "third_party/libsrtp/include/srtp_priv.h" #endif // SRTP_RELATIVE_PATH } -#ifdef ENABLE_EXTERNAL_AUTH -#include "webrtc/pc/externalhmac.h" -#endif // ENABLE_EXTERNAL_AUTH + #if !defined(NDEBUG) -extern "C" debug_module_t mod_srtp; -extern "C" debug_module_t mod_auth; -extern "C" debug_module_t mod_cipher; -extern "C" debug_module_t mod_stat; -extern "C" debug_module_t mod_alloc; -extern "C" debug_module_t mod_aes_icm; -extern "C" debug_module_t mod_aes_hmac; +extern "C" srtp_debug_module_t mod_srtp; +extern "C" srtp_debug_module_t mod_auth; +extern "C" srtp_debug_module_t mod_cipher; +extern "C" srtp_debug_module_t mod_stat; +extern "C" srtp_debug_module_t mod_alloc; +extern "C" srtp_debug_module_t mod_aes_icm; +extern "C" srtp_debug_module_t mod_aes_hmac; #endif #endif // HAVE_SRTP @@ -537,7 +536,7 @@ bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { } int seq_num; GetRtpSeqNum(p, in_len, &seq_num); - if (err != err_status_ok) { + if (err != srtp_err_status_ok) { LOG(LS_WARNING) << "Failed to protect SRTP packet, seqnum=" << seq_num << ", err=" << err << ", last seqnum=" << last_send_seq_num_; @@ -575,7 +574,7 @@ bool SrtpSession::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { *out_len = in_len; int err = srtp_protect_rtcp(session_, p, out_len); srtp_stat_->AddProtectRtcpResult(err); - if (err != err_status_ok) { + if (err != srtp_err_status_ok) { LOG(LS_WARNING) << "Failed to protect SRTCP packet, err=" << err; return false; } @@ -595,7 +594,7 @@ bool SrtpSession::UnprotectRtp(void* p, int in_len, int* out_len) { if (GetRtpSsrc(p, in_len, &ssrc)) { srtp_stat_->AddUnprotectRtpResult(ssrc, err); } - if (err != err_status_ok) { + if (err != srtp_err_status_ok) { LOG(LS_WARNING) << "Failed to unprotect SRTP packet, err=" << err; return false; } @@ -612,7 +611,7 @@ bool SrtpSession::UnprotectRtcp(void* p, int in_len, int* out_len) { *out_len = in_len; int err = srtp_unprotect_rtcp(session_, p, out_len); srtp_stat_->AddUnprotectRtcpResult(err); - if (err != err_status_ok) { + if (err != srtp_err_status_ok) { LOG(LS_WARNING) << "Failed to unprotect SRTCP packet, err=" << err; return false; } @@ -657,7 +656,8 @@ bool SrtpSession::GetSendStreamPacketIndex(void* p, // Shift packet index, put into network byte order *index = static_cast( - rtc::NetworkToHost64(rdbx_get_packet_index(&stream->rtp_rdbx) << 16)); + rtc::NetworkToHost64( + srtp_rdbx_get_packet_index(&stream->rtp_rdbx) << 16)); return true; } @@ -680,19 +680,20 @@ bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, size_t len) { srtp_policy_t policy; memset(&policy, 0, sizeof(policy)); if (cs == rtc::SRTP_AES128_CM_SHA1_80) { - crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp); - crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); + srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp); + srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); } else if (cs == rtc::SRTP_AES128_CM_SHA1_32) { - crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); // rtp is 32, - crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); // rtcp still 80 + // RTP HMAC is shortened to 32 bits, but RTCP remains 80 bits. + srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); + srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); #if !defined(ENABLE_EXTERNAL_AUTH) // TODO(jbauch): Re-enable once https://crbug.com/628400 is resolved. } else if (cs == rtc::SRTP_AEAD_AES_128_GCM) { - crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp); - crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp); + srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp); + srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp); } else if (cs == rtc::SRTP_AEAD_AES_256_GCM) { - crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp); - crypto_policy_set_aes_gcm_256_16_auth(&policy.rtcp); + srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp); + srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtcp); #endif // ENABLE_EXTERNAL_AUTH } else { LOG(LS_WARNING) << "Failed to create SRTP session: unsupported" @@ -716,7 +717,7 @@ bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, size_t len) { return false; } - policy.ssrc.type = static_cast(type); + policy.ssrc.type = static_cast(type); policy.ssrc.value = 0; policy.key = const_cast(key); // TODO(astor) parse window size from WSH session-param @@ -735,7 +736,7 @@ bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, size_t len) { policy.next = nullptr; int err = srtp_create(&session_, &policy); - if (err != err_status_ok) { + if (err != srtp_err_status_ok) { session_ = nullptr; LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err; return false; @@ -753,19 +754,19 @@ bool SrtpSession::Init() { if (!inited_) { int err; err = srtp_init(); - if (err != err_status_ok) { + if (err != srtp_err_status_ok) { LOG(LS_ERROR) << "Failed to init SRTP, err=" << err; return false; } err = srtp_install_event_handler(&SrtpSession::HandleEventThunk); - if (err != err_status_ok) { + if (err != srtp_err_status_ok) { LOG(LS_ERROR) << "Failed to install SRTP event handler, err=" << err; return false; } #if defined(ENABLE_EXTERNAL_AUTH) err = external_crypto_init(); - if (err != err_status_ok) { + if (err != srtp_err_status_ok) { LOG(LS_ERROR) << "Failed to initialize fake auth, err=" << err; return false; } @@ -877,10 +878,10 @@ void SrtpStat::AddProtectRtpResult(uint32_t ssrc, int result) { key.ssrc = ssrc; key.mode = SrtpFilter::PROTECT; switch (result) { - case err_status_ok: + case srtp_err_status_ok: key.error = SrtpFilter::ERROR_NONE; break; - case err_status_auth_fail: + case srtp_err_status_auth_fail: key.error = SrtpFilter::ERROR_AUTH; break; default: @@ -894,14 +895,14 @@ void SrtpStat::AddUnprotectRtpResult(uint32_t ssrc, int result) { key.ssrc = ssrc; key.mode = SrtpFilter::UNPROTECT; switch (result) { - case err_status_ok: + case srtp_err_status_ok: key.error = SrtpFilter::ERROR_NONE; break; - case err_status_auth_fail: + case srtp_err_status_auth_fail: key.error = SrtpFilter::ERROR_AUTH; break; - case err_status_replay_fail: - case err_status_replay_old: + case srtp_err_status_replay_fail: + case srtp_err_status_replay_old: key.error = SrtpFilter::ERROR_REPLAY; break; default: diff --git a/webrtc/pc/srtpfilter.h b/webrtc/pc/srtpfilter.h index 26a335fbae..26e1e24e31 100644 --- a/webrtc/pc/srtpfilter.h +++ b/webrtc/pc/srtpfilter.h @@ -28,8 +28,12 @@ // Forward declaration to avoid pulling in libsrtp headers here struct srtp_event_data_t; -struct srtp_ctx_t; -struct srtp_policy_t; + +// Libsrtp V1/V2 compatibility hack. +// TODO(mattdr): Remove this #define after libsrtp 2.0 is in. +#define srtp_ctx_t_ srtp_ctx_t + +struct srtp_ctx_t_; namespace cricket { @@ -222,7 +226,7 @@ class SrtpSession { static void HandleEventThunk(srtp_event_data_t* ev); rtc::ThreadChecker thread_checker_; - srtp_ctx_t* session_; + srtp_ctx_t_* session_; int rtp_auth_tag_len_; int rtcp_auth_tag_len_; std::unique_ptr srtp_stat_; diff --git a/webrtc/pc/srtpfilter_unittest.cc b/webrtc/pc/srtpfilter_unittest.cc index cf80bdf2a5..fda571195c 100644 --- a/webrtc/pc/srtpfilter_unittest.cc +++ b/webrtc/pc/srtpfilter_unittest.cc @@ -20,7 +20,7 @@ extern "C" { #ifdef SRTP_RELATIVE_PATH #include "crypto/include/err.h" #else -#include "third_party/libsrtp/srtp/crypto/include/err.h" +#include "third_party/libsrtp/crypto/include/err.h" #endif } @@ -813,30 +813,30 @@ class SrtpStatTest TEST_F(SrtpStatTest, TestProtectRtpError) { Reset(); - srtp_stat_.AddProtectRtpResult(1, err_status_ok); + srtp_stat_.AddProtectRtpResult(1, srtp_err_status_ok); EXPECT_EQ(0U, ssrc_); EXPECT_EQ(-1, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_); Reset(); - srtp_stat_.AddProtectRtpResult(1, err_status_auth_fail); + srtp_stat_.AddProtectRtpResult(1, srtp_err_status_auth_fail); EXPECT_EQ(1U, ssrc_); EXPECT_EQ(cricket::SrtpFilter::PROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_AUTH, error_); Reset(); - srtp_stat_.AddProtectRtpResult(1, err_status_fail); + srtp_stat_.AddProtectRtpResult(1, srtp_err_status_fail); EXPECT_EQ(1U, ssrc_); EXPECT_EQ(cricket::SrtpFilter::PROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_); // Within 200ms, the error will not be triggered. Reset(); - srtp_stat_.AddProtectRtpResult(1, err_status_fail); + srtp_stat_.AddProtectRtpResult(1, srtp_err_status_fail); EXPECT_EQ(0U, ssrc_); EXPECT_EQ(-1, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_); // Now the error will be triggered again. Reset(); rtc::Thread::Current()->SleepMs(210); - srtp_stat_.AddProtectRtpResult(1, err_status_fail); + srtp_stat_.AddProtectRtpResult(1, srtp_err_status_fail); EXPECT_EQ(1U, ssrc_); EXPECT_EQ(cricket::SrtpFilter::PROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_); @@ -844,41 +844,41 @@ TEST_F(SrtpStatTest, TestProtectRtpError) { TEST_F(SrtpStatTest, TestUnprotectRtpError) { Reset(); - srtp_stat_.AddUnprotectRtpResult(1, err_status_ok); + srtp_stat_.AddUnprotectRtpResult(1, srtp_err_status_ok); EXPECT_EQ(0U, ssrc_); EXPECT_EQ(-1, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_); Reset(); - srtp_stat_.AddUnprotectRtpResult(1, err_status_auth_fail); + srtp_stat_.AddUnprotectRtpResult(1, srtp_err_status_auth_fail); EXPECT_EQ(1U, ssrc_); EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_AUTH, error_); Reset(); - srtp_stat_.AddUnprotectRtpResult(1, err_status_replay_fail); + srtp_stat_.AddUnprotectRtpResult(1, srtp_err_status_replay_fail); EXPECT_EQ(1U, ssrc_); EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_REPLAY, error_); Reset(); rtc::Thread::Current()->SleepMs(210); - srtp_stat_.AddUnprotectRtpResult(1, err_status_replay_old); + srtp_stat_.AddUnprotectRtpResult(1, srtp_err_status_replay_old); EXPECT_EQ(1U, ssrc_); EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_REPLAY, error_); Reset(); - srtp_stat_.AddUnprotectRtpResult(1, err_status_fail); + srtp_stat_.AddUnprotectRtpResult(1, srtp_err_status_fail); EXPECT_EQ(1U, ssrc_); EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_); // Within 200ms, the error will not be triggered. Reset(); - srtp_stat_.AddUnprotectRtpResult(1, err_status_fail); + srtp_stat_.AddUnprotectRtpResult(1, srtp_err_status_fail); EXPECT_EQ(0U, ssrc_); EXPECT_EQ(-1, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_); // Now the error will be triggered again. Reset(); rtc::Thread::Current()->SleepMs(210); - srtp_stat_.AddUnprotectRtpResult(1, err_status_fail); + srtp_stat_.AddUnprotectRtpResult(1, srtp_err_status_fail); EXPECT_EQ(1U, ssrc_); EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_); @@ -886,61 +886,61 @@ TEST_F(SrtpStatTest, TestUnprotectRtpError) { TEST_F(SrtpStatTest, TestProtectRtcpError) { Reset(); - srtp_stat_.AddProtectRtcpResult(err_status_ok); + srtp_stat_.AddProtectRtcpResult(srtp_err_status_ok); EXPECT_EQ(-1, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_); Reset(); - srtp_stat_.AddProtectRtcpResult(err_status_auth_fail); + srtp_stat_.AddProtectRtcpResult(srtp_err_status_auth_fail); EXPECT_EQ(cricket::SrtpFilter::PROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_AUTH, error_); Reset(); - srtp_stat_.AddProtectRtcpResult(err_status_fail); + srtp_stat_.AddProtectRtcpResult(srtp_err_status_fail); EXPECT_EQ(cricket::SrtpFilter::PROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_); // Within 200ms, the error will not be triggered. Reset(); - srtp_stat_.AddProtectRtcpResult(err_status_fail); + srtp_stat_.AddProtectRtcpResult(srtp_err_status_fail); EXPECT_EQ(-1, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_); // Now the error will be triggered again. Reset(); rtc::Thread::Current()->SleepMs(210); - srtp_stat_.AddProtectRtcpResult(err_status_fail); + srtp_stat_.AddProtectRtcpResult(srtp_err_status_fail); EXPECT_EQ(cricket::SrtpFilter::PROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_); } TEST_F(SrtpStatTest, TestUnprotectRtcpError) { Reset(); - srtp_stat_.AddUnprotectRtcpResult(err_status_ok); + srtp_stat_.AddUnprotectRtcpResult(srtp_err_status_ok); EXPECT_EQ(-1, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_); Reset(); - srtp_stat_.AddUnprotectRtcpResult(err_status_auth_fail); + srtp_stat_.AddUnprotectRtcpResult(srtp_err_status_auth_fail); EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_AUTH, error_); Reset(); - srtp_stat_.AddUnprotectRtcpResult(err_status_replay_fail); + srtp_stat_.AddUnprotectRtcpResult(srtp_err_status_replay_fail); EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_REPLAY, error_); Reset(); rtc::Thread::Current()->SleepMs(210); - srtp_stat_.AddUnprotectRtcpResult(err_status_replay_fail); + srtp_stat_.AddUnprotectRtcpResult(srtp_err_status_replay_fail); EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_REPLAY, error_); Reset(); - srtp_stat_.AddUnprotectRtcpResult(err_status_fail); + srtp_stat_.AddUnprotectRtcpResult(srtp_err_status_fail); EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_); // Within 200ms, the error will not be triggered. Reset(); - srtp_stat_.AddUnprotectRtcpResult(err_status_fail); + srtp_stat_.AddUnprotectRtcpResult(srtp_err_status_fail); EXPECT_EQ(-1, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_); // Now the error will be triggered again. Reset(); rtc::Thread::Current()->SleepMs(210); - srtp_stat_.AddUnprotectRtcpResult(err_status_fail); + srtp_stat_.AddUnprotectRtcpResult(srtp_err_status_fail); EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_); EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_); }