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

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: Updates after feedback from Peter 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 44
45 #ifdef HAVE_SCTP 45 #ifdef HAVE_SCTP
46 #include "talk/media/sctp/sctpdataengine.h" 46 #include "talk/media/sctp/sctpdataengine.h"
47 #else 47 #else
48 static const uint32_t kMaxSctpSid = 1023; 48 static const uint32_t kMaxSctpSid = 1023;
49 #endif 49 #endif
50 50
51 namespace { 51 namespace {
52 const char kInline[] = "inline:"; 52 const char kInline[] = "inline:";
53 53
54 void GetSupportedCryptoSuiteNames(void (*func)(std::vector<int>*), 54 void GetSupportedCryptoSuiteNames(void (*func)(std::vector<int>*,
55 std::vector<std::string>* names) { 55 const cricket::MediaSessionOptions&),
56 std::vector<std::string>* names,
57 const cricket::MediaSessionOptions& options) {
56 #ifdef HAVE_SRTP 58 #ifdef HAVE_SRTP
57 std::vector<int> crypto_suites; 59 std::vector<int> crypto_suites;
58 func(&crypto_suites); 60 func(&crypto_suites, options);
59 for (const auto crypto : crypto_suites) { 61 for (const auto crypto : crypto_suites) {
60 names->push_back(rtc::SrtpCryptoSuiteToName(crypto)); 62 names->push_back(rtc::SrtpCryptoSuiteToName(crypto));
61 } 63 }
62 #endif 64 #endif
63 } 65 }
64 } 66 }
65 67
66 namespace cricket { 68 namespace cricket {
67 69
68 using rtc::scoped_ptr; 70 using rtc::scoped_ptr;
(...skipping 22 matching lines...) Expand all
91 return false; 93 return false;
92 } 94 }
93 95
94 const MediaContentDescription* mdesc = 96 const MediaContentDescription* mdesc =
95 static_cast<const MediaContentDescription*>(content->description); 97 static_cast<const MediaContentDescription*>(content->description);
96 return mdesc && mdesc->type() == media_type; 98 return mdesc && mdesc->type() == media_type;
97 } 99 }
98 100
99 static bool CreateCryptoParams(int tag, const std::string& cipher, 101 static bool CreateCryptoParams(int tag, const std::string& cipher,
100 CryptoParams *out) { 102 CryptoParams *out) {
103 int key_len;
104 int salt_len;
105 if (!rtc::GetSrtpKeyAndSaltLengths(
106 rtc::SrtpCryptoSuiteFromName(cipher), &key_len, &salt_len)) {
107 return false;
108 }
109
110 int master_key_base64_len = (key_len + salt_len) * 4 / 3;
111
101 std::string key; 112 std::string key;
102 key.reserve(SRTP_MASTER_KEY_BASE64_LEN); 113 key.reserve(master_key_base64_len);
103 114
104 if (!rtc::CreateRandomString(SRTP_MASTER_KEY_BASE64_LEN, &key)) { 115 if (!rtc::CreateRandomString(master_key_base64_len, &key)) {
105 return false; 116 return false;
106 } 117 }
107 out->tag = tag; 118 out->tag = tag;
108 out->cipher_suite = cipher; 119 out->cipher_suite = cipher;
109 out->key_params = kInline; 120 out->key_params = kInline;
110 out->key_params += key; 121 out->key_params += key;
111 return true; 122 return true;
112 } 123 }
113 124
114 #ifdef HAVE_SRTP 125 #ifdef HAVE_SRTP
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 for (CryptoParamsVec::const_iterator it = cryptos.begin(); 166 for (CryptoParamsVec::const_iterator it = cryptos.begin();
156 it != cryptos.end(); ++it) { 167 it != cryptos.end(); ++it) {
157 if (crypto.Matches(*it)) { 168 if (crypto.Matches(*it)) {
158 *out = *it; 169 *out = *it;
159 return true; 170 return true;
160 } 171 }
161 } 172 }
162 return false; 173 return false;
163 } 174 }
164 175
165 // For audio, HMAC 32 is prefered because of the low overhead. 176 // For audio, HMAC 32 is prefered over HMAC 80 because of the low overhead.
166 void GetSupportedAudioCryptoSuites(std::vector<int>* crypto_suites) { 177 void GetSupportedAudioCryptoSuites(std::vector<int>* crypto_suites,
178 const MediaSessionOptions& options) {
167 #ifdef HAVE_SRTP 179 #ifdef HAVE_SRTP
180 if (options.enable_gcm_crypto_suites) {
181 crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM);
182 crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM);
183 }
168 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32); 184 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32);
169 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); 185 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80);
170 #endif 186 #endif
171 } 187 }
172 188
173 void GetSupportedAudioCryptoSuiteNames( 189 void GetSupportedAudioCryptoSuiteNames(
174 std::vector<std::string>* crypto_suite_names) { 190 std::vector<std::string>* crypto_suite_names,
191 const MediaSessionOptions& options) {
175 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites, 192 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites,
176 crypto_suite_names); 193 crypto_suite_names, options);
177 } 194 }
178 195
179 void GetSupportedVideoCryptoSuites(std::vector<int>* crypto_suites) { 196 void GetSupportedVideoCryptoSuites(std::vector<int>* crypto_suites,
180 GetDefaultSrtpCryptoSuites(crypto_suites); 197 const MediaSessionOptions& options) {
198 GetDefaultSrtpCryptoSuites(crypto_suites, options);
181 } 199 }
182 200
183 void GetSupportedVideoCryptoSuiteNames( 201 void GetSupportedVideoCryptoSuiteNames(
184 std::vector<std::string>* crypto_suite_names) { 202 std::vector<std::string>* crypto_suite_names,
203 const MediaSessionOptions& options) {
185 GetSupportedCryptoSuiteNames(GetSupportedVideoCryptoSuites, 204 GetSupportedCryptoSuiteNames(GetSupportedVideoCryptoSuites,
186 crypto_suite_names); 205 crypto_suite_names, options);
187 } 206 }
188 207
189 void GetSupportedDataCryptoSuites(std::vector<int>* crypto_suites) { 208 void GetSupportedDataCryptoSuites(std::vector<int>* crypto_suites,
190 GetDefaultSrtpCryptoSuites(crypto_suites); 209 const MediaSessionOptions& options) {
210 GetDefaultSrtpCryptoSuites(crypto_suites, options);
191 } 211 }
192 212
193 void GetSupportedDataCryptoSuiteNames( 213 void GetSupportedDataCryptoSuiteNames(
194 std::vector<std::string>* crypto_suite_names) { 214 std::vector<std::string>* crypto_suite_names,
215 const MediaSessionOptions& options) {
195 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites, 216 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites,
196 crypto_suite_names); 217 crypto_suite_names, options);
197 } 218 }
198 219
199 void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites) { 220 void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites,
221 const MediaSessionOptions& options) {
200 #ifdef HAVE_SRTP 222 #ifdef HAVE_SRTP
223 if (options.enable_gcm_crypto_suites) {
224 crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM);
225 crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM);
226 }
201 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); 227 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80);
202 #endif 228 #endif
203 } 229 }
204 230
205 void GetDefaultSrtpCryptoSuiteNames( 231 void GetDefaultSrtpCryptoSuiteNames(
206 std::vector<std::string>* crypto_suite_names) { 232 std::vector<std::string>* crypto_suite_names,
207 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, crypto_suite_names); 233 const MediaSessionOptions& options) {
234 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites,
235 crypto_suite_names, options);
208 } 236 }
209 237
210 // For video support only 80-bit SHA1 HMAC. For audio 32-bit HMAC is 238 // 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 239 // 80-bit SHA1 HMAC. For audio 32-bit HMAC is tolerated unless bundle is enabled
212 // crypto in the list that is supported. 240 // because it is low overhead.
241 // Pick the crypto in the list that is supported.
213 static bool SelectCrypto(const MediaContentDescription* offer, 242 static bool SelectCrypto(const MediaContentDescription* offer,
214 bool bundle, 243 bool bundle,
244 const MediaSessionOptions& options,
215 CryptoParams *crypto) { 245 CryptoParams *crypto) {
216 bool audio = offer->type() == MEDIA_TYPE_AUDIO; 246 bool audio = offer->type() == MEDIA_TYPE_AUDIO;
217 const CryptoParamsVec& cryptos = offer->cryptos(); 247 const CryptoParamsVec& cryptos = offer->cryptos();
218 248
219 for (CryptoParamsVec::const_iterator i = cryptos.begin(); 249 for (CryptoParamsVec::const_iterator i = cryptos.begin();
220 i != cryptos.end(); ++i) { 250 i != cryptos.end(); ++i) {
221 if (rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || 251 if ((options.enable_gcm_crypto_suites &&
252 rtc::IsGcmCryptoSuiteName(i->cipher_suite)) ||
253 rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite ||
222 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && 254 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio &&
223 !bundle)) { 255 !bundle)) {
224 return CreateCryptoParams(i->tag, i->cipher_suite, crypto); 256 return CreateCryptoParams(i->tag, i->cipher_suite, crypto);
225 } 257 }
226 } 258 }
227 return false; 259 return false;
228 } 260 }
229 261
230 static const StreamParams* FindFirstStreamParamsByCname( 262 static const StreamParams* FindFirstStreamParamsByCname(
231 const StreamParamsVec& params_vec, 263 const StreamParamsVec& params_vec,
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 1076
1045 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux()); 1077 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux());
1046 // TODO(deadbeef): Once we're sure this works correctly, enable it in 1078 // TODO(deadbeef): Once we're sure this works correctly, enable it in
1047 // CreateAnswer. 1079 // CreateAnswer.
1048 // if (answer->type() == cricket::MEDIA_TYPE_VIDEO) { 1080 // if (answer->type() == cricket::MEDIA_TYPE_VIDEO) {
1049 // answer->set_rtcp_reduced_size(offer->rtcp_reduced_size()); 1081 // answer->set_rtcp_reduced_size(offer->rtcp_reduced_size());
1050 // } 1082 // }
1051 1083
1052 if (sdes_policy != SEC_DISABLED) { 1084 if (sdes_policy != SEC_DISABLED) {
1053 CryptoParams crypto; 1085 CryptoParams crypto;
1054 if (SelectCrypto(offer, bundle_enabled, &crypto)) { 1086 if (SelectCrypto(offer, bundle_enabled, options, &crypto)) {
1055 if (current_cryptos) { 1087 if (current_cryptos) {
1056 FindMatchingCrypto(*current_cryptos, crypto, &crypto); 1088 FindMatchingCrypto(*current_cryptos, crypto, &crypto);
1057 } 1089 }
1058 answer->AddCrypto(crypto); 1090 answer->AddCrypto(crypto);
1059 } 1091 }
1060 } 1092 }
1061 1093
1062 if (answer->cryptos().empty() && 1094 if (answer->cryptos().empty() &&
1063 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) { 1095 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) {
1064 return false; 1096 return false;
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
1555 const RtpHeaderExtensions& audio_rtp_extensions, 1587 const RtpHeaderExtensions& audio_rtp_extensions,
1556 const AudioCodecs& audio_codecs, 1588 const AudioCodecs& audio_codecs,
1557 StreamParamsVec* current_streams, 1589 StreamParamsVec* current_streams,
1558 SessionDescription* desc) const { 1590 SessionDescription* desc) const {
1559 cricket::SecurePolicy sdes_policy = 1591 cricket::SecurePolicy sdes_policy =
1560 IsDtlsActive(CN_AUDIO, current_description) ? 1592 IsDtlsActive(CN_AUDIO, current_description) ?
1561 cricket::SEC_DISABLED : secure(); 1593 cricket::SEC_DISABLED : secure();
1562 1594
1563 scoped_ptr<AudioContentDescription> audio(new AudioContentDescription()); 1595 scoped_ptr<AudioContentDescription> audio(new AudioContentDescription());
1564 std::vector<std::string> crypto_suites; 1596 std::vector<std::string> crypto_suites;
1565 GetSupportedAudioCryptoSuiteNames(&crypto_suites); 1597 GetSupportedAudioCryptoSuiteNames(&crypto_suites, options);
1566 if (!CreateMediaContentOffer( 1598 if (!CreateMediaContentOffer(
1567 options, 1599 options,
1568 audio_codecs, 1600 audio_codecs,
1569 sdes_policy, 1601 sdes_policy,
1570 GetCryptos(GetFirstAudioContentDescription(current_description)), 1602 GetCryptos(GetFirstAudioContentDescription(current_description)),
1571 crypto_suites, 1603 crypto_suites,
1572 audio_rtp_extensions, 1604 audio_rtp_extensions,
1573 add_legacy_, 1605 add_legacy_,
1574 current_streams, 1606 current_streams,
1575 audio.get())) { 1607 audio.get())) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1609 const RtpHeaderExtensions& video_rtp_extensions, 1641 const RtpHeaderExtensions& video_rtp_extensions,
1610 const VideoCodecs& video_codecs, 1642 const VideoCodecs& video_codecs,
1611 StreamParamsVec* current_streams, 1643 StreamParamsVec* current_streams,
1612 SessionDescription* desc) const { 1644 SessionDescription* desc) const {
1613 cricket::SecurePolicy sdes_policy = 1645 cricket::SecurePolicy sdes_policy =
1614 IsDtlsActive(CN_VIDEO, current_description) ? 1646 IsDtlsActive(CN_VIDEO, current_description) ?
1615 cricket::SEC_DISABLED : secure(); 1647 cricket::SEC_DISABLED : secure();
1616 1648
1617 scoped_ptr<VideoContentDescription> video(new VideoContentDescription()); 1649 scoped_ptr<VideoContentDescription> video(new VideoContentDescription());
1618 std::vector<std::string> crypto_suites; 1650 std::vector<std::string> crypto_suites;
1619 GetSupportedVideoCryptoSuiteNames(&crypto_suites); 1651 GetSupportedVideoCryptoSuiteNames(&crypto_suites, options);
1620 if (!CreateMediaContentOffer( 1652 if (!CreateMediaContentOffer(
1621 options, 1653 options,
1622 video_codecs, 1654 video_codecs,
1623 sdes_policy, 1655 sdes_policy,
1624 GetCryptos(GetFirstVideoContentDescription(current_description)), 1656 GetCryptos(GetFirstVideoContentDescription(current_description)),
1625 crypto_suites, 1657 crypto_suites,
1626 video_rtp_extensions, 1658 video_rtp_extensions,
1627 add_legacy_, 1659 add_legacy_,
1628 current_streams, 1660 current_streams,
1629 video.get())) { 1661 video.get())) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 // SDES doesn't make sense for SCTP, so we disable it, and we only 1711 // SDES doesn't make sense for SCTP, so we disable it, and we only
1680 // get SDES crypto suites for RTP-based data channels. 1712 // get SDES crypto suites for RTP-based data channels.
1681 sdes_policy = cricket::SEC_DISABLED; 1713 sdes_policy = cricket::SEC_DISABLED;
1682 // Unlike SetMediaProtocol below, we need to set the protocol 1714 // Unlike SetMediaProtocol below, we need to set the protocol
1683 // before we call CreateMediaContentOffer. Otherwise, 1715 // before we call CreateMediaContentOffer. Otherwise,
1684 // CreateMediaContentOffer won't know this is SCTP and will 1716 // CreateMediaContentOffer won't know this is SCTP and will
1685 // generate SSRCs rather than SIDs. 1717 // generate SSRCs rather than SIDs.
1686 data->set_protocol( 1718 data->set_protocol(
1687 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp); 1719 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp);
1688 } else { 1720 } else {
1689 GetSupportedDataCryptoSuiteNames(&crypto_suites); 1721 GetSupportedDataCryptoSuiteNames(&crypto_suites, options);
1690 } 1722 }
1691 1723
1692 if (!CreateMediaContentOffer( 1724 if (!CreateMediaContentOffer(
1693 options, 1725 options,
1694 *data_codecs, 1726 *data_codecs,
1695 sdes_policy, 1727 sdes_policy,
1696 GetCryptos(GetFirstDataContentDescription(current_description)), 1728 GetCryptos(GetFirstDataContentDescription(current_description)),
1697 crypto_suites, 1729 crypto_suites,
1698 RtpHeaderExtensions(), 1730 RtpHeaderExtensions(),
1699 add_legacy_, 1731 add_legacy_,
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); 2004 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO));
1973 } 2005 }
1974 2006
1975 const DataContentDescription* GetFirstDataContentDescription( 2007 const DataContentDescription* GetFirstDataContentDescription(
1976 const SessionDescription* sdesc) { 2008 const SessionDescription* sdesc) {
1977 return static_cast<const DataContentDescription*>( 2009 return static_cast<const DataContentDescription*>(
1978 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); 2010 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA));
1979 } 2011 }
1980 2012
1981 } // namespace cricket 2013 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698