Coverage Report

Created: 2025-11-17 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/ssl/encrypted_client_hello.cc
Line
Count
Source
1
// Copyright 2021 The BoringSSL Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
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 "../crypto/internal.h"
32
#include "internal.h"
33
34
35
BSSL_NAMESPACE_BEGIN
36
37
// ECH reuses the extension code point for the version number.
38
static constexpr uint16_t kECHConfigVersion =
39
    TLSEXT_TYPE_encrypted_client_hello;
40
41
static const decltype(&EVP_hpke_aes_128_gcm) kSupportedAEADs[] = {
42
    &EVP_hpke_aes_128_gcm,
43
    &EVP_hpke_aes_256_gcm,
44
    &EVP_hpke_chacha20_poly1305,
45
};
46
47
1.40k
static const EVP_HPKE_AEAD *get_ech_aead(uint16_t aead_id) {
48
2.85k
  for (const auto aead_func : kSupportedAEADs) {
49
2.85k
    const EVP_HPKE_AEAD *aead = aead_func();
50
2.85k
    if (aead_id == EVP_HPKE_AEAD_id(aead)) {
51
950
      return aead;
52
950
    }
53
2.85k
  }
54
458
  return nullptr;
55
1.40k
}
56
57
// ssl_client_hello_write_without_extensions serializes |client_hello| into
58
// |out|, omitting the length-prefixed extensions. It serializes individual
59
// fields, starting with |client_hello->version|, and ignores the
60
// |client_hello->client_hello| field. It returns true on success and false on
61
// failure.
62
static bool ssl_client_hello_write_without_extensions(
63
525
    const SSL_CLIENT_HELLO *client_hello, CBB *out) {
64
525
  CBB cbb;
65
525
  if (!CBB_add_u16(out, client_hello->version) ||
66
525
      !CBB_add_bytes(out, client_hello->random, client_hello->random_len) ||
67
525
      !CBB_add_u8_length_prefixed(out, &cbb) ||
68
525
      !CBB_add_bytes(&cbb, client_hello->session_id,
69
525
                     client_hello->session_id_len)) {
70
0
    return false;
71
0
  }
72
525
  if (SSL_is_dtls(client_hello->ssl)) {
73
109
    if (!CBB_add_u8_length_prefixed(out, &cbb) ||
74
109
        !CBB_add_bytes(&cbb, client_hello->dtls_cookie,
75
109
                       client_hello->dtls_cookie_len)) {
76
0
      return false;
77
0
    }
78
109
  }
79
525
  if (!CBB_add_u16_length_prefixed(out, &cbb) ||
80
525
      !CBB_add_bytes(&cbb, client_hello->cipher_suites,
81
525
                     client_hello->cipher_suites_len) ||
82
525
      !CBB_add_u8_length_prefixed(out, &cbb) ||
83
525
      !CBB_add_bytes(&cbb, client_hello->compression_methods,
84
525
                     client_hello->compression_methods_len) ||
85
525
      !CBB_flush(out)) {
86
0
    return false;
87
0
  }
88
525
  return true;
89
525
}
90
91
static bool is_valid_client_hello_inner(SSL *ssl, uint8_t *out_alert,
92
408
                                        Span<const uint8_t> body) {
93
  // See draft-ietf-tls-esni-13, section 7.1.
94
408
  SSL_CLIENT_HELLO client_hello;
95
408
  CBS extension;
96
408
  if (!SSL_parse_client_hello(ssl, &client_hello, body.data(), body.size()) ||
97
402
      !ssl_client_hello_get_extension(&client_hello, &extension,
98
402
                                      TLSEXT_TYPE_encrypted_client_hello) ||
99
294
      CBS_len(&extension) != 1 ||  //
100
278
      CBS_data(&extension)[0] != ECH_CLIENT_INNER ||
101
264
      !ssl_client_hello_get_extension(&client_hello, &extension,
102
264
                                      TLSEXT_TYPE_supported_versions)) {
103
156
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
104
156
    OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_CLIENT_HELLO_INNER);
105
156
    return false;
106
156
  }
107
  // Parse supported_versions and reject TLS versions prior to TLS 1.3. Older
108
  // versions are incompatible with ECH.
109
252
  CBS versions;
110
252
  if (!CBS_get_u8_length_prefixed(&extension, &versions) ||
111
247
      CBS_len(&extension) != 0 ||  //
112
231
      CBS_len(&versions) == 0) {
113
28
    *out_alert = SSL_AD_DECODE_ERROR;
114
28
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
115
28
    return false;
116
28
  }
117
1.22k
  while (CBS_len(&versions) != 0) {
118
1.04k
    uint16_t version;
119
1.04k
    if (!CBS_get_u16(&versions, &version)) {
120
16
      *out_alert = SSL_AD_DECODE_ERROR;
121
16
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
122
16
      return false;
123
16
    }
124
1.03k
    if (version == SSL3_VERSION || version == TLS1_VERSION ||
125
1.02k
        version == TLS1_1_VERSION || version == TLS1_2_VERSION ||
126
1.01k
        version == DTLS1_VERSION || version == DTLS1_2_VERSION) {
127
30
      *out_alert = SSL_AD_ILLEGAL_PARAMETER;
128
30
      OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_CLIENT_HELLO_INNER);
129
30
      return false;
130
30
    }
131
1.03k
  }
132
178
  return true;
133
224
}
134
135
bool ssl_decode_client_hello_inner(
136
    SSL *ssl, uint8_t *out_alert, Array<uint8_t> *out_client_hello_inner,
137
    Span<const uint8_t> encoded_client_hello_inner,
138
643
    const SSL_CLIENT_HELLO *client_hello_outer) {
139
643
  SSL_CLIENT_HELLO client_hello_inner;
140
643
  CBS cbs = encoded_client_hello_inner;
141
643
  if (!ssl_parse_client_hello_with_trailing_data(ssl, &cbs,
142
643
                                                 &client_hello_inner)) {
143
65
    return false;
144
65
  }
145
  // The remaining data is padding.
146
578
  uint8_t padding;
147
5.56k
  while (CBS_get_u8(&cbs, &padding)) {
148
5.02k
    if (padding != 0) {
149
30
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
150
30
      *out_alert = SSL_AD_ILLEGAL_PARAMETER;
151
30
      return false;
152
30
    }
153
5.02k
  }
154
155
  // TLS 1.3 ClientHellos must have extensions, and EncodedClientHelloInners use
156
  // ClientHelloOuter's session_id.
157
548
  if (client_hello_inner.extensions_len == 0 ||
158
532
      client_hello_inner.session_id_len != 0) {
159
23
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
160
23
    return false;
161
23
  }
162
525
  client_hello_inner.session_id = client_hello_outer->session_id;
163
525
  client_hello_inner.session_id_len = client_hello_outer->session_id_len;
164
165
  // Begin serializing a message containing the ClientHelloInner in |cbb|.
166
525
  ScopedCBB cbb;
167
525
  CBB body, extensions_cbb;
168
525
  if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO) ||
