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

Side by Side Diff: net/quic/crypto/crypto_utils.cc

Issue 1904213002: QUIC: support diversified keys with version 33. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@hkdf
Patch Set: Rebase Created 4 years, 8 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
« no previous file with comments | « net/quic/crypto/crypto_utils.h ('k') | net/quic/crypto/null_decrypter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/crypto/crypto_utils.h" 5 #include "net/quic/crypto/crypto_utils.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "crypto/hkdf.h" 9 #include "crypto/hkdf.h"
10 #include "crypto/secure_hash.h" 10 #include "crypto/secure_hash.h"
11 #include "net/base/url_util.h" 11 #include "net/base/url_util.h"
12 #include "net/quic/crypto/crypto_handshake.h" 12 #include "net/quic/crypto/crypto_handshake.h"
13 #include "net/quic/crypto/crypto_protocol.h" 13 #include "net/quic/crypto/crypto_protocol.h"
14 #include "net/quic/crypto/quic_decrypter.h" 14 #include "net/quic/crypto/quic_decrypter.h"
15 #include "net/quic/crypto/quic_encrypter.h" 15 #include "net/quic/crypto/quic_encrypter.h"
16 #include "net/quic/crypto/quic_random.h" 16 #include "net/quic/crypto/quic_random.h"
17 #include "net/quic/quic_bug_tracker.h"
17 #include "net/quic/quic_time.h" 18 #include "net/quic/quic_time.h"
18 #include "net/quic/quic_utils.h" 19 #include "net/quic/quic_utils.h"
19 #include "url/url_canon.h" 20 #include "url/url_canon.h"
20 21
21 using base::StringPiece; 22 using base::StringPiece;
22 using std::numeric_limits; 23 using std::numeric_limits;
23 using std::string; 24 using std::string;
24 25
25 namespace net { 26 namespace net {
26 27
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 return host; 84 return host;
84 } 85 }
85 86
86 // static 87 // static
87 bool CryptoUtils::DeriveKeys(StringPiece premaster_secret, 88 bool CryptoUtils::DeriveKeys(StringPiece premaster_secret,
88 QuicTag aead, 89 QuicTag aead,
89 StringPiece client_nonce, 90 StringPiece client_nonce,
90 StringPiece server_nonce, 91 StringPiece server_nonce,
91 const string& hkdf_input, 92 const string& hkdf_input,
92 Perspective perspective, 93 Perspective perspective,
94 Diversification diversification,
93 CrypterPair* crypters, 95 CrypterPair* crypters,
94 string* subkey_secret) { 96 string* subkey_secret) {
95 crypters->encrypter.reset(QuicEncrypter::Create(aead)); 97 crypters->encrypter.reset(QuicEncrypter::Create(aead));
96 crypters->decrypter.reset(QuicDecrypter::Create(aead)); 98 crypters->decrypter.reset(QuicDecrypter::Create(aead));
97 size_t key_bytes = crypters->encrypter->GetKeySize(); 99 size_t key_bytes = crypters->encrypter->GetKeySize();
98 size_t nonce_prefix_bytes = crypters->encrypter->GetNoncePrefixSize(); 100 size_t nonce_prefix_bytes = crypters->encrypter->GetNoncePrefixSize();
99 size_t subkey_secret_bytes = 101 size_t subkey_secret_bytes =
100 subkey_secret == nullptr ? 0 : premaster_secret.length(); 102 subkey_secret == nullptr ? 0 : premaster_secret.length();
101 103
102 StringPiece nonce = client_nonce; 104 StringPiece nonce = client_nonce;
103 string nonce_storage; 105 string nonce_storage;
104 if (!server_nonce.empty()) { 106 if (!server_nonce.empty()) {
105 nonce_storage = client_nonce.as_string() + server_nonce.as_string(); 107 nonce_storage = client_nonce.as_string() + server_nonce.as_string();
106 nonce = nonce_storage; 108 nonce = nonce_storage;
107 } 109 }
108 110
109 crypto::HKDF hkdf(premaster_secret, nonce, hkdf_input, key_bytes, 111 crypto::HKDF hkdf(premaster_secret, nonce, hkdf_input, key_bytes,
110 nonce_prefix_bytes, subkey_secret_bytes); 112 nonce_prefix_bytes, subkey_secret_bytes);
111 if (perspective == Perspective::IS_SERVER) { 113
112 if (!crypters->encrypter->SetKey(hkdf.server_write_key()) || 114 // Key derivation depends on the key diversification method being employed.
113 !crypters->encrypter->SetNoncePrefix(hkdf.server_write_iv()) || 115 // both the client and the server support never doing key diversification.
114 !crypters->decrypter->SetKey(hkdf.client_write_key()) || 116 // The server also supports immediate diversification, and the client
115 !crypters->decrypter->SetNoncePrefix(hkdf.client_write_iv())) { 117 // supports pending diversification.
116 return false; 118 switch (diversification.mode()) {
119 case Diversification::NEVER: {
120 if (perspective == Perspective::IS_SERVER) {
121 if (!crypters->encrypter->SetKey(hkdf.server_write_key()) ||
122 !crypters->encrypter->SetNoncePrefix(hkdf.server_write_iv()) ||
123 !crypters->decrypter->SetKey(hkdf.client_write_key()) ||
124 !crypters->decrypter->SetNoncePrefix(hkdf.client_write_iv())) {
125 return false;
126 }
127 } else {
128 if (!crypters->encrypter->SetKey(hkdf.client_write_key()) ||
129 !crypters->encrypter->SetNoncePrefix(hkdf.client_write_iv()) ||
130 !crypters->decrypter->SetKey(hkdf.server_write_key()) ||
131 !crypters->decrypter->SetNoncePrefix(hkdf.server_write_iv())) {
132 return false;
133 }
134 }
135 break;
117 } 136 }
118 } else { 137 case Diversification::PENDING: {
119 if (!crypters->encrypter->SetKey(hkdf.client_write_key()) || 138 if (perspective == Perspective::IS_SERVER) {
120 !crypters->encrypter->SetNoncePrefix(hkdf.client_write_iv()) || 139 QUIC_BUG << "Pending diversification is only for clients.";
121 !crypters->decrypter->SetKey(hkdf.server_write_key()) || 140 return false;
122 !crypters->decrypter->SetNoncePrefix(hkdf.server_write_iv())) { 141 }
123 return false; 142
143 if (!crypters->encrypter->SetKey(hkdf.client_write_key()) ||
144 !crypters->encrypter->SetNoncePrefix(hkdf.client_write_iv()) ||
145 !crypters->decrypter->SetPreliminaryKey(hkdf.server_write_key()) ||
146 !crypters->decrypter->SetNoncePrefix(hkdf.server_write_iv())) {
147 return false;
148 }
149 break;
124 } 150 }
151 case Diversification::NOW: {
152 if (perspective == Perspective::IS_CLIENT) {
153 QUIC_BUG << "Immediate diversification is only for servers.";
154 return false;
155 }
156
157 string key, nonce_prefix;
158 QuicDecrypter::DiversifyPreliminaryKey(
159 hkdf.server_write_key(), hkdf.server_write_iv(),
160 *diversification.nonce(), key_bytes, nonce_prefix_bytes, &key,
161 &nonce_prefix);
162 if (!crypters->decrypter->SetKey(hkdf.client_write_key()) ||
163 !crypters->decrypter->SetNoncePrefix(hkdf.client_write_iv()) ||
164 !crypters->encrypter->SetKey(key) ||
165 !crypters->encrypter->SetNoncePrefix(nonce_prefix)) {
166 return false;
167 }
168 break;
169 }
170 default:
171 DCHECK(false);
125 } 172 }
173
126 if (subkey_secret != nullptr) { 174 if (subkey_secret != nullptr) {
127 hkdf.subkey_secret().CopyToString(subkey_secret); 175 hkdf.subkey_secret().CopyToString(subkey_secret);
128 } 176 }
129 177
130 return true; 178 return true;
131 } 179 }
132 180
133 // static 181 // static
134 bool CryptoUtils::ExportKeyingMaterial(StringPiece subkey_secret, 182 bool CryptoUtils::ExportKeyingMaterial(StringPiece subkey_secret,
135 StringPiece label, 183 StringPiece label,
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 const QuicData& serialized = message.GetSerialized(); 331 const QuicData& serialized = message.GetSerialized();
284 std::unique_ptr<crypto::SecureHash> hash( 332 std::unique_ptr<crypto::SecureHash> hash(
285 crypto::SecureHash::Create(crypto::SecureHash::SHA256)); 333 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
286 hash->Update(serialized.data(), serialized.length()); 334 hash->Update(serialized.data(), serialized.length());
287 uint8_t digest[32]; 335 uint8_t digest[32];
288 hash->Finish(digest, sizeof(digest)); 336 hash->Finish(digest, sizeof(digest));
289 output->assign(reinterpret_cast<const char*>(&digest), sizeof(digest)); 337 output->assign(reinterpret_cast<const char*>(&digest), sizeof(digest));
290 } 338 }
291 339
292 } // namespace net 340 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/crypto/crypto_utils.h ('k') | net/quic/crypto/null_decrypter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698