encrypted_client_hello.cc
Go to the documentation of this file.
1 /* Copyright (c) 2021, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <openssl/ssl.h>
16 
17 #include <assert.h>
18 #include <string.h>
19 
20 #include <algorithm>
21 #include <utility>
22 
23 #include <openssl/aead.h>
24 #include <openssl/bytestring.h>
25 #include <openssl/curve25519.h>
26 #include <openssl/err.h>
27 #include <openssl/hkdf.h>
28 #include <openssl/hpke.h>
29 #include <openssl/rand.h>
30 
31 #include "internal.h"
32 
33 
35 
36 // ECH reuses the extension code point for the version number.
37 static constexpr uint16_t kECHConfigVersion =
39 
40 static const decltype(&EVP_hpke_aes_128_gcm) kSupportedAEADs[] = {
44 };
45 
46 static const EVP_HPKE_AEAD *get_ech_aead(uint16_t aead_id) {
47  for (const auto aead_func : kSupportedAEADs) {
48  const EVP_HPKE_AEAD *aead = aead_func();
49  if (aead_id == EVP_HPKE_AEAD_id(aead)) {
50  return aead;
51  }
52  }
53  return nullptr;
54 }
55 
56 // ssl_client_hello_write_without_extensions serializes |client_hello| into
57 // |out|, omitting the length-prefixed extensions. It serializes individual
58 // fields, starting with |client_hello->version|, and ignores the
59 // |client_hello->client_hello| field. It returns true on success and false on
60 // failure.
62  const SSL_CLIENT_HELLO *client_hello, CBB *out) {
63  CBB cbb;
64  if (!CBB_add_u16(out, client_hello->version) ||
65  !CBB_add_bytes(out, client_hello->random, client_hello->random_len) ||
67  !CBB_add_bytes(&cbb, client_hello->session_id,
68  client_hello->session_id_len) ||
70  !CBB_add_bytes(&cbb, client_hello->cipher_suites,
71  client_hello->cipher_suites_len) ||
73  !CBB_add_bytes(&cbb, client_hello->compression_methods,
74  client_hello->compression_methods_len) ||
75  !CBB_flush(out)) {
76  return false;
77  }
78  return true;
79 }
80 
81 static bool is_valid_client_hello_inner(SSL *ssl, uint8_t *out_alert,
82  Span<const uint8_t> body) {
83  // See draft-ietf-tls-esni-13, section 7.1.
84  SSL_CLIENT_HELLO client_hello;
85  CBS extension;
86  if (!ssl_client_hello_init(ssl, &client_hello, body) ||
89  CBS_len(&extension) != 1 || //
93  *out_alert = SSL_AD_ILLEGAL_PARAMETER;
95  return false;
96  }
97  // Parse supported_versions and reject TLS versions prior to TLS 1.3. Older
98  // versions are incompatible with ECH.
99  CBS versions;
100  if (!CBS_get_u8_length_prefixed(&extension, &versions) ||
101  CBS_len(&extension) != 0 || //
102  CBS_len(&versions) == 0) {
103  *out_alert = SSL_AD_DECODE_ERROR;
105  return false;
106  }
107  while (CBS_len(&versions) != 0) {
109  if (!CBS_get_u16(&versions, &version)) {
110  *out_alert = SSL_AD_DECODE_ERROR;
112  return false;
113  }
114  if (version == SSL3_VERSION || version == TLS1_VERSION ||
117  *out_alert = SSL_AD_ILLEGAL_PARAMETER;
119  return false;
120  }
121  }
122  return true;
123 }
124 
126  SSL *ssl, uint8_t *out_alert, Array<uint8_t> *out_client_hello_inner,
127  Span<const uint8_t> encoded_client_hello_inner,
128  const SSL_CLIENT_HELLO *client_hello_outer) {
129  SSL_CLIENT_HELLO client_hello_inner;
130  CBS cbs = encoded_client_hello_inner;
132  &client_hello_inner)) {
134  return false;
135  }
136  // The remaining data is padding.
137  uint8_t padding;
138  while (CBS_get_u8(&cbs, &padding)) {
139  if (padding != 0) {
141  *out_alert = SSL_AD_ILLEGAL_PARAMETER;
142  return false;
143  }
144  }
145 
146  // TLS 1.3 ClientHellos must have extensions, and EncodedClientHelloInners use
147  // ClientHelloOuter's session_id.
148  if (client_hello_inner.extensions_len == 0 ||
149  client_hello_inner.session_id_len != 0) {
151  return false;
152  }
153  client_hello_inner.session_id = client_hello_outer->session_id;
154  client_hello_inner.session_id_len = client_hello_outer->session_id_len;
155 
156  // Begin serializing a message containing the ClientHelloInner in |cbb|.
157  ScopedCBB cbb;
158  CBB body, extensions_cbb;
159  if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO) ||
160  !ssl_client_hello_write_without_extensions(&client_hello_inner, &body) ||
161  !CBB_add_u16_length_prefixed(&body, &extensions_cbb)) {
163  return false;
164  }
165 
166  auto inner_extensions = MakeConstSpan(client_hello_inner.extensions,
167  client_hello_inner.extensions_len);
168  CBS ext_list_wrapper;
169  if (!ssl_client_hello_get_extension(&client_hello_inner, &ext_list_wrapper,
171  // No ech_outer_extensions. Copy everything.
172  if (!CBB_add_bytes(&extensions_cbb, inner_extensions.data(),
173  inner_extensions.size())) {
175  return false;
176  }
177  } else {
178  const size_t offset = CBS_data(&ext_list_wrapper) - inner_extensions.data();
179  auto inner_extensions_before =
180  inner_extensions.subspan(0, offset - 4 /* extension header */);
181  auto inner_extensions_after =
182  inner_extensions.subspan(offset + CBS_len(&ext_list_wrapper));
183  if (!CBB_add_bytes(&extensions_cbb, inner_extensions_before.data(),
184  inner_extensions_before.size())) {
186  return false;
187  }
188 
189  // Expand ech_outer_extensions. See draft-ietf-tls-esni-13, Appendix B.
190  CBS ext_list;
191  if (!CBS_get_u8_length_prefixed(&ext_list_wrapper, &ext_list) ||
192  CBS_len(&ext_list) == 0 || CBS_len(&ext_list_wrapper) != 0) {
194  return false;
195  }
196  CBS outer_extensions;
197  CBS_init(&outer_extensions, client_hello_outer->extensions,
198  client_hello_outer->extensions_len);
199  while (CBS_len(&ext_list) != 0) {
200  // Find the next extension to copy.
201  uint16_t want;
202  if (!CBS_get_u16(&ext_list, &want)) {
204  return false;
205  }
206  // Seek to |want| in |outer_extensions|. |ext_list| is required to match
207  // ClientHelloOuter in order.
208  uint16_t found;
209  CBS ext_body;
210  do {
211  if (CBS_len(&outer_extensions) == 0) {
212  *out_alert = SSL_AD_ILLEGAL_PARAMETER;
214  return false;
215  }
216  if (!CBS_get_u16(&outer_extensions, &found) ||
217  !CBS_get_u16_length_prefixed(&outer_extensions, &ext_body)) {
219  return false;
220  }
221  } while (found != want);
222  // Copy the extension.
223  if (!CBB_add_u16(&extensions_cbb, found) ||
224  !CBB_add_u16(&extensions_cbb, CBS_len(&ext_body)) ||
225  !CBB_add_bytes(&extensions_cbb, CBS_data(&ext_body),
226  CBS_len(&ext_body))) {
228  return false;
229  }
230  }
231 
232  if (!CBB_add_bytes(&extensions_cbb, inner_extensions_after.data(),
233  inner_extensions_after.size())) {
235  return false;
236  }
237  }
238  if (!CBB_flush(&body)) {
240  return false;
241  }
242 
244  ssl, out_alert, MakeConstSpan(CBB_data(&body), CBB_len(&body)))) {
245  return false;
246  }
247 
248  if (!ssl->method->finish_message(ssl, cbb.get(), out_client_hello_inner)) {
250  return false;
251  }
252  return true;
253 }
254 
256  bool *out_is_decrypt_error,
257  const SSL_CLIENT_HELLO *client_hello_outer,
259  *out_is_decrypt_error = false;
260 
261  // The ClientHelloOuterAAD is |client_hello_outer| with |payload| (which must
262  // point within |client_hello_outer->extensions|) replaced with zeros. See
263  // draft-ietf-tls-esni-13, section 5.2.
264  Array<uint8_t> aad;
265  if (!aad.CopyFrom(MakeConstSpan(client_hello_outer->client_hello,
266  client_hello_outer->client_hello_len))) {
267  return false;
268  }
269 
270  // We assert with |uintptr_t| because the comparison would be UB if they
271  // didn't alias.
272  assert(reinterpret_cast<uintptr_t>(client_hello_outer->extensions) <=
273  reinterpret_cast<uintptr_t>(payload.data()));
274  assert(reinterpret_cast<uintptr_t>(client_hello_outer->extensions +
275  client_hello_outer->extensions_len) >=
276  reinterpret_cast<uintptr_t>(payload.data() + payload.size()));
277  Span<uint8_t> payload_aad = MakeSpan(aad).subspan(
278  payload.data() - client_hello_outer->client_hello, payload.size());
279  OPENSSL_memset(payload_aad.data(), 0, payload_aad.size());
280 
281 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
282  // In fuzzer mode, disable encryption to improve coverage. We reserve a short
283  // input to signal decryption failure, so the fuzzer can explore fallback to
284  // ClientHelloOuter.
285  const uint8_t kBadPayload[] = {0xff};
286  if (payload == kBadPayload) {
287  *out_is_decrypt_error = true;
289  return false;
290  }
291  if (!out->CopyFrom(payload)) {
292  return false;
293  }
294 #else
295  // Attempt to decrypt into |out|.
296  if (!out->Init(payload.size())) {
298  return false;
299  }
300  size_t len;
301  if (!EVP_HPKE_CTX_open(hpke_ctx, out->data(), &len, out->size(),
302  payload.data(), payload.size(), aad.data(),
303  aad.size())) {
304  *out_is_decrypt_error = true;
306  return false;
307  }
308  out->Shrink(len);
309 #endif
310  return true;
311 }
312 
314  if (in.size() < 2 || in[0] != '0' || (in[1] != 'x' && in[1] != 'X')) {
315  return false;
316  }
317  for (uint8_t b : in.subspan(2)) {
318  if (!('0' <= b && b <= '9') && !('a' <= b && b <= 'f') &&
319  !('A' <= b && b <= 'F')) {
320  return false;
321  }
322  }
323  return true;
324 }
325 
327  if (in.empty()) {
328  return false;
329  }
330  for (uint8_t b : in) {
331  if (!('0' <= b && b <= '9')) {
332  return false;
333  }
334  }
335  return true;
336 }
337 
339  // See draft-ietf-tls-esni-13, Section 4 and RFC 5890, Section 2.3.1. The
340  // public name must be a dot-separated sequence of LDH labels and not begin or
341  // end with a dot.
342  auto remaining = public_name;
343  if (remaining.empty()) {
344  return false;
345  }
346  Span<const uint8_t> last;
347  while (!remaining.empty()) {
348  // Find the next dot-separated component.
349  auto dot = std::find(remaining.begin(), remaining.end(), '.');
350  Span<const uint8_t> component;
351  if (dot == remaining.end()) {
352  component = remaining;
353  last = component;
354  remaining = Span<const uint8_t>();
355  } else {
356  component = remaining.subspan(0, dot - remaining.begin());
357  // Skip the dot.
358  remaining = remaining.subspan(dot - remaining.begin() + 1);
359  if (remaining.empty()) {
360  // Trailing dots are not allowed.
361  return false;
362  }
363  }
364  // |component| must be a valid LDH label. Checking for empty components also
365  // rejects leading dots.
366  if (component.empty() || component.size() > 63 ||
367  component.front() == '-' || component.back() == '-') {
368  return false;
369  }
370  for (uint8_t c : component) {
371  if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z') &&
372  !('0' <= c && c <= '9') && c != '-') {
373  return false;
374  }
375  }
376  }
377 
378  // The WHATWG URL parser additionally does not allow any DNS names that end in
379  // a numeric component. See:
380  // https://url.spec.whatwg.org/#concept-host-parser
381  // https://url.spec.whatwg.org/#ends-in-a-number-checker
382  //
383  // The WHATWG parser is formulated in terms of parsing decimal, octal, and
384  // hex, along with a separate ASCII digits check. The ASCII digits check
385  // subsumes the decimal and octal check, so we only need to check two cases.
386  return !is_hex_component(last) && !is_decimal_component(last);
387 }
388 
389 static bool parse_ech_config(CBS *cbs, ECHConfig *out, bool *out_supported,
390  bool all_extensions_mandatory) {
392  CBS orig = *cbs;
393  CBS contents;
394  if (!CBS_get_u16(cbs, &version) ||
397  return false;
398  }
399 
400  if (version != kECHConfigVersion) {
401  *out_supported = false;
402  return true;
403  }
404 
405  // Make a copy of the ECHConfig and parse from it, so the results alias into
406  // the saved copy.
407  if (!out->raw.CopyFrom(
408  MakeConstSpan(CBS_data(&orig), CBS_len(&orig) - CBS_len(cbs)))) {
409  return false;
410  }
411 
412  CBS ech_config(out->raw);
413  CBS public_name, public_key, cipher_suites, extensions;
414  if (!CBS_skip(&ech_config, 2) || // version
415  !CBS_get_u16_length_prefixed(&ech_config, &contents) ||
416  !CBS_get_u8(&contents, &out->config_id) ||
417  !CBS_get_u16(&contents, &out->kem_id) ||
419  CBS_len(&public_key) == 0 ||
421  CBS_len(&cipher_suites) == 0 || CBS_len(&cipher_suites) % 4 != 0 ||
422  !CBS_get_u8(&contents, &out->maximum_name_length) ||
423  !CBS_get_u8_length_prefixed(&contents, &public_name) ||
424  CBS_len(&public_name) == 0 ||
426  CBS_len(&contents) != 0) {
428  return false;
429  }
430 
431  if (!ssl_is_valid_ech_public_name(public_name)) {
432  // TODO(https://crbug.com/boringssl/275): The draft says ECHConfigs with
433  // invalid public names should be ignored, but LDH syntax failures are
434  // unambiguously invalid.
435  *out_supported = false;
436  return true;
437  }
438 
439  out->public_key = public_key;
440  out->public_name = public_name;
441  // This function does not ensure |out->kem_id| and |out->cipher_suites| use
442  // supported algorithms. The caller must do this.
443  out->cipher_suites = cipher_suites;
444 
445  bool has_unknown_mandatory_extension = false;
446  while (CBS_len(&extensions) != 0) {
447  uint16_t type;
448  CBS body;
449  if (!CBS_get_u16(&extensions, &type) ||
452  return false;
453  }
454  // We currently do not support any extensions.
455  if (type & 0x8000 || all_extensions_mandatory) {
456  // Extension numbers with the high bit set are mandatory. Continue parsing
457  // to enforce syntax, but we will ultimately ignore this ECHConfig as a
458  // client and reject it as a server.
459  has_unknown_mandatory_extension = true;
460  }
461  }
462 
463  *out_supported = !has_unknown_mandatory_extension;
464  return true;
465 }
466 
468  const EVP_HPKE_KEY *key, bool is_retry_config) {
470 
471  // Parse the ECHConfig, rejecting all unsupported parameters and extensions.
472  // Unlike most server options, ECH's server configuration is serialized and
473  // configured in both the server and DNS. If the caller configures an
474  // unsupported parameter, this is a deployment error. To catch these errors,
475  // we fail early.
476  CBS cbs = ech_config;
477  bool supported;
478  if (!parse_ech_config(&cbs, &ech_config_, &supported,
479  /*all_extensions_mandatory=*/true)) {
480  return false;
481  }
482  if (CBS_len(&cbs) != 0) {
484  return false;
485  }
486  if (!supported) {
488  return false;
489  }
490 
492  while (CBS_len(&cipher_suites) > 0) {
493  uint16_t kdf_id, aead_id;
494  if (!CBS_get_u16(&cipher_suites, &kdf_id) ||
495  !CBS_get_u16(&cipher_suites, &aead_id)) {
497  return false;
498  }
499  // The server promises to support every option in the ECHConfig, so reject
500  // any unsupported cipher suites.
501  if (kdf_id != EVP_HPKE_HKDF_SHA256 || get_ech_aead(aead_id) == nullptr) {
503  return false;
504  }
505  }
506 
507  // Check the public key in the ECHConfig matches |key|.
508  uint8_t expected_public_key[EVP_HPKE_MAX_PUBLIC_KEY_LENGTH];
509  size_t expected_public_key_len;
510  if (!EVP_HPKE_KEY_public_key(key, expected_public_key,
511  &expected_public_key_len,
512  sizeof(expected_public_key))) {
513  return false;
514  }
516  MakeConstSpan(expected_public_key, expected_public_key_len) !=
519  return false;
520  }
521 
522  if (!EVP_HPKE_KEY_copy(key_.get(), key)) {
523  return false;
524  }
525 
526  return true;
527 }
528 
530  uint16_t aead_id,
531  Span<const uint8_t> enc) const {
532  // Check the cipher suite is supported by this ECHServerConfig.
534  bool cipher_ok = false;
535  while (CBS_len(&cbs) != 0) {
536  uint16_t supported_kdf_id, supported_aead_id;
537  if (!CBS_get_u16(&cbs, &supported_kdf_id) ||
538  !CBS_get_u16(&cbs, &supported_aead_id)) {
539  return false;
540  }
541  if (kdf_id == supported_kdf_id && aead_id == supported_aead_id) {
542  cipher_ok = true;
543  break;
544  }
545  }
546  if (!cipher_ok) {
547  return false;
548  }
549 
550  static const uint8_t kInfoLabel[] = "tls ech";
551  ScopedCBB info_cbb;
552  if (!CBB_init(info_cbb.get(), sizeof(kInfoLabel) + ech_config_.raw.size()) ||
553  !CBB_add_bytes(info_cbb.get(), kInfoLabel,
554  sizeof(kInfoLabel) /* includes trailing NUL */) ||
555  !CBB_add_bytes(info_cbb.get(), ech_config_.raw.data(),
556  ech_config_.raw.size())) {
558  return false;
559  }
560 
561  assert(kdf_id == EVP_HPKE_HKDF_SHA256);
562  assert(get_ech_aead(aead_id) != NULL);
564  ctx, key_.get(), EVP_hpke_hkdf_sha256(), get_ech_aead(aead_id), enc.data(),
565  enc.size(), CBB_data(info_cbb.get()), CBB_len(info_cbb.get()));
566 }
567 
569  CBS cbs = ech_config_list, child;
570  if (!CBS_get_u16_length_prefixed(&cbs, &child) || //
571  CBS_len(&child) == 0 || //
572  CBS_len(&cbs) > 0) {
573  return false;
574  }
575  while (CBS_len(&child) > 0) {
576  ECHConfig ech_config;
577  bool supported;
578  if (!parse_ech_config(&child, &ech_config, &supported,
579  /*all_extensions_mandatory=*/false)) {
580  return false;
581  }
582  }
583  return true;
584 }
585 
586 static bool select_ech_cipher_suite(const EVP_HPKE_KDF **out_kdf,
587  const EVP_HPKE_AEAD **out_aead,
589  const bool has_aes_hardware = EVP_has_aes_hardware();
590  const EVP_HPKE_AEAD *aead = nullptr;
592  while (CBS_len(&cbs) != 0) {
593  uint16_t kdf_id, aead_id;
594  if (!CBS_get_u16(&cbs, &kdf_id) || //
595  !CBS_get_u16(&cbs, &aead_id)) {
596  return false;
597  }
598  // Pick the first common cipher suite, but prefer ChaCha20-Poly1305 if we
599  // don't have AES hardware.
600  const EVP_HPKE_AEAD *candidate = get_ech_aead(aead_id);
601  if (kdf_id != EVP_HPKE_HKDF_SHA256 || candidate == nullptr) {
602  continue;
603  }
604  if (aead == nullptr ||
605  (!has_aes_hardware && aead_id == EVP_HPKE_CHACHA20_POLY1305)) {
606  aead = candidate;
607  }
608  }
609  if (aead == nullptr) {
610  return false;
611  }
612 
613  *out_kdf = EVP_hpke_hkdf_sha256();
614  *out_aead = aead;
615  return true;
616 }
617 
619  size_t *out_enc_len) {
620  *out_enc_len = 0;
621  if (hs->max_version < TLS1_3_VERSION) {
622  // ECH requires TLS 1.3.
623  return true;
624  }
625 
626  if (!hs->config->client_ech_config_list.empty()) {
628  CBS child;
629  if (!CBS_get_u16_length_prefixed(&cbs, &child) || //
630  CBS_len(&child) == 0 || //
631  CBS_len(&cbs) > 0) {
632  return false;
633  }
634  // Look for the first ECHConfig with supported parameters.
635  while (CBS_len(&child) > 0) {
636  ECHConfig ech_config;
637  bool supported;
638  if (!parse_ech_config(&child, &ech_config, &supported,
639  /*all_extensions_mandatory=*/false)) {
640  return false;
641  }
643  const EVP_HPKE_KDF *kdf;
644  const EVP_HPKE_AEAD *aead;
645  if (supported && //
647  select_ech_cipher_suite(&kdf, &aead, ech_config.cipher_suites)) {
648  ScopedCBB info;
649  static const uint8_t kInfoLabel[] = "tls ech"; // includes trailing NUL
650  if (!CBB_init(info.get(), sizeof(kInfoLabel) + ech_config.raw.size()) ||
651  !CBB_add_bytes(info.get(), kInfoLabel, sizeof(kInfoLabel)) ||
652  !CBB_add_bytes(info.get(), ech_config.raw.data(),
653  ech_config.raw.size())) {
655  return false;
656  }
657 
659  hs->ech_hpke_ctx.get(), out_enc.data(), out_enc_len,
660  out_enc.size(), kem, kdf, aead, ech_config.public_key.data(),
661  ech_config.public_key.size(), CBB_data(info.get()),
662  CBB_len(info.get())) ||
663  !hs->inner_transcript.Init()) {
664  return false;
665  }
666 
667  hs->selected_ech_config = MakeUnique<ECHConfig>(std::move(ech_config));
668  return hs->selected_ech_config != nullptr;
669  }
670  }
671  }
672 
673  return true;
674 }
675 
676 static size_t aead_overhead(const EVP_HPKE_AEAD *aead) {
677 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
678  // TODO(https://crbug.com/boringssl/275): Having to adjust the overhead
679  // everywhere is tedious. Change fuzzer mode to append a fake tag but still
680  // otherwise be cleartext, refresh corpora, and then inline this function.
681  return 0;
682 #else
684 #endif
685 }
686 
687 // random_size returns a random value between |min| and |max|, inclusive.
688 static size_t random_size(size_t min, size_t max) {
689  assert(min < max);
690  size_t value;
691  RAND_bytes(reinterpret_cast<uint8_t *>(&value), sizeof(value));
692  return value % (max - min + 1) + min;
693 }
694 
695 static bool setup_ech_grease(SSL_HANDSHAKE *hs) {
696  assert(!hs->selected_ech_config);
698  return true;
699  }
700 
701  const uint16_t kdf_id = EVP_HPKE_HKDF_SHA256;
702  const EVP_HPKE_AEAD *aead = EVP_has_aes_hardware()
705  static_assert(ssl_grease_ech_config_id < sizeof(hs->grease_seed),
706  "hs->grease_seed is too small");
708 
710  uint8_t private_key_unused[X25519_PRIVATE_KEY_LEN];
711  X25519_keypair(enc, private_key_unused);
712 
713  // To determine a plausible length for the payload, we estimate the size of a
714  // typical EncodedClientHelloInner without resumption:
715  //
716  // 2+32+1+2 version, random, legacy_session_id, legacy_compression_methods
717  // 2+4*2 cipher_suites (three TLS 1.3 ciphers, GREASE)
718  // 2 extensions prefix
719  // 5 inner encrypted_client_hello
720  // 4+1+2*2 supported_versions (TLS 1.3, GREASE)
721  // 4+1+10*2 outer_extensions (key_share, sigalgs, sct, alpn,
722  // supported_groups, status_request, psk_key_exchange_modes,
723  // compress_certificate, GREASE x2)
724  //
725  // The server_name extension has an overhead of 9 bytes. For now, arbitrarily
726  // estimate maximum_name_length to be between 32 and 100 bytes. Then round up
727  // to a multiple of 32, to match draft-ietf-tls-esni-13, section 6.1.3.
728  const size_t payload_len =
729  32 * random_size(128 / 32, 224 / 32) + aead_overhead(aead);
730  bssl::ScopedCBB cbb;
731  CBB enc_cbb, payload_cbb;
732  uint8_t *payload;
733  if (!CBB_init(cbb.get(), 256) ||
734  !CBB_add_u16(cbb.get(), kdf_id) ||
735  !CBB_add_u16(cbb.get(), EVP_HPKE_AEAD_id(aead)) ||
736  !CBB_add_u8(cbb.get(), config_id) ||
737  !CBB_add_u16_length_prefixed(cbb.get(), &enc_cbb) ||
738  !CBB_add_bytes(&enc_cbb, enc, sizeof(enc)) ||
739  !CBB_add_u16_length_prefixed(cbb.get(), &payload_cbb) ||
740  !CBB_add_space(&payload_cbb, &payload, payload_len) ||
742  !CBBFinishArray(cbb.get(), &hs->ech_client_outer)) {
743  return false;
744  }
745  return true;
746 }
747 
749  SSL *const ssl = hs->ssl;
750  if (!hs->selected_ech_config) {
751  return setup_ech_grease(hs);
752  }
753 
754  // Construct ClientHelloInner and EncodedClientHelloInner. See
755  // draft-ietf-tls-esni-13, sections 5.1 and 6.1.
756  ScopedCBB cbb, encoded_cbb;
757  CBB body;
758  bool needs_psk_binder;
759  Array<uint8_t> hello_inner;
760  if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO) ||
761  !CBB_init(encoded_cbb.get(), 256) ||
764  /*empty_session_id=*/false) ||
765  !ssl_write_client_hello_without_extensions(hs, encoded_cbb.get(),
767  /*empty_session_id=*/true) ||
768  !ssl_add_clienthello_tlsext(hs, &body, encoded_cbb.get(),
769  &needs_psk_binder, ssl_client_hello_inner,
770  CBB_len(&body)) ||
771  !ssl->method->finish_message(ssl, cbb.get(), &hello_inner)) {
773  return false;
774  }
775 
776  if (needs_psk_binder) {
777  size_t binder_len;
778  if (!tls13_write_psk_binder(hs, hs->inner_transcript, MakeSpan(hello_inner),
779  &binder_len)) {
780  return false;
781  }
782  // Also update the EncodedClientHelloInner.
783  auto encoded_binder =
784  MakeSpan(const_cast<uint8_t *>(CBB_data(encoded_cbb.get())),
785  CBB_len(encoded_cbb.get()))
786  .last(binder_len);
787  auto hello_inner_binder = MakeConstSpan(hello_inner).last(binder_len);
788  OPENSSL_memcpy(encoded_binder.data(), hello_inner_binder.data(),
789  binder_len);
790  }
791 
792  if (!hs->inner_transcript.Update(hello_inner)) {
793  return false;
794  }
795 
796  // Pad the EncodedClientHelloInner. See draft-ietf-tls-esni-13, section 6.1.3.
797  size_t padding_len = 0;
798  size_t maximum_name_length = hs->selected_ech_config->maximum_name_length;
799  if (ssl->hostname) {
800  size_t hostname_len = strlen(ssl->hostname.get());
801  if (hostname_len <= maximum_name_length) {
802  padding_len = maximum_name_length - hostname_len;
803  }
804  } else {
805  // No SNI. Pad up to |maximum_name_length|, including server_name extension
806  // overhead.
807  padding_len = 9 + maximum_name_length;
808  }
809  // Pad the whole thing to a multiple of 32 bytes.
810  padding_len += 31 - ((CBB_len(encoded_cbb.get()) + padding_len - 1) % 32);
811  Array<uint8_t> encoded;
812  if (!CBB_add_zeros(encoded_cbb.get(), padding_len) ||
813  !CBBFinishArray(encoded_cbb.get(), &encoded)) {
814  return false;
815  }
816 
817  // Encrypt |encoded|. See draft-ietf-tls-esni-13, section 6.1.1. First,
818  // assemble the extension with a placeholder value for ClientHelloOuterAAD.
819  // See draft-ietf-tls-esni-13, section 5.2.
820  const EVP_HPKE_KDF *kdf = EVP_HPKE_CTX_kdf(hs->ech_hpke_ctx.get());
821  const EVP_HPKE_AEAD *aead = EVP_HPKE_CTX_aead(hs->ech_hpke_ctx.get());
822  size_t payload_len = encoded.size() + aead_overhead(aead);
823  CBB enc_cbb, payload_cbb;
824  if (!CBB_init(cbb.get(), 256) ||
825  !CBB_add_u16(cbb.get(), EVP_HPKE_KDF_id(kdf)) ||
826  !CBB_add_u16(cbb.get(), EVP_HPKE_AEAD_id(aead)) ||
827  !CBB_add_u8(cbb.get(), hs->selected_ech_config->config_id) ||
828  !CBB_add_u16_length_prefixed(cbb.get(), &enc_cbb) ||
829  !CBB_add_bytes(&enc_cbb, enc.data(), enc.size()) ||
830  !CBB_add_u16_length_prefixed(cbb.get(), &payload_cbb) ||
831  !CBB_add_zeros(&payload_cbb, payload_len) ||
832  !CBBFinishArray(cbb.get(), &hs->ech_client_outer)) {
833  return false;
834  }
835 
836  // Construct ClientHelloOuterAAD.
837  // TODO(https://crbug.com/boringssl/275): This ends up constructing the
838  // ClientHelloOuter twice. Instead, reuse |aad| for the ClientHello, now that
839  // draft-12 made the length prefixes match.
840  bssl::ScopedCBB aad;
841  if (!CBB_init(aad.get(), 256) ||
844  /*empty_session_id=*/false) ||
845  !ssl_add_clienthello_tlsext(hs, aad.get(), /*out_encoded=*/nullptr,
846  &needs_psk_binder, ssl_client_hello_outer,
847  CBB_len(aad.get()))) {
849  return false;
850  }
851 
852  // ClientHelloOuter may not require a PSK binder. Otherwise, we have a
853  // circular dependency.
854  assert(!needs_psk_binder);
855 
856  // Replace the payload in |hs->ech_client_outer| with the encrypted value.
857  auto payload_span = MakeSpan(hs->ech_client_outer).last(payload_len);
858 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
859  // In fuzzer mode, the server expects a cleartext payload.
860  assert(payload_span.size() == encoded.size());
861  OPENSSL_memcpy(payload_span.data(), encoded.data(), encoded.size());
862 #else
863  if (!EVP_HPKE_CTX_seal(hs->ech_hpke_ctx.get(), payload_span.data(),
864  &payload_len, payload_span.size(), encoded.data(),
865  encoded.size(), CBB_data(aad.get()),
866  CBB_len(aad.get())) ||
867  payload_len != payload_span.size()) {
868  return false;
869  }
870 #endif // BORINGSSL_UNSAFE_FUZZER_MODE
871 
872  return true;
873 }
874 
876 
877 using namespace bssl;
878 
879 void SSL_set_enable_ech_grease(SSL *ssl, int enable) {
880  if (!ssl->config) {
881  return;
882  }
883  ssl->config->ech_grease_enabled = !!enable;
884 }
885 
886 int SSL_set1_ech_config_list(SSL *ssl, const uint8_t *ech_config_list,
887  size_t ech_config_list_len) {
888  if (!ssl->config) {
889  return 0;
890  }
891 
892  auto span = MakeConstSpan(ech_config_list, ech_config_list_len);
893  if (!ssl_is_valid_ech_config_list(span)) {
895  return 0;
896  }
897  return ssl->config->client_ech_config_list.CopyFrom(span);
898 }
899 
900 void SSL_get0_ech_name_override(const SSL *ssl, const char **out_name,
901  size_t *out_name_len) {
902  // When ECH is rejected, we use the public name. Note that, if
903  // |SSL_CTX_set_reverify_on_resume| is enabled, we reverify the certificate
904  // before the 0-RTT point. If also offering ECH, we verify as if
905  // ClientHelloInner was accepted and do not override. This works because, at
906  // this point, |ech_status| will be |ssl_ech_none|. See the
907  // ECH-Client-Reject-EarlyDataReject-OverrideNameOnRetry tests in runner.go.
908  const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
909  if (!ssl->server && hs && ssl->s3->ech_status == ssl_ech_rejected) {
910  *out_name = reinterpret_cast<const char *>(
911  hs->selected_ech_config->public_name.data());
912  *out_name_len = hs->selected_ech_config->public_name.size();
913  } else {
914  *out_name = nullptr;
915  *out_name_len = 0;
916  }
917 }
918 
920  const SSL *ssl, const uint8_t **out_retry_configs,
921  size_t *out_retry_configs_len) {
922  const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
923  if (!hs || !hs->ech_authenticated_reject) {
924  // It is an error to call this function except in response to
925  // |SSL_R_ECH_REJECTED|. Returning an empty string risks the caller
926  // mistakenly believing the server has disabled ECH. Instead, return a
927  // non-empty ECHConfigList with a syntax error, so the subsequent
928  // |SSL_set1_ech_config_list| call will fail.
929  assert(0);
930  static const uint8_t kPlaceholder[] = {
931  kECHConfigVersion >> 8, kECHConfigVersion & 0xff, 0xff, 0xff, 0xff};
932  *out_retry_configs = kPlaceholder;
933  *out_retry_configs_len = sizeof(kPlaceholder);
934  return;
935  }
936 
937  *out_retry_configs = hs->ech_retry_configs.data();
938  *out_retry_configs_len = hs->ech_retry_configs.size();
939 }
940 
941 int SSL_marshal_ech_config(uint8_t **out, size_t *out_len, uint8_t config_id,
942  const EVP_HPKE_KEY *key, const char *public_name,
943  size_t max_name_len) {
944  Span<const uint8_t> public_name_u8 = MakeConstSpan(
945  reinterpret_cast<const uint8_t *>(public_name), strlen(public_name));
946  if (!ssl_is_valid_ech_public_name(public_name_u8)) {
948  return 0;
949  }
950 
951  // The maximum name length is encoded in one byte.
952  if (max_name_len > 0xff) {
954  return 0;
955  }
956 
957  // See draft-ietf-tls-esni-13, section 4.
958  ScopedCBB cbb;
959  CBB contents, child;
961  size_t public_key_len;
962  if (!CBB_init(cbb.get(), 128) || //
963  !CBB_add_u16(cbb.get(), kECHConfigVersion) ||
964  !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
965  !CBB_add_u8(&contents, config_id) ||
969  !EVP_HPKE_KEY_public_key(key, public_key, &public_key_len,
971  !CBB_did_write(&child, public_key_len) ||
973  // Write a default cipher suite configuration.
978  !CBB_add_u8(&contents, max_name_len) ||
980  !CBB_add_bytes(&child, public_name_u8.data(), public_name_u8.size()) ||
981  // TODO(https://crbug.com/boringssl/275): Reserve some GREASE extensions
982  // and include some.
983  !CBB_add_u16(&contents, 0 /* no extensions */) ||
984  !CBB_finish(cbb.get(), out, out_len)) {
986  return 0;
987  }
988  return 1;
989 }
990 
991 SSL_ECH_KEYS *SSL_ECH_KEYS_new() { return New<SSL_ECH_KEYS>(); }
992 
994  CRYPTO_refcount_inc(&keys->references);
995 }
996 
998  if (keys == nullptr ||
999  !CRYPTO_refcount_dec_and_test_zero(&keys->references)) {
1000  return;
1001  }
1002 
1003  keys->~ssl_ech_keys_st();
1004  OPENSSL_free(keys);
1005 }
1006 
1007 int SSL_ECH_KEYS_add(SSL_ECH_KEYS *configs, int is_retry_config,
1008  const uint8_t *ech_config, size_t ech_config_len,
1009  const EVP_HPKE_KEY *key) {
1010  UniquePtr<ECHServerConfig> parsed_config = MakeUnique<ECHServerConfig>();
1011  if (!parsed_config) {
1012  return 0;
1013  }
1014  if (!parsed_config->Init(MakeConstSpan(ech_config, ech_config_len), key,
1015  !!is_retry_config)) {
1017  return 0;
1018  }
1019  if (!configs->configs.Push(std::move(parsed_config))) {
1021  return 0;
1022  }
1023  return 1;
1024 }
1025 
1027  bool seen[256] = {false};
1028  for (const auto &config : keys->configs) {
1029  if (seen[config->ech_config().config_id]) {
1030  return 1;
1031  }
1032  seen[config->ech_config().config_id] = true;
1033  }
1034  return 0;
1035 }
1036 
1038  size_t *out_len) {
1039  ScopedCBB cbb;
1040  CBB child;
1041  if (!CBB_init(cbb.get(), 128) ||
1042  !CBB_add_u16_length_prefixed(cbb.get(), &child)) {
1044  return false;
1045  }
1046  for (const auto &config : keys->configs) {
1047  if (config->is_retry_config() &&
1048  !CBB_add_bytes(&child, config->ech_config().raw.data(),
1049  config->ech_config().raw.size())) {
1051  return false;
1052  }
1053  }
1054  return CBB_finish(cbb.get(), out, out_len);
1055 }
1056 
1058  bool has_retry_config = false;
1059  for (const auto &config : keys->configs) {
1060  if (config->is_retry_config()) {
1061  has_retry_config = true;
1062  break;
1063  }
1064  }
1065  if (!has_retry_config) {
1067  return 0;
1068  }
1069  UniquePtr<SSL_ECH_KEYS> owned_keys = UpRef(keys);
1070  MutexWriteLock lock(&ctx->lock);
1071  ctx->ech_keys.swap(owned_keys);
1072  return 1;
1073 }
1074 
1075 int SSL_ech_accepted(const SSL *ssl) {
1076  if (SSL_in_early_data(ssl) && !ssl->server) {
1077  // In the client early data state, we report properties as if the server
1078  // accepted early data. The server can only accept early data with
1079  // ClientHelloInner.
1080  return ssl->s3->hs->selected_ech_config != nullptr;
1081  }
1082 
1083  return ssl->s3->ech_status == ssl_ech_accepted;
1084 }
ssl_select_ech_config
bool ssl_select_ech_config(SSL_HANDSHAKE *hs, Span< uint8_t > out_enc, size_t *out_enc_len)
Definition: encrypted_client_hello.cc:618
ssl_st::server
bool server
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3777
Span::subspan
Span subspan(size_t pos=0, size_t len=npos) const
Definition: boringssl-with-bazel/src/include/openssl/span.h:162
ssl_early_callback_ctx::cipher_suites
const uint8_t * cipher_suites
Definition: ssl.h:4195
CBB_flush
#define CBB_flush
Definition: boringssl_prefix_symbols.h:1045
CBB_data
#define CBB_data
Definition: boringssl_prefix_symbols.h:1040
ECH_CLIENT_INNER
#define ECH_CLIENT_INNER
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1493
EVP_HPKE_CTX_setup_recipient
#define EVP_HPKE_CTX_setup_recipient
Definition: boringssl_prefix_symbols.h:1544
SSL_CONFIG::client_ech_config_list
Array< uint8_t > client_ech_config_list
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3041
public_key
Definition: hrss.c:1881
CBB_init
#define CBB_init
Definition: boringssl_prefix_symbols.h:1047
EVP_hpke_chacha20_poly1305
#define EVP_hpke_chacha20_poly1305
Definition: boringssl_prefix_symbols.h:1732
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
RAND_bytes
#define RAND_bytes
Definition: boringssl_prefix_symbols.h:2060
SSL_get0_ech_name_override
void SSL_get0_ech_name_override(const SSL *ssl, const char **out_name, size_t *out_name_len)
Definition: encrypted_client_hello.cc:900
SSL_CTX_set1_ech_keys
int SSL_CTX_set1_ech_keys(SSL_CTX *ctx, SSL_ECH_KEYS *keys)
Definition: encrypted_client_hello.cc:1057
CBS_get_u16
#define CBS_get_u16
Definition: boringssl_prefix_symbols.h:1073
ECHServerConfig::ech_config
const ECHConfig & ech_config() const
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1476
Span::size
size_t size() const
Definition: boringssl-with-bazel/src/include/openssl/span.h:133
cbs_st
Definition: bytestring.h:39
ctx
Definition: benchmark-async.c:30
CBS_skip
#define CBS_skip
Definition: boringssl_prefix_symbols.h:1092
ECHServerConfig::is_retry_config
bool is_retry_config() const
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1477
EVP_HPKE_CTX_setup_sender
#define EVP_HPKE_CTX_setup_sender
Definition: boringssl_prefix_symbols.h:1545
find
static void ** find(grpc_chttp2_stream_map *map, uint32_t key)
Definition: stream_map.cc:99
ssl_early_callback_ctx::compression_methods_len
size_t compression_methods_len
Definition: ssl.h:4198
is_decimal_component
static bool is_decimal_component(Span< const uint8_t > in)
Definition: encrypted_client_hello.cc:326
google::protobuf::extension
const Descriptor::ReservedRange const EnumValueDescriptor const MethodDescriptor extension
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:2001
EVP_HPKE_DHKEM_X25519_HKDF_SHA256
#define EVP_HPKE_DHKEM_X25519_HKDF_SHA256
Definition: hpke.h:43
DTLS1_2_VERSION
#define DTLS1_2_VERSION
Definition: ssl.h:656
Array::data
const T * data() const
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:274
X25519_PRIVATE_KEY_LEN
#define X25519_PRIVATE_KEY_LEN
Definition: curve25519.h:36
setup_ech_grease
static bool setup_ech_grease(SSL_HANDSHAKE *hs)
Definition: encrypted_client_hello.cc:695
CBS_data
#define CBS_data
Definition: boringssl_prefix_symbols.h:1057
ssl_is_valid_ech_config_list
bool ssl_is_valid_ech_config_list(Span< const uint8_t > ech_config_list)
Definition: encrypted_client_hello.cc:568
keys
const void * keys
Definition: abseil-cpp/absl/random/internal/randen.cc:49
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
ssl_early_callback_ctx::random_len
size_t random_len
Definition: ssl.h:4192
SSL_HANDSHAKE::inner_transcript
SSLTranscript inner_transcript
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1826
evp_hpke_kem_st
Definition: hpke.c:38
OPENSSL_PUT_ERROR
#define OPENSSL_PUT_ERROR(library, reason)
Definition: err.h:423
string.h
evp_hpke_ctx_st
Definition: hpke.h:309
CBB_add_u16_length_prefixed
#define CBB_add_u16_length_prefixed
Definition: boringssl_prefix_symbols.h:1028
CBB_add_u8
#define CBB_add_u8
Definition: boringssl_prefix_symbols.h:1036
ssl_st::config
bssl::UniquePtr< bssl::SSL_CONFIG > config
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3712
SSL_HANDSHAKE::ssl
SSL * ssl
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1726
SSL_R_ECH_SERVER_WOULD_HAVE_NO_RETRY_CONFIGS
#define SSL_R_ECH_SERVER_WOULD_HAVE_NO_RETRY_CONFIGS
Definition: ssl.h:5580
SSL_ECH_KEYS_add
int SSL_ECH_KEYS_add(SSL_ECH_KEYS *configs, int is_retry_config, const uint8_t *ech_config, size_t ech_config_len, const EVP_HPKE_KEY *key)
Definition: encrypted_client_hello.cc:1007
hpke.h
CBS_get_u8_length_prefixed
#define CBS_get_u8_length_prefixed
Definition: boringssl_prefix_symbols.h:1083
aead_overhead
static size_t aead_overhead(const EVP_HPKE_AEAD *aead)
Definition: encrypted_client_hello.cc:676
ECHServerConfig::is_retry_config_
bool is_retry_config_
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1482
tls13_write_psk_binder
bool tls13_write_psk_binder(const SSL_HANDSHAKE *hs, const SSLTranscript &transcript, Span< uint8_t > msg, size_t *out_binder_len)
Definition: tls13_enc.cc:473
SSL_set_enable_ech_grease
void SSL_set_enable_ech_grease(SSL *ssl, int enable)
Definition: encrypted_client_hello.cc:879
CBS_len
#define CBS_len
Definition: boringssl_prefix_symbols.h:1089
ssl_grease_ech_config_id
@ ssl_grease_ech_config_id
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1637
evp_hpke_key_st
Definition: hpke.h:319
SSL_HANDSHAKE::selected_ech_config
UniquePtr< ECHConfig > selected_ech_config
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1930
ssl_write_client_hello_without_extensions
bool ssl_write_client_hello_without_extensions(const SSL_HANDSHAKE *hs, CBB *cbb, ssl_client_hello_type_t type, bool empty_session_id)
Definition: handshake_client.cc:286
bssl
Definition: hpke_test.cc:37
Span::back
T & back() const
Definition: boringssl-with-bazel/src/include/openssl/span.h:147
CBB_add_space
#define CBB_add_space
Definition: boringssl_prefix_symbols.h:1026
version
Definition: version.py:1
ECHConfig
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1445
internal.h
cipher_suites
static const char * cipher_suites
Definition: ssl_utils.cc:78
cbs
const CBS * cbs
Definition: third_party/boringssl-with-bazel/src/crypto/trust_token/internal.h:107
SSL_AD_ILLEGAL_PARAMETER
#define SSL_AD_ILLEGAL_PARAMETER
Definition: ssl.h:3807
get_ech_aead
static const EVP_HPKE_AEAD * get_ech_aead(uint16_t aead_id)
Definition: encrypted_client_hello.cc:46
ssl_ech_accepted
@ ssl_ech_accepted
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:2614
ssl_early_callback_ctx::client_hello_len
size_t client_hello_len
Definition: ssl.h:4189
CBS_init
#define CBS_init
Definition: boringssl_prefix_symbols.h:1085
EVP_hpke_hkdf_sha256
#define EVP_hpke_hkdf_sha256
Definition: boringssl_prefix_symbols.h:1733
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
select_ech_cipher_suite
static bool select_ech_cipher_suite(const EVP_HPKE_KDF **out_kdf, const EVP_HPKE_AEAD **out_aead, Span< const uint8_t > cipher_suites)
Definition: encrypted_client_hello.cc:586
ssl_ctx_st
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3404
TLSEXT_TYPE_ech_outer_extensions
#define TLSEXT_TYPE_ech_outer_extensions
Definition: tls1.h:252
SSL3_MT_CLIENT_HELLO
#define SSL3_MT_CLIENT_HELLO
Definition: ssl3.h:299
evp_hpke_kdf_st
Definition: hpke.c:57
OPENSSL_memset
static void * OPENSSL_memset(void *dst, int c, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:835
Array::CopyFrom
bool CopyFrom(Span< const T > in)
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:338
EVP_HPKE_CTX_aead
#define EVP_HPKE_CTX_aead
Definition: boringssl_prefix_symbols.h:1535
ECHConfig::raw
Array< uint8_t > raw
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1448
ECHConfig::kem_id
uint16_t kem_id
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1453
SSL_ECH_KEYS_has_duplicate_config_id
int SSL_ECH_KEYS_has_duplicate_config_id(const SSL_ECH_KEYS *keys)
Definition: encrypted_client_hello.cc:1026
EVP_HPKE_KEY_kem
#define EVP_HPKE_KEY_kem
Definition: boringssl_prefix_symbols.h:1555
EVP_HPKE_KEY_public_key
#define EVP_HPKE_KEY_public_key
Definition: boringssl_prefix_symbols.h:1558
SSL_HANDSHAKE::ech_client_outer
Array< uint8_t > ech_client_outer
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1837
SSL_HANDSHAKE::ech_hpke_ctx
ScopedEVP_HPKE_CTX ech_hpke_ctx
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1884
kSupportedAEADs
static const decltype(&EVP_hpke_aes_128_gcm) kSupportedAEADs[]
Definition: encrypted_client_hello.cc:40
CBB_reserve
#define CBB_reserve
Definition: boringssl_prefix_symbols.h:1050
TLSEXT_TYPE_supported_versions
#define TLSEXT_TYPE_supported_versions
Definition: tls1.h:232
Array::empty
bool empty() const
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:277
ECHServerConfig::Init
bool Init(Span< const uint8_t > ech_config, const EVP_HPKE_KEY *key, bool is_retry_config)
Definition: encrypted_client_hello.cc:467
CBB_did_write
#define CBB_did_write
Definition: boringssl_prefix_symbols.h:1041
bytestring.h
ssl_add_clienthello_tlsext
bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, CBB *out_encoded, bool *out_needs_psk_binder, ssl_client_hello_type_t type, size_t header_len)
Definition: extensions.cc:3426
ssl_decode_client_hello_inner
bool ssl_decode_client_hello_inner(SSL *ssl, uint8_t *out_alert, Array< uint8_t > *out_client_hello_inner, Span< const uint8_t > encoded_client_hello_inner, const SSL_CLIENT_HELLO *client_hello_outer)
Definition: encrypted_client_hello.cc:125
SSL_HANDSHAKE::ech_authenticated_reject
bool ech_authenticated_reject
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1951
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
SSL_ech_accepted
int SSL_ech_accepted(const SSL *ssl)
Definition: encrypted_client_hello.cc:1075
CBB_add_u16
#define CBB_add_u16
Definition: boringssl_prefix_symbols.h:1027
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
SSL_ECH_KEYS_marshal_retry_configs
int SSL_ECH_KEYS_marshal_retry_configs(const SSL_ECH_KEYS *keys, uint8_t **out, size_t *out_len)
Definition: encrypted_client_hello.cc:1037
TLS1_1_VERSION
#define TLS1_1_VERSION
Definition: ssl.h:651
SSL_HANDSHAKE
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1720
SSL_R_OUTER_EXTENSION_NOT_FOUND
#define SSL_R_OUTER_EXTENSION_NOT_FOUND
Definition: ssl.h:5587
SSL_R_DECRYPTION_FAILED
#define SSL_R_DECRYPTION_FAILED
Definition: ssl.h:5406
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
Array< uint8_t >
gen_stats_data.found
bool found
Definition: gen_stats_data.py:61
Span::empty
bool empty() const
Definition: boringssl-with-bazel/src/include/openssl/span.h:134
config
struct config_s config
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
Array::size
size_t size() const
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:276
CBB_add_zeros
#define CBB_add_zeros
Definition: boringssl_prefix_symbols.h:1038
CBB_add_u8_length_prefixed
#define CBB_add_u8_length_prefixed
Definition: boringssl_prefix_symbols.h:1037
ssl_st
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3698
ssl_early_callback_ctx
Definition: ssl.h:4186
CBB_finish
#define CBB_finish
Definition: boringssl_prefix_symbols.h:1043
EVP_HPKE_HKDF_SHA256
#define EVP_HPKE_HKDF_SHA256
Definition: hpke.h:55
ssl_early_callback_ctx::cipher_suites_len
size_t cipher_suites_len
Definition: ssl.h:4196
ECHServerConfig::SetupContext
bool SetupContext(EVP_HPKE_CTX *ctx, uint16_t kdf_id, uint16_t aead_id, Span< const uint8_t > enc) const
Definition: encrypted_client_hello.cc:529
conf.version
string version
Definition: doc/python/sphinx/conf.py:36
random_size
static size_t random_size(size_t min, size_t max)
Definition: encrypted_client_hello.cc:688
ssl_client_hello_get_extension
bool ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello, CBS *out, uint16_t extension_type)
Definition: extensions.cc:283
OPENSSL_memcpy
static void * OPENSSL_memcpy(void *dst, const void *src, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:819
SSL_marshal_ech_config
int SSL_marshal_ech_config(uint8_t **out, size_t *out_len, uint8_t config_id, const EVP_HPKE_KEY *key, const char *public_name, size_t max_name_len)
Definition: encrypted_client_hello.cc:941
BSSL_NAMESPACE_END
#define BSSL_NAMESPACE_END
Definition: base.h:480
CBS_get_u8
#define CBS_get_u8
Definition: boringssl_prefix_symbols.h:1082
ssl_early_callback_ctx::random
const uint8_t * random
Definition: ssl.h:4191
err.h
ERR_R_INTERNAL_ERROR
#define ERR_R_INTERNAL_ERROR
Definition: err.h:374
Span::front
T & front() const
Definition: boringssl-with-bazel/src/include/openssl/span.h:141
configs
static grpc_end2end_test_config configs[]
Definition: h2_census.cc:111
googletest-filter-unittest.child
child
Definition: bloaty/third_party/googletest/googletest/test/googletest-filter-unittest.py:62
SSL_R_BAD_LENGTH
#define SSL_R_BAD_LENGTH
Definition: ssl.h:5379
SSL_set1_ech_config_list
int SSL_set1_ech_config_list(SSL *ssl, const uint8_t *ech_config_list, size_t ech_config_list_len)
Definition: encrypted_client_hello.cc:886
conf.extensions
list extensions
Definition: doc/python/sphinx/conf.py:54
SSL_HANDSHAKE::max_version
uint16_t max_version
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1749
uintptr_t
_W64 unsigned int uintptr_t
Definition: stdint-msvc2008.h:119
min
#define min(a, b)
Definition: qsort.h:83
EVP_HPKE_CTX_kdf
#define EVP_HPKE_CTX_kdf
Definition: boringssl_prefix_symbols.h:1539
aead.h
kECHConfigVersion
static constexpr BSSL_NAMESPACE_BEGIN uint16_t kECHConfigVersion
Definition: encrypted_client_hello.cc:37
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
SSL_HANDSHAKE::ech_retry_configs
Array< uint8_t > ech_retry_configs
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1841
ssl_client_hello_write_without_extensions
static bool ssl_client_hello_write_without_extensions(const SSL_CLIENT_HELLO *client_hello, CBB *out)
Definition: encrypted_client_hello.cc:61
Span< const uint8_t >
ssl_st::hostname
bssl::UniquePtr< char > hostname
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3766
ssl_client_hello_init
bool ssl_client_hello_init(const SSL *ssl, SSL_CLIENT_HELLO *out, Span< const uint8_t > body)
Definition: extensions.cc:211
ssl.h
ssl_early_callback_ctx::session_id
const uint8_t * session_id
Definition: ssl.h:4193
ssl_is_valid_ech_public_name
bool ssl_is_valid_ech_public_name(Span< const uint8_t > public_name)
Definition: encrypted_client_hello.cc:338
ssl_parse_client_hello_with_trailing_data
bool ssl_parse_client_hello_with_trailing_data(const SSL *ssl, CBS *cbs, SSL_CLIENT_HELLO *out)
Definition: extensions.cc:221
SSL3_VERSION
#define SSL3_VERSION
Definition: ssl.h:649
X25519_keypair
#define X25519_keypair
Definition: boringssl_prefix_symbols.h:2210
value
const char * value
Definition: hpack_parser_table.cc:165
ECHConfig::public_key
Span< const uint8_t > public_key
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1450
EVP_HPKE_CTX_open
#define EVP_HPKE_CTX_open
Definition: boringssl_prefix_symbols.h:1542
TLS1_3_VERSION
#define TLS1_3_VERSION
Definition: ssl.h:653
EVP_HPKE_KEM_id
#define EVP_HPKE_KEM_id
Definition: boringssl_prefix_symbols.h:1549
ssl_early_callback_ctx::session_id_len
size_t session_id_len
Definition: ssl.h:4194
EVP_has_aes_hardware
#define EVP_has_aes_hardware
Definition: boringssl_prefix_symbols.h:1729
ssl_early_callback_ctx::compression_methods
const uint8_t * compression_methods
Definition: ssl.h:4197
CBB_add_bytes
#define CBB_add_bytes
Definition: boringssl_prefix_symbols.h:1025
contents
string_view contents
Definition: elf.cc:597
SSL_R_INVALID_ECH_PUBLIC_NAME
#define SSL_R_INVALID_ECH_PUBLIC_NAME
Definition: ssl.h:5584
TLS1_2_VERSION
#define TLS1_2_VERSION
Definition: ssl.h:652
CBBFinishArray
OPENSSL_EXPORT bool CBBFinishArray(CBB *cbb, Array< uint8_t > *out)
Definition: ssl_lib.cc:190
is_hex_component
static bool is_hex_component(Span< const uint8_t > in)
Definition: encrypted_client_hello.cc:313
ssl_early_callback_ctx::version
uint16_t version
Definition: ssl.h:4190
BSSL_NAMESPACE_BEGIN
Definition: trust_token_test.cc:45
ssl_st::s3
bssl::SSL3_STATE * s3
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3730
rand.h
key
const char * key
Definition: hpack_parser_table.cc:164
SSL_HANDSHAKE::config
SSL_CONFIG * config
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1729
EVP_hpke_x25519_hkdf_sha256
#define EVP_hpke_x25519_hkdf_sha256
Definition: boringssl_prefix_symbols.h:1734
ssl_early_callback_ctx::extensions
const uint8_t * extensions
Definition: ssl.h:4199
SSL_HANDSHAKE::grease_seed
uint8_t grease_seed[ssl_grease_last_index+1]
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:2062
EVP_HPKE_KDF_id
#define EVP_HPKE_KDF_id
Definition: boringssl_prefix_symbols.h:1548
TLS1_VERSION
#define TLS1_VERSION
Definition: ssl.h:650
EVP_HPKE_AES_128_GCM
#define EVP_HPKE_AES_128_GCM
Definition: hpke.h:64
is_valid_client_hello_inner
static bool is_valid_client_hello_inner(SSL *ssl, uint8_t *out_alert, Span< const uint8_t > body)
Definition: encrypted_client_hello.cc:81
SSL_R_INVALID_ECH_CONFIG_LIST
#define SSL_R_INVALID_ECH_CONFIG_LIST
Definition: ssl.h:5585
hkdf.h
SSL_CONFIG::ech_grease_enabled
bool ech_grease_enabled
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3048
SSL_AD_DECODE_ERROR
#define SSL_AD_DECODE_ERROR
Definition: ssl.h:3810
SSL_ECH_KEYS_free
void SSL_ECH_KEYS_free(SSL_ECH_KEYS *keys)
Definition: encrypted_client_hello.cc:997
CBS_get_u16_length_prefixed
#define CBS_get_u16_length_prefixed
Definition: boringssl_prefix_symbols.h:1074
ECHServerConfig::key_
ScopedEVP_HPKE_KEY key_
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1481
ssl_client_hello_inner
@ ssl_client_hello_inner
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1487
EVP_hpke_aes_128_gcm
#define EVP_hpke_aes_128_gcm
Definition: boringssl_prefix_symbols.h:1730
SSLTranscript::Update
bool Update(Span< const uint8_t > in)
Definition: ssl_transcript.cc:220
gen_header_frame.payload_len
int payload_len
Definition: gen_header_frame.py:89
EVP_HPKE_AEAD_id
#define EVP_HPKE_AEAD_id
Definition: boringssl_prefix_symbols.h:1534
EVP_HPKE_CHACHA20_POLY1305
#define EVP_HPKE_CHACHA20_POLY1305
Definition: hpke.h:66
EVP_HPKE_CTX_seal
#define EVP_HPKE_CTX_seal
Definition: boringssl_prefix_symbols.h:1543
curve25519.h
ssl_client_hello_outer
@ ssl_client_hello_outer
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1488
ssl_client_hello_decrypt
bool ssl_client_hello_decrypt(EVP_HPKE_CTX *hpke_ctx, Array< uint8_t > *out, bool *out_is_decrypt_error, const SSL_CLIENT_HELLO *client_hello_outer, Span< const uint8_t > payload)
Definition: encrypted_client_hello.cc:255
EVP_hpke_aes_256_gcm
#define EVP_hpke_aes_256_gcm
Definition: boringssl_prefix_symbols.h:1731
ssl_ech_rejected
@ ssl_ech_rejected
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:2616
ssl_st::method
const bssl::SSL_PROTOCOL_METHOD * method
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3706
ECHConfig::cipher_suites
Span< const uint8_t > cipher_suites
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1452
SSL_get0_ech_retry_configs
void SSL_get0_ech_retry_configs(const SSL *ssl, const uint8_t **out_retry_configs, size_t *out_retry_configs_len)
Definition: encrypted_client_hello.cc:919
SSLTranscript::Init
bool Init()
Definition: ssl_transcript.cc:151
CRYPTO_refcount_inc
#define CRYPTO_refcount_inc
Definition: boringssl_prefix_symbols.h:1191
SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG
#define SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG
Definition: ssl.h:5579
ssl_encrypt_client_hello
bool ssl_encrypt_client_hello(SSL_HANDSHAKE *hs, Span< const uint8_t > enc)
Definition: encrypted_client_hello.cc:748
ssl_early_callback_ctx::client_hello
const uint8_t * client_hello
Definition: ssl.h:4188
parse_ech_config
static bool parse_ech_config(CBS *cbs, ECHConfig *out, bool *out_supported, bool all_extensions_mandatory)
Definition: encrypted_client_hello.cc:389
Span::data
T * data() const
Definition: boringssl-with-bazel/src/include/openssl/span.h:132
ECHServerConfig::ech_config_
ECHConfig ech_config_
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1480
TLSEXT_TYPE_encrypted_client_hello
#define TLSEXT_TYPE_encrypted_client_hello
Definition: tls1.h:251
CBB_len
#define CBB_len
Definition: boringssl_prefix_symbols.h:1049
SSL_R_DECODE_ERROR
#define SSL_R_DECODE_ERROR
Definition: ssl.h:5405
EVP_HPKE_MAX_PUBLIC_KEY_LENGTH
#define EVP_HPKE_MAX_PUBLIC_KEY_LENGTH
Definition: hpke.h:132
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
SSL_in_early_data
#define SSL_in_early_data
Definition: boringssl_prefix_symbols.h:399
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
SSL_ECH_KEYS_up_ref
void SSL_ECH_KEYS_up_ref(SSL_ECH_KEYS *keys)
Definition: encrypted_client_hello.cc:993
DTLS1_VERSION
#define DTLS1_VERSION
Definition: ssl.h:655
SSL_ECH_KEYS_new
SSL_ECH_KEYS * SSL_ECH_KEYS_new()
Definition: encrypted_client_hello.cc:991
SSL_R_INVALID_CLIENT_HELLO_INNER
#define SSL_R_INVALID_CLIENT_HELLO_INNER
Definition: ssl.h:5581
seen
bool * seen
Definition: async_end2end_test.cc:198
X25519_PUBLIC_VALUE_LEN
#define X25519_PUBLIC_VALUE_LEN
Definition: curve25519.h:37
gen_server_registered_method_bad_client_test_body.payload
list payload
Definition: gen_server_registered_method_bad_client_test_body.py:40
ssl_ech_keys_st
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3940
OPENSSL_free
#define OPENSSL_free
Definition: boringssl_prefix_symbols.h:1869
EVP_HPKE_KEY_copy
#define EVP_HPKE_KEY_copy
Definition: boringssl_prefix_symbols.h:1551
SSL_R_ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH
#define SSL_R_ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH
Definition: ssl.h:5577
absl::MakeSpan
constexpr Span< T > MakeSpan(T *ptr, size_t size) noexcept
Definition: abseil-cpp/absl/types/span.h:661
evp_hpke_aead_st
Definition: hpke.c:63
ssl_early_callback_ctx::extensions_len
size_t extensions_len
Definition: ssl.h:4200
ERR_R_MALLOC_FAILURE
#define ERR_R_MALLOC_FAILURE
Definition: err.h:371
offset
voidpf uLong offset
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:142
EVP_AEAD_max_overhead
#define EVP_AEAD_max_overhead
Definition: boringssl_prefix_symbols.h:1459
CRYPTO_refcount_dec_and_test_zero
#define CRYPTO_refcount_dec_and_test_zero
Definition: boringssl_prefix_symbols.h:1190
EVP_HPKE_AEAD_aead
#define EVP_HPKE_AEAD_aead
Definition: boringssl_prefix_symbols.h:1533
absl::MakeConstSpan
constexpr Span< const T > MakeConstSpan(T *ptr, size_t size) noexcept
Definition: abseil-cpp/absl/types/span.h:707
cbb_st
Definition: bytestring.h:375


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:59:15