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
34 BSSL_NAMESPACE_BEGIN
35
36 // ECH reuses the extension code point for the version number.
37 static constexpr uint16_t kECHConfigVersion =
38 TLSEXT_TYPE_encrypted_client_hello;
39
40 static const decltype(&EVP_hpke_aes_128_gcm) kSupportedAEADs[] = {
41 &EVP_hpke_aes_128_gcm,
42 &EVP_hpke_aes_256_gcm,
43 &EVP_hpke_chacha20_poly1305,
44 };
45
get_ech_aead(uint16_t aead_id)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.
ssl_client_hello_write_without_extensions(const SSL_CLIENT_HELLO * client_hello,CBB * out)61 static bool ssl_client_hello_write_without_extensions(
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) ||
66 !CBB_add_u8_length_prefixed(out, &cbb) ||
67 !CBB_add_bytes(&cbb, client_hello->session_id,
68 client_hello->session_id_len) ||
69 !CBB_add_u16_length_prefixed(out, &cbb) ||
70 !CBB_add_bytes(&cbb, client_hello->cipher_suites,
71 client_hello->cipher_suites_len) ||
72 !CBB_add_u8_length_prefixed(out, &cbb) ||
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
is_valid_client_hello_inner(SSL * ssl,uint8_t * out_alert,Span<const uint8_t> body)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) ||
87 !ssl_client_hello_get_extension(&client_hello, &extension,
88 TLSEXT_TYPE_encrypted_client_hello) ||
89 CBS_len(&extension) != 1 || //
90 CBS_data(&extension)[0] != ECH_CLIENT_INNER ||
91 !ssl_client_hello_get_extension(&client_hello, &extension,
92 TLSEXT_TYPE_supported_versions)) {
93 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
94 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_CLIENT_HELLO_INNER);
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;
104 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
105 return false;
106 }
107 while (CBS_len(&versions) != 0) {
108 uint16_t version;
109 if (!CBS_get_u16(&versions, &version)) {
110 *out_alert = SSL_AD_DECODE_ERROR;
111 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
112 return false;
113 }
114 if (version == SSL3_VERSION || version == TLS1_VERSION ||
115 version == TLS1_1_VERSION || version == TLS1_2_VERSION ||
116 version == DTLS1_VERSION || version == DTLS1_2_VERSION) {
117 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
118 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_CLIENT_HELLO_INNER);
119 return false;
120 }
121 }
122 return true;
123 }
124
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)125 bool ssl_decode_client_hello_inner(
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;
131 if (!ssl_parse_client_hello_with_trailing_data(ssl, &cbs,
132 &client_hello_inner)) {
133 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
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) {
140 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
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) {
150 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
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)) {
162 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
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,
170 TLSEXT_TYPE_ech_outer_extensions)) {
171 // No ech_outer_extensions. Copy everything.
172 if (!CBB_add_bytes(&extensions_cbb, inner_extensions.data(),
173 inner_extensions.size())) {
174 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
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())) {
185 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
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) {
193 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
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)) {
203 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
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;
213 OPENSSL_PUT_ERROR(SSL, SSL_R_OUTER_EXTENSION_NOT_FOUND);
214 return false;
215 }
216 if (!CBS_get_u16(&outer_extensions, &found) ||
217 !CBS_get_u16_length_prefixed(&outer_extensions, &ext_body)) {
218 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
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))) {
227 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
228 return false;
229 }
230 }
231
232 if (!CBB_add_bytes(&extensions_cbb, inner_extensions_after.data(),
233 inner_extensions_after.size())) {
234 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
235 return false;
236 }
237 }
238 if (!CBB_flush(&body)) {
239 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
240 return false;
241 }
242
243 if (!is_valid_client_hello_inner(
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)) {
249 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
250 return false;
251 }
252 return true;
253 }
254
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)255 bool ssl_client_hello_decrypt(EVP_HPKE_CTX *hpke_ctx, Array<uint8_t> *out,
256 bool *out_is_decrypt_error,
257 const SSL_CLIENT_HELLO *client_hello_outer,
258 Span<const uint8_t> payload) {
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;
288 OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
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())) {
297 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
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;
305 OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
306 return false;
307 }
308 out->Shrink(len);
309 #endif
310 return true;
311 }
312
parse_ipv4_number(Span<const uint8_t> in,uint32_t * out)313 static bool parse_ipv4_number(Span<const uint8_t> in, uint32_t *out) {
314 // See https://url.spec.whatwg.org/#ipv4-number-parser.
315 uint32_t base = 10;
316 if (in.size() >= 2 && in[0] == '0' && (in[1] == 'x' || in[1] == 'X')) {
317 in = in.subspan(2);
318 base = 16;
319 } else if (in.size() >= 1 && in[0] == '0') {
320 in = in.subspan(1);
321 base = 8;
322 }
323 *out = 0;
324 for (uint8_t c : in) {
325 uint32_t d;
326 if ('0' <= c && c <= '9') {
327 d = c - '0';
328 } else if ('a' <= c && c <= 'f') {
329 d = c - 'a' + 10;
330 } else if ('A' <= c && c <= 'F') {
331 d = c - 'A' + 10;
332 } else {
333 return false;
334 }
335 if (d >= base ||
336 *out > UINT32_MAX / base) {
337 return false;
338 }
339 *out *= base;
340 if (*out > UINT32_MAX - d) {
341 return false;
342 }
343 *out += d;
344 }
345 return true;
346 }
347
is_ipv4_address(Span<const uint8_t> in)348 static bool is_ipv4_address(Span<const uint8_t> in) {
349 // See https://url.spec.whatwg.org/#concept-ipv4-parser
350 //
351 // TODO(https://crbug.com/boringssl/275): Revise this, and maybe the spec, per
352 // https://groups.google.com/a/chromium.org/g/blink-dev/c/7QN5nxjwIfM/m/q9dw9MxoAwAJ
353 uint32_t numbers[4];
354 size_t num_numbers = 0;
355 while (!in.empty()) {
356 if (num_numbers == 4) {
357 // Too many components.
358 return false;
359 }
360 // Find the next dot-separated component.
361 auto dot = std::find(in.begin(), in.end(), '.');
362 if (dot == in.begin()) {
363 // Empty components are not allowed.
364 return false;
365 }
366 Span<const uint8_t> component;
367 if (dot == in.end()) {
368 component = in;
369 in = Span<const uint8_t>();
370 } else {
371 component = in.subspan(0, dot - in.begin());
372 in = in.subspan(dot - in.begin() + 1); // Skip the dot.
373 }
374 if (!parse_ipv4_number(component, &numbers[num_numbers])) {
375 return false;
376 }
377 num_numbers++;
378 }
379 if (num_numbers == 0) {
380 return false;
381 }
382 for (size_t i = 0; i < num_numbers - 1; i++) {
383 if (numbers[i] > 255) {
384 return false;
385 }
386 }
387 return num_numbers == 1 ||
388 numbers[num_numbers - 1] < 1u << (8 * (5 - num_numbers));
389 }
390
ssl_is_valid_ech_public_name(Span<const uint8_t> public_name)391 bool ssl_is_valid_ech_public_name(Span<const uint8_t> public_name) {
392 // See draft-ietf-tls-esni-13, Section 4 and RFC 5890, Section 2.3.1. The
393 // public name must be a dot-separated sequence of LDH labels and not begin or
394 // end with a dot.
395 auto copy = public_name;
396 if (copy.empty()) {
397 return false;
398 }
399 while (!copy.empty()) {
400 // Find the next dot-separated component.
401 auto dot = std::find(copy.begin(), copy.end(), '.');
402 Span<const uint8_t> component;
403 if (dot == copy.end()) {
404 component = copy;
405 copy = Span<const uint8_t>();
406 } else {
407 component = copy.subspan(0, dot - copy.begin());
408 copy = copy.subspan(dot - copy.begin() + 1); // Skip the dot.
409 if (copy.empty()) {
410 // Trailing dots are not allowed.
411 return false;
412 }
413 }
414 // |component| must be a valid LDH label. Checking for empty components also
415 // rejects leading dots.
416 if (component.empty() || component.size() > 63 ||
417 component.front() == '-' || component.back() == '-') {
418 return false;
419 }
420 for (uint8_t c : component) {
421 if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z') &&
422 !('0' <= c && c <= '9') && c != '-') {
423 return false;
424 }
425 }
426 }
427
428 return !is_ipv4_address(public_name);
429 }
430
parse_ech_config(CBS * cbs,ECHConfig * out,bool * out_supported,bool all_extensions_mandatory)431 static bool parse_ech_config(CBS *cbs, ECHConfig *out, bool *out_supported,
432 bool all_extensions_mandatory) {
433 uint16_t version;
434 CBS orig = *cbs;
435 CBS contents;
436 if (!CBS_get_u16(cbs, &version) ||
437 !CBS_get_u16_length_prefixed(cbs, &contents)) {
438 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
439 return false;
440 }
441
442 if (version != kECHConfigVersion) {
443 *out_supported = false;
444 return true;
445 }
446
447 // Make a copy of the ECHConfig and parse from it, so the results alias into
448 // the saved copy.
449 if (!out->raw.CopyFrom(
450 MakeConstSpan(CBS_data(&orig), CBS_len(&orig) - CBS_len(cbs)))) {
451 return false;
452 }
453
454 CBS ech_config(out->raw);
455 CBS public_name, public_key, cipher_suites, extensions;
456 if (!CBS_skip(&ech_config, 2) || // version
457 !CBS_get_u16_length_prefixed(&ech_config, &contents) ||
458 !CBS_get_u8(&contents, &out->config_id) ||
459 !CBS_get_u16(&contents, &out->kem_id) ||
460 !CBS_get_u16_length_prefixed(&contents, &public_key) ||
461 CBS_len(&public_key) == 0 ||
462 !CBS_get_u16_length_prefixed(&contents, &cipher_suites) ||
463 CBS_len(&cipher_suites) == 0 || CBS_len(&cipher_suites) % 4 != 0 ||
464 !CBS_get_u8(&contents, &out->maximum_name_length) ||
465 !CBS_get_u8_length_prefixed(&contents, &public_name) ||
466 CBS_len(&public_name) == 0 ||
467 !CBS_get_u16_length_prefixed(&contents, &extensions) ||
468 CBS_len(&contents) != 0) {
469 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
470 return false;
471 }
472
473 if (!ssl_is_valid_ech_public_name(public_name)) {
474 // TODO(https://crbug.com/boringssl/275): The draft says ECHConfigs with
475 // invalid public names should be ignored, but LDH syntax failures are
476 // unambiguously invalid.
477 *out_supported = false;
478 return true;
479 }
480
481 out->public_key = public_key;
482 out->public_name = public_name;
483 // This function does not ensure |out->kem_id| and |out->cipher_suites| use
484 // supported algorithms. The caller must do this.
485 out->cipher_suites = cipher_suites;
486
487 bool has_unknown_mandatory_extension = false;
488 while (CBS_len(&extensions) != 0) {
489 uint16_t type;
490 CBS body;
491 if (!CBS_get_u16(&extensions, &type) ||
492 !CBS_get_u16_length_prefixed(&extensions, &body)) {
493 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
494 return false;
495 }
496 // We currently do not support any extensions.
497 if (type & 0x8000 || all_extensions_mandatory) {
498 // Extension numbers with the high bit set are mandatory. Continue parsing
499 // to enforce syntax, but we will ultimately ignore this ECHConfig as a
500 // client and reject it as a server.
501 has_unknown_mandatory_extension = true;
502 }
503 }
504
505 *out_supported = !has_unknown_mandatory_extension;
506 return true;
507 }
508
Init(Span<const uint8_t> ech_config,const EVP_HPKE_KEY * key,bool is_retry_config)509 bool ECHServerConfig::Init(Span<const uint8_t> ech_config,
510 const EVP_HPKE_KEY *key, bool is_retry_config) {
511 is_retry_config_ = is_retry_config;
512
513 // Parse the ECHConfig, rejecting all unsupported parameters and extensions.
514 // Unlike most server options, ECH's server configuration is serialized and
515 // configured in both the server and DNS. If the caller configures an
516 // unsupported parameter, this is a deployment error. To catch these errors,
517 // we fail early.
518 CBS cbs = ech_config;
519 bool supported;
520 if (!parse_ech_config(&cbs, &ech_config_, &supported,
521 /*all_extensions_mandatory=*/true)) {
522 return false;
523 }
524 if (CBS_len(&cbs) != 0) {
525 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
526 return false;
527 }
528 if (!supported) {
529 OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG);
530 return false;
531 }
532
533 CBS cipher_suites = ech_config_.cipher_suites;
534 while (CBS_len(&cipher_suites) > 0) {
535 uint16_t kdf_id, aead_id;
536 if (!CBS_get_u16(&cipher_suites, &kdf_id) ||
537 !CBS_get_u16(&cipher_suites, &aead_id)) {
538 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
539 return false;
540 }
541 // The server promises to support every option in the ECHConfig, so reject
542 // any unsupported cipher suites.
543 if (kdf_id != EVP_HPKE_HKDF_SHA256 || get_ech_aead(aead_id) == nullptr) {
544 OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG);
545 return false;
546 }
547 }
548
549 // Check the public key in the ECHConfig matches |key|.
550 uint8_t expected_public_key[EVP_HPKE_MAX_PUBLIC_KEY_LENGTH];
551 size_t expected_public_key_len;
552 if (!EVP_HPKE_KEY_public_key(key, expected_public_key,
553 &expected_public_key_len,
554 sizeof(expected_public_key))) {
555 return false;
556 }
557 if (ech_config_.kem_id != EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(key)) ||
558 MakeConstSpan(expected_public_key, expected_public_key_len) !=
559 ech_config_.public_key) {
560 OPENSSL_PUT_ERROR(SSL, SSL_R_ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH);
561 return false;
562 }
563
564 if (!EVP_HPKE_KEY_copy(key_.get(), key)) {
565 return false;
566 }
567
568 return true;
569 }
570
SetupContext(EVP_HPKE_CTX * ctx,uint16_t kdf_id,uint16_t aead_id,Span<const uint8_t> enc) const571 bool ECHServerConfig::SetupContext(EVP_HPKE_CTX *ctx, uint16_t kdf_id,
572 uint16_t aead_id,
573 Span<const uint8_t> enc) const {
574 // Check the cipher suite is supported by this ECHServerConfig.
575 CBS cbs(ech_config_.cipher_suites);
576 bool cipher_ok = false;
577 while (CBS_len(&cbs) != 0) {
578 uint16_t supported_kdf_id, supported_aead_id;
579 if (!CBS_get_u16(&cbs, &supported_kdf_id) ||
580 !CBS_get_u16(&cbs, &supported_aead_id)) {
581 return false;
582 }
583 if (kdf_id == supported_kdf_id && aead_id == supported_aead_id) {
584 cipher_ok = true;
585 break;
586 }
587 }
588 if (!cipher_ok) {
589 return false;
590 }
591
592 static const uint8_t kInfoLabel[] = "tls ech";
593 ScopedCBB info_cbb;
594 if (!CBB_init(info_cbb.get(), sizeof(kInfoLabel) + ech_config_.raw.size()) ||
595 !CBB_add_bytes(info_cbb.get(), kInfoLabel,
596 sizeof(kInfoLabel) /* includes trailing NUL */) ||
597 !CBB_add_bytes(info_cbb.get(), ech_config_.raw.data(),
598 ech_config_.raw.size())) {
599 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
600 return false;
601 }
602
603 assert(kdf_id == EVP_HPKE_HKDF_SHA256);
604 assert(get_ech_aead(aead_id) != NULL);
605 return EVP_HPKE_CTX_setup_recipient(
606 ctx, key_.get(), EVP_hpke_hkdf_sha256(), get_ech_aead(aead_id), enc.data(),
607 enc.size(), CBB_data(info_cbb.get()), CBB_len(info_cbb.get()));
608 }
609
ssl_is_valid_ech_config_list(Span<const uint8_t> ech_config_list)610 bool ssl_is_valid_ech_config_list(Span<const uint8_t> ech_config_list) {
611 CBS cbs = ech_config_list, child;
612 if (!CBS_get_u16_length_prefixed(&cbs, &child) || //
613 CBS_len(&child) == 0 || //
614 CBS_len(&cbs) > 0) {
615 return false;
616 }
617 while (CBS_len(&child) > 0) {
618 ECHConfig ech_config;
619 bool supported;
620 if (!parse_ech_config(&child, &ech_config, &supported,
621 /*all_extensions_mandatory=*/false)) {
622 return false;
623 }
624 }
625 return true;
626 }
627
select_ech_cipher_suite(const EVP_HPKE_KDF ** out_kdf,const EVP_HPKE_AEAD ** out_aead,Span<const uint8_t> cipher_suites)628 static bool select_ech_cipher_suite(const EVP_HPKE_KDF **out_kdf,
629 const EVP_HPKE_AEAD **out_aead,
630 Span<const uint8_t> cipher_suites) {
631 const bool has_aes_hardware = EVP_has_aes_hardware();
632 const EVP_HPKE_AEAD *aead = nullptr;
633 CBS cbs = cipher_suites;
634 while (CBS_len(&cbs) != 0) {
635 uint16_t kdf_id, aead_id;
636 if (!CBS_get_u16(&cbs, &kdf_id) || //
637 !CBS_get_u16(&cbs, &aead_id)) {
638 return false;
639 }
640 // Pick the first common cipher suite, but prefer ChaCha20-Poly1305 if we
641 // don't have AES hardware.
642 const EVP_HPKE_AEAD *candidate = get_ech_aead(aead_id);
643 if (kdf_id != EVP_HPKE_HKDF_SHA256 || candidate == nullptr) {
644 continue;
645 }
646 if (aead == nullptr ||
647 (!has_aes_hardware && aead_id == EVP_HPKE_CHACHA20_POLY1305)) {
648 aead = candidate;
649 }
650 }
651 if (aead == nullptr) {
652 return false;
653 }
654
655 *out_kdf = EVP_hpke_hkdf_sha256();
656 *out_aead = aead;
657 return true;
658 }
659
ssl_select_ech_config(SSL_HANDSHAKE * hs,Span<uint8_t> out_enc,size_t * out_enc_len)660 bool ssl_select_ech_config(SSL_HANDSHAKE *hs, Span<uint8_t> out_enc,
661 size_t *out_enc_len) {
662 *out_enc_len = 0;
663 if (hs->max_version < TLS1_3_VERSION) {
664 // ECH requires TLS 1.3.
665 return true;
666 }
667
668 if (!hs->config->client_ech_config_list.empty()) {
669 CBS cbs = MakeConstSpan(hs->config->client_ech_config_list);
670 CBS child;
671 if (!CBS_get_u16_length_prefixed(&cbs, &child) || //
672 CBS_len(&child) == 0 || //
673 CBS_len(&cbs) > 0) {
674 return false;
675 }
676 // Look for the first ECHConfig with supported parameters.
677 while (CBS_len(&child) > 0) {
678 ECHConfig ech_config;
679 bool supported;
680 if (!parse_ech_config(&child, &ech_config, &supported,
681 /*all_extensions_mandatory=*/false)) {
682 return false;
683 }
684 const EVP_HPKE_KEM *kem = EVP_hpke_x25519_hkdf_sha256();
685 const EVP_HPKE_KDF *kdf;
686 const EVP_HPKE_AEAD *aead;
687 if (supported && //
688 ech_config.kem_id == EVP_HPKE_DHKEM_X25519_HKDF_SHA256 &&
689 select_ech_cipher_suite(&kdf, &aead, ech_config.cipher_suites)) {
690 ScopedCBB info;
691 static const uint8_t kInfoLabel[] = "tls ech"; // includes trailing NUL
692 if (!CBB_init(info.get(), sizeof(kInfoLabel) + ech_config.raw.size()) ||
693 !CBB_add_bytes(info.get(), kInfoLabel, sizeof(kInfoLabel)) ||
694 !CBB_add_bytes(info.get(), ech_config.raw.data(),
695 ech_config.raw.size())) {
696 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
697 return false;
698 }
699
700 if (!EVP_HPKE_CTX_setup_sender(
701 hs->ech_hpke_ctx.get(), out_enc.data(), out_enc_len,
702 out_enc.size(), kem, kdf, aead, ech_config.public_key.data(),
703 ech_config.public_key.size(), CBB_data(info.get()),
704 CBB_len(info.get())) ||
705 !hs->inner_transcript.Init()) {
706 return false;
707 }
708
709 hs->selected_ech_config = MakeUnique<ECHConfig>(std::move(ech_config));
710 return hs->selected_ech_config != nullptr;
711 }
712 }
713 }
714
715 return true;
716 }
717
aead_overhead(const EVP_HPKE_AEAD * aead)718 static size_t aead_overhead(const EVP_HPKE_AEAD *aead) {
719 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
720 // TODO(https://crbug.com/boringssl/275): Having to adjust the overhead
721 // everywhere is tedious. Change fuzzer mode to append a fake tag but still
722 // otherwise be cleartext, refresh corpora, and then inline this function.
723 return 0;
724 #else
725 return EVP_AEAD_max_overhead(EVP_HPKE_AEAD_aead(aead));
726 #endif
727 }
728
729 // random_size returns a random value between |min| and |max|, inclusive.
random_size(size_t min,size_t max)730 static size_t random_size(size_t min, size_t max) {
731 assert(min < max);
732 size_t value;
733 RAND_bytes(reinterpret_cast<uint8_t *>(&value), sizeof(value));
734 return value % (max - min + 1) + min;
735 }
736
setup_ech_grease(SSL_HANDSHAKE * hs)737 static bool setup_ech_grease(SSL_HANDSHAKE *hs) {
738 assert(!hs->selected_ech_config);
739 if (hs->max_version < TLS1_3_VERSION || !hs->config->ech_grease_enabled) {
740 return true;
741 }
742
743 const uint16_t kdf_id = EVP_HPKE_HKDF_SHA256;
744 const EVP_HPKE_AEAD *aead = EVP_has_aes_hardware()
745 ? EVP_hpke_aes_128_gcm()
746 : EVP_hpke_chacha20_poly1305();
747 static_assert(ssl_grease_ech_config_id < sizeof(hs->grease_seed),
748 "hs->grease_seed is too small");
749 uint8_t config_id = hs->grease_seed[ssl_grease_ech_config_id];
750
751 uint8_t enc[X25519_PUBLIC_VALUE_LEN];
752 uint8_t private_key_unused[X25519_PRIVATE_KEY_LEN];
753 X25519_keypair(enc, private_key_unused);
754
755 // To determine a plausible length for the payload, we estimate the size of a
756 // typical EncodedClientHelloInner without resumption:
757 //
758 // 2+32+1+2 version, random, legacy_session_id, legacy_compression_methods
759 // 2+4*2 cipher_suites (three TLS 1.3 ciphers, GREASE)
760 // 2 extensions prefix
761 // 5 inner encrypted_client_hello
762 // 4+1+2*2 supported_versions (TLS 1.3, GREASE)
763 // 4+1+10*2 outer_extensions (key_share, sigalgs, sct, alpn,
764 // supported_groups, status_request, psk_key_exchange_modes,
765 // compress_certificate, GREASE x2)
766 //
767 // The server_name extension has an overhead of 9 bytes. For now, arbitrarily
768 // estimate maximum_name_length to be between 32 and 100 bytes. Then round up
769 // to a multiple of 32, to match draft-ietf-tls-esni-13, section 6.1.3.
770 const size_t payload_len =
771 32 * random_size(128 / 32, 224 / 32) + aead_overhead(aead);
772 bssl::ScopedCBB cbb;
773 CBB enc_cbb, payload_cbb;
774 uint8_t *payload;
775 if (!CBB_init(cbb.get(), 256) ||
776 !CBB_add_u16(cbb.get(), kdf_id) ||
777 !CBB_add_u16(cbb.get(), EVP_HPKE_AEAD_id(aead)) ||
778 !CBB_add_u8(cbb.get(), config_id) ||
779 !CBB_add_u16_length_prefixed(cbb.get(), &enc_cbb) ||
780 !CBB_add_bytes(&enc_cbb, enc, sizeof(enc)) ||
781 !CBB_add_u16_length_prefixed(cbb.get(), &payload_cbb) ||
782 !CBB_add_space(&payload_cbb, &payload, payload_len) ||
783 !RAND_bytes(payload, payload_len) ||
784 !CBBFinishArray(cbb.get(), &hs->ech_client_outer)) {
785 return false;
786 }
787 return true;
788 }
789
ssl_encrypt_client_hello(SSL_HANDSHAKE * hs,Span<const uint8_t> enc)790 bool ssl_encrypt_client_hello(SSL_HANDSHAKE *hs, Span<const uint8_t> enc) {
791 SSL *const ssl = hs->ssl;
792 if (!hs->selected_ech_config) {
793 return setup_ech_grease(hs);
794 }
795
796 // Construct ClientHelloInner and EncodedClientHelloInner. See
797 // draft-ietf-tls-esni-13, sections 5.1 and 6.1.
798 ScopedCBB cbb, encoded_cbb;
799 CBB body;
800 bool needs_psk_binder;
801 Array<uint8_t> hello_inner;
802 if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO) ||
803 !CBB_init(encoded_cbb.get(), 256) ||
804 !ssl_write_client_hello_without_extensions(hs, &body,
805 ssl_client_hello_inner,
806 /*empty_session_id=*/false) ||
807 !ssl_write_client_hello_without_extensions(hs, encoded_cbb.get(),
808 ssl_client_hello_inner,
809 /*empty_session_id=*/true) ||
810 !ssl_add_clienthello_tlsext(hs, &body, encoded_cbb.get(),
811 &needs_psk_binder, ssl_client_hello_inner,
812 CBB_len(&body)) ||
813 !ssl->method->finish_message(ssl, cbb.get(), &hello_inner)) {
814 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
815 return false;
816 }
817
818 if (needs_psk_binder) {
819 size_t binder_len;
820 if (!tls13_write_psk_binder(hs, hs->inner_transcript, MakeSpan(hello_inner),
821 &binder_len)) {
822 return false;
823 }
824 // Also update the EncodedClientHelloInner.
825 auto encoded_binder =
826 MakeSpan(const_cast<uint8_t *>(CBB_data(encoded_cbb.get())),
827 CBB_len(encoded_cbb.get()))
828 .last(binder_len);
829 auto hello_inner_binder = MakeConstSpan(hello_inner).last(binder_len);
830 OPENSSL_memcpy(encoded_binder.data(), hello_inner_binder.data(),
831 binder_len);
832 }
833
834 if (!hs->inner_transcript.Update(hello_inner)) {
835 return false;
836 }
837
838 // Pad the EncodedClientHelloInner. See draft-ietf-tls-esni-13, section 6.1.3.
839 size_t padding_len = 0;
840 size_t maximum_name_length = hs->selected_ech_config->maximum_name_length;
841 if (ssl->hostname) {
842 size_t hostname_len = strlen(ssl->hostname.get());
843 if (hostname_len <= maximum_name_length) {
844 padding_len = maximum_name_length - hostname_len;
845 }
846 } else {
847 // No SNI. Pad up to |maximum_name_length|, including server_name extension
848 // overhead.
849 padding_len = 9 + maximum_name_length;
850 }
851 // Pad the whole thing to a multiple of 32 bytes.
852 padding_len += 31 - ((CBB_len(encoded_cbb.get()) + padding_len - 1) % 32);
853 Array<uint8_t> encoded;
854 if (!CBB_add_zeros(encoded_cbb.get(), padding_len) ||
855 !CBBFinishArray(encoded_cbb.get(), &encoded)) {
856 return false;
857 }
858
859 // Encrypt |encoded|. See draft-ietf-tls-esni-13, section 6.1.1. First,
860 // assemble the extension with a placeholder value for ClientHelloOuterAAD.
861 // See draft-ietf-tls-esni-13, section 5.2.
862 const EVP_HPKE_KDF *kdf = EVP_HPKE_CTX_kdf(hs->ech_hpke_ctx.get());
863 const EVP_HPKE_AEAD *aead = EVP_HPKE_CTX_aead(hs->ech_hpke_ctx.get());
864 size_t payload_len = encoded.size() + aead_overhead(aead);
865 CBB enc_cbb, payload_cbb;
866 if (!CBB_init(cbb.get(), 256) ||
867 !CBB_add_u16(cbb.get(), EVP_HPKE_KDF_id(kdf)) ||
868 !CBB_add_u16(cbb.get(), EVP_HPKE_AEAD_id(aead)) ||
869 !CBB_add_u8(cbb.get(), hs->selected_ech_config->config_id) ||
870 !CBB_add_u16_length_prefixed(cbb.get(), &enc_cbb) ||
871 !CBB_add_bytes(&enc_cbb, enc.data(), enc.size()) ||
872 !CBB_add_u16_length_prefixed(cbb.get(), &payload_cbb) ||
873 !CBB_add_zeros(&payload_cbb, payload_len) ||
874 !CBBFinishArray(cbb.get(), &hs->ech_client_outer)) {
875 return false;
876 }
877
878 // Construct ClientHelloOuterAAD.
879 // TODO(https://crbug.com/boringssl/275): This ends up constructing the
880 // ClientHelloOuter twice. Instead, reuse |aad| for the ClientHello, now that
881 // draft-12 made the length prefixes match.
882 bssl::ScopedCBB aad;
883 if (!CBB_init(aad.get(), 256) ||
884 !ssl_write_client_hello_without_extensions(hs, aad.get(),
885 ssl_client_hello_outer,
886 /*empty_session_id=*/false) ||
887 !ssl_add_clienthello_tlsext(hs, aad.get(), /*out_encoded=*/nullptr,
888 &needs_psk_binder, ssl_client_hello_outer,
889 CBB_len(aad.get()))) {
890 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
891 return false;
892 }
893
894 // ClientHelloOuter may not require a PSK binder. Otherwise, we have a
895 // circular dependency.
896 assert(!needs_psk_binder);
897
898 // Replace the payload in |hs->ech_client_outer| with the encrypted value.
899 auto payload_span = MakeSpan(hs->ech_client_outer).last(payload_len);
900 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
901 // In fuzzer mode, the server expects a cleartext payload.
902 assert(payload_span.size() == encoded.size());
903 OPENSSL_memcpy(payload_span.data(), encoded.data(), encoded.size());
904 #else
905 if (!EVP_HPKE_CTX_seal(hs->ech_hpke_ctx.get(), payload_span.data(),
906 &payload_len, payload_span.size(), encoded.data(),
907 encoded.size(), CBB_data(aad.get()),
908 CBB_len(aad.get())) ||
909 payload_len != payload_span.size()) {
910 return false;
911 }
912 #endif // BORINGSSL_UNSAFE_FUZZER_MODE
913
914 return true;
915 }
916
917 BSSL_NAMESPACE_END
918
919 using namespace bssl;
920
SSL_set_enable_ech_grease(SSL * ssl,int enable)921 void SSL_set_enable_ech_grease(SSL *ssl, int enable) {
922 if (!ssl->config) {
923 return;
924 }
925 ssl->config->ech_grease_enabled = !!enable;
926 }
927
SSL_set1_ech_config_list(SSL * ssl,const uint8_t * ech_config_list,size_t ech_config_list_len)928 int SSL_set1_ech_config_list(SSL *ssl, const uint8_t *ech_config_list,
929 size_t ech_config_list_len) {
930 if (!ssl->config) {
931 return 0;
932 }
933
934 auto span = MakeConstSpan(ech_config_list, ech_config_list_len);
935 if (!ssl_is_valid_ech_config_list(span)) {
936 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ECH_CONFIG_LIST);
937 return 0;
938 }
939 return ssl->config->client_ech_config_list.CopyFrom(span);
940 }
941
SSL_get0_ech_name_override(const SSL * ssl,const char ** out_name,size_t * out_name_len)942 void SSL_get0_ech_name_override(const SSL *ssl, const char **out_name,
943 size_t *out_name_len) {
944 // When ECH is rejected, we use the public name. Note that, if
945 // |SSL_CTX_set_reverify_on_resume| is enabled, we reverify the certificate
946 // before the 0-RTT point. If also offering ECH, we verify as if
947 // ClientHelloInner was accepted and do not override. This works because, at
948 // this point, |ech_status| will be |ssl_ech_none|. See the
949 // ECH-Client-Reject-EarlyDataReject-OverrideNameOnRetry tests in runner.go.
950 const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
951 if (!ssl->server && hs && ssl->s3->ech_status == ssl_ech_rejected) {
952 *out_name = reinterpret_cast<const char *>(
953 hs->selected_ech_config->public_name.data());
954 *out_name_len = hs->selected_ech_config->public_name.size();
955 } else {
956 *out_name = nullptr;
957 *out_name_len = 0;
958 }
959 }
960
SSL_get0_ech_retry_configs(const SSL * ssl,const uint8_t ** out_retry_configs,size_t * out_retry_configs_len)961 void SSL_get0_ech_retry_configs(
962 const SSL *ssl, const uint8_t **out_retry_configs,
963 size_t *out_retry_configs_len) {
964 const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
965 if (!hs || !hs->ech_authenticated_reject) {
966 // It is an error to call this function except in response to
967 // |SSL_R_ECH_REJECTED|. Returning an empty string risks the caller
968 // mistakenly believing the server has disabled ECH. Instead, return a
969 // non-empty ECHConfigList with a syntax error, so the subsequent
970 // |SSL_set1_ech_config_list| call will fail.
971 assert(0);
972 static const uint8_t kPlaceholder[] = {
973 kECHConfigVersion >> 8, kECHConfigVersion & 0xff, 0xff, 0xff, 0xff};
974 *out_retry_configs = kPlaceholder;
975 *out_retry_configs_len = sizeof(kPlaceholder);
976 return;
977 }
978
979 *out_retry_configs = hs->ech_retry_configs.data();
980 *out_retry_configs_len = hs->ech_retry_configs.size();
981 }
982
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)983 int SSL_marshal_ech_config(uint8_t **out, size_t *out_len, uint8_t config_id,
984 const EVP_HPKE_KEY *key, const char *public_name,
985 size_t max_name_len) {
986 Span<const uint8_t> public_name_u8 = MakeConstSpan(
987 reinterpret_cast<const uint8_t *>(public_name), strlen(public_name));
988 if (!ssl_is_valid_ech_public_name(public_name_u8)) {
989 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ECH_PUBLIC_NAME);
990 return 0;
991 }
992
993 // The maximum name length is encoded in one byte.
994 if (max_name_len > 0xff) {
995 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH);
996 return 0;
997 }
998
999 // See draft-ietf-tls-esni-13, section 4.
1000 ScopedCBB cbb;
1001 CBB contents, child;
1002 uint8_t *public_key;
1003 size_t public_key_len;
1004 if (!CBB_init(cbb.get(), 128) || //
1005 !CBB_add_u16(cbb.get(), kECHConfigVersion) ||
1006 !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
1007 !CBB_add_u8(&contents, config_id) ||
1008 !CBB_add_u16(&contents, EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(key))) ||
1009 !CBB_add_u16_length_prefixed(&contents, &child) ||
1010 !CBB_reserve(&child, &public_key, EVP_HPKE_MAX_PUBLIC_KEY_LENGTH) ||
1011 !EVP_HPKE_KEY_public_key(key, public_key, &public_key_len,
1012 EVP_HPKE_MAX_PUBLIC_KEY_LENGTH) ||
1013 !CBB_did_write(&child, public_key_len) ||
1014 !CBB_add_u16_length_prefixed(&contents, &child) ||
1015 // Write a default cipher suite configuration.
1016 !CBB_add_u16(&child, EVP_HPKE_HKDF_SHA256) ||
1017 !CBB_add_u16(&child, EVP_HPKE_AES_128_GCM) ||
1018 !CBB_add_u16(&child, EVP_HPKE_HKDF_SHA256) ||
1019 !CBB_add_u16(&child, EVP_HPKE_CHACHA20_POLY1305) ||
1020 !CBB_add_u8(&contents, max_name_len) ||
1021 !CBB_add_u8_length_prefixed(&contents, &child) ||
1022 !CBB_add_bytes(&child, public_name_u8.data(), public_name_u8.size()) ||
1023 // TODO(https://crbug.com/boringssl/275): Reserve some GREASE extensions
1024 // and include some.
1025 !CBB_add_u16(&contents, 0 /* no extensions */) ||
1026 !CBB_finish(cbb.get(), out, out_len)) {
1027 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
1028 return 0;
1029 }
1030 return 1;
1031 }
1032
SSL_ECH_KEYS_new()1033 SSL_ECH_KEYS *SSL_ECH_KEYS_new() { return New<SSL_ECH_KEYS>(); }
1034
SSL_ECH_KEYS_up_ref(SSL_ECH_KEYS * keys)1035 void SSL_ECH_KEYS_up_ref(SSL_ECH_KEYS *keys) {
1036 CRYPTO_refcount_inc(&keys->references);
1037 }
1038
SSL_ECH_KEYS_free(SSL_ECH_KEYS * keys)1039 void SSL_ECH_KEYS_free(SSL_ECH_KEYS *keys) {
1040 if (keys == nullptr ||
1041 !CRYPTO_refcount_dec_and_test_zero(&keys->references)) {
1042 return;
1043 }
1044
1045 keys->~ssl_ech_keys_st();
1046 OPENSSL_free(keys);
1047 }
1048
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)1049 int SSL_ECH_KEYS_add(SSL_ECH_KEYS *configs, int is_retry_config,
1050 const uint8_t *ech_config, size_t ech_config_len,
1051 const EVP_HPKE_KEY *key) {
1052 UniquePtr<ECHServerConfig> parsed_config = MakeUnique<ECHServerConfig>();
1053 if (!parsed_config) {
1054 return 0;
1055 }
1056 if (!parsed_config->Init(MakeConstSpan(ech_config, ech_config_len), key,
1057 !!is_retry_config)) {
1058 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
1059 return 0;
1060 }
1061 if (!configs->configs.Push(std::move(parsed_config))) {
1062 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
1063 return 0;
1064 }
1065 return 1;
1066 }
1067
SSL_ECH_KEYS_has_duplicate_config_id(const SSL_ECH_KEYS * keys)1068 int SSL_ECH_KEYS_has_duplicate_config_id(const SSL_ECH_KEYS *keys) {
1069 bool seen[256] = {false};
1070 for (const auto &config : keys->configs) {
1071 if (seen[config->ech_config().config_id]) {
1072 return 1;
1073 }
1074 seen[config->ech_config().config_id] = true;
1075 }
1076 return 0;
1077 }
1078
SSL_ECH_KEYS_marshal_retry_configs(const SSL_ECH_KEYS * keys,uint8_t ** out,size_t * out_len)1079 int SSL_ECH_KEYS_marshal_retry_configs(const SSL_ECH_KEYS *keys, uint8_t **out,
1080 size_t *out_len) {
1081 ScopedCBB cbb;
1082 CBB child;
1083 if (!CBB_init(cbb.get(), 128) ||
1084 !CBB_add_u16_length_prefixed(cbb.get(), &child)) {
1085 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
1086 return false;
1087 }
1088 for (const auto &config : keys->configs) {
1089 if (config->is_retry_config() &&
1090 !CBB_add_bytes(&child, config->ech_config().raw.data(),
1091 config->ech_config().raw.size())) {
1092 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
1093 return false;
1094 }
1095 }
1096 return CBB_finish(cbb.get(), out, out_len);
1097 }
1098
SSL_CTX_set1_ech_keys(SSL_CTX * ctx,SSL_ECH_KEYS * keys)1099 int SSL_CTX_set1_ech_keys(SSL_CTX *ctx, SSL_ECH_KEYS *keys) {
1100 bool has_retry_config = false;
1101 for (const auto &config : keys->configs) {
1102 if (config->is_retry_config()) {
1103 has_retry_config = true;
1104 break;
1105 }
1106 }
1107 if (!has_retry_config) {
1108 OPENSSL_PUT_ERROR(SSL, SSL_R_ECH_SERVER_WOULD_HAVE_NO_RETRY_CONFIGS);
1109 return 0;
1110 }
1111 UniquePtr<SSL_ECH_KEYS> owned_keys = UpRef(keys);
1112 MutexWriteLock lock(&ctx->lock);
1113 ctx->ech_keys.swap(owned_keys);
1114 return 1;
1115 }
1116
SSL_ech_accepted(const SSL * ssl)1117 int SSL_ech_accepted(const SSL *ssl) {
1118 if (SSL_in_early_data(ssl) && !ssl->server) {
1119 // In the client early data state, we report properties as if the server
1120 // accepted early data. The server can only accept early data with
1121 // ClientHelloInner.
1122 return ssl->s3->hs->selected_ech_config != nullptr;
1123 }
1124
1125 return ssl->s3->ech_status == ssl_ech_accepted;
1126 }
1127