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

Side by Side Diff: talk/session/media/mediasession.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: Added PeerConnection tests using GCM ciphers, fixed passing of flag through DtlsTransportChannel. Created 5 years 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 * libjingle 2 * libjingle
3 * Copyright 2004 Google Inc. 3 * Copyright 2004 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 return false; 91 return false;
92 } 92 }
93 93
94 const MediaContentDescription* mdesc = 94 const MediaContentDescription* mdesc =
95 static_cast<const MediaContentDescription*>(content->description); 95 static_cast<const MediaContentDescription*>(content->description);
96 return mdesc && mdesc->type() == media_type; 96 return mdesc && mdesc->type() == media_type;
97 } 97 }
98 98
99 static bool CreateCryptoParams(int tag, const std::string& cipher, 99 static bool CreateCryptoParams(int tag, const std::string& cipher,
100 CryptoParams *out) { 100 CryptoParams *out) {
101 int key_len;
102 int salt_len;
103 if (!rtc::SrtpCryptoSuiteParams(
104 rtc::SrtpCryptoSuiteFromName(cipher), &key_len, &salt_len)) {
105 return false;
106 }
107
108 int master_key_base64_len = (key_len + salt_len) * 4 / 3;
109
101 std::string key; 110 std::string key;
102 key.reserve(SRTP_MASTER_KEY_BASE64_LEN); 111 key.reserve(master_key_base64_len);
103 112
104 if (!rtc::CreateRandomString(SRTP_MASTER_KEY_BASE64_LEN, &key)) { 113 if (!rtc::CreateRandomString(master_key_base64_len, &key)) {
105 return false; 114 return false;
106 } 115 }
107 out->tag = tag; 116 out->tag = tag;
108 out->cipher_suite = cipher; 117 out->cipher_suite = cipher;
109 out->key_params = kInline; 118 out->key_params = kInline;
110 out->key_params += key; 119 out->key_params += key;
111 return true; 120 return true;
112 } 121 }
113 122
114 #ifdef HAVE_SRTP 123 #ifdef HAVE_SRTP
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 for (CryptoParamsVec::const_iterator it = cryptos.begin(); 164 for (CryptoParamsVec::const_iterator it = cryptos.begin();
156 it != cryptos.end(); ++it) { 165 it != cryptos.end(); ++it) {
157 if (crypto.Matches(*it)) { 166 if (crypto.Matches(*it)) {
158 *out = *it; 167 *out = *it;
159 return true; 168 return true;
160 } 169 }
161 } 170 }
162 return false; 171 return false;
163 } 172 }
164 173
165 // For audio, HMAC 32 is prefered because of the low overhead. 174 void FilterGcmCiphers(std::vector<int>* crypto_suites) {
pthatcher1 2015/12/18 20:31:31 Can you break this up to be a bit more generic and
joachim 2015/12/19 15:26:23 Done. Implemented functions in sslstreamadapter (w
175 for (std::vector<int>::iterator it = crypto_suites->begin();
176 it != crypto_suites->end(); ) {
177 if (*it == rtc::SRTP_AEAD_AES_256_GCM ||
178 *it == rtc::SRTP_AEAD_AES_128_GCM) {
179 it = crypto_suites->erase(it);
180 } else {
181 ++it;
182 }
183 }
184 }
pthatcher1 2015/12/18 20:31:31 Then you can just remove this function and replace
joachim 2015/12/19 15:26:23 Done.
185
186 void FilterGcmCipherNames(std::vector<std::string>* crypto_suites) {
187 for (std::vector<std::string>::iterator it = crypto_suites->begin();
188 it != crypto_suites->end(); ) {
189 if (*it == rtc::CS_AEAD_AES_256_GCM ||
190 *it == rtc::CS_AEAD_AES_128_GCM) {
191 it = crypto_suites->erase(it);
192 } else {
193 ++it;
194 }
195 }
196 }
pthatcher1 2015/12/18 20:31:32 Similarly here: cipher_names.erase(std::remove_if
joachim 2015/12/19 15:26:23 Done.
197
198 // For audio, HMAC 32 is prefered over HMAC 80 because of the low overhead.
166 void GetSupportedAudioCryptoSuites(std::vector<int>* crypto_suites) { 199 void GetSupportedAudioCryptoSuites(std::vector<int>* crypto_suites) {
167 #ifdef HAVE_SRTP 200 #ifdef HAVE_SRTP
201 crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM);
202 crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM);
168 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32); 203 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32);
169 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); 204 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80);
170 #endif 205 #endif
171 } 206 }
172 207
173 void GetSupportedAudioCryptoSuiteNames( 208 void GetSupportedAudioCryptoSuiteNames(
174 std::vector<std::string>* crypto_suite_names) { 209 std::vector<std::string>* crypto_suite_names) {
175 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites, 210 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites,
176 crypto_suite_names); 211 crypto_suite_names);
177 } 212 }
(...skipping 13 matching lines...) Expand all
191 } 226 }
192 227
193 void GetSupportedDataCryptoSuiteNames( 228 void GetSupportedDataCryptoSuiteNames(
194 std::vector<std::string>* crypto_suite_names) { 229 std::vector<std::string>* crypto_suite_names) {
195 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites, 230 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites,
196 crypto_suite_names); 231 crypto_suite_names);
197 } 232 }
198 233
199 void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites) { 234 void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites) {
200 #ifdef HAVE_SRTP 235 #ifdef HAVE_SRTP
236 crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM);
237 crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM);
201 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); 238 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80);
202 #endif 239 #endif
203 } 240 }
204 241
205 void GetDefaultSrtpCryptoSuiteNames( 242 void GetDefaultSrtpCryptoSuiteNames(
206 std::vector<std::string>* crypto_suite_names) { 243 std::vector<std::string>* crypto_suite_names) {
207 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, crypto_suite_names); 244 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, crypto_suite_names);
208 } 245 }
209 246
210 // For video support only 80-bit SHA1 HMAC. For audio 32-bit HMAC is 247 // Support any GCM cipher (if enabled through options). For video support only
211 // tolerated unless bundle is enabled because it is low overhead. Pick the 248 // 80-bit SHA1 HMAC. For audio 32-bit HMAC is tolerated unless bundle is enabled
212 // crypto in the list that is supported. 249 // because it is low overhead.
250 // Pick the crypto in the list that is supported.
213 static bool SelectCrypto(const MediaContentDescription* offer, 251 static bool SelectCrypto(const MediaContentDescription* offer,
214 bool bundle, 252 bool bundle,
253 const MediaSessionOptions& options,
215 CryptoParams *crypto) { 254 CryptoParams *crypto) {
216 bool audio = offer->type() == MEDIA_TYPE_AUDIO; 255 bool audio = offer->type() == MEDIA_TYPE_AUDIO;
217 const CryptoParamsVec& cryptos = offer->cryptos(); 256 const CryptoParamsVec& cryptos = offer->cryptos();
218 257
219 for (CryptoParamsVec::const_iterator i = cryptos.begin(); 258 for (CryptoParamsVec::const_iterator i = cryptos.begin();
220 i != cryptos.end(); ++i) { 259 i != cryptos.end(); ++i) {
221 if (rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || 260 if ((options.enable_gcm_ciphers &&
261 (rtc::CS_AEAD_AES_256_GCM == i->cipher_suite ||
262 rtc::CS_AEAD_AES_128_GCM == i->cipher_suite)) ||
pthatcher1 2015/12/18 20:31:31 IsGcmCipherName or IsGcmCryptoSuite would be usefu
joachim 2015/12/19 15:26:23 Done.
263 rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite ||
222 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && 264 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio &&
223 !bundle)) { 265 !bundle)) {
pthatcher1 2015/12/18 20:31:32 Actually this, method seems to duplicate a lot wit
joachim 2015/12/19 15:26:23 Done.
224 return CreateCryptoParams(i->tag, i->cipher_suite, crypto); 266 return CreateCryptoParams(i->tag, i->cipher_suite, crypto);
225 } 267 }
226 } 268 }
227 return false; 269 return false;
228 } 270 }
229 271
230 static const StreamParams* FindFirstStreamParamsByCname( 272 static const StreamParams* FindFirstStreamParamsByCname(
231 const StreamParamsVec& params_vec, 273 const StreamParamsVec& params_vec,
232 const std::string& cname) { 274 const std::string& cname) {
233 for (StreamParamsVec::const_iterator it = params_vec.begin(); 275 for (StreamParamsVec::const_iterator it = params_vec.begin();
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 1086
1045 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux()); 1087 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux());
1046 // TODO(deadbeef): Once we're sure this works correctly, enable it in 1088 // TODO(deadbeef): Once we're sure this works correctly, enable it in
1047 // CreateAnswer. 1089 // CreateAnswer.
1048 // if (answer->type() == cricket::MEDIA_TYPE_VIDEO) { 1090 // if (answer->type() == cricket::MEDIA_TYPE_VIDEO) {
1049 // answer->set_rtcp_reduced_size(offer->rtcp_reduced_size()); 1091 // answer->set_rtcp_reduced_size(offer->rtcp_reduced_size());
1050 // } 1092 // }
1051 1093
1052 if (sdes_policy != SEC_DISABLED) { 1094 if (sdes_policy != SEC_DISABLED) {
1053 CryptoParams crypto; 1095 CryptoParams crypto;
1054 if (SelectCrypto(offer, bundle_enabled, &crypto)) { 1096 if (SelectCrypto(offer, bundle_enabled, options, &crypto)) {
1055 if (current_cryptos) { 1097 if (current_cryptos) {
1056 FindMatchingCrypto(*current_cryptos, crypto, &crypto); 1098 FindMatchingCrypto(*current_cryptos, crypto, &crypto);
1057 } 1099 }
1058 answer->AddCrypto(crypto); 1100 answer->AddCrypto(crypto);
1059 } 1101 }
1060 } 1102 }
1061 1103
1062 if (answer->cryptos().empty() && 1104 if (answer->cryptos().empty() &&
1063 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) { 1105 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) {
1064 return false; 1106 return false;
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
1556 const AudioCodecs& audio_codecs, 1598 const AudioCodecs& audio_codecs,
1557 StreamParamsVec* current_streams, 1599 StreamParamsVec* current_streams,
1558 SessionDescription* desc) const { 1600 SessionDescription* desc) const {
1559 cricket::SecurePolicy sdes_policy = 1601 cricket::SecurePolicy sdes_policy =
1560 IsDtlsActive(CN_AUDIO, current_description) ? 1602 IsDtlsActive(CN_AUDIO, current_description) ?
1561 cricket::SEC_DISABLED : secure(); 1603 cricket::SEC_DISABLED : secure();
1562 1604
1563 scoped_ptr<AudioContentDescription> audio(new AudioContentDescription()); 1605 scoped_ptr<AudioContentDescription> audio(new AudioContentDescription());
1564 std::vector<std::string> crypto_suites; 1606 std::vector<std::string> crypto_suites;
1565 GetSupportedAudioCryptoSuiteNames(&crypto_suites); 1607 GetSupportedAudioCryptoSuiteNames(&crypto_suites);
1608 if (!options.enable_gcm_ciphers) {
pthatcher1 2015/12/18 20:31:32 Instead of filtering, can we pass options into Get
joachim 2015/12/19 15:26:23 Done.
1609 FilterGcmCipherNames(&crypto_suites);
1610 }
1566 if (!CreateMediaContentOffer( 1611 if (!CreateMediaContentOffer(
1567 options, 1612 options,
1568 audio_codecs, 1613 audio_codecs,
1569 sdes_policy, 1614 sdes_policy,
1570 GetCryptos(GetFirstAudioContentDescription(current_description)), 1615 GetCryptos(GetFirstAudioContentDescription(current_description)),
1571 crypto_suites, 1616 crypto_suites,
1572 audio_rtp_extensions, 1617 audio_rtp_extensions,
1573 add_legacy_, 1618 add_legacy_,
1574 current_streams, 1619 current_streams,
1575 audio.get())) { 1620 audio.get())) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1610 const VideoCodecs& video_codecs, 1655 const VideoCodecs& video_codecs,
1611 StreamParamsVec* current_streams, 1656 StreamParamsVec* current_streams,
1612 SessionDescription* desc) const { 1657 SessionDescription* desc) const {
1613 cricket::SecurePolicy sdes_policy = 1658 cricket::SecurePolicy sdes_policy =
1614 IsDtlsActive(CN_VIDEO, current_description) ? 1659 IsDtlsActive(CN_VIDEO, current_description) ?
1615 cricket::SEC_DISABLED : secure(); 1660 cricket::SEC_DISABLED : secure();
1616 1661
1617 scoped_ptr<VideoContentDescription> video(new VideoContentDescription()); 1662 scoped_ptr<VideoContentDescription> video(new VideoContentDescription());
1618 std::vector<std::string> crypto_suites; 1663 std::vector<std::string> crypto_suites;
1619 GetSupportedVideoCryptoSuiteNames(&crypto_suites); 1664 GetSupportedVideoCryptoSuiteNames(&crypto_suites);
1665 if (!options.enable_gcm_ciphers) {
1666 FilterGcmCipherNames(&crypto_suites);
1667 }
pthatcher1 2015/12/18 20:31:32 Instead of filtering, can we pass options into Get
joachim 2015/12/19 15:26:23 Done.
1620 if (!CreateMediaContentOffer( 1668 if (!CreateMediaContentOffer(
1621 options, 1669 options,
1622 video_codecs, 1670 video_codecs,
1623 sdes_policy, 1671 sdes_policy,
1624 GetCryptos(GetFirstVideoContentDescription(current_description)), 1672 GetCryptos(GetFirstVideoContentDescription(current_description)),
1625 crypto_suites, 1673 crypto_suites,
1626 video_rtp_extensions, 1674 video_rtp_extensions,
1627 add_legacy_, 1675 add_legacy_,
1628 current_streams, 1676 current_streams,
1629 video.get())) { 1677 video.get())) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 // get SDES crypto suites for RTP-based data channels. 1728 // get SDES crypto suites for RTP-based data channels.
1681 sdes_policy = cricket::SEC_DISABLED; 1729 sdes_policy = cricket::SEC_DISABLED;
1682 // Unlike SetMediaProtocol below, we need to set the protocol 1730 // Unlike SetMediaProtocol below, we need to set the protocol
1683 // before we call CreateMediaContentOffer. Otherwise, 1731 // before we call CreateMediaContentOffer. Otherwise,
1684 // CreateMediaContentOffer won't know this is SCTP and will 1732 // CreateMediaContentOffer won't know this is SCTP and will
1685 // generate SSRCs rather than SIDs. 1733 // generate SSRCs rather than SIDs.
1686 data->set_protocol( 1734 data->set_protocol(
1687 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp); 1735 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp);
1688 } else { 1736 } else {
1689 GetSupportedDataCryptoSuiteNames(&crypto_suites); 1737 GetSupportedDataCryptoSuiteNames(&crypto_suites);
1738 if (!options.enable_gcm_ciphers) {
1739 FilterGcmCipherNames(&crypto_suites);
1740 }
1690 } 1741 }
1691 1742
1692 if (!CreateMediaContentOffer( 1743 if (!CreateMediaContentOffer(
1693 options, 1744 options,
1694 *data_codecs, 1745 *data_codecs,
1695 sdes_policy, 1746 sdes_policy,
1696 GetCryptos(GetFirstDataContentDescription(current_description)), 1747 GetCryptos(GetFirstDataContentDescription(current_description)),
1697 crypto_suites, 1748 crypto_suites,
1698 RtpHeaderExtensions(), 1749 RtpHeaderExtensions(),
1699 add_legacy_, 1750 add_legacy_,
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); 2023 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO));
1973 } 2024 }
1974 2025
1975 const DataContentDescription* GetFirstDataContentDescription( 2026 const DataContentDescription* GetFirstDataContentDescription(
1976 const SessionDescription* sdesc) { 2027 const SessionDescription* sdesc) {
1977 return static_cast<const DataContentDescription*>( 2028 return static_cast<const DataContentDescription*>(
1978 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); 2029 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA));
1979 } 2030 }
1980 2031
1981 } // namespace cricket 2032 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698