Commit b838297a authored by Ryan Hamilton's avatar Ryan Hamilton Committed by Commit Bot

Create a QUIC platform wrapper around crypto::HKDF

Merge internal change: 202544067

Change-Id: Ibf16eef2c6f61fe1e34920494a03a7ae5c93e433
Reviewed-on: https://chromium-review.googlesource.com/1119259Reviewed-by: default avatarZhongyi Shi <zhongyi@chromium.org>
Commit-Queue: Ryan Hamilton <rch@chromium.org>
Cr-Commit-Position: refs/heads/master@{#571752}
parent ef6f2c2c
......@@ -1481,6 +1481,7 @@ component("net") {
"third_party/quic/platform/api/quic_file_utils.h",
"third_party/quic/platform/api/quic_flag_utils.h",
"third_party/quic/platform/api/quic_flags.h",
"third_party/quic/platform/api/quic_hkdf.h",
"third_party/quic/platform/api/quic_hostname_utils.cc",
"third_party/quic/platform/api/quic_hostname_utils.h",
"third_party/quic/platform/api/quic_interval.h",
......@@ -1526,6 +1527,7 @@ component("net") {
"third_party/quic/platform/impl/quic_flag_utils_impl.h",
"third_party/quic/platform/impl/quic_flags_impl.cc",
"third_party/quic/platform/impl/quic_flags_impl.h",
"third_party/quic/platform/impl/quic_hkdf_impl.h",
"third_party/quic/platform/impl/quic_hostname_utils_impl.cc",
"third_party/quic/platform/impl/quic_hostname_utils_impl.h",
"third_party/quic/platform/impl/quic_interval_impl.h",
......@@ -3048,6 +3050,7 @@ source_set("quic_test_tools") {
testonly = true
sources = [
"quic/chromium/crypto_test_utils_chromium.cc",
"third_party/quic/platform/api/quic_hkdf_test.cc",
"third_party/quic/platform/api/quic_mock_log.h",
"third_party/quic/platform/api/quic_test.h",
"third_party/quic/platform/api/quic_test_loopback.cc",
......
......@@ -19,6 +19,7 @@
#include "net/third_party/quic/core/quic_utils.h"
#include "net/third_party/quic/platform/api/quic_arraysize.h"
#include "net/third_party/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quic/platform/api/quic_hkdf.h"
#include "net/third_party/quic/platform/api/quic_logging.h"
#include "net/third_party/quic/platform/api/quic_ptr_util.h"
#include "net/third_party/quic/platform/api/quic_str_cat.h"
......@@ -205,8 +206,8 @@ bool CryptoUtils::DeriveKeys(QuicStringPiece premaster_secret,
nonce = nonce_storage;
}
crypto::HKDF hkdf(premaster_secret, nonce, hkdf_input, key_bytes,
nonce_prefix_bytes, subkey_secret_bytes);
QuicHKDF hkdf(premaster_secret, nonce, hkdf_input, key_bytes,
nonce_prefix_bytes, subkey_secret_bytes);
// Key derivation depends on the key diversification method being employed.
// both the client and the server support never doing key diversification.
......@@ -298,8 +299,8 @@ bool CryptoUtils::ExportKeyingMaterial(QuicStringPiece subkey_secret,
info.append(reinterpret_cast<char*>(&context_length), sizeof(context_length));
info.append(context.data(), context.length());
crypto::HKDF hkdf(subkey_secret, QuicStringPiece() /* no salt */, info,
result_len, 0 /* no fixed IV */, 0 /* no subkey secret */);
QuicHKDF hkdf(subkey_secret, QuicStringPiece() /* no salt */, info,
result_len, 0 /* no fixed IV */, 0 /* no subkey secret */);
*result = QuicString(hkdf.client_write_key());
return true;
}
......
......@@ -37,6 +37,7 @@
#include "net/third_party/quic/platform/api/quic_endian.h"
#include "net/third_party/quic/platform/api/quic_fallthrough.h"
#include "net/third_party/quic/platform/api/quic_flags.h"
#include "net/third_party/quic/platform/api/quic_hkdf.h"
#include "net/third_party/quic/platform/api/quic_hostname_utils.h"
#include "net/third_party/quic/platform/api/quic_logging.h"
#include "net/third_party/quic/platform/api/quic_reference_counted.h"
......@@ -61,10 +62,10 @@ const int kMaxTokenAddresses = 4;
QuicString DeriveSourceAddressTokenKey(
QuicStringPiece source_address_token_secret) {
crypto::HKDF hkdf(
source_address_token_secret, QuicStringPiece() /* no salt */,
"QUIC source address token key", CryptoSecretBoxer::GetKeySize(),
0 /* no fixed IV needed */, 0 /* no subkey secret */);
QuicHKDF hkdf(source_address_token_secret, QuicStringPiece() /* no salt */,
"QUIC source address token key",
CryptoSecretBoxer::GetKeySize(), 0 /* no fixed IV needed */,
0 /* no subkey secret */);
return string(hkdf.server_write_key());
}
......
......@@ -13,6 +13,7 @@
#include "net/third_party/quic/core/crypto/crypto_protocol.h"
#include "net/third_party/quic/core/crypto/null_decrypter.h"
#include "net/third_party/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quic/platform/api/quic_hkdf.h"
#include "net/third_party/quic/platform/api/quic_logging.h"
#include "net/third_party/quic/platform/api/quic_ptr_util.h"
#include "net/third_party/quic/platform/api/quic_string.h"
......@@ -59,10 +60,10 @@ void QuicDecrypter::DiversifyPreliminaryKey(QuicStringPiece preliminary_key,
size_t nonce_prefix_size,
QuicString* out_key,
QuicString* out_nonce_prefix) {
crypto::HKDF hkdf((string(preliminary_key)) + (string(nonce_prefix)),
QuicStringPiece(nonce.data(), nonce.size()),
"QUIC key diversification", 0, key_size, 0,
nonce_prefix_size, 0);
QuicHKDF hkdf((string(preliminary_key)) + (string(nonce_prefix)),
QuicStringPiece(nonce.data(), nonce.size()),
"QUIC key diversification", 0, key_size, 0, nonce_prefix_size,
0);
*out_key = string(hkdf.server_write_key());
*out_nonce_prefix = string(hkdf.server_write_iv());
}
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_HKDF_H_
#define NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_HKDF_H_
#include "net/third_party/quic/platform/impl/quic_hkdf_impl.h"
#include "net/third_party/quic/platform/api/quic_string_piece.h"
namespace quic {
// QuicHKDF implements the key derivation function specified in RFC 5869
// (using SHA-256) and outputs key material, as needed by QUIC.
// See https://tools.ietf.org/html/rfc5869 for details.
class QuicHKDF {
public:
// |secret|: the input shared secret (or, from RFC 5869, the IKM).
// |salt|: an (optional) public salt / non-secret random value. While
// optional, callers are strongly recommended to provide a salt. There is no
// added security value in making this larger than the SHA-256 block size of
// 64 bytes.
// |info|: an (optional) label to distinguish different uses of HKDF. It is
// optional context and application specific information (can be a zero-length
// string).
// |key_bytes_to_generate|: the number of bytes of key material to generate
// for both client and server.
// |iv_bytes_to_generate|: the number of bytes of IV to generate for both
// client and server.
// |subkey_secret_bytes_to_generate|: the number of bytes of subkey secret to
// generate, shared between client and server.
QuicHKDF(QuicStringPiece secret,
QuicStringPiece salt,
QuicStringPiece info,
size_t key_bytes_to_generate,
size_t iv_bytes_to_generate,
size_t subkey_secret_bytes_to_generate)
: impl_(secret,
salt,
info,
key_bytes_to_generate,
iv_bytes_to_generate,
subkey_secret_bytes_to_generate) {}
// An alternative constructor that allows the client and server key/IV
// lengths to be different.
QuicHKDF(QuicStringPiece secret,
QuicStringPiece salt,
QuicStringPiece info,
size_t client_key_bytes_to_generate,
size_t server_key_bytes_to_generate,
size_t client_iv_bytes_to_generate,
size_t server_iv_bytes_to_generate,
size_t subkey_secret_bytes_to_generate)
: impl_(secret,
salt,
info,
client_key_bytes_to_generate,
server_key_bytes_to_generate,
client_iv_bytes_to_generate,
server_iv_bytes_to_generate,
subkey_secret_bytes_to_generate) {}
~QuicHKDF() = default;
QuicStringPiece client_write_key() const { return impl_.client_write_key(); }
QuicStringPiece client_write_iv() const { return impl_.client_write_iv(); }
QuicStringPiece server_write_key() const { return impl_.server_write_key(); }
QuicStringPiece server_write_iv() const { return impl_.server_write_iv(); }
QuicStringPiece subkey_secret() const { return impl_.subkey_secret(); }
private:
QuicHKDFImpl impl_;
};
} // namespace quic
#endif // NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_HKDF_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/third_party/quic/platform/api/quic_hkdf.h"
#include "net/third_party/quic/platform/api/quic_arraysize.h"
#include "net/third_party/quic/platform/api/quic_string.h"
#include "net/third_party/quic/platform/api/quic_test.h"
#include "net/third_party/quic/platform/api/quic_text_utils.h"
namespace quic {
namespace test {
namespace {
struct HKDFInput {
const char* key_hex;
const char* salt_hex;
const char* info_hex;
const char* output_hex;
};
// These test cases are taken from
// https://tools.ietf.org/html/rfc5869#appendix-A.
static const HKDFInput kHKDFInputs[] = {
{
"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
"000102030405060708090a0b0c", "f0f1f2f3f4f5f6f7f8f9",
"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf340072"
"08d5"
"b887185865",
},
{
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122"
"2324"
"25262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344454647"
"4849"
"4a4b4c4d4e4f",
"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182"
"8384"
"85868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7"
"a8a9"
"aaabacadaeaf",
"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2"
"d3d4"
"d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7"
"f8f9"
"fafbfcfdfeff",
"b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a"
"99ca"
"c7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87"
"c14c"
"01d5c1f3434f1d87",
},
{
"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "",
"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d2013"
"95fa"
"a4b61a96c8",
},
};
class QuicHKDFTest : public QuicTest {};
TEST_F(QuicHKDFTest, HKDF) {
for (size_t i = 0; i < QUIC_ARRAYSIZE(kHKDFInputs); i++) {
const HKDFInput& test(kHKDFInputs[i]);
SCOPED_TRACE(i);
const QuicString key = QuicTextUtils::HexDecode(test.key_hex);
const QuicString salt = QuicTextUtils::HexDecode(test.salt_hex);
const QuicString info = QuicTextUtils::HexDecode(test.info_hex);
const QuicString expected = QuicTextUtils::HexDecode(test.output_hex);
// We set the key_length to the length of the expected output and then take
// the result from the first key, which is the client write key.
QuicHKDFImpl hkdf(key, salt, info, expected.size(), 0, 0);
ASSERT_EQ(expected.size(), hkdf.client_write_key().size());
EXPECT_EQ(0, memcmp(expected.data(), hkdf.client_write_key().data(),
expected.size()));
}
}
} // namespace
} // namespace test
} // namespace quic
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_HKDF_IMPL_H_
#define NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_HKDF_IMPL_H_
#include "crypto/hkdf.h"
namespace quic {
using QuicHKDFImpl = crypto::HKDF;
} // namespace quic
#endif // NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_HKDF_IMPL_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment