xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/crypto/quic_hkdf.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/crypto/quic_hkdf.h"
6 
7 #include <memory>
8 
9 #include "absl/strings/string_view.h"
10 #include "openssl/digest.h"
11 #include "openssl/hkdf.h"
12 #include "quiche/quic/platform/api/quic_logging.h"
13 
14 namespace quic {
15 
16 const size_t kSHA256HashLength = 32;
17 const size_t kMaxKeyMaterialSize = kSHA256HashLength * 256;
18 
QuicHKDF(absl::string_view secret,absl::string_view salt,absl::string_view info,size_t key_bytes_to_generate,size_t iv_bytes_to_generate,size_t subkey_secret_bytes_to_generate)19 QuicHKDF::QuicHKDF(absl::string_view secret, absl::string_view salt,
20                    absl::string_view info, size_t key_bytes_to_generate,
21                    size_t iv_bytes_to_generate,
22                    size_t subkey_secret_bytes_to_generate)
23     : QuicHKDF(secret, salt, info, key_bytes_to_generate, key_bytes_to_generate,
24                iv_bytes_to_generate, iv_bytes_to_generate,
25                subkey_secret_bytes_to_generate) {}
26 
QuicHKDF(absl::string_view secret,absl::string_view salt,absl::string_view 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)27 QuicHKDF::QuicHKDF(absl::string_view secret, absl::string_view salt,
28                    absl::string_view info, size_t client_key_bytes_to_generate,
29                    size_t server_key_bytes_to_generate,
30                    size_t client_iv_bytes_to_generate,
31                    size_t server_iv_bytes_to_generate,
32                    size_t subkey_secret_bytes_to_generate) {
33   const size_t material_length =
34       2 * client_key_bytes_to_generate + client_iv_bytes_to_generate +
35       2 * server_key_bytes_to_generate + server_iv_bytes_to_generate +
36       subkey_secret_bytes_to_generate;
37   QUICHE_DCHECK_LT(material_length, kMaxKeyMaterialSize);
38 
39   output_.resize(material_length);
40   // On Windows, when the size of output_ is zero, dereference of 0'th element
41   // results in a crash. C++11 solves this problem by adding a data() getter
42   // method to std::vector.
43   if (output_.empty()) {
44     return;
45   }
46 
47   ::HKDF(&output_[0], output_.size(), ::EVP_sha256(),
48          reinterpret_cast<const uint8_t*>(secret.data()), secret.size(),
49          reinterpret_cast<const uint8_t*>(salt.data()), salt.size(),
50          reinterpret_cast<const uint8_t*>(info.data()), info.size());
51 
52   size_t j = 0;
53   if (client_key_bytes_to_generate) {
54     client_write_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
55                                           client_key_bytes_to_generate);
56     j += client_key_bytes_to_generate;
57   }
58 
59   if (server_key_bytes_to_generate) {
60     server_write_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
61                                           server_key_bytes_to_generate);
62     j += server_key_bytes_to_generate;
63   }
64 
65   if (client_iv_bytes_to_generate) {
66     client_write_iv_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
67                                          client_iv_bytes_to_generate);
68     j += client_iv_bytes_to_generate;
69   }
70 
71   if (server_iv_bytes_to_generate) {
72     server_write_iv_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
73                                          server_iv_bytes_to_generate);
74     j += server_iv_bytes_to_generate;
75   }
76 
77   if (subkey_secret_bytes_to_generate) {
78     subkey_secret_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
79                                        subkey_secret_bytes_to_generate);
80     j += subkey_secret_bytes_to_generate;
81   }
82   // Repeat client and server key bytes for header protection keys.
83   if (client_key_bytes_to_generate) {
84     client_hp_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
85                                        client_key_bytes_to_generate);
86     j += client_key_bytes_to_generate;
87   }
88 
89   if (server_key_bytes_to_generate) {
90     server_hp_key_ = absl::string_view(reinterpret_cast<char*>(&output_[j]),
91                                        server_key_bytes_to_generate);
92     j += server_key_bytes_to_generate;
93   }
94 }
95 
~QuicHKDF()96 QuicHKDF::~QuicHKDF() {}
97 
98 }  // namespace quic
99