Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(393)

Side by Side Diff: webrtc/pc/srtpfilter.cc

Issue 1528843005: Add support for GCM cipher suites from RFC 7714. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: More feedback from Matt Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2009 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2009 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/pc/srtpfilter.h" 11 #include "webrtc/pc/srtpfilter.h"
12 12
13 #include <string.h> 13 #include <string.h>
14 14
15 #include <algorithm> 15 #include <algorithm>
16 16
17 #include "webrtc/base/base64.h" 17 #include "webrtc/base/base64.h"
18 #include "webrtc/base/buffer.h"
18 #include "webrtc/base/byteorder.h" 19 #include "webrtc/base/byteorder.h"
19 #include "webrtc/base/common.h" 20 #include "webrtc/base/common.h"
20 #include "webrtc/base/logging.h" 21 #include "webrtc/base/logging.h"
21 #include "webrtc/base/stringencode.h" 22 #include "webrtc/base/stringencode.h"
22 #include "webrtc/base/timeutils.h" 23 #include "webrtc/base/timeutils.h"
23 #include "webrtc/media/base/rtputils.h" 24 #include "webrtc/media/base/rtputils.h"
24 25
25 // Enable this line to turn on SRTP debugging 26 // Enable this line to turn on SRTP debugging
26 // #define SRTP_DEBUG 27 // #define SRTP_DEBUG
27 28
(...skipping 12 matching lines...) Expand all
40 #endif // ENABLE_EXTERNAL_AUTH 41 #endif // ENABLE_EXTERNAL_AUTH
41 #if !defined(NDEBUG) 42 #if !defined(NDEBUG)
42 extern "C" debug_module_t mod_srtp; 43 extern "C" debug_module_t mod_srtp;
43 extern "C" debug_module_t mod_auth; 44 extern "C" debug_module_t mod_auth;
44 extern "C" debug_module_t mod_cipher; 45 extern "C" debug_module_t mod_cipher;
45 extern "C" debug_module_t mod_stat; 46 extern "C" debug_module_t mod_stat;
46 extern "C" debug_module_t mod_alloc; 47 extern "C" debug_module_t mod_alloc;
47 extern "C" debug_module_t mod_aes_icm; 48 extern "C" debug_module_t mod_aes_icm;
48 extern "C" debug_module_t mod_aes_hmac; 49 extern "C" debug_module_t mod_aes_hmac;
49 #endif 50 #endif
50 #else
51 // SrtpFilter needs that constant.
52 #define SRTP_MASTER_KEY_LEN 30
53 #endif // HAVE_SRTP 51 #endif // HAVE_SRTP
54 52
55 namespace cricket { 53 namespace cricket {
56 54
57 const int SRTP_MASTER_KEY_BASE64_LEN = SRTP_MASTER_KEY_LEN * 4 / 3;
58 const int SRTP_MASTER_KEY_KEY_LEN = 16;
59 const int SRTP_MASTER_KEY_SALT_LEN = 14;
60
61 #ifndef HAVE_SRTP 55 #ifndef HAVE_SRTP
62 56
63 // This helper function is used on systems that don't (yet) have SRTP, 57 // This helper function is used on systems that don't (yet) have SRTP,
64 // to log that the functions that require it won't do anything. 58 // to log that the functions that require it won't do anything.
65 namespace { 59 namespace {
66 bool SrtpNotAvailable(const char *func) { 60 bool SrtpNotAvailable(const char *func) {
67 LOG(LS_ERROR) << func << ": SRTP is not available on your system."; 61 LOG(LS_ERROR) << func << ": SRTP is not available on your system.";
68 return false; 62 return false;
69 } 63 }
70 } // anonymous namespace 64 } // anonymous namespace
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 // CryptoParams is unchanged. 389 // CryptoParams is unchanged.
396 if (applied_send_params_.cipher_suite == send_params.cipher_suite && 390 if (applied_send_params_.cipher_suite == send_params.cipher_suite &&
397 applied_send_params_.key_params == send_params.key_params && 391 applied_send_params_.key_params == send_params.key_params &&
398 applied_recv_params_.cipher_suite == recv_params.cipher_suite && 392 applied_recv_params_.cipher_suite == recv_params.cipher_suite &&
399 applied_recv_params_.key_params == recv_params.key_params) { 393 applied_recv_params_.key_params == recv_params.key_params) {
400 LOG(LS_INFO) << "Applying the same SRTP parameters again. No-op."; 394 LOG(LS_INFO) << "Applying the same SRTP parameters again. No-op.";
401 395
402 // We do not want to reset the ROC if the keys are the same. So just return. 396 // We do not want to reset the ROC if the keys are the same. So just return.
403 return true; 397 return true;
404 } 398 }
399
400 int send_suite = rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite);
401 int recv_suite = rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite);
402 if (send_suite == rtc::SRTP_INVALID_CRYPTO_SUITE ||
403 recv_suite == rtc::SRTP_INVALID_CRYPTO_SUITE) {
404 LOG(LS_WARNING) << "Unknown crypto suite(s) received:"
405 << " send cipher_suite " << send_params.cipher_suite
406 << " recv cipher_suite " << recv_params.cipher_suite;
407 return false;
408 }
409
410 int send_key_len, send_salt_len;
411 int recv_key_len, recv_salt_len;
412 if (!rtc::GetSrtpKeyAndSaltLengths(send_suite, &send_key_len,
413 &send_salt_len) ||
414 !rtc::GetSrtpKeyAndSaltLengths(recv_suite, &recv_key_len,
415 &recv_salt_len)) {
416 LOG(LS_WARNING) << "Could not get lengths for crypto suite(s):"
417 << " send cipher_suite " << send_params.cipher_suite
418 << " recv cipher_suite " << recv_params.cipher_suite;
419 return false;
420 }
421
405 // TODO(juberti): Zero these buffers after use. 422 // TODO(juberti): Zero these buffers after use.
406 bool ret; 423 bool ret;
407 uint8_t send_key[SRTP_MASTER_KEY_LEN], recv_key[SRTP_MASTER_KEY_LEN]; 424 rtc::Buffer send_key(send_key_len + send_salt_len);
408 ret = (ParseKeyParams(send_params.key_params, send_key, sizeof(send_key)) && 425 rtc::Buffer recv_key(recv_key_len + recv_salt_len);
409 ParseKeyParams(recv_params.key_params, recv_key, sizeof(recv_key))); 426 ret = (ParseKeyParams(send_params.key_params, send_key.data(),
427 send_key.size()) &&
428 ParseKeyParams(recv_params.key_params, recv_key.data(),
429 recv_key.size()));
410 if (ret) { 430 if (ret) {
411 CreateSrtpSessions(); 431 CreateSrtpSessions();
412 ret = (send_session_->SetSend( 432 ret = (send_session_->SetSend(
413 rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite), send_key, 433 rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite),
414 sizeof(send_key)) && 434 send_key.data(), send_key.size()) &&
415 recv_session_->SetRecv( 435 recv_session_->SetRecv(
416 rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite), recv_key, 436 rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite),
417 sizeof(recv_key))); 437 recv_key.data(), recv_key.size()));
418 } 438 }
419 if (ret) { 439 if (ret) {
420 LOG(LS_INFO) << "SRTP activated with negotiated parameters:" 440 LOG(LS_INFO) << "SRTP activated with negotiated parameters:"
421 << " send cipher_suite " << send_params.cipher_suite 441 << " send cipher_suite " << send_params.cipher_suite
422 << " recv cipher_suite " << recv_params.cipher_suite; 442 << " recv cipher_suite " << recv_params.cipher_suite;
423 applied_send_params_ = send_params; 443 applied_send_params_ = send_params;
424 applied_recv_params_ = recv_params; 444 applied_recv_params_ = recv_params;
425 } else { 445 } else {
426 LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters"; 446 LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters";
427 } 447 }
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 << "SRTP session already created"; 671 << "SRTP session already created";
652 return false; 672 return false;
653 } 673 }
654 674
655 if (!Init()) { 675 if (!Init()) {
656 return false; 676 return false;
657 } 677 }
658 678
659 srtp_policy_t policy; 679 srtp_policy_t policy;
660 memset(&policy, 0, sizeof(policy)); 680 memset(&policy, 0, sizeof(policy));
661
662 if (cs == rtc::SRTP_AES128_CM_SHA1_80) { 681 if (cs == rtc::SRTP_AES128_CM_SHA1_80) {
663 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp); 682 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
664 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); 683 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
665 } else if (cs == rtc::SRTP_AES128_CM_SHA1_32) { 684 } else if (cs == rtc::SRTP_AES128_CM_SHA1_32) {
666 crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); // rtp is 32, 685 crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); // rtp is 32,
667 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); // rtcp still 80 686 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); // rtcp still 80
687 } else if (cs == rtc::SRTP_AEAD_AES_128_GCM) {
688 crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
689 crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp);
690 } else if (cs == rtc::SRTP_AEAD_AES_256_GCM) {
691 crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp);
692 crypto_policy_set_aes_gcm_256_16_auth(&policy.rtcp);
668 } else { 693 } else {
669 LOG(LS_WARNING) << "Failed to create SRTP session: unsupported" 694 LOG(LS_WARNING) << "Failed to create SRTP session: unsupported"
670 << " cipher_suite " << cs; 695 << " cipher_suite " << cs;
671 return false; 696 return false;
672 } 697 }
673 698
674 if (!key || len != SRTP_MASTER_KEY_LEN) { 699 int expected_key_len;
700 int expected_salt_len;
701 if (!rtc::GetSrtpKeyAndSaltLengths(cs, &expected_key_len,
702 &expected_salt_len)) {
703 // This should never happen.
704 LOG(LS_WARNING) << "Failed to create SRTP session: unsupported"
705 << " cipher_suite without length information" << cs;
706 return false;
707 }
708
709 if (!key || len != (expected_key_len + expected_salt_len)) {
675 LOG(LS_WARNING) << "Failed to create SRTP session: invalid key"; 710 LOG(LS_WARNING) << "Failed to create SRTP session: invalid key";
676 return false; 711 return false;
677 } 712 }
678 713
679 policy.ssrc.type = static_cast<ssrc_type_t>(type); 714 policy.ssrc.type = static_cast<ssrc_type_t>(type);
680 policy.ssrc.value = 0; 715 policy.ssrc.value = 0;
681 policy.key = const_cast<uint8_t*>(key); 716 policy.key = const_cast<uint8_t*>(key);
682 // TODO(astor) parse window size from WSH session-param 717 // TODO(astor) parse window size from WSH session-param
683 policy.window_size = 1024; 718 policy.window_size = 1024;
684 policy.allow_repeat_tx = 1; 719 policy.allow_repeat_tx = 1;
685 // If external authentication option is enabled, supply custom auth module 720 // If external authentication option is enabled, supply custom auth module
686 // id EXTERNAL_HMAC_SHA1 in the policy structure. 721 // id EXTERNAL_HMAC_SHA1 in the policy structure.
687 // We want to set this option only for rtp packets. 722 // We want to set this option only for rtp packets.
688 // By default policy structure is initialized to HMAC_SHA1. 723 // By default policy structure is initialized to HMAC_SHA1.
689 #if defined(ENABLE_EXTERNAL_AUTH) 724 #if defined(ENABLE_EXTERNAL_AUTH)
690 // Enable external HMAC authentication only for outgoing streams. 725 // Enable external HMAC authentication only for outgoing streams.
691 if (type == ssrc_any_outbound) { 726 if (type == ssrc_any_outbound) {
692 policy.rtp.auth_type = EXTERNAL_HMAC_SHA1; 727 policy.rtp.auth_type = EXTERNAL_HMAC_SHA1;
693 } 728 }
694 #endif 729 #endif
695 policy.next = NULL; 730 policy.next = NULL;
696 731
697 int err = srtp_create(&session_, &policy); 732 int err = srtp_create(&session_, &policy);
698 if (err != err_status_ok) { 733 if (err != err_status_ok) {
699 session_ = NULL; 734 session_ = NULL;
700 LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err; 735 LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err;
701 return false; 736 return false;
702 } 737 }
703 738
704
705 rtp_auth_tag_len_ = policy.rtp.auth_tag_len; 739 rtp_auth_tag_len_ = policy.rtp.auth_tag_len;
706 rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len; 740 rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len;
707 return true; 741 return true;
708 } 742 }
709 743
710 bool SrtpSession::Init() { 744 bool SrtpSession::Init() {
711 rtc::GlobalLockScope ls(&lock_); 745 rtc::GlobalLockScope ls(&lock_);
712 746
713 if (!inited_) { 747 if (!inited_) {
714 int err; 748 int err;
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 SrtpNotAvailable(__FUNCTION__); 960 SrtpNotAvailable(__FUNCTION__);
927 } 961 }
928 962
929 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { 963 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) {
930 SrtpNotAvailable(__FUNCTION__); 964 SrtpNotAvailable(__FUNCTION__);
931 } 965 }
932 966
933 #endif // HAVE_SRTP 967 #endif // HAVE_SRTP
934 968
935 } // namespace cricket 969 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698