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