169
525
      !ssl_client_hello_write_without_extensions(&client_hello_inner, &body) ||
170
525
      !CBB_add_u16_length_prefixed(&body, &extensions_cbb)) {
171
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
172
0
    return false;
173
0
  }
174
175
525
  auto inner_extensions =
176
525
      Span(client_hello_inner.extensions, client_hello_inner.extensions_len);
177
525
  CBS ext_list_wrapper;
178
525
  if (!ssl_client_hello_get_extension(&client_hello_inner, &ext_list_wrapper,
179
525
                                      TLSEXT_TYPE_ech_outer_extensions)) {
180
    // No ech_outer_extensions. Copy everything.
181
372
    if (!CBB_add_bytes(&extensions_cbb, inner_extensions.data(),
182
372
                       inner_extensions.size())) {
183
0
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
184
0
      return false;
185
0
    }
186
372
  } else {
187
153
    const size_t offset = CBS_data(&ext_list_wrapper) - inner_extensions.data();
188
153
    auto inner_extensions_before =
189
153
        inner_extensions.subspan(0, offset - 4 /* extension header */);
190
153
    auto inner_extensions_after =
191
153
        inner_extensions.subspan(offset + CBS_len(&ext_list_wrapper));
192
153
    if (!CBB_add_bytes(&extensions_cbb, inner_extensions_before.data(),
193
153
                       inner_extensions_before.size())) {
194
0
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
195
0
      return false;
196
0
    }
197
198
    // Expand ech_outer_extensions. See draft-ietf-tls-esni-13, Appendix B.
199
153
    CBS ext_list;
200
153
    if (!CBS_get_u8_length_prefixed(&ext_list_wrapper, &ext_list) ||
201
139
        CBS_len(&ext_list) == 0 || CBS_len(&ext_list_wrapper) != 0) {
202
43
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
203
43
      return false;
204
43
    }
205
110
    CBS outer_extensions;
206
110
    CBS_init(&outer_extensions, client_hello_outer->extensions,
207
110
             client_hello_outer->extensions_len);
208
225
    while (CBS_len(&ext_list) != 0) {
209
      // Find the next extension to copy.
210
189
      uint16_t want;
211
189
      if (!CBS_get_u16(&ext_list, &want)) {
212
5
        OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
213
5
        return false;
214
5
      }
215
      // The ECH extension itself is not in the AAD and may not be referenced.
216
184
      if (want == TLSEXT_TYPE_encrypted_client_hello) {
217
3
        *out_alert = SSL_AD_ILLEGAL_PARAMETER;
218
3
        OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_EXTENSION);
219
3
        return false;
220
3
      }
221
      // Seek to |want| in |outer_extensions|. |ext_list| is required to match
222
      // ClientHelloOuter in order.
223
181
      uint16_t found;
224
181
      CBS ext_body;
225
429
      do {
226
429
        if (CBS_len(&outer_extensions) == 0) {
227
66
          *out_alert = SSL_AD_ILLEGAL_PARAMETER;
228
66
          OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_EXTENSION);
229
66
          return false;
230
66
        }
231
363
        if (!CBS_get_u16(&outer_extensions, &found) ||
232
363
            !CBS_get_u16_length_prefixed(&outer_extensions, &ext_body)) {
233
0
          OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
234
0
          return false;
235
0
        }
236
363
      } while (found != want);
237
      // Copy the extension.
238
115
      if (!CBB_add_u16(&extensions_cbb, found) ||
239
115
          !CBB_add_u16(&extensions_cbb, CBS_len(&ext_body)) ||
240
115
          !CBB_add_bytes(&extensions_cbb, CBS_data(&ext_body),
241
115
                         CBS_len(&ext_body))) {
242
0
        OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
243
0
        return false;
244
0
      }
245
115
    }
246
247
36
    if (!CBB_add_bytes(&extensions_cbb, inner_extensions_after.data(),
248
36
                       inner_extensions_after.size())) {
249
0
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
250
0
      return false;
251
0
    }
252
36
  }
253
408
  if (!CBB_flush(&body)) {
254
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
255
0
    return false;
256
0
  }
257
258
408
  if (!is_valid_client_hello_inner(ssl, out_alert,
259
408
                                   Span(CBB_data(&body), CBB_len(&body)))) {
260
230
    return false;
261
230
  }
262
263
178
  if (!ssl->method->finish_message(ssl, cbb.get(), out_client_hello_inner)) {
264
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
265
0
    return false;
266
0
  }
267
178
  return true;
