| OLD | NEW |
| 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/core/crypto/crypto_utils.h" | 5 #include "net/quic/core/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 "net/quic/core/crypto/crypto_handshake.h" | 10 #include "net/quic/core/crypto/crypto_handshake.h" |
| 11 #include "net/quic/core/crypto/crypto_protocol.h" | 11 #include "net/quic/core/crypto/crypto_protocol.h" |
| 12 #include "net/quic/core/crypto/quic_decrypter.h" | 12 #include "net/quic/core/crypto/quic_decrypter.h" |
| 13 #include "net/quic/core/crypto/quic_encrypter.h" | 13 #include "net/quic/core/crypto/quic_encrypter.h" |
| 14 #include "net/quic/core/crypto/quic_random.h" | 14 #include "net/quic/core/crypto/quic_random.h" |
| 15 #include "net/quic/core/quic_time.h" | 15 #include "net/quic/core/quic_time.h" |
| 16 #include "net/quic/core/quic_utils.h" | 16 #include "net/quic/core/quic_utils.h" |
| 17 #include "net/quic/platform/api/quic_bug_tracker.h" | 17 #include "net/quic/platform/api/quic_bug_tracker.h" |
| 18 #include "net/quic/platform/api/quic_logging.h" | 18 #include "net/quic/platform/api/quic_logging.h" |
| 19 #include "third_party/boringssl/src/include/openssl/sha.h" | 19 #include "third_party/boringssl/src/include/openssl/sha.h" |
| 20 | 20 |
| 21 using base::StringPiece; | |
| 22 using std::string; | 21 using std::string; |
| 23 | 22 |
| 24 namespace net { | 23 namespace net { |
| 25 | 24 |
| 26 // static | 25 // static |
| 27 void CryptoUtils::GenerateNonce(QuicWallTime now, | 26 void CryptoUtils::GenerateNonce(QuicWallTime now, |
| 28 QuicRandom* random_generator, | 27 QuicRandom* random_generator, |
| 29 StringPiece orbit, | 28 QuicStringPiece orbit, |
| 30 string* nonce) { | 29 string* nonce) { |
| 31 // a 4-byte timestamp + 28 random bytes. | 30 // a 4-byte timestamp + 28 random bytes. |
| 32 nonce->reserve(kNonceSize); | 31 nonce->reserve(kNonceSize); |
| 33 nonce->resize(kNonceSize); | 32 nonce->resize(kNonceSize); |
| 34 | 33 |
| 35 uint32_t gmt_unix_time = static_cast<uint32_t>(now.ToUNIXSeconds()); | 34 uint32_t gmt_unix_time = static_cast<uint32_t>(now.ToUNIXSeconds()); |
| 36 // The time in the nonce must be encoded in big-endian because the | 35 // The time in the nonce must be encoded in big-endian because the |
| 37 // strike-register depends on the nonces being ordered by time. | 36 // strike-register depends on the nonces being ordered by time. |
| 38 (*nonce)[0] = static_cast<char>(gmt_unix_time >> 24); | 37 (*nonce)[0] = static_cast<char>(gmt_unix_time >> 24); |
| 39 (*nonce)[1] = static_cast<char>(gmt_unix_time >> 16); | 38 (*nonce)[1] = static_cast<char>(gmt_unix_time >> 16); |
| 40 (*nonce)[2] = static_cast<char>(gmt_unix_time >> 8); | 39 (*nonce)[2] = static_cast<char>(gmt_unix_time >> 8); |
| 41 (*nonce)[3] = static_cast<char>(gmt_unix_time); | 40 (*nonce)[3] = static_cast<char>(gmt_unix_time); |
| 42 size_t bytes_written = 4; | 41 size_t bytes_written = 4; |
| 43 | 42 |
| 44 if (orbit.size() == 8) { | 43 if (orbit.size() == 8) { |
| 45 memcpy(&(*nonce)[bytes_written], orbit.data(), orbit.size()); | 44 memcpy(&(*nonce)[bytes_written], orbit.data(), orbit.size()); |
| 46 bytes_written += orbit.size(); | 45 bytes_written += orbit.size(); |
| 47 } | 46 } |
| 48 | 47 |
| 49 random_generator->RandBytes(&(*nonce)[bytes_written], | 48 random_generator->RandBytes(&(*nonce)[bytes_written], |
| 50 kNonceSize - bytes_written); | 49 kNonceSize - bytes_written); |
| 51 } | 50 } |
| 52 | 51 |
| 53 // static | 52 // static |
| 54 bool CryptoUtils::DeriveKeys(StringPiece premaster_secret, | 53 bool CryptoUtils::DeriveKeys(QuicStringPiece premaster_secret, |
| 55 QuicTag aead, | 54 QuicTag aead, |
| 56 StringPiece client_nonce, | 55 QuicStringPiece client_nonce, |
| 57 StringPiece server_nonce, | 56 QuicStringPiece server_nonce, |
| 58 const string& hkdf_input, | 57 const string& hkdf_input, |
| 59 Perspective perspective, | 58 Perspective perspective, |
| 60 Diversification diversification, | 59 Diversification diversification, |
| 61 CrypterPair* crypters, | 60 CrypterPair* crypters, |
| 62 string* subkey_secret) { | 61 string* subkey_secret) { |
| 63 crypters->encrypter.reset(QuicEncrypter::Create(aead)); | 62 crypters->encrypter.reset(QuicEncrypter::Create(aead)); |
| 64 crypters->decrypter.reset(QuicDecrypter::Create(aead)); | 63 crypters->decrypter.reset(QuicDecrypter::Create(aead)); |
| 65 size_t key_bytes = crypters->encrypter->GetKeySize(); | 64 size_t key_bytes = crypters->encrypter->GetKeySize(); |
| 66 size_t nonce_prefix_bytes = crypters->encrypter->GetNoncePrefixSize(); | 65 size_t nonce_prefix_bytes = crypters->encrypter->GetNoncePrefixSize(); |
| 67 size_t subkey_secret_bytes = | 66 size_t subkey_secret_bytes = |
| 68 subkey_secret == nullptr ? 0 : premaster_secret.length(); | 67 subkey_secret == nullptr ? 0 : premaster_secret.length(); |
| 69 | 68 |
| 70 StringPiece nonce = client_nonce; | 69 QuicStringPiece nonce = client_nonce; |
| 71 string nonce_storage; | 70 string nonce_storage; |
| 72 if (!server_nonce.empty()) { | 71 if (!server_nonce.empty()) { |
| 73 nonce_storage = client_nonce.as_string() + server_nonce.as_string(); | 72 nonce_storage = client_nonce.as_string() + server_nonce.as_string(); |
| 74 nonce = nonce_storage; | 73 nonce = nonce_storage; |
| 75 } | 74 } |
| 76 | 75 |
| 77 crypto::HKDF hkdf(premaster_secret, nonce, hkdf_input, key_bytes, | 76 crypto::HKDF hkdf(premaster_secret, nonce, hkdf_input, key_bytes, |
| 78 nonce_prefix_bytes, subkey_secret_bytes); | 77 nonce_prefix_bytes, subkey_secret_bytes); |
| 79 | 78 |
| 80 // Key derivation depends on the key diversification method being employed. | 79 // Key derivation depends on the key diversification method being employed. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 } | 137 } |
| 139 | 138 |
| 140 if (subkey_secret != nullptr) { | 139 if (subkey_secret != nullptr) { |
| 141 hkdf.subkey_secret().CopyToString(subkey_secret); | 140 hkdf.subkey_secret().CopyToString(subkey_secret); |
| 142 } | 141 } |
| 143 | 142 |
| 144 return true; | 143 return true; |
| 145 } | 144 } |
| 146 | 145 |
| 147 // static | 146 // static |
| 148 bool CryptoUtils::ExportKeyingMaterial(StringPiece subkey_secret, | 147 bool CryptoUtils::ExportKeyingMaterial(QuicStringPiece subkey_secret, |
| 149 StringPiece label, | 148 QuicStringPiece label, |
| 150 StringPiece context, | 149 QuicStringPiece context, |
| 151 size_t result_len, | 150 size_t result_len, |
| 152 string* result) { | 151 string* result) { |
| 153 for (size_t i = 0; i < label.length(); i++) { | 152 for (size_t i = 0; i < label.length(); i++) { |
| 154 if (label[i] == '\0') { | 153 if (label[i] == '\0') { |
| 155 QUIC_LOG(ERROR) << "ExportKeyingMaterial label may not contain NULs"; | 154 QUIC_LOG(ERROR) << "ExportKeyingMaterial label may not contain NULs"; |
| 156 return false; | 155 return false; |
| 157 } | 156 } |
| 158 } | 157 } |
| 159 // Create HKDF info input: null-terminated label + length-prefixed context | 158 // Create HKDF info input: null-terminated label + length-prefixed context |
| 160 if (context.length() >= std::numeric_limits<uint32_t>::max()) { | 159 if (context.length() >= std::numeric_limits<uint32_t>::max()) { |
| 161 QUIC_LOG(ERROR) << "Context value longer than 2^32"; | 160 QUIC_LOG(ERROR) << "Context value longer than 2^32"; |
| 162 return false; | 161 return false; |
| 163 } | 162 } |
| 164 uint32_t context_length = static_cast<uint32_t>(context.length()); | 163 uint32_t context_length = static_cast<uint32_t>(context.length()); |
| 165 string info = label.as_string(); | 164 string info = label.as_string(); |
| 166 info.push_back('\0'); | 165 info.push_back('\0'); |
| 167 info.append(reinterpret_cast<char*>(&context_length), sizeof(context_length)); | 166 info.append(reinterpret_cast<char*>(&context_length), sizeof(context_length)); |
| 168 info.append(context.data(), context.length()); | 167 info.append(context.data(), context.length()); |
| 169 | 168 |
| 170 crypto::HKDF hkdf(subkey_secret, StringPiece() /* no salt */, info, | 169 crypto::HKDF hkdf(subkey_secret, QuicStringPiece() /* no salt */, info, |
| 171 result_len, 0 /* no fixed IV */, 0 /* no subkey secret */); | 170 result_len, 0 /* no fixed IV */, 0 /* no subkey secret */); |
| 172 hkdf.client_write_key().CopyToString(result); | 171 hkdf.client_write_key().CopyToString(result); |
| 173 return true; | 172 return true; |
| 174 } | 173 } |
| 175 | 174 |
| 176 // static | 175 // static |
| 177 uint64_t CryptoUtils::ComputeLeafCertHash(StringPiece cert) { | 176 uint64_t CryptoUtils::ComputeLeafCertHash(QuicStringPiece cert) { |
| 178 return QuicUtils::FNV1a_64_Hash(cert); | 177 return QuicUtils::FNV1a_64_Hash(cert); |
| 179 } | 178 } |
| 180 | 179 |
| 181 QuicErrorCode CryptoUtils::ValidateServerHello( | 180 QuicErrorCode CryptoUtils::ValidateServerHello( |
| 182 const CryptoHandshakeMessage& server_hello, | 181 const CryptoHandshakeMessage& server_hello, |
| 183 const QuicVersionVector& negotiated_versions, | 182 const QuicVersionVector& negotiated_versions, |
| 184 string* error_details) { | 183 string* error_details) { |
| 185 DCHECK(error_details != nullptr); | 184 DCHECK(error_details != nullptr); |
| 186 | 185 |
| 187 if (server_hello.tag() != kSHLO) { | 186 if (server_hello.tag() != kSHLO) { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 void CryptoUtils::HashHandshakeMessage(const CryptoHandshakeMessage& message, | 294 void CryptoUtils::HashHandshakeMessage(const CryptoHandshakeMessage& message, |
| 296 string* output) { | 295 string* output) { |
| 297 const QuicData& serialized = message.GetSerialized(); | 296 const QuicData& serialized = message.GetSerialized(); |
| 298 uint8_t digest[SHA256_DIGEST_LENGTH]; | 297 uint8_t digest[SHA256_DIGEST_LENGTH]; |
| 299 SHA256(reinterpret_cast<const uint8_t*>(serialized.data()), | 298 SHA256(reinterpret_cast<const uint8_t*>(serialized.data()), |
| 300 serialized.length(), digest); | 299 serialized.length(), digest); |
| 301 output->assign(reinterpret_cast<const char*>(digest), sizeof(digest)); | 300 output->assign(reinterpret_cast<const char*>(digest), sizeof(digest)); |
| 302 } | 301 } |
| 303 | 302 |
| 304 } // namespace net | 303 } // namespace net |
| OLD | NEW |