Index: talk/session/media/mediasession.cc |
diff --git a/talk/session/media/mediasession.cc b/talk/session/media/mediasession.cc |
index 8db37d049abad3dddd1b7be4782b16348c59dbe1..525891f059af278cf1c481664bab73cfc70ef007 100644 |
--- a/talk/session/media/mediasession.cc |
+++ b/talk/session/media/mediasession.cc |
@@ -51,11 +51,13 @@ static const uint32_t kMaxSctpSid = 1023; |
namespace { |
const char kInline[] = "inline:"; |
-void GetSupportedCryptoSuiteNames(void (*func)(std::vector<int>*), |
- std::vector<std::string>* names) { |
+void GetSupportedCryptoSuiteNames(void (*func)(std::vector<int>*, |
+ const cricket::MediaSessionOptions&), |
+ std::vector<std::string>* names, |
+ const cricket::MediaSessionOptions& options) { |
#ifdef HAVE_SRTP |
std::vector<int> crypto_suites; |
- func(&crypto_suites); |
+ func(&crypto_suites, options); |
for (const auto crypto : crypto_suites) { |
names->push_back(rtc::SrtpCryptoSuiteToName(crypto)); |
} |
@@ -98,10 +100,19 @@ static bool IsMediaContentOfType(const ContentInfo* content, |
static bool CreateCryptoParams(int tag, const std::string& cipher, |
CryptoParams *out) { |
+ int key_len; |
+ int salt_len; |
+ if (!rtc::GetSrtpKeyAndSaltLengths( |
+ rtc::SrtpCryptoSuiteFromName(cipher), &key_len, &salt_len)) { |
+ return false; |
+ } |
+ |
+ int master_key_base64_len = (key_len + salt_len) * 4 / 3; |
+ |
std::string key; |
- key.reserve(SRTP_MASTER_KEY_BASE64_LEN); |
+ key.reserve(master_key_base64_len); |
- if (!rtc::CreateRandomString(SRTP_MASTER_KEY_BASE64_LEN, &key)) { |
+ if (!rtc::CreateRandomString(master_key_base64_len, &key)) { |
return false; |
} |
out->tag = tag; |
@@ -162,63 +173,84 @@ bool FindMatchingCrypto(const CryptoParamsVec& cryptos, |
return false; |
} |
-// For audio, HMAC 32 is prefered because of the low overhead. |
-void GetSupportedAudioCryptoSuites(std::vector<int>* crypto_suites) { |
+// For audio, HMAC 32 is prefered over HMAC 80 because of the low overhead. |
+void GetSupportedAudioCryptoSuites(std::vector<int>* crypto_suites, |
+ const MediaSessionOptions& options) { |
#ifdef HAVE_SRTP |
+ if (options.enable_gcm_crypto_suites) { |
+ crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM); |
+ crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM); |
+ } |
crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32); |
crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); |
#endif |
} |
void GetSupportedAudioCryptoSuiteNames( |
- std::vector<std::string>* crypto_suite_names) { |
+ std::vector<std::string>* crypto_suite_names, |
+ const MediaSessionOptions& options) { |
GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites, |
- crypto_suite_names); |
+ crypto_suite_names, options); |
} |
-void GetSupportedVideoCryptoSuites(std::vector<int>* crypto_suites) { |
- GetDefaultSrtpCryptoSuites(crypto_suites); |
+void GetSupportedVideoCryptoSuites(std::vector<int>* crypto_suites, |
+ const MediaSessionOptions& options) { |
+ GetDefaultSrtpCryptoSuites(crypto_suites, options); |
} |
void GetSupportedVideoCryptoSuiteNames( |
- std::vector<std::string>* crypto_suite_names) { |
+ std::vector<std::string>* crypto_suite_names, |
+ const MediaSessionOptions& options) { |
GetSupportedCryptoSuiteNames(GetSupportedVideoCryptoSuites, |
- crypto_suite_names); |
+ crypto_suite_names, options); |
} |
-void GetSupportedDataCryptoSuites(std::vector<int>* crypto_suites) { |
- GetDefaultSrtpCryptoSuites(crypto_suites); |
+void GetSupportedDataCryptoSuites(std::vector<int>* crypto_suites, |
+ const MediaSessionOptions& options) { |
+ GetDefaultSrtpCryptoSuites(crypto_suites, options); |
} |
void GetSupportedDataCryptoSuiteNames( |
- std::vector<std::string>* crypto_suite_names) { |
+ std::vector<std::string>* crypto_suite_names, |
+ const MediaSessionOptions& options) { |
GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites, |
- crypto_suite_names); |
+ crypto_suite_names, options); |
} |
-void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites) { |
+void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites, |
+ const MediaSessionOptions& options) { |
#ifdef HAVE_SRTP |
+ if (options.enable_gcm_crypto_suites) { |
+ crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM); |
+ crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM); |
+ } |
crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); |
#endif |
} |
void GetDefaultSrtpCryptoSuiteNames( |
- std::vector<std::string>* crypto_suite_names) { |
- GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, crypto_suite_names); |
+ std::vector<std::string>* crypto_suite_names, |
+ const MediaSessionOptions& options) { |
+ GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, |
+ crypto_suite_names, options); |
} |
-// For video support only 80-bit SHA1 HMAC. For audio 32-bit HMAC is |
-// tolerated unless bundle is enabled because it is low overhead. Pick the |
-// crypto in the list that is supported. |
+// Support any GCM cipher (if enabled through options). For video support only |
+// 80-bit SHA1 HMAC. For audio 32-bit HMAC is tolerated unless bundle is enabled |
+// because it is low overhead. |
+// Pick the crypto in the list that is supported. |
static bool SelectCrypto(const MediaContentDescription* offer, |
bool bundle, |
+ const MediaSessionOptions& options, |
CryptoParams *crypto) { |
bool audio = offer->type() == MEDIA_TYPE_AUDIO; |
const CryptoParamsVec& cryptos = offer->cryptos(); |
for (CryptoParamsVec::const_iterator i = cryptos.begin(); |
i != cryptos.end(); ++i) { |
- if (rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || |
+ if ((options.enable_gcm_crypto_suites && |
+ rtc::IsGcmCryptoSuiteName(i->cipher_suite)) || |
+ rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || |
(rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && |
!bundle)) { |
return CreateCryptoParams(i->tag, i->cipher_suite, crypto); |
@@ -1051,7 +1083,7 @@ static bool CreateMediaContentAnswer( |
if (sdes_policy != SEC_DISABLED) { |
CryptoParams crypto; |
- if (SelectCrypto(offer, bundle_enabled, &crypto)) { |
+ if (SelectCrypto(offer, bundle_enabled, options, &crypto)) { |
if (current_cryptos) { |
FindMatchingCrypto(*current_cryptos, crypto, &crypto); |
} |
@@ -1562,7 +1594,7 @@ bool MediaSessionDescriptionFactory::AddAudioContentForOffer( |
scoped_ptr<AudioContentDescription> audio(new AudioContentDescription()); |
std::vector<std::string> crypto_suites; |
- GetSupportedAudioCryptoSuiteNames(&crypto_suites); |
+ GetSupportedAudioCryptoSuiteNames(&crypto_suites, options); |
if (!CreateMediaContentOffer( |
options, |
audio_codecs, |
@@ -1616,7 +1648,7 @@ bool MediaSessionDescriptionFactory::AddVideoContentForOffer( |
scoped_ptr<VideoContentDescription> video(new VideoContentDescription()); |
std::vector<std::string> crypto_suites; |
- GetSupportedVideoCryptoSuiteNames(&crypto_suites); |
+ GetSupportedVideoCryptoSuiteNames(&crypto_suites, options); |
if (!CreateMediaContentOffer( |
options, |
video_codecs, |
@@ -1686,7 +1718,7 @@ bool MediaSessionDescriptionFactory::AddDataContentForOffer( |
data->set_protocol( |
secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp); |
} else { |
- GetSupportedDataCryptoSuiteNames(&crypto_suites); |
+ GetSupportedDataCryptoSuiteNames(&crypto_suites, options); |
} |
if (!CreateMediaContentOffer( |