268
178
}
269
270
bool ssl_client_hello_decrypt(SSL_HANDSHAKE *hs, uint8_t *out_alert,
271
                              bool *out_is_decrypt_error, Array<uint8_t> *out,
272
                              const SSL_CLIENT_HELLO *client_hello_outer,
273
273
                              Span<const uint8_t> payload) {
274
273
  *out_is_decrypt_error = false;
275
276
  // The ClientHelloOuterAAD is |client_hello_outer| with |payload| (which must
277
  // point within |client_hello_outer->extensions|) replaced with zeros. See
278
  // draft-ietf-tls-esni-13, section 5.2.
279
273
  Array<uint8_t> aad;
280
273
  if (!aad.CopyFrom(Span(client_hello_outer->client_hello,
281
273
                         client_hello_outer->client_hello_len))) {
282
0
    *out_alert = SSL_AD_INTERNAL_ERROR;
283
0
    return false;
284
0
  }
285
286
  // We assert with |uintptr_t| because the comparison would be UB if they
287
  // didn't alias.
288
  // - |payload| must be contained in |extensions|.
289
273
  assert(reinterpret_cast<uintptr_t>(client_hello_outer->extensions) <=
290
273
         reinterpret_cast<uintptr_t>(payload.data()));
291
273
  assert(reinterpret_cast<uintptr_t>(client_hello_outer->extensions +
292
273
                                     client_hello_outer->extensions_len) >=
293
273
         reinterpret_cast<uintptr_t>(payload.data() + payload.size()));
294
  // - |extensions| must be contained in |client_hello|.
295
273
  assert(reinterpret_cast<uintptr_t>(client_hello_outer->client_hello) <=
296
273
         reinterpret_cast<uintptr_t>(client_hello_outer->extensions));
297
273
  assert(reinterpret_cast<uintptr_t>(client_hello_outer->client_hello +
298
273
                                     client_hello_outer->client_hello_len) >=
299
273
         reinterpret_cast<uintptr_t>(client_hello_outer->extensions +
300
273
                                     client_hello_outer->extensions_len));
301
  // From this then follows that |aad|, being a copy of |client_hello|, contains
302
  // the |payload| byte range as well.
303
273
  Span<uint8_t> payload_aad = Span(aad).subspan(
304
273
      payload.data() - client_hello_outer->client_hello, payload.size());
305
273
  OPENSSL_memset(payload_aad.data(), 0, payload_aad.size());
306
307
  // Decrypt the EncodedClientHelloInner.
308
273
  Array<uint8_t> encoded;
309
273
  if (CRYPTO_fuzzer_mode_enabled()) {
310
    // In fuzzer mode, disable encryption to improve coverage. We reserve a
311
    // short input to signal decryption failure, so the fuzzer can explore
312
    // fallback to ClientHelloOuter.
313
245
    const uint8_t kBadPayload[] = {0xff};
314
245
    if (payload == kBadPayload) {
315
6
      *out_alert = SSL_AD_DECRYPT_ERROR;
316
6
      *out_is_decrypt_error = true;
317
6
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
318
6
      return false;
319
6
    }
320
239
    if (!encoded.CopyFrom(payload)) {
321
0
      *out_alert = SSL_AD_INTERNAL_ERROR;
322
0
      return false;
323
0
    }
324
239
  } else {
325
28
    if (!encoded.InitForOverwrite(payload.size())) {
326
0
      *out_alert = SSL_AD_INTERNAL_ERROR;
327
0
      return false;
328
0
    }
329
28
    size_t len;
330
28
    if (!EVP_HPKE_CTX_open(hs->ech_hpke_ctx.get(), encoded.data(), &len,
331
28
                           encoded.size(), payload.data(), payload.size(),
332
28
                           aad.data(), aad.size())) {
333
28
      *out_alert = SSL_AD_DECRYPT_ERROR;
334
28
      *out_is_decrypt_error = true;
335
28
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
336
28
      return false;
337
28
    }
338
0
    encoded.Shrink(len);
339
0
  }
340
341
239
  if (!ssl_decode_client_hello_inner(hs->ssl, out_alert, out, encoded,
342
239
                                     client_hello_outer)) {
343
114
    return false;
344
114
  }
345
346
125
  ssl_do_msg_callback(hs->ssl, /*is_write=*/0, SSL3_RT_CLIENT_HELLO_INNER,
347
125
                      *out);
348
125
  return true;
349
239
}
350
351
3.02k
static bool is_hex_component(Span<const uint8_t> in) {
352
3.02k
  if (in.size() < 2 || in[0] != '0' || (in[1] != 'x' && in[1] != 'X')) {
353
1.69k
    return false;
354
1.69k
  }
355
5.03k
  for (uint8_t b : in.subspan(2)) {
356
5.03k
    if (!OPENSSL_isxdigit(b)) {
357
678
      return false;
358
678
    }
359
5.03k
  }
360
651
  return true;
361
1.32k
}
362
363
2.37k
static bool is_decimal_component(Span<const uint8_t> in) {
364
2.37k
  if (in.empty()) {
365
0
    return false;
366
0
  }
367
4.25k
  for (uint8_t b : in) {
368
4.25k
    if (!('0' <= b && b <= '9')) {
369
2.14k
      return false;
370
2.14k
    }
371
4.25k
  }
372
225
  return true;
373
2.37k
}
374
375
4.33k
bool ssl_is_valid_ech_public_name(Span<const uint8_t> public_name) {
376
  // See draft-ietf-tls-esni-13, Section 4 and RFC 5890, Section 2.3.1. The
377
  // public name must be a dot-separated sequence of LDH labels and not begin or
378
  // end with a dot.
379
4.33k
  auto remaining = public_name;
380
4.33k
  if (remaining.empty()) {
381
0
    return false;
382
0
  }
383
4.33k
  Span<const uint8_t> last;
384
7.77k
  while (!remaining.empty()) {
385
    // Find the next dot-separated component.
386
4.74k
    auto dot = std::find(remaining.begin(), remaining.end(), '.');
387
4.74k
    Span<const uint8_t> component;
388
4.74k
    if (dot == remaining.end()) {
389
3.73k
      component = remaining;
390
3.73k
      last = component;
391
3.73k
      remaining = Span<const uint8_t>();
392
3.73k
    } else {
393
1.01k
      component = remaining.subspan(0, dot - remaining.begin());
394
      // Skip the dot.
395
1.01k
      remaining = remaining.subspan(dot - remaining.begin() + 1);
396
1.01k
      if (remaining.empty()) {
397
        // Trailing dots are not allowed.
398
194
        return false;
399
194
      }
400
1.01k
    }
401
    // |component| must be a valid LDH label. Checking for empty components also
402
    // rejects leading dots.
403
4.55k
    if (component.empty() || component.size() > 63 ||
404
4.16k
        component.front() == '-' || component.back() == '-') {
405
853
      return false;
406
853
    }
407
14.2k
    for (uint8_t c : component) {
408
14.2k
      if (!OPENSSL_isalnum(c) && c != '-') {
409
265
        return false;
410
265
      }
411
14.2k
    }
412
3.70k
  }
413
414
  // The WHATWG URL parser additionally does not allow any DNS names that end in
415
  // a numeric component. See:
416
  // https://url.spec.whatwg.org/#concept-host-parser
417
  // https://url.spec.whatwg.org/#ends-in-a-number-checker
418
  //
419
  // The WHATWG parser is formulated in terms of parsing decimal, octal, and
420
  // hex, along with a separate ASCII digits check. The ASCII digits check
421
  // subsumes the decimal and octal check, so we only need to check two cases.
422
3.02k
  return !is_hex_component(last) && !is_decimal_component(last);
423
4.33k
}
424
425
static bool parse_ech_config(CBS *cbs, ECHConfig *out, bool *out_supported,
426
11.6k
                             bool all_extensions_mandatory) {
427
11.6k
  uint16_t version;
428
11.6k
  CBS orig = *cbs;
429
11.6k
  CBS contents;
430
11.6k
  if (!CBS_get_u16(cbs, &version) ||
431
7.93k
      !CBS_get_u16_length_prefixed(cbs, &contents)) {
432
3.95k
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
433
3.95k
    return false;
434
3.95k
  }
435
436
7.71k
  if (version != kECHConfigVersion) {
437
501
    *out_supported = false;
438
501
    return true;
439
501
  }
440
441
  // Make a copy of the ECHConfig and parse from it, so the results alias into
442
  // the saved copy.
443
7.21k
  if (!out->raw.CopyFrom(
444
7.21k
          Span(CBS_data(&orig), CBS_len(&orig) - CBS_len(cbs)))) {
445
0
    return false;
446
0
  }
447
448
7.21k
  CBS ech_config(out->raw);
449
7.21k
  CBS public_name, public_key, cipher_suites, extensions;
450
7.21k
  if (!CBS_skip(&ech_config, 2) ||  // version
451
7.21k
      !CBS_get_u16_length_prefixed(&ech_config, &contents) ||
452
7.21k
      !CBS_get_u8(&contents, &out->config_id) ||
453
6.84k
      !CBS_get_u16(&contents, &out->kem_id) ||
454
6.64k
      !CBS_get_u16_length_prefixed(&contents, &public_key) ||
455
6.42k
      CBS_len(&public_key) == 0 ||
456
6.21k
      !CBS_get_u16_length_prefixed(&contents, &cipher_suites) ||
457
6.01k
      CBS_len(&cipher_suites) == 0 || CBS_len(&cipher_suites) % 4 != 0 ||
458
5.60k
      !CBS_get_u8(&contents, &out->maximum_name_length) ||
459
5.41k
      !CBS_get_u8_length_prefixed(&contents, &public_name) ||
460
5.03k
      CBS_len(&public_name) == 0 ||
461
4.83k
      !CBS_get_u16_length_prefixed(&contents, &extensions) ||
462
4.57k
      CBS_len(&contents) != 0) {
463
2.89k
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
464
2.89k
    return false;
465
2.89k
  }
466
467
4.32k
  if (!ssl_is_valid_ech_public_name(public_name)) {
468
    // TODO(https://crbug.com/boringssl/275): The draft says ECHConfigs with
469
    // invalid public names should be ignored, but LDH syntax failures are
470
    // unambiguously invalid.
471
2.18k
    *out_supported = false;
472
2.18k
    return true;
473
2.18k
  }
474
475
2.14k
  out->public_key = public_key;
476
2.14k
  out->public_name = public_name;
477
  // This function does not ensure |out->kem_id| and |out->cipher_suites| use
478
  // supported algorithms. The caller must do this.
479
2.14k
  out->cipher_suites = cipher_suites;
480
481
2.14k
  bool has_unknown_mandatory_extension = false;
482
2.95k
  while (CBS_len(&extensions) != 0) {
483
1.42k
    uint16_t type;
484
1.42k
    CBS body;
485
1.42k
    if (!CBS_get_u16(&extensions, &type) ||
486
1.09k
        !CBS_get_u16_length_prefixed(&extensions, &body)) {
487
609
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
488
609
      return false;
489
609
    }
490
    // We currently do not support any extensions.
491
819
    if (type & 0x8000 || all_extensions_mandatory) {
492
      // Extension numbers with the high bit set are mandatory. Continue parsing
493
      // to enforce syntax, but we will ultimately ignore this ECHConfig as a
494
      // client and reject it as a server.
495
819
      has_unknown_mandatory_extension = true;
496
819
    }
497
819
  }
498
499
1.53k
  *out_supported = !has_unknown_mandatory_extension;
500
1.53k
  return true;
501
2.14k
}
502
503
bool ECHServerConfig::Init(Span<const uint8_t> ech_config,
504
11.6k
                           const EVP_HPKE_KEY *key, bool is_retry_config) {
505
11.6k
  is_retry_config_ = is_retry_config;
506
507
  // Parse the ECHConfig, rejecting all unsupported parameters and extensions.
508
  // Unlike most server options, ECH's server configuration is serialized and
509
  // configured in both the server and DNS. If the caller configures an
510
  // unsupported parameter, this is a deployment error. To catch these errors,
511
  // we fail early.
512
11.6k
  CBS cbs = ech_config;
513
11.6k
  bool supported;
514
11.6k
  if (!parse_ech_config(&cbs, &ech_config_, &supported,
515
11.6k
                        /*all_extensions_mandatory=*/true)) {
516
7.45k
    return false;
517
7.45k
  }
518
4.22k
  if (CBS_len(&cbs) != 0) {
519
1.05k
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
520
1.05k
    return false;
521
1.05k
  }
522
3.16k
  if (!supported) {
523
2.05k
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG);
524
2.05k
    return false;
525
2.05k
  }
526
527
1.11k
  CBS cipher_suites = ech_config_.cipher_suites;
528
1.55k
  while (CBS_len(&cipher_suites) > 0) {
529
1.11k
    uint16_t kdf_id, aead_id;
530
1.11k
    if (!CBS_get_u16(&cipher_suites, &kdf_id) ||
531
1.11k
        !CBS_get_u16(&cipher_suites, &aead_id)) {
532
0
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
533
0
      return false;
534
0
    }
535
    // The server promises to support every option in the ECHConfig, so reject
536
    // any unsupported cipher suites.
537
1.11k
    if (kdf_id != EVP_HPKE_HKDF_SHA256 || get_ech_aead(aead_id) == nullptr) {
538
673
      OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG);
539
673
      return false;
540
673
    }
541
1.11k
  }
542
543
  // Check the public key in the ECHConfig matches |key|.
544
440
  uint8_t expected_public_key[EVP_HPKE_MAX_PUBLIC_KEY_LENGTH];
545
440
  size_t expected_public_key_len;
546
440
  if (!EVP_HPKE_KEY_public_key(key, expected_public_key,
547
440
                               &expected_public_key_len,
548
440
                               sizeof(expected_public_key))) {
549
0
    return false;
550
0
  }
551
440
  if (ech_config_.kem_id != EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(key)) ||
552
217
      Span(expected_public_key, expected_public_key_len) !=
553
434
          ech_config_.public_key) {
554
434
    OPENSSL_PUT_ERROR(SSL, SSL_R_ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH);
555
434
    return false;
556
434
  }
557
558
6
  if (!EVP_HPKE_KEY_copy(key_.get(), key)) {
559
0
    return false;
560
0
  }
561
562
6
  return true;
563
6
}
564
565
bool ECHServerConfig::SetupContext(EVP_HPKE_CTX *ctx, uint16_t kdf_id,
566
                                   uint16_t aead_id,
567
379
                                   Span<const uint8_t> enc) const {
568
  // Check the cipher suite is supported by this ECHServerConfig.
569
379
  CBS cbs(ech_config_.cipher_suites);
570
379
  bool cipher_ok = false;
571
659
  while (CBS_len(&cbs) != 0) {
572
532
    uint16_t supported_kdf_id, supported_aead_id;
573
532
    if (!CBS_get_u16(&cbs, &supported_kdf_id) ||
574
532
        !CBS_get_u16(&cbs, &supported_aead_id)) {
575
0
      return false;
576
0
    }
577
532
    if (kdf_id == supported_kdf_id && aead_id == supported_aead_id) {
578
252
      cipher_ok = true;
579
252
      break;
580
252
    }
581
532
  }
582
379
  if (!cipher_ok) {
583
127
    return false;
584
127
  }
585
586
252
  static const uint8_t kInfoLabel[] = "tls ech";
587
252
  ScopedCBB info_cbb;
588
252
  if (!CBB_init(info_cbb.get(), sizeof(kInfoLabel) + ech_config_.raw.size()) ||
589
252
      !CBB_add_bytes(info_cbb.get(), kInfoLabel,
590
252
                     sizeof(kInfoLabel) /* includes trailing NUL */) ||
591
252
      !CBB_add_bytes(info_cbb.get(), ech_config_.raw.data(),
592
252
                     ech_config_.raw.size())) {
593
0
    return false;
594
0
  }
595
596
252
  assert(kdf_id == EVP_HPKE_HKDF_SHA256);
597
252
  assert(get_ech_aead(aead_id) != nullptr);
598
252
  return EVP_HPKE_CTX_setup_recipient(ctx, key_.get(), EVP_hpke_hkdf_sha256(),
599
252
                                      get_ech_aead(aead_id), enc.data(),
600
252
                                      enc.size(), CBB_data(info_cbb.get()),
601
252
                                      CBB_len(info_cbb.get()));
602
252
}
603
604
0
bool ssl_is_valid_ech_config_list(Span<const uint8_t> ech_config_list) {
605
0
  CBS cbs = ech_config_list, child;
606
0
  if (!CBS_get_u16_length_prefixed(&cbs, &child) ||  //
607
0
      CBS_len(&child) == 0 ||                        //
608
0
      CBS_len(&cbs) > 0) {
609
0
    return false;
610
0
  }
611
0
  while (CBS_len(&child) > 0) {
612
0
    ECHConfig ech_config;
613
0
    bool supported;
614
0
    if (!parse_ech_config(&child, &ech_config, &supported,
615
0
                          /*all_extensions_mandatory=*/false)) {
616
0
      return false;
617
0
    }
618
0
  }
619
0
  return true;
620
0
}
621
622
static bool select_ech_cipher_suite(const EVP_HPKE_KDF **out_kdf,
623
                                    const EVP_HPKE_AEAD **out_aead,
624
                                    Span<const uint8_t> cipher_suites,
625
0
                                    const bool has_aes_hardware) {
626
0
  const EVP_HPKE_AEAD *aead = nullptr;
627
0
  CBS cbs = cipher_suites;
628
0
  while (CBS_len(&cbs) != 0) {
629
0
    uint16_t kdf_id, aead_id;
630
0
    if (!CBS_get_u16(&cbs, &kdf_id) ||  //
631
0
        !CBS_get_u16(&cbs, &aead_id)) {
632
0
      return false;
633
0
    }
634
    // Pick the first common cipher suite, but prefer ChaCha20-Poly1305 if we
635
    // don't have AES hardware.
636
0
    const EVP_HPKE_AEAD *candidate = get_ech_aead(aead_id);
637
0
    if (kdf_id != EVP_HPKE_HKDF_SHA256 || candidate == nullptr) {
638
0
      continue;
639
0
    }
640
0
    if (aead == nullptr ||
641
0
        (!has_aes_hardware && aead_id == EVP_HPKE_CHACHA20_POLY1305)) {
642
0
      aead = candidate;
643
0
    }
644
0
  }
645
0
  if (aead == nullptr) {
646
0
    return false;
647
0
  }
648
649
0
  *out_kdf = EVP_hpke_hkdf_sha256();
650
0
  *out_aead = aead;
651
0
  return true;
652
0
}
653
654
bool ssl_select_ech_config(SSL_HANDSHAKE *hs, Span<uint8_t> out_enc,
655
66.3k
                           size_t *out_enc_len) {
656
66.3k
  *out_enc_len = 0;
657
66.3k
  if (hs->max_version < TLS1_3_VERSION) {
658
    // ECH requires TLS 1.3.
659
0
    return true;
660
0
  }
661
662
66.3k
  if (!hs->config->client_ech_config_list.empty()) {
663
0
    CBS cbs = CBS(hs->config->client_ech_config_list);
664
0
    CBS child;
665
0
    if (!CBS_get_u16_length_prefixed(&cbs, &child) ||  //
666
0
        CBS_len(&child) == 0 ||                        //
667
0
        CBS_len(&cbs) > 0) {
668
0
      return false;
669
0
    }
670
    // Look for the first ECHConfig with supported parameters.
671
0
    while (CBS_len(&child) > 0) {
672
0
      ECHConfig ech_config;
673
0
      bool supported;
674
0
      if (!parse_ech_config(&child, &ech_config, &supported,
675
0
                            /*all_extensions_mandatory=*/false)) {
676
0
        return false;
677
0
      }
678
0
      const EVP_HPKE_KEM *kem = EVP_hpke_x25519_hkdf_sha256();
679
0
      const EVP_HPKE_KDF *kdf;
680
0
      const EVP_HPKE_AEAD *aead;
681
0
      if (supported &&  //
682
0
          ech_config.kem_id == EVP_HPKE_DHKEM_X25519_HKDF_SHA256 &&
683
0
          select_ech_cipher_suite(&kdf, &aead, ech_config.cipher_suites,
684
0
                                  hs->ssl->config->aes_hw_override
685
0
                                      ? hs->ssl->config->aes_hw_override_value
686
0
                                      : EVP_has_aes_hardware())) {
687
0
        ScopedCBB info;
688
0
        static const uint8_t kInfoLabel[] = "tls ech";  // includes trailing NUL
689
0
        if (!CBB_init(info.get(), sizeof(kInfoLabel) + ech_config.raw.size()) ||
690
0
            !CBB_add_bytes(info.get(), kInfoLabel, sizeof(kInfoLabel)) ||
691
0
            !CBB_add_bytes(info.get(), ech_config.raw.data(),
692
0
                           ech_config.raw.size())) {
693
0
          return false;
694
0
        }
695
696
0
        if (!EVP_HPKE_CTX_setup_sender(
697
0
                hs->ech_hpke_ctx.get(), out_enc.data(), out_enc_len,
698
0
                out_enc.size(), kem, kdf, aead, ech_config.public_key.data(),
699
0
                ech_config.public_key.size(), CBB_data(info.get()),
700
0
                CBB_len(info.get())) ||
701
0
            !hs->inner_transcript.Init()) {
702
0
          return false;
703
0
        }
704
705
0
        hs->selected_ech_config = MakeUnique<ECHConfig>(std::move(ech_config));
706
0
        return hs->selected_ech_config != nullptr;
707
0
      }
708
0
    }
709
0
  }
710
711
66.3k
  return true;
712
66.3k
}
713
714
0
static size_t aead_overhead(const EVP_HPKE_AEAD *aead) {
715
0
  if (CRYPTO_fuzzer_mode_enabled()) {
716
    // TODO(https://crbug.com/boringssl/275): Having to adjust the overhead
717
    // everywhere is tedious. Change fuzzer mode to append a fake tag but still
718
    // otherwise be cleartext, refresh corpora, and then inline this function.
719
0
    return 0;
720
0
  }
721
0
  return EVP_AEAD_max_overhead(EVP_HPKE_AEAD_aead(aead));
722
0
}
723
724
// random_size returns a random value between |min| and |max|, inclusive.
725
0
static size_t random_size(size_t min, size_t max) {
726
0
  assert(min < max);
727
0
  size_t value;
728
0
  RAND_bytes(reinterpret_cast<uint8_t *>(&value), sizeof(value));
729
0
  return value % (max - min + 1) + min;
730
0
}
731
732
66.3k
static bool setup_ech_grease(SSL_HANDSHAKE *hs) {
733
66.3k
  assert(!hs->selected_ech_config);
734
66.3k
  if (hs->max_version < TLS1_3_VERSION || !hs->config->ech_grease_enabled) {
735
66.3k
    return true;
736
66.3k
  }
737
738
0
  const uint16_t kdf_id = EVP_HPKE_HKDF_SHA256;
739
0
  const bool has_aes_hw = hs->ssl->config->aes_hw_override
740
0
                              ? hs->ssl->config->aes_hw_override_value
741
0
                              : EVP_has_aes_hardware();
742
0
  const EVP_HPKE_AEAD *aead =
743
0
      has_aes_hw ? EVP_hpke_aes_128_gcm() : EVP_hpke_chacha20_poly1305();
744
0
  static_assert(ssl_grease_ech_config_id < sizeof(hs->grease_seed),
745
0
                "hs->grease_seed is too small");
746
0
  uint8_t config_id = hs->grease_seed[ssl_grease_ech_config_id];
747
748
0
  uint8_t enc[X25519_PUBLIC_VALUE_LEN];
749
0
  uint8_t private_key_unused[X25519_PRIVATE_KEY_LEN];
750
0
  X25519_keypair(enc, private_key_unused);
751
752
  // To determine a plausible length for the payload, we estimate the size of a
753
  // typical EncodedClientHelloInner without resumption:
754
  //
755
  //   2+32+1+2   version, random, legacy_session_id, legacy_compression_methods
756
  //   2+4*2      cipher_suites (three TLS 1.3 ciphers, GREASE)
757
  //   2          extensions prefix
758
  //   5          inner encrypted_client_hello
759
  //   4+1+2*2    supported_versions (TLS 1.3, GREASE)
760
  //   4+1+10*2   outer_extensions (key_share, sigalgs, sct, alpn,
761
  //              supported_groups, status_request, psk_key_exchange_modes,
762
  //              compress_certificate, GREASE x2)
763
  //
764
  // The server_name extension has an overhead of 9 bytes. For now, arbitrarily
765
  // estimate maximum_name_length to be between 32 and 100 bytes. Then round up
766
  // to a multiple of 32, to match draft-ietf-tls-esni-13, section 6.1.3.
767
0
  const size_t payload_len =
768
0
      32 * random_size(128 / 32, 224 / 32) + aead_overhead(aead);
769
0
  bssl::ScopedCBB cbb;
770
0
  CBB enc_cbb, payload_cbb;
771
0
  uint8_t *payload;
772
0
  if (!CBB_init(cbb.get(), 256) || !CBB_add_u16(cbb.get(), kdf_id) ||
773
0
      !CBB_add_u16(cbb.get(), EVP_HPKE_AEAD_id(aead)) ||
774
0
      !CBB_add_u8(cbb.get(), config_id) ||
775
0
      !CBB_add_u16_length_prefixed(cbb.get(), &enc_cbb) ||
776
0
      !CBB_add_bytes(&enc_cbb, enc, sizeof(enc)) ||
777
0
      !CBB_add_u16_length_prefixed(cbb.get(), &payload_cbb) ||
778
0
      !CBB_add_space(&payload_cbb, &payload, payload_len) ||
779
0
      !RAND_bytes(payload, payload_len) ||
780
0
      !CBBFinishArray(cbb.get(), &hs->ech_client_outer)) {
781
0
    return false;
782
0
  }
783
0
  return true;
784
0
}
785
786
66.3k
bool ssl_encrypt_client_hello(SSL_HANDSHAKE *hs, Span<const uint8_t> enc) {
787
66.3k
  SSL *const ssl = hs->ssl;
788
66.3k
  if (!hs->selected_ech_config) {
789
66.3k
    return setup_ech_grease(hs);
790
66.3k
  }
791
792
  // Construct ClientHelloInner and EncodedClientHelloInner. See
793
  // draft-ietf-tls-esni-13, sections 5.1 and 6.1.
794
0
  ScopedCBB cbb, encoded_cbb;
795
0
  CBB body;
796
0
  bool needs_psk_binder;
797
0
  Array<uint8_t> hello_inner;
798
0
  if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO) ||
799
0
      !CBB_init(encoded_cbb.get(), 256) ||
800
0
      !ssl_write_client_hello_without_extensions(hs, &body,
801
0
                                                 ssl_client_hello_inner,
802
0
                                                 /*empty_session_id=*/false) ||
803
0
      !ssl_write_client_hello_without_extensions(hs, encoded_cbb.get(),
804
0
                                                 ssl_client_hello_inner,
805
0
                                                 /*empty_session_id=*/true) ||
806
0
      !ssl_add_clienthello_tlsext(hs, &body, encoded_cbb.get(),
807
0
                                  &needs_psk_binder, ssl_client_hello_inner,
808
0
                                  CBB_len(&body)) ||
809
0
      !ssl->method->finish_message(ssl, cbb.get(), &hello_inner)) {
810
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
811
0
    return false;
812
0
  }
813
814
0
  if (needs_psk_binder) {
815
0
    size_t binder_len;
816
0
    if (!tls13_write_psk_binder(hs, hs->inner_transcript, Span(hello_inner),
817
0
                                &binder_len)) {
818
0
      return false;
819
0
    }
820
    // Also update the EncodedClientHelloInner.
821
0
    auto encoded_binder =
822
0
        Span(const_cast<uint8_t *>(CBB_data(encoded_cbb.get())),
823
0
             CBB_len(encoded_cbb.get()))
824
0
            .last(binder_len);
825
0
    auto hello_inner_binder = Span(hello_inner).last(binder_len);
826
0
    OPENSSL_memcpy(encoded_binder.data(), hello_inner_binder.data(),
827
0
                   binder_len);
828
0
  }
829
830
0
  ssl_do_msg_callback(ssl, /*is_write=*/1, SSL3_RT_CLIENT_HELLO_INNER,
831
0
                      hello_inner);
832
0
  if (!hs->inner_transcript.Update(hello_inner)) {
833
0
    return false;
834
0
  }
835
836
  // Pad the EncodedClientHelloInner. See draft-ietf-tls-esni-13, section 6.1.3.
837
0
  size_t padding_len = 0;
838
0
  size_t maximum_name_length = hs->selected_ech_config->maximum_name_length;
839
0
  if (ssl->hostname) {
840
0
    size_t hostname_len = strlen(ssl->hostname.get());
841
0
    if (hostname_len <= maximum_name_length) {
842
0
      padding_len = maximum_name_length - hostname_len;
843
0
    }
844
0
  } else {
845
    // No SNI. Pad up to |maximum_name_length|, including server_name extension
846
    // overhead.
847
0
    padding_len = 9 + maximum_name_length;
848
0
  }
849
  // Pad the whole thing to a multiple of 32 bytes.
850
0
  padding_len += 31 - ((CBB_len(encoded_cbb.get()) + padding_len - 1) % 32);
851
0
  Array<uint8_t> encoded;
852
0
  if (!CBB_add_zeros(encoded_cbb.get(), padding_len) ||
853
0
      !CBBFinishArray(encoded_cbb.get(), &encoded)) {
854
0
    return false;
855
0
  }
856
857
  // Encrypt |encoded|. See draft-ietf-tls-esni-13, section 6.1.1. First,
858
  // assemble the extension with a placeholder value for ClientHelloOuterAAD.
859
  // See draft-ietf-tls-esni-13, section 5.2.
860
0
  const EVP_HPKE_KDF *kdf = EVP_HPKE_CTX_kdf(hs->ech_hpke_ctx.get());
861
0
  const EVP_HPKE_AEAD *aead = EVP_HPKE_CTX_aead(hs->ech_hpke_ctx.get());
862
0
  size_t payload_len = encoded.size() + aead_overhead(aead);
863
0
  CBB enc_cbb, payload_cbb;
864
0
  if (!CBB_init(cbb.get(), 256) ||
865
0
      !CBB_add_u16(cbb.get(), EVP_HPKE_KDF_id(kdf)) ||
866
0
      !CBB_add_u16(cbb.get(), EVP_HPKE_AEAD_id(aead)) ||
867
0
      !CBB_add_u8(cbb.get(), hs->selected_ech_config->config_id) ||
868
0
      !CBB_add_u16_length_prefixed(cbb.get(), &enc_cbb) ||
869
0
      !CBB_add_bytes(&enc_cbb, enc.data(), enc.size()) ||
870
0
      !CBB_add_u16_length_prefixed(cbb.get(), &payload_cbb) ||
871
0
      !CBB_add_zeros(&payload_cbb, payload_len) ||
872
0
      !CBBFinishArray(cbb.get(), &hs->ech_client_outer)) {
873
0
    return false;
874
0
  }
875
876
  // Construct ClientHelloOuterAAD.
877
  // TODO(https://crbug.com/boringssl/275): This ends up constructing the
878
  // ClientHelloOuter twice. Instead, reuse |aad| for the ClientHello, now that
879
  // draft-12 made the length prefixes match.
880
0
  bssl::ScopedCBB aad;
881
0
  if (!CBB_init(aad.get(), 256) ||
882
0
      !ssl_write_client_hello_without_extensions(hs, aad.get(),
883
0
                                                 ssl_client_hello_outer,
884
0
                                                 /*empty_session_id=*/false) ||
885
0
      !ssl_add_clienthello_tlsext(hs, aad.get(), /*out_encoded=*/nullptr,
886
0
                                  &needs_psk_binder, ssl_client_hello_outer,
887
0
                                  CBB_len(aad.get()))) {
888
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
889
0
    return false;
890
0
  }
891
892
  // ClientHelloOuter may not require a PSK binder. Otherwise, we have a
893
  // circular dependency.
894
0
  assert(!needs_psk_binder);
895
896
  // Replace the payload in |hs->ech_client_outer| with the encrypted value.
897
0
  auto payload_span = Span(hs->ech_client_outer).last(payload_len);
898
0
  if (CRYPTO_fuzzer_mode_enabled()) {
899
    // In fuzzer mode, the server expects a cleartext payload.
900
0
    assert(payload_span.size() == encoded.size());
901
0
    OPENSSL_memcpy(payload_span.data(), encoded.data(), encoded.size());
902
0
  } else {
903
0
    if (!EVP_HPKE_CTX_seal(hs->ech_hpke_ctx.get(), payload_span.data(),
904
0
                           &payload_len, payload_span.size(), encoded.data(),
905
0
                           encoded.size(), CBB_data(aad.get()),
906
0
                           CBB_len(aad.get())) ||
907
0
        payload_len != payload_span.size()) {
908
0
      return false;
909
0
    }
910
0
  }
911
912
0
  return true;
913
0
}
914
915
BSSL_NAMESPACE_END
916
917
using namespace bssl;
918
919
0
void SSL_set_enable_ech_grease(SSL *ssl, int enable) {
920
0
  if (!ssl->config) {
921
0
    return;
922
0
  }
923
0
  ssl->config->ech_grease_enabled = !!enable;
924
0
}
925
926
int SSL_set1_ech_config_list(SSL *ssl, const uint8_t *ech_config_list,
927
0
                             size_t ech_config_list_len) {
928
0
  if (!ssl->config) {
929
0
    return 0;
930
0
  }
931
932
0
  auto span = Span(ech_config_list, ech_config_list_len);
933
0
  if (!ssl_is_valid_ech_config_list(span)) {
934
0
    OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ECH_CONFIG_LIST);
935
0
    return 0;
936
0
  }
937
0
  return ssl->config->client_ech_config_list.CopyFrom(span);
938
0
}
939
940
void SSL_get0_ech_name_override(const SSL *ssl, const char **out_name,
941
8.35k
                                size_t *out_name_len) {
942
  // When ECH is rejected, we use the public name. Note that, if
943
  // |SSL_CTX_set_reverify_on_resume| is enabled, we reverify the certificate
944
  // before the 0-RTT point. If also offering ECH, we verify as if
945
  // ClientHelloInner was accepted and do not override. This works because, at
946
  // this point, |ech_status| will be |ssl_ech_none|. See the
947
  // ECH-Client-Reject-EarlyDataReject-OverrideNameOnRetry tests in runner.go.
948
8.35k
  const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
949
8.35k
  if (!ssl->server && hs && ssl->s3->ech_status == ssl_ech_rejected) {
950
0
    *out_name = reinterpret_cast<const char *>(
951
0
        hs->selected_ech_config->public_name.data());
952
0
    *out_name_len = hs->selected_ech_config->public_name.size();
953
8.35k
  } else {
954
8.35k
    *out_name = nullptr;
955
8.35k
    *out_name_len = 0;
956
8.35k
  }
957
8.35k
}
958
959
void SSL_get0_ech_retry_configs(const SSL *ssl,
960
                                const uint8_t **out_retry_configs,
961
0
                                size_t *out_retry_configs_len) {
962
0
  const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
963
0
  if (!hs || !hs->ech_authenticated_reject) {
964
    // It is an error to call this function except in response to
965
    // |SSL_R_ECH_REJECTED|. Returning an empty string risks the caller
966
    // mistakenly believing the server has disabled ECH. Instead, return a
967
    // non-empty ECHConfigList with a syntax error, so the subsequent
968
    // |SSL_set1_ech_config_list| call will fail.
969
0
    assert(0);
970
0
    static const uint8_t kPlaceholder[] = {
971
0
        kECHConfigVersion >> 8, kECHConfigVersion & 0xff, 0xff, 0xff, 0xff};
972
0
    *out_retry_configs = kPlaceholder;
973
0
    *out_retry_configs_len = sizeof(kPlaceholder);
974
0
    return;
975
0
  }
976
977
0
  *out_retry_configs = hs->ech_retry_configs.data();
978
0
  *out_retry_configs_len = hs->ech_retry_configs.size();
979
0
}
980
981
int SSL_marshal_ech_config(uint8_t **out, size_t *out_len, uint8_t config_id,
982
                           const EVP_HPKE_KEY *key, const char *public_name,
983
6
                           size_t max_name_len) {
984
6
  Span<const uint8_t> public_name_u8 = StringAsBytes(public_name);
985
6
  if (!ssl_is_valid_ech_public_name(public_name_u8)) {
986
0
    OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ECH_PUBLIC_NAME);
987
0
    return 0;
988
0
  }
989
990
  // The maximum name length is encoded in one byte.
991
6
  if (max_name_len > 0xff) {
992
0
    OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH);
993
0
    return 0;
994
0
  }
995
996
  // See draft-ietf-tls-esni-13, section 4.
997
6
  ScopedCBB cbb;
998
6
  CBB contents, child;
999
6
  uint8_t *public_key;
1000
6
  size_t public_key_len;
1001
6
  if (!CBB_init(cbb.get(), 128) ||  //
1002
6
      !CBB_add_u16(cbb.get(), kECHConfigVersion) ||
1003
6
      !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
1004
6
      !CBB_add_u8(&contents, config_id) ||
1005
6
      !CBB_add_u16(&contents, EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(key))) ||
1006
6
      !CBB_add_u16_length_prefixed(&contents, &child) ||
1007
6
      !CBB_reserve(&child, &public_key, EVP_HPKE_MAX_PUBLIC_KEY_LENGTH) ||
1008
6
      !EVP_HPKE_KEY_public_key(key, public_key, &public_key_len,
1009
6
                               EVP_HPKE_MAX_PUBLIC_KEY_LENGTH) ||
1010
6
      !CBB_did_write(&child, public_key_len) ||
1011
6
      !CBB_add_u16_length_prefixed(&contents, &child) ||
1012
      // Write a default cipher suite configuration.
1013
6
      !CBB_add_u16(&child, EVP_HPKE_HKDF_SHA256) ||
1014
6
      !CBB_add_u16(&child, EVP_HPKE_AES_128_GCM) ||
1015
6
      !CBB_add_u16(&child, EVP_HPKE_HKDF_SHA256) ||
1016
6
      !CBB_add_u16(&child, EVP_HPKE_CHACHA20_POLY1305) ||
1017
6
      !CBB_add_u8(&contents, max_name_len) ||
1018
6
      !CBB_add_u8_length_prefixed(&contents, &child) ||
1019
6
      !CBB_add_bytes(&child, public_name_u8.data(), public_name_u8.size()) ||
1020
      // TODO(https://crbug.com/boringssl/275): Reserve some GREASE extensions
1021
      // and include some.
1022
6
      !CBB_add_u16(&contents, 0 /* no extensions */) ||
1023
6
      !CBB_finish(cbb.get(), out, out_len)) {
1024
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
1025
0
    return 0;
1026
0
  }
1027
6
  return 1;
1028
6
}
1029
1030
13.5k
SSL_ECH_KEYS *SSL_ECH_KEYS_new() { return New<SSL_ECH_KEYS>(); }
1031
1032
405
void SSL_ECH_KEYS_up_ref(SSL_ECH_KEYS *keys) { keys->UpRefInternal(); }
1033
1034
13.9k
void SSL_ECH_KEYS_free(SSL_ECH_KEYS *keys) {
1035
13.9k
  if (keys != nullptr) {
1036
13.9k
    keys->DecRefInternal();
1037
13.9k
  }
1038
13.9k
}
1039
1040
int SSL_ECH_KEYS_add(SSL_ECH_KEYS *configs, int is_retry_config,
1041
                     const uint8_t *ech_config, size_t ech_config_len,
1042
11.6k
                     const EVP_HPKE_KEY *key) {
1043
11.6k
  UniquePtr<ECHServerConfig> parsed_config = MakeUnique<ECHServerConfig>();
1044
11.6k
  if (!parsed_config) {
1045
0
    return 0;
1046
0
  }
1047
11.6k
  if (!parsed_config->Init(Span(ech_config, ech_config_len), key,
1048
11.6k
                           !!is_retry_config)) {
1049
11.6k
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
1050
11.6k
    return 0;
1051
11.6k
  }
1052
6
  if (!configs->configs.Push(std::move(parsed_config))) {
1053
0
    return 0;
1054
0
  }
1055
6
  return 1;
1056
6
}
1057
1058
0
int SSL_ECH_KEYS_has_duplicate_config_id(const SSL_ECH_KEYS *keys) {
1059
0
  bool seen[256] = {false};
1060
0
  for (const auto &config : keys->configs) {
1061
0
    if (seen[config->ech_config().config_id]) {
1062
0
      return 1;
1063
0
    }
1064
0
    seen[config->ech_config().config_id] = true;
1065
0
  }
1066
0
  return 0;
1067
0
}
1068
1069
int SSL_ECH_KEYS_marshal_retry_configs(const SSL_ECH_KEYS *keys, uint8_t **out,
1070
0
                                       size_t *out_len) {
1071
0
  ScopedCBB cbb;
1072
0
  CBB child;
1073
0
  if (!CBB_init(cbb.get(), 128) ||
1074
0
      !CBB_add_u16_length_prefixed(cbb.get(), &child)) {
1075
0
    return false;
1076
0
  }
1077
0
  for (const auto &config : keys->configs) {
1078
0
    if (config->is_retry_config() &&
1079
0
        !CBB_add_bytes(&child, config->ech_config().raw.data(),
1080
0
                       config->ech_config().raw.size())) {
1081
0
      return false;
1082
0
    }
1083
0
  }
1084
0
  return CBB_finish(cbb.get(), out, out_len);
1085
0
}
1086
1087
6
int SSL_CTX_set1_ech_keys(SSL_CTX *ctx, SSL_ECH_KEYS *keys) {
1088
6
  bool has_retry_config = false;
1089
6
  for (const auto &config : keys->configs) {
1090
6
    if (config->is_retry_config()) {
1091
6
      has_retry_config = true;
1092
6
      break;
1093
6
    }
1094
6
  }
1095
6
  if (!has_retry_config) {
1096
0
    OPENSSL_PUT_ERROR(SSL, SSL_R_ECH_SERVER_WOULD_HAVE_NO_RETRY_CONFIGS);
1097
0
    return 0;
1098
0
  }
1099
6
  UniquePtr<SSL_ECH_KEYS> owned_keys = UpRef(keys);
1100
6
  MutexWriteLock lock(&ctx->lock);
1101
6
  ctx->ech_keys.swap(owned_keys);
1102
6
  return 1;
1103
6
}
1104
1105
0
int SSL_ech_accepted(const SSL *ssl) {
1106
0
  if (SSL_in_early_data(ssl) && !ssl->server) {
1107
    // In the client early data state, we report properties as if the server
1108
    // accepted early data. The server can only accept early data with
1109
    // ClientHelloInner.
1110
0
    return ssl->s3->hs->selected_ech_config != nullptr;
1111
0
  }
1112
1113
0
  return ssl->s3->ech_status == ssl_ech_accepted;
1114
0
}