Bug Summary

File:s/lib/ssl/tls13ech.c
Warning:line 2174, column 5
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name tls13ech.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/ssl -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/ssl -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -D NSS_ALLOW_SSLKEYLOGFILE=1 -I ../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/nss -I ../../../dist/private/nss -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c tls13ech.c
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7#include "nss.h"
8#include "pk11func.h"
9#include "pk11hpke.h"
10#include "ssl.h"
11#include "sslproto.h"
12#include "sslimpl.h"
13#include "selfencrypt.h"
14#include "ssl3exthandle.h"
15#include "tls13ech.h"
16#include "tls13exthandle.h"
17#include "tls13hashstate.h"
18#include "tls13hkdf.h"
19
20extern SECStatus
21ssl3_UpdateHandshakeHashesInt(sslSocket *ss, const unsigned char *b,
22 unsigned int l, sslBuffer *transcriptBuf);
23extern SECStatus
24ssl3_HandleClientHelloPreamble(sslSocket *ss, PRUint8 **b, PRUint32 *length, SECItem *sidBytes,
25 SECItem *cookieBytes, SECItem *suites, SECItem *comps);
26extern SECStatus
27tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key,
28 const char *label,
29 unsigned int labelLen,
30 const SSL3Hashes *hashes,
31 PK11SymKey **dest,
32 SSLHashType hash);
33
34PRBool
35tls13_Debug_CheckXtnBegins(const PRUint8 *start, const PRUint16 xtnType)
36{
37#ifdef DEBUG1
38 SECStatus rv;
39 sslReader ext_reader = SSL_READER(start, 2){ { start, 2 }, 0 };
40 PRUint64 extension_number;
41 rv = sslRead_ReadNumber(&ext_reader, 2, &extension_number);
42 return ((rv == SECSuccess) && (extension_number == xtnType));
43#else
44 return PR_TRUE1;
45#endif
46}
47
48void
49tls13_DestroyEchConfig(sslEchConfig *config)
50{
51 if (!config) {
52 return;
53 }
54 SECITEM_FreeItemSECITEM_FreeItem_Util(&config->contents.publicKey, PR_FALSE0);
55 SECITEM_FreeItemSECITEM_FreeItem_Util(&config->contents.suites, PR_FALSE0);
56 SECITEM_FreeItemSECITEM_FreeItem_Util(&config->raw, PR_FALSE0);
57 PORT_FreePORT_Free_Util(config->contents.publicName);
58 config->contents.publicName = NULL((void*)0);
59 PORT_ZFreePORT_ZFree_Util(config, sizeof(*config));
60}
61
62void
63tls13_DestroyEchConfigs(PRCList *list)
64{
65 PRCList *cur_p;
66 while (!PR_CLIST_IS_EMPTY(list)((list)->next == (list))) {
67 cur_p = PR_LIST_TAIL(list)(list)->prev;
68 PR_REMOVE_LINK(cur_p)do { (cur_p)->prev->next = (cur_p)->next; (cur_p)->
next->prev = (cur_p)->prev; } while (0)
;
69 tls13_DestroyEchConfig((sslEchConfig *)cur_p);
70 }
71}
72
73void
74tls13_DestroyEchXtnState(sslEchXtnState *state)
75{
76 if (!state) {
77 return;
78 }
79 SECITEM_FreeItemSECITEM_FreeItem_Util(&state->innerCh, PR_FALSE0);
80 SECITEM_FreeItemSECITEM_FreeItem_Util(&state->senderPubKey, PR_FALSE0);
81 SECITEM_FreeItemSECITEM_FreeItem_Util(&state->retryConfigs, PR_FALSE0);
82 PORT_ZFreePORT_ZFree_Util(state, sizeof(*state));
83}
84
85SECStatus
86tls13_CopyEchConfigs(PRCList *oConfigs, PRCList *configs)
87{
88 SECStatus rv;
89 sslEchConfig *config;
90 sslEchConfig *newConfig = NULL((void*)0);
91
92 for (PRCList *cur_p = PR_LIST_HEAD(oConfigs)(oConfigs)->next;
93 cur_p != oConfigs;
94 cur_p = PR_NEXT_LINK(cur_p)((cur_p)->next)) {
95 config = (sslEchConfig *)PR_LIST_TAIL(oConfigs)(oConfigs)->prev;
96 newConfig = PORT_ZNew(sslEchConfig)(sslEchConfig *)PORT_ZAlloc_Util(sizeof(sslEchConfig));
97 if (!newConfig) {
98 goto loser;
99 }
100
101 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), &newConfig->raw, &config->raw);
102 if (rv != SECSuccess) {
103 goto loser;
104 }
105 newConfig->contents.publicName = PORT_StrdupPORT_Strdup_Util(config->contents.publicName);
106 if (!newConfig->contents.publicName) {
107 goto loser;
108 }
109 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), &newConfig->contents.publicKey,
110 &config->contents.publicKey);
111 if (rv != SECSuccess) {
112 goto loser;
113 }
114 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), &newConfig->contents.suites,
115 &config->contents.suites);
116 if (rv != SECSuccess) {
117 goto loser;
118 }
119 newConfig->contents.configId = config->contents.configId;
120 newConfig->contents.kemId = config->contents.kemId;
121 newConfig->contents.kdfId = config->contents.kdfId;
122 newConfig->contents.aeadId = config->contents.aeadId;
123 newConfig->contents.maxNameLen = config->contents.maxNameLen;
124 newConfig->version = config->version;
125 PR_APPEND_LINK(&newConfig->link, configs)do { (&newConfig->link)->next = (configs); (&newConfig
->link)->prev = (configs)->prev; (configs)->prev->
next = (&newConfig->link); (configs)->prev = (&
newConfig->link); } while (0)
;
126 }
127 return SECSuccess;
128
129loser:
130 tls13_DestroyEchConfig(newConfig);
131 tls13_DestroyEchConfigs(configs);
132 return SECFailure;
133}
134
135/*
136 * struct {
137 * HpkeKdfId kdf_id;
138 * HpkeAeadId aead_id;
139 * } HpkeSymmetricCipherSuite;
140 *
141 * struct {
142 * uint8 config_id;
143 * HpkeKemId kem_id;
144 * HpkePublicKey public_key;
145 * HpkeSymmetricCipherSuite cipher_suites<4..2^16-4>;
146 * } HpkeKeyConfig;
147 *
148 * struct {
149 * HpkeKeyConfig key_config;
150 * uint16 maximum_name_length;
151 * opaque public_name<1..2^16-1>;
152 * Extension extensions<0..2^16-1>;
153 * } ECHConfigContents;
154 *
155 * struct {
156 * uint16 version;
157 * uint16 length;
158 * select (ECHConfig.version) {
159 * case 0xfe0d: ECHConfigContents contents;
160 * }
161 * } ECHConfig;
162 */
163static SECStatus
164tls13_DecodeEchConfigContents(const sslReadBuffer *rawConfig,
165 sslEchConfig **outConfig)
166{
167 SECStatus rv;
168 sslEchConfigContents contents = { 0 };
169 sslEchConfig *decodedConfig;
170 PRUint64 tmpn;
171 PRUint64 tmpn2;
172 sslReadBuffer tmpBuf;
173 PRUint16 *extensionTypes = NULL((void*)0);
174 unsigned int extensionIndex = 0;
175 sslReader configReader = SSL_READER(rawConfig->buf, rawConfig->len){ { rawConfig->buf, rawConfig->len }, 0 };
176 sslReader suiteReader;
177 sslReader extensionReader;
178 PRBool hasValidSuite = PR_FALSE0;
179 PRBool unsupportedMandatoryXtn = PR_FALSE0;
180
181 /* HpkeKeyConfig key_config */
182 /* uint8 config_id */
183 rv = sslRead_ReadNumber(&configReader, 1, &tmpn);
184 if (rv != SECSuccess) {
185 goto loser;
186 }
187 contents.configId = tmpn;
188
189 /* HpkeKemId kem_id */
190 rv = sslRead_ReadNumber(&configReader, 2, &tmpn);
191 if (rv != SECSuccess) {
192 goto loser;
193 }
194 contents.kemId = tmpn;
195
196 /* HpkePublicKey public_key */
197 rv = sslRead_ReadVariable(&configReader, 2, &tmpBuf);
198 if (rv != SECSuccess) {
199 goto loser;
200 }
201 rv = SECITEM_MakeItem(NULL((void*)0), &contents.publicKey, (PRUint8 *)tmpBuf.buf, tmpBuf.len);
202 if (rv != SECSuccess) {
203 goto loser;
204 }
205
206 /* HpkeSymmetricCipherSuite cipher_suites<4..2^16-4> */
207 rv = sslRead_ReadVariable(&configReader, 2, &tmpBuf);
208 if (rv != SECSuccess) {
209 goto loser;
210 }
211 if (tmpBuf.len & 1) {
212 PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_ECH_CONFIGSSL_ERROR_RX_MALFORMED_ESNI_KEYS);
213 goto loser;
214 }
215 suiteReader = (sslReader)SSL_READER(tmpBuf.buf, tmpBuf.len){ { tmpBuf.buf, tmpBuf.len }, 0 };
216 while (SSL_READER_REMAINING(&suiteReader)((&suiteReader)->buf.len - (&suiteReader)->offset
)
) {
217 /* HpkeKdfId kdf_id */
218 rv = sslRead_ReadNumber(&suiteReader, 2, &tmpn);
219 if (rv != SECSuccess) {
220 goto loser;
221 }
222 /* HpkeAeadId aead_id */
223 rv = sslRead_ReadNumber(&suiteReader, 2, &tmpn2);
224 if (rv != SECSuccess) {
225 goto loser;
226 }
227 if (!hasValidSuite) {
228 /* Use the first compatible ciphersuite. */
229 rv = PK11_HPKE_ValidateParameters(contents.kemId, tmpn, tmpn2);
230 if (rv == SECSuccess) {
231 hasValidSuite = PR_TRUE1;
232 contents.kdfId = tmpn;
233 contents.aeadId = tmpn2;
234 break;
235 }
236 }
237 }
238
239 rv = SECITEM_MakeItem(NULL((void*)0), &contents.suites, (PRUint8 *)tmpBuf.buf, tmpBuf.len);
240 if (rv != SECSuccess) {
241 goto loser;
242 }
243
244 /* uint8 maximum_name_length */
245 rv = sslRead_ReadNumber(&configReader, 1, &tmpn);
246 if (rv != SECSuccess) {
247 goto loser;
248 }
249 contents.maxNameLen = (PRUint8)tmpn;
250
251 /* opaque public_name<1..2^16-1> */
252 rv = sslRead_ReadVariable(&configReader, 1, &tmpBuf);
253 if (rv != SECSuccess) {
254 goto loser;
255 }
256
257 if (tmpBuf.len == 0) {
258 PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_ECH_CONFIGSSL_ERROR_RX_MALFORMED_ESNI_KEYS);
259 goto loser;
260 }
261 if (!tls13_IsLDH(tmpBuf.buf, tmpBuf.len) ||
262 tls13_IsIp(tmpBuf.buf, tmpBuf.len)) {
263 PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_ECH_CONFIGSSL_ERROR_RX_MALFORMED_ESNI_KEYS);
264 goto loser;
265 }
266
267 contents.publicName = PORT_ZAllocPORT_ZAlloc_Util(tmpBuf.len + 1);
268 if (!contents.publicName) {
269 goto loser;
270 }
271 PORT_Memcpymemcpy(contents.publicName, (PRUint8 *)tmpBuf.buf, tmpBuf.len);
272
273 /* Extensions. We don't support any, but must
274 * check for any that are marked critical. */
275 rv = sslRead_ReadVariable(&configReader, 2, &tmpBuf);
276 if (rv != SECSuccess) {
277 goto loser;
278 }
279
280 extensionReader = (sslReader)SSL_READER(tmpBuf.buf, tmpBuf.len){ { tmpBuf.buf, tmpBuf.len }, 0 };
281 extensionTypes = PORT_NewArray(PRUint16, tmpBuf.len / 2 * sizeof(PRUint16))(PRUint16 *)PORT_Alloc_Util(sizeof(PRUint16) * (tmpBuf.len / 2
* sizeof(PRUint16)))
;
282 if (!extensionTypes) {
283 goto loser;
284 }
285
286 while (SSL_READER_REMAINING(&extensionReader)((&extensionReader)->buf.len - (&extensionReader)->
offset)
) {
287 /* Get the extension's type field */
288 rv = sslRead_ReadNumber(&extensionReader, 2, &tmpn);
289 if (rv != SECSuccess) {
290 goto loser;
291 }
292
293 for (unsigned int i = 0; i < extensionIndex; i++) {
294 if (extensionTypes[i] == tmpn) {
295 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_EXTENSION_VALUE_INVALID);
296 goto loser;
297 }
298 }
299 extensionTypes[extensionIndex++] = (PRUint16)tmpn;
300
301 /* Clients MUST parse the extension list and check for unsupported
302 * mandatory extensions. If an unsupported mandatory extension is
303 * present, clients MUST ignore the ECHConfig
304 * [draft-ietf-tls-esni, Section 4.2]. */
305 if (tmpn & (1 << 15)) {
306 unsupportedMandatoryXtn = PR_TRUE1;
307 }
308
309 /* Skip. */
310 rv = sslRead_ReadVariable(&extensionReader, 2, &tmpBuf);
311 if (rv != SECSuccess) {
312 goto loser;
313 }
314 }
315
316 /* Check that we consumed the entire ECHConfig */
317 if (SSL_READER_REMAINING(&configReader)((&configReader)->buf.len - (&configReader)->offset
)
) {
318 PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_ECH_CONFIGSSL_ERROR_RX_MALFORMED_ESNI_KEYS);
319 goto loser;
320 }
321
322 /* If the ciphersuites were compatible AND if NO unsupported mandatory
323 * extensions were found set the outparam. Return success either way if the
324 * config was well-formed. */
325 if (hasValidSuite && !unsupportedMandatoryXtn) {
326 decodedConfig = PORT_ZNew(sslEchConfig)(sslEchConfig *)PORT_ZAlloc_Util(sizeof(sslEchConfig));
327 if (!decodedConfig) {
328 goto loser;
329 }
330 decodedConfig->contents = contents;
331 *outConfig = decodedConfig;
332 } else {
333 PORT_FreePORT_Free_Util(contents.publicName);
334 SECITEM_FreeItemSECITEM_FreeItem_Util(&contents.publicKey, PR_FALSE0);
335 SECITEM_FreeItemSECITEM_FreeItem_Util(&contents.suites, PR_FALSE0);
336 }
337 PORT_FreePORT_Free_Util(extensionTypes);
338 return SECSuccess;
339
340loser:
341 PORT_FreePORT_Free_Util(extensionTypes);
342 PORT_FreePORT_Free_Util(contents.publicName);
343 SECITEM_FreeItemSECITEM_FreeItem_Util(&contents.publicKey, PR_FALSE0);
344 SECITEM_FreeItemSECITEM_FreeItem_Util(&contents.suites, PR_FALSE0);
345 return SECFailure;
346}
347
348/* Decode an ECHConfigList struct and store each ECHConfig
349 * into |configs|. */
350SECStatus
351tls13_DecodeEchConfigs(const SECItem *data, PRCList *configs)
352{
353 SECStatus rv;
354 sslEchConfig *decodedConfig = NULL((void*)0);
355 sslReader rdr = SSL_READER(data->data, data->len){ { data->data, data->len }, 0 };
356 sslReadBuffer tmp;
357 sslReadBuffer singleConfig;
358 PRUint64 version;
359 PRUint64 length;
360 PORT_Assert(PR_CLIST_IS_EMPTY(configs))((((configs)->next == (configs)))?((void)0):PR_Assert("PR_CLIST_IS_EMPTY(configs)"
,"tls13ech.c",360))
;
361
362 rv = sslRead_ReadVariable(&rdr, 2, &tmp);
363 if (rv != SECSuccess) {
364 return SECFailure;
365 }
366 SSL_TRC(100, ("Read EchConfig list of size %u", SSL_READER_REMAINING(&rdr)))if (ssl_trace >= (100)) ssl_Trace ("Read EchConfig list of size %u"
, ((&rdr)->buf.len - (&rdr)->offset))
;
367 if (SSL_READER_REMAINING(&rdr)((&rdr)->buf.len - (&rdr)->offset)) {
368 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_DATA);
369 return SECFailure;
370 }
371
372 sslReader configsReader = SSL_READER(tmp.buf, tmp.len){ { tmp.buf, tmp.len }, 0 };
373
374 if (!SSL_READER_REMAINING(&configsReader)((&configsReader)->buf.len - (&configsReader)->
offset)
) {
375 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_DATA);
376 return SECFailure;
377 }
378
379 /* Handle each ECHConfig. */
380 while (SSL_READER_REMAINING(&configsReader)((&configsReader)->buf.len - (&configsReader)->
offset)
) {
381 singleConfig.buf = SSL_READER_CURRENT(&configsReader)((&configsReader)->buf.buf + (&configsReader)->
offset)
;
382 /* uint16 version */
383 rv = sslRead_ReadNumber(&configsReader, 2, &version);
384 if (rv != SECSuccess) {
385 goto loser;
386 }
387 /* uint16 length */
388 rv = sslRead_ReadNumber(&configsReader, 2, &length);
389 if (rv != SECSuccess) {
390 goto loser;
391 }
392 singleConfig.len = 4 + length;
393
394 rv = sslRead_Read(&configsReader, length, &tmp);
395 if (rv != SECSuccess) {
396 goto loser;
397 }
398
399 if (version == TLS13_ECH_VERSION0xfe0d) {
400 rv = tls13_DecodeEchConfigContents(&tmp, &decodedConfig);
401 if (rv != SECSuccess) {
402 goto loser; /* code set */
403 }
404
405 if (decodedConfig) {
406 decodedConfig->version = version;
407 rv = SECITEM_MakeItem(NULL((void*)0), &decodedConfig->raw, singleConfig.buf,
408 singleConfig.len);
409 if (rv != SECSuccess) {
410 goto loser;
411 }
412
413 PR_APPEND_LINK(&decodedConfig->link, configs)do { (&decodedConfig->link)->next = (configs); (&
decodedConfig->link)->prev = (configs)->prev; (configs
)->prev->next = (&decodedConfig->link); (configs
)->prev = (&decodedConfig->link); } while (0)
;
414 decodedConfig = NULL((void*)0);
415 }
416 }
417 }
418 return SECSuccess;
419
420loser:
421 tls13_DestroyEchConfigs(configs);
422 return SECFailure;
423}
424
425/* Encode an ECHConfigList structure. We only create one config, and as the
426 * primary use for this function is to generate test inputs, we don't
427 * validate against what HPKE and libssl can actually support. */
428SECStatus
429SSLExp_EncodeEchConfigId(PRUint8 configId, const char *publicName, unsigned int maxNameLen,
430 HpkeKemId kemId, const SECKEYPublicKey *pubKey,
431 const HpkeSymmetricSuite *hpkeSuites, unsigned int hpkeSuiteCount,
432 PRUint8 *out, unsigned int *outlen, unsigned int maxlen)
433{
434 SECStatus rv;
435 unsigned int savedOffset;
436 unsigned int len;
437 sslBuffer b = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
438 PRUint8 tmpBuf[66]; // Large enough for an EC public key, currently only X25519.
439 unsigned int tmpLen;
440
441 if (!publicName || !hpkeSuites || hpkeSuiteCount == 0 ||
442 !pubKey || maxNameLen == 0 || !out || !outlen) {
443 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
444 return SECFailure;
445 }
446
447 /* ECHConfig ECHConfigList<1..2^16-1>; */
448 rv = sslBuffer_Skip(&b, 2, NULL((void*)0));
449 if (rv != SECSuccess) {
450 goto loser;
451 }
452
453 /*
454 * struct {
455 * uint16 version;
456 * uint16 length;
457 * select (ECHConfig.version) {
458 * case 0xfe0d: ECHConfigContents contents;
459 * }
460 * } ECHConfig;
461 */
462 rv = sslBuffer_AppendNumber(&b, TLS13_ECH_VERSION0xfe0d, 2);
463 if (rv != SECSuccess) {
464 goto loser;
465 }
466
467 rv = sslBuffer_Skip(&b, 2, &savedOffset);
468 if (rv != SECSuccess) {
469 goto loser;
470 }
471
472 /*
473 * struct {
474 * uint8 config_id;
475 * HpkeKemId kem_id;
476 * HpkePublicKey public_key;
477 * HpkeSymmetricCipherSuite cipher_suites<4..2^16-4>;
478 * } HpkeKeyConfig;
479 */
480 rv = sslBuffer_AppendNumber(&b, configId, 1);
481 if (rv != SECSuccess) {
482 goto loser;
483 }
484
485 rv = sslBuffer_AppendNumber(&b, kemId, 2);
486 if (rv != SECSuccess) {
487 goto loser;
488 }
489
490 rv = PK11_HPKE_Serialize(pubKey, tmpBuf, &tmpLen, sizeof(tmpBuf));
491 if (rv != SECSuccess) {
492 goto loser;
493 }
494 rv = sslBuffer_AppendVariable(&b, tmpBuf, tmpLen, 2);
495 if (rv != SECSuccess) {
496 goto loser;
497 }
498
499 rv = sslBuffer_AppendNumber(&b, hpkeSuiteCount * 4, 2);
500 if (rv != SECSuccess) {
501 goto loser;
502 }
503 for (unsigned int i = 0; i < hpkeSuiteCount; i++) {
504 rv = sslBuffer_AppendNumber(&b, hpkeSuites[i].kdfId, 2);
505 if (rv != SECSuccess) {
506 goto loser;
507 }
508 rv = sslBuffer_AppendNumber(&b, hpkeSuites[i].aeadId, 2);
509 if (rv != SECSuccess) {
510 goto loser;
511 }
512 }
513
514 /*
515 * struct {
516 * HpkeKeyConfig key_config;
517 * uint8 maximum_name_length;
518 * opaque public_name<1..255>;
519 * Extension extensions<0..2^16-1>;
520 * } ECHConfigContents;
521 */
522 rv = sslBuffer_AppendNumber(&b, maxNameLen, 1);
523 if (rv != SECSuccess) {
524 goto loser;
525 }
526
527 len = PORT_Strlen(publicName)strlen(publicName);
528 if (len > 0xff) {
529 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
530 goto loser;
531 }
532 rv = sslBuffer_AppendVariable(&b, (const PRUint8 *)publicName, len, 1);
533 if (rv != SECSuccess) {
534 goto loser;
535 }
536
537 /* extensions */
538 rv = sslBuffer_AppendNumber(&b, 0, 2);
539 if (rv != SECSuccess) {
540 goto loser;
541 }
542
543 /* Write the length now that we know it. */
544 rv = sslBuffer_InsertLength(&b, 0, 2);
545 if (rv != SECSuccess) {
546 goto loser;
547 }
548 rv = sslBuffer_InsertLength(&b, savedOffset, 2);
549 if (rv != SECSuccess) {
550 goto loser;
551 }
552
553 if (SSL_BUFFER_LEN(&b)((&b)->len) > maxlen) {
554 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
555 goto loser;
556 }
557 PORT_Memcpymemcpy(out, SSL_BUFFER_BASE(&b)((&b)->buf), SSL_BUFFER_LEN(&b)((&b)->len));
558 *outlen = SSL_BUFFER_LEN(&b)((&b)->len);
559 sslBuffer_Clear(&b);
560 return SECSuccess;
561
562loser:
563 sslBuffer_Clear(&b);
564 return SECFailure;
565}
566
567SECStatus
568SSLExp_GetEchRetryConfigs(PRFileDesc *fd, SECItem *retryConfigs)
569{
570 SECStatus rv;
571 sslSocket *ss;
572 SECItem out = { siBuffer, NULL((void*)0), 0 };
573
574 if (!fd || !retryConfigs) {
575 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
576 return SECFailure;
577 }
578 ss = ssl_FindSocket(fd);
579 if (!ss) {
580 SSL_DBG(("%d: SSL[%d]: bad socket in %s",if (ssl_debug) ssl_Trace ("%d: SSL[%d]: bad socket in %s", getpid
(), fd, __FUNCTION__)
581 SSL_GETPID(), fd, __FUNCTION__))if (ssl_debug) ssl_Trace ("%d: SSL[%d]: bad socket in %s", getpid
(), fd, __FUNCTION__)
;
582 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
583 return SECFailure;
584 }
585
586 /* We don't distinguish between "handshake completed
587 * without retry configs", and "handshake not completed".
588 * An application should only call this after receiving a
589 * RETRY_WITH_ECH error code, which implies retry_configs. */
590 if (!ss->xtnData.ech || !ss->xtnData.ech->retryConfigsValid) {
591 PORT_SetErrorPORT_SetError_Util(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
592 return SECFailure;
593 }
594
595 /* May be empty. */
596 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), &out, &ss->xtnData.ech->retryConfigs);
597 if (rv == SECFailure) {
598 return SECFailure;
599 }
600 *retryConfigs = out;
601 return SECSuccess;
602}
603
604SECStatus
605SSLExp_RemoveEchConfigs(PRFileDesc *fd)
606{
607 sslSocket *ss;
608
609 if (!fd) {
610 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
611 return SECFailure;
612 }
613
614 ss = ssl_FindSocket(fd);
615 if (!ss) {
616 SSL_DBG(("%d: SSL[%d]: bad socket in %s",if (ssl_debug) ssl_Trace ("%d: SSL[%d]: bad socket in %s", getpid
(), fd, __FUNCTION__)
617 SSL_GETPID(), fd, __FUNCTION__))if (ssl_debug) ssl_Trace ("%d: SSL[%d]: bad socket in %s", getpid
(), fd, __FUNCTION__)
;
618 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
619 return SECFailure;
620 }
621
622 SECKEY_DestroyPrivateKey(ss->echPrivKey);
623 ss->echPrivKey = NULL((void*)0);
624 SECKEY_DestroyPublicKey(ss->echPubKey);
625 ss->echPubKey = NULL((void*)0);
626 tls13_DestroyEchConfigs(&ss->echConfigs);
627
628 /* Also remove any retry_configs and handshake context. */
629 if (ss->xtnData.ech && ss->xtnData.ech->retryConfigs.len) {
630 SECITEM_FreeItemSECITEM_FreeItem_Util(&ss->xtnData.ech->retryConfigs, PR_FALSE0);
631 }
632
633 if (ss->ssl3.hs.echHpkeCtx) {
634 PK11_HPKE_DestroyContext(ss->ssl3.hs.echHpkeCtx, PR_TRUE1);
635 ss->ssl3.hs.echHpkeCtx = NULL((void*)0);
636 }
637 PORT_FreePORT_Free_Util(CONST_CAST(char, ss->ssl3.hs.echPublicName)((char *)(ss->ssl3.hs.echPublicName)));
638 ss->ssl3.hs.echPublicName = NULL((void*)0);
639
640 return SECSuccess;
641}
642
643/* Import one or more ECHConfigs for the given keypair. The AEAD/KDF
644 * may differ , but only X25519 is supported for the KEM.*/
645SECStatus
646SSLExp_SetServerEchConfigs(PRFileDesc *fd,
647 const SECKEYPublicKey *pubKey, const SECKEYPrivateKey *privKey,
648 const PRUint8 *echConfigs, unsigned int echConfigsLen)
649{
650 sslSocket *ss;
651 SECStatus rv;
652 SECItem data = { siBuffer, CONST_CAST(PRUint8, echConfigs)((PRUint8 *)(echConfigs)), echConfigsLen };
653
654 if (!fd || !pubKey || !privKey || !echConfigs || echConfigsLen == 0) {
655 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
656 return SECFailure;
657 }
658
659 ss = ssl_FindSocket(fd);
660 if (!ss) {
661 SSL_DBG(("%d: SSL[%d]: bad socket in %s",if (ssl_debug) ssl_Trace ("%d: SSL[%d]: bad socket in %s", getpid
(), fd, __FUNCTION__)
662 SSL_GETPID(), fd, __FUNCTION__))if (ssl_debug) ssl_Trace ("%d: SSL[%d]: bad socket in %s", getpid
(), fd, __FUNCTION__)
;
663 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
664 return SECFailure;
665 }
666
667 if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) {
668 return SECFailure;
669 }
670
671 /* Overwrite if we're already configured. */
672 rv = SSLExp_RemoveEchConfigs(fd);
673 if (rv != SECSuccess) {
674 return SECFailure;
675 }
676
677 rv = tls13_DecodeEchConfigs(&data, &ss->echConfigs);
678 if (rv != SECSuccess) {
679 goto loser;
680 }
681 if (PR_CLIST_IS_EMPTY(&ss->echConfigs)((&ss->echConfigs)->next == (&ss->echConfigs
))
) {
682 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
683 goto loser;
684 }
685
686 ss->echPubKey = SECKEY_CopyPublicKey(pubKey);
687 if (!ss->echPubKey) {
688 goto loser;
689 }
690 ss->echPrivKey = SECKEY_CopyPrivateKey(privKey);
691 if (!ss->echPrivKey) {
692 goto loser;
693 }
694 return SECSuccess;
695
696loser:
697 tls13_DestroyEchConfigs(&ss->echConfigs);
698 SECKEY_DestroyPrivateKey(ss->echPrivKey);
699 SECKEY_DestroyPublicKey(ss->echPubKey);
700 ss->echPubKey = NULL((void*)0);
701 ss->echPrivKey = NULL((void*)0);
702 return SECFailure;
703}
704
705/* Client enable. For now, we'll use the first
706 * compatible config (server preference). */
707SECStatus
708SSLExp_SetClientEchConfigs(PRFileDesc *fd,
709 const PRUint8 *echConfigs,
710 unsigned int echConfigsLen)
711{
712 SECStatus rv;
713 sslSocket *ss;
714 SECItem data = { siBuffer, CONST_CAST(PRUint8, echConfigs)((PRUint8 *)(echConfigs)), echConfigsLen };
715
716 if (!fd || !echConfigs || echConfigsLen == 0) {
717 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
718 return SECFailure;
719 }
720
721 ss = ssl_FindSocket(fd);
722 if (!ss) {
723 SSL_DBG(("%d: SSL[%d]: bad socket in %s",if (ssl_debug) ssl_Trace ("%d: SSL[%d]: bad socket in %s", getpid
(), fd, __FUNCTION__)
724 SSL_GETPID(), fd, __FUNCTION__))if (ssl_debug) ssl_Trace ("%d: SSL[%d]: bad socket in %s", getpid
(), fd, __FUNCTION__)
;
725 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
726 return SECFailure;
727 }
728
729 if (IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) {
730 return SECFailure;
731 }
732
733 /* Overwrite if we're already configured. */
734 rv = SSLExp_RemoveEchConfigs(fd);
735 if (rv != SECSuccess) {
736 return SECFailure;
737 }
738
739 rv = tls13_DecodeEchConfigs(&data, &ss->echConfigs);
740 if (rv != SECSuccess) {
741 return SECFailure;
742 }
743 if (PR_CLIST_IS_EMPTY(&ss->echConfigs)((&ss->echConfigs)->next == (&ss->echConfigs
))
) {
744 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
745 return SECFailure;
746 }
747
748 return SECSuccess;
749}
750
751/* Set up ECH. This generates an ephemeral sender
752 * keypair and the HPKE context */
753SECStatus
754tls13_ClientSetupEch(sslSocket *ss, sslClientHelloType type)
755{
756 SECStatus rv;
757 HpkeContext *cx = NULL((void*)0);
758 SECKEYPublicKey *pkR = NULL((void*)0);
759 SECItem hpkeInfo = { siBuffer, NULL((void*)0), 0 };
760 sslEchConfig *cfg = NULL((void*)0);
761
762 if (PR_CLIST_IS_EMPTY(&ss->echConfigs)((&ss->echConfigs)->next == (&ss->echConfigs
))
||
763 !ssl_ShouldSendSNIExtension(ss, ss->url) ||
764 IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) {
765 return SECSuccess;
766 }
767
768 /* Maybe apply our own priority if >1. For now, we only support
769 * one version and one KEM. Each ECHConfig can specify multiple
770 * KDF/AEADs, so just use the first. */
771 cfg = (sslEchConfig *)PR_LIST_HEAD(&ss->echConfigs)(&ss->echConfigs)->next;
772
773 SSL_TRC(50, ("%d: TLS13[%d]: Setup client ECH",if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: Setup client ECH"
, getpid(), ss->fd)
774 SSL_GETPID(), ss->fd))if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: Setup client ECH"
, getpid(), ss->fd)
;
775
776 switch (type) {
777 case client_hello_initial:
778 PORT_Assert(!ss->ssl3.hs.echHpkeCtx && !ss->ssl3.hs.echPublicName)((!ss->ssl3.hs.echHpkeCtx && !ss->ssl3.hs.echPublicName
)?((void)0):PR_Assert("!ss->ssl3.hs.echHpkeCtx && !ss->ssl3.hs.echPublicName"
,"tls13ech.c",778))
;
779 cx = PK11_HPKE_NewContext(cfg->contents.kemId, cfg->contents.kdfId,
780 cfg->contents.aeadId, NULL((void*)0), NULL((void*)0));
781 break;
782 case client_hello_retry:
783 if (!ss->ssl3.hs.echHpkeCtx || !ss->ssl3.hs.echPublicName) {
784 FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error)do { do { if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)"
, getpid(), ss->fd, SEC_ERROR_LIBRARY_FAILURE, __func__, "tls13ech.c"
, 784); PORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); } while
(0); tls13_FatalError(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error
); } while (0)
;
785 return SECFailure;
786 }
787 /* Nothing else to do. */
788 return SECSuccess;
789 default:
790 PORT_Assert(0)((0)?((void)0):PR_Assert("0","tls13ech.c",790));
791 goto loser;
792 }
793 if (!cx) {
794 goto loser;
795 }
796
797 rv = PK11_HPKE_Deserialize(cx, cfg->contents.publicKey.data, cfg->contents.publicKey.len, &pkR);
798 if (rv != SECSuccess) {
799 goto loser;
800 }
801
802 if (!SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &hpkeInfo, strlen(kHpkeInfoEch) + 1 + cfg->raw.len)) {
803 goto loser;
804 }
805 PORT_Memcpymemcpy(&hpkeInfo.data[0], kHpkeInfoEch, strlen(kHpkeInfoEch));
806 PORT_Memsetmemset(&hpkeInfo.data[strlen(kHpkeInfoEch)], 0, 1);
807 PORT_Memcpymemcpy(&hpkeInfo.data[strlen(kHpkeInfoEch) + 1], cfg->raw.data, cfg->raw.len);
808
809 PRINT_BUF(50, (ss, "Info", hpkeInfo.data, hpkeInfo.len))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "Info", hpkeInfo.
data, hpkeInfo.len)
;
810
811 /* Setup with an ephemeral sender keypair. */
812 rv = PK11_HPKE_SetupS(cx, NULL((void*)0), NULL((void*)0), pkR, &hpkeInfo);
813 if (rv != SECSuccess) {
814 goto loser;
815 }
816
817 rv = ssl3_GetNewRandom(ss->ssl3.hs.client_inner_random);
818 if (rv != SECSuccess) {
819 goto loser; /* code set */
820 }
821
822 /* If ECH is rejected, the application will use SSLChannelInfo
823 * to fetch this field and perform cert chain verification. */
824 ss->ssl3.hs.echPublicName = PORT_StrdupPORT_Strdup_Util(cfg->contents.publicName);
825 if (!ss->ssl3.hs.echPublicName) {
826 goto loser;
827 }
828
829 ss->ssl3.hs.echHpkeCtx = cx;
830 SECKEY_DestroyPublicKey(pkR);
831 SECITEM_FreeItemSECITEM_FreeItem_Util(&hpkeInfo, PR_FALSE0);
832 return SECSuccess;
833
834loser:
835 PK11_HPKE_DestroyContext(cx, PR_TRUE1);
836 SECKEY_DestroyPublicKey(pkR);
837 SECITEM_FreeItemSECITEM_FreeItem_Util(&hpkeInfo, PR_FALSE0);
838 PORT_Assert(PORT_GetError() != 0)((PORT_GetError_Util() != 0)?((void)0):PR_Assert("PORT_GetError() != 0"
,"tls13ech.c",838))
;
839 return SECFailure;
840}
841
842/*
843 * outerAAD - The associated data for the AEAD (the entire client hello with the ECH payload zeroed)
844 * chInner - The plaintext which will be encrypted (the ClientHelloInner plus padding)
845 * echPayload - Output location. A buffer containing all-zeroes of at least chInner->len + TLS13_ECH_AEAD_TAG_LEN bytes.
846 *
847 * echPayload may point into outerAAD to avoid the need to duplicate the ClientHelloOuter buffer.
848 */
849static SECStatus
850tls13_EncryptClientHello(sslSocket *ss, SECItem *aadItem, const sslBuffer *chInner, PRUint8 *echPayload)
851{
852 SECStatus rv;
853 SECItem chPt = { siBuffer, chInner->buf, chInner->len };
854 SECItem *chCt = NULL((void*)0);
855
856 PRINT_BUF(50, (ss, "aad for ECH Encrypt", aadItem->data, aadItem->len))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "aad for ECH Encrypt"
, aadItem->data, aadItem->len)
;
857 PRINT_BUF(50, (ss, "plaintext for ECH Encrypt", chInner->buf, chInner->len))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "plaintext for ECH Encrypt"
, chInner->buf, chInner->len)
;
858
859#ifndef UNSAFE_FUZZER_MODE
860 rv = PK11_HPKE_Seal(ss->ssl3.hs.echHpkeCtx, aadItem, &chPt, &chCt);
861 if (rv != SECSuccess) {
862 goto loser;
863 }
864 PRINT_BUF(50, (ss, "ciphertext from ECH Encrypt", chCt->data, chCt->len))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "ciphertext from ECH Encrypt"
, chCt->data, chCt->len)
;
865#else
866 /* Fake a tag. */
867 SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), chCt, chPt.len + TLS13_ECH_AEAD_TAG_LEN16);
868 if (!chCt) {
869 goto loser;
870 }
871 PORT_Memcpymemcpy(chCt->data, chPt.data, chPt.len);
872#endif
873
874#ifdef DEBUG1
875 /* When encrypting in-place, the payload is part of the AAD and must be zeroed. */
876 PRUint8 val = 0;
877 for (int i = 0; i < chCt->len; i++) {
878 val |= *(echPayload + i);
879 }
880 PRINT_BUF(100, (ss, "Empty Placeholder for output of ECH Encryption", echPayload, chCt->len))if (ssl_trace >= (100)) ssl_PrintBuf (ss, "Empty Placeholder for output of ECH Encryption"
, echPayload, chCt->len)
;
881 PR_ASSERT(val == 0)((val == 0)?((void)0):PR_Assert("val == 0","tls13ech.c",881));
882#endif
883
884 PORT_Memcpymemcpy(echPayload, chCt->data, chCt->len);
885 SECITEM_FreeItemSECITEM_FreeItem_Util(chCt, PR_TRUE1);
886 return SECSuccess;
887
888loser:
889 SECITEM_FreeItemSECITEM_FreeItem_Util(chCt, PR_TRUE1);
890 return SECFailure;
891}
892
893SECStatus
894tls13_GetMatchingEchConfigs(const sslSocket *ss, HpkeKdfId kdf, HpkeAeadId aead,
895 const PRUint8 configId, const sslEchConfig *cur, sslEchConfig **next)
896{
897 SSL_TRC(50, ("%d: TLS13[%d]: GetMatchingEchConfig %d",if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: GetMatchingEchConfig %d"
, getpid(), ss->fd, configId)
898 SSL_GETPID(), ss->fd, configId))if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: GetMatchingEchConfig %d"
, getpid(), ss->fd, configId)
;
899
900 /* If |cur|, resume the search at that node, else the list head. */
901 for (PRCList *cur_p = cur ? ((PRCList *)cur)->next : PR_LIST_HEAD(&ss->echConfigs)(&ss->echConfigs)->next;
902 cur_p != &ss->echConfigs;
903 cur_p = PR_NEXT_LINK(cur_p)((cur_p)->next)) {
904 sslEchConfig *echConfig = (sslEchConfig *)cur_p;
905 if (echConfig->contents.configId == configId &&
906 echConfig->contents.aeadId == aead &&
907 echConfig->contents.kdfId == kdf) {
908 *next = echConfig;
909 return SECSuccess;
910 }
911 }
912
913 *next = NULL((void*)0);
914 return SECSuccess;
915}
916
917/* Given a CH with extensions, copy from the start up to the extensions
918 * into |writer| and return the extensions themselves in |extensions|.
919 * If |explicitSid|, place this value into |writer| as the SID. Else,
920 * the sid is copied from |reader| to |writer|. */
921static SECStatus
922tls13_CopyChPreamble(sslSocket *ss, sslReader *reader, const SECItem *explicitSid, sslBuffer *writer, sslReadBuffer *extensions)
923{
924 SECStatus rv;
925 sslReadBuffer tmpReadBuf;
926
927 /* Locate the extensions. */
928 rv = sslRead_Read(reader, 2 + SSL3_RANDOM_LENGTH32, &tmpReadBuf);
929 if (rv != SECSuccess) {
930 return SECFailure;
931 }
932 rv = sslBuffer_Append(writer, tmpReadBuf.buf, tmpReadBuf.len);
933 if (rv != SECSuccess) {
934 return SECFailure;
935 }
936
937 /* legacy_session_id */
938 rv = sslRead_ReadVariable(reader, 1, &tmpReadBuf);
939 if (explicitSid) {
940 /* Encoded SID should be empty when copying from CHOuter. */
941 if (tmpReadBuf.len > 0) {
942 PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_MALFORMED_ECH_EXTENSIONSSL_ERROR_RX_MALFORMED_ESNI_EXTENSION);
943 return SECFailure;
944 }
945 rv = sslBuffer_AppendVariable(writer, explicitSid->data, explicitSid->len, 1);
946 } else {
947 rv = sslBuffer_AppendVariable(writer, tmpReadBuf.buf, tmpReadBuf.len, 1);
948 }
949 if (rv != SECSuccess) {
950 return SECFailure;
951 }
952
953 /* cipher suites */
954 rv = sslRead_ReadVariable(reader, 2, &tmpReadBuf);
955 if (rv != SECSuccess) {
956 return SECFailure;
957 }
958 rv = sslBuffer_AppendVariable(writer, tmpReadBuf.buf, tmpReadBuf.len, 2);
959 if (rv != SECSuccess) {
960 return SECFailure;
961 }
962
963 /* compression */
964 rv = sslRead_ReadVariable(reader, 1, &tmpReadBuf);
965 if (rv != SECSuccess) {
966 return SECFailure;
967 }
968 rv = sslBuffer_AppendVariable(writer, tmpReadBuf.buf, tmpReadBuf.len, 1);
969 if (rv != SECSuccess) {
970 return SECFailure;
971 }
972
973 /* extensions */
974 rv = sslRead_ReadVariable(reader, 2, extensions);
975 if (rv != SECSuccess) {
976 return SECFailure;
977 }
978
979 /* padding (optional) */
980 sslReadBuffer padding;
981 rv = sslRead_Read(reader, SSL_READER_REMAINING(reader)((reader)->buf.len - (reader)->offset), &padding);
982 if (rv != SECSuccess) {
983 return SECFailure;
984 }
985 PRUint8 result = 0;
986 for (int i = 0; i < padding.len; i++) {
987 result |= padding.buf[i];
988 }
989 if (result) {
990 SSL_TRC(50, ("%d: TLS13: Invalid ECH ClientHelloInner padding decoded", SSL_GETPID()))if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13: Invalid ECH ClientHelloInner padding decoded"
, getpid())
;
991 FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_ECH_EXTENSION, illegal_parameter)do { do { if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)"
, getpid(), ss->fd, SSL_ERROR_RX_MALFORMED_ESNI_EXTENSION,
__func__, "tls13ech.c", 991); PORT_SetError_Util(SSL_ERROR_RX_MALFORMED_ESNI_EXTENSION
); } while (0); tls13_FatalError(ss, SSL_ERROR_RX_MALFORMED_ESNI_EXTENSION
, illegal_parameter); } while (0)
;
992 return SECFailure;
993 }
994 return SECSuccess;
995}
996
997/*
998 * The ClientHelloOuterAAD is a serialized ClientHello structure, defined in
999 * Section 4.1.2 of [RFC8446], which matches the ClientHelloOuter except the
1000 * payload field of the "encrypted_client_hello" is replaced with a byte
1001 * string of the same length but whose contents are zeros. This value does
1002 * not include the four-byte header from the Handshake structure.
1003 */
1004static SECStatus
1005tls13_ServerMakeChOuterAAD(sslSocket *ss, const PRUint8 *outerCh, unsigned int outerChLen, SECItem *outerAAD)
1006{
1007 SECStatus rv;
1008 sslBuffer aad = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
1009 const unsigned int echPayloadLen = ss->xtnData.ech->innerCh.len; /* Length of incoming payload */
1010 const unsigned int echPayloadOffset = ss->xtnData.ech->payloadStart - outerCh; /* Offset from start of CHO */
1011
1012 PORT_Assert(outerChLen > echPayloadLen)((outerChLen > echPayloadLen)?((void)0):PR_Assert("outerChLen > echPayloadLen"
,"tls13ech.c",1012))
;
1013 PORT_Assert(echPayloadOffset + echPayloadLen <= outerChLen)((echPayloadOffset + echPayloadLen <= outerChLen)?((void)0
):PR_Assert("echPayloadOffset + echPayloadLen <= outerChLen"
,"tls13ech.c",1013))
;
1014 PORT_Assert(ss->sec.isServer)((ss->sec.isServer)?((void)0):PR_Assert("ss->sec.isServer"
,"tls13ech.c",1014))
;
1015 PORT_Assert(ss->xtnData.ech)((ss->xtnData.ech)?((void)0):PR_Assert("ss->xtnData.ech"
,"tls13ech.c",1015))
;
1016
1017#ifdef DEBUG1
1018 /* Safety check that payload length pointed to by offset matches expected length */
1019 sslReader echXtnReader = SSL_READER(outerCh + echPayloadOffset - 2, 2){ { outerCh + echPayloadOffset - 2, 2 }, 0 };
1020 PRUint64 parsedXtnSize;
1021 rv = sslRead_ReadNumber(&echXtnReader, 2, &parsedXtnSize);
1022 PR_ASSERT(rv == SECSuccess)((rv == SECSuccess)?((void)0):PR_Assert("rv == SECSuccess","tls13ech.c"
,1022))
;
1023 PR_ASSERT(parsedXtnSize == echPayloadLen)((parsedXtnSize == echPayloadLen)?((void)0):PR_Assert("parsedXtnSize == echPayloadLen"
,"tls13ech.c",1023))
;
1024#endif
1025
1026 rv = sslBuffer_Append(&aad, outerCh, outerChLen);
1027 if (rv != SECSuccess) {
1028 goto loser;
1029 }
1030 PORT_Memsetmemset(aad.buf + echPayloadOffset, 0, echPayloadLen);
1031
1032 PRINT_BUF(50, (ss, "AAD for ECH Decryption", aad.buf, aad.len))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "AAD for ECH Decryption"
, aad.buf, aad.len)
;
1033
1034 outerAAD->data = aad.buf;
1035 outerAAD->len = aad.len;
1036 return SECSuccess;
1037
1038loser:
1039 sslBuffer_Clear(&aad);
1040 return SECFailure;
1041}
1042
1043SECStatus
1044tls13_OpenClientHelloInner(sslSocket *ss, const SECItem *outer, const SECItem *outerAAD, sslEchConfig *cfg, SECItem **chInner)
1045{
1046 SECStatus rv;
1047 HpkeContext *cx = NULL((void*)0);
1048 SECItem *decryptedChInner = NULL((void*)0);
1049 SECItem hpkeInfo = { siBuffer, NULL((void*)0), 0 };
1050 SSL_TRC(50, ("%d: TLS13[%d]: Server opening ECH Inner%s", SSL_GETPID(),if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: Server opening ECH Inner%s"
, getpid(), ss->fd, ss->ssl3.hs.helloRetry ? " after HRR"
: "")
1051 ss->fd, ss->ssl3.hs.helloRetry ? " after HRR" : ""))if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: Server opening ECH Inner%s"
, getpid(), ss->fd, ss->ssl3.hs.helloRetry ? " after HRR"
: "")
;
1052
1053 if (!ss->ssl3.hs.helloRetry) {
1054 PORT_Assert(!ss->ssl3.hs.echHpkeCtx)((!ss->ssl3.hs.echHpkeCtx)?((void)0):PR_Assert("!ss->ssl3.hs.echHpkeCtx"
,"tls13ech.c",1054))
;
1055 cx = PK11_HPKE_NewContext(cfg->contents.kemId, cfg->contents.kdfId,
1056 cfg->contents.aeadId, NULL((void*)0), NULL((void*)0));
1057 if (!cx) {
1058 goto loser;
1059 }
1060
1061 if (!SECITEM_AllocItemSECITEM_AllocItem_Util(NULL((void*)0), &hpkeInfo, strlen(kHpkeInfoEch) + 1 + cfg->raw.len)) {
1062 goto loser;
1063 }
1064 PORT_Memcpymemcpy(&hpkeInfo.data[0], kHpkeInfoEch, strlen(kHpkeInfoEch));
1065 PORT_Memsetmemset(&hpkeInfo.data[strlen(kHpkeInfoEch)], 0, 1);
1066 PORT_Memcpymemcpy(&hpkeInfo.data[strlen(kHpkeInfoEch) + 1], cfg->raw.data, cfg->raw.len);
1067
1068 rv = PK11_HPKE_SetupR(cx, ss->echPubKey, ss->echPrivKey,
1069 &ss->xtnData.ech->senderPubKey, &hpkeInfo);
1070 if (rv != SECSuccess) {
1071 goto loser; /* code set */
1072 }
1073 } else {
1074 PORT_Assert(ss->ssl3.hs.echHpkeCtx)((ss->ssl3.hs.echHpkeCtx)?((void)0):PR_Assert("ss->ssl3.hs.echHpkeCtx"
,"tls13ech.c",1074))
;
1075 cx = ss->ssl3.hs.echHpkeCtx;
1076 }
1077
1078#ifndef UNSAFE_FUZZER_MODE
1079 rv = PK11_HPKE_Open(cx, outerAAD, &ss->xtnData.ech->innerCh, &decryptedChInner);
1080 if (rv != SECSuccess) {
1081 SSL_TRC(10, ("%d: SSL3[%d]: Failed to decrypt inner CH with this candidate",if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: Failed to decrypt inner CH with this candidate"
, getpid(), ss->fd)
1082 SSL_GETPID(), ss->fd))if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: Failed to decrypt inner CH with this candidate"
, getpid(), ss->fd)
;
1083 goto loser; /* code set */
1084 }
1085#else
1086 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), decryptedChInner, &ss->xtnData.ech->innerCh);
1087 if (rv != SECSuccess) {
1088 goto loser;
1089 }
1090 decryptedChInner->len -= TLS13_ECH_AEAD_TAG_LEN16; /* Fake tag */
1091#endif
1092
1093 /* Stash the context, we may need it for HRR. */
1094 ss->ssl3.hs.echHpkeCtx = cx;
1095 *chInner = decryptedChInner;
1096 PRINT_BUF(100, (ss, "Decrypted ECH Inner", decryptedChInner->data, decryptedChInner->len))if (ssl_trace >= (100)) ssl_PrintBuf (ss, "Decrypted ECH Inner"
, decryptedChInner->data, decryptedChInner->len)
;
1097 SECITEM_FreeItemSECITEM_FreeItem_Util(&hpkeInfo, PR_FALSE0);
1098 return SECSuccess;
1099
1100loser:
1101 SECITEM_FreeItemSECITEM_FreeItem_Util(decryptedChInner, PR_TRUE1);
1102 SECITEM_FreeItemSECITEM_FreeItem_Util(&hpkeInfo, PR_FALSE0);
1103 if (cx != ss->ssl3.hs.echHpkeCtx) {
1104 /* Don't double-free if it's already global. */
1105 PK11_HPKE_DestroyContext(cx, PR_TRUE1);
1106 }
1107 return SECFailure;
1108}
1109
1110/* This is the maximum number of extension hooks that the following functions can handle. */
1111#define MAX_EXTENSION_WRITERS32 32
1112
1113static SECStatus
1114tls13_WriteDupXtnsToChInner(PRBool compressing, sslBuffer *dupXtns, sslBuffer *chInnerXtns)
1115{
1116 SECStatus rv;
1117 if (compressing && SSL_BUFFER_LEN(dupXtns)((dupXtns)->len) > 0) {
1118 rv = sslBuffer_AppendNumber(chInnerXtns, ssl_tls13_outer_extensions_xtn, 2);
1119 if (rv != SECSuccess) {
1120 return SECFailure;
1121 }
1122 rv = sslBuffer_AppendNumber(chInnerXtns, dupXtns->len + 1, 2);
1123 if (rv != SECSuccess) {
1124 return SECFailure;
1125 }
1126 rv = sslBuffer_AppendBufferVariable(chInnerXtns, dupXtns, 1);
1127 if (rv != SECSuccess) {
1128 return SECFailure;
1129 }
1130 } else {
1131 /* dupXtns carries whole extensions with lengths on each. */
1132 rv = sslBuffer_AppendBuffer(chInnerXtns, dupXtns);
1133 if (rv != SECSuccess) {
1134 return SECFailure;
1135 }
1136 }
1137 sslBuffer_Clear(dupXtns);
1138 return SECSuccess;
1139}
1140
1141/* Add ordinary extensions to CHInner.
1142 * The value of the extension from CHOuter is in |extensionData|.
1143 *
1144 * If the value is to be compressed, it is written to |dupXtns|.
1145 * Otherwise, a full extension is written to |chInnerXtns|.
1146 *
1147 * This function is always called twice:
1148 * once without compression and once with compression if possible.
1149 *
1150 * Because we want to allow extensions that did not appear in CHOuter
1151 * to be included in CHInner, we also need to track which extensions
1152 * have been included. This is what |called| and |nCalled| track.
1153 */
1154static SECStatus
1155tls13_ChInnerAppendExtension(sslSocket *ss, PRUint16 extensionType,
1156 const sslReadBuffer *extensionData,
1157 sslBuffer *dupXtns, sslBuffer *chInnerXtns,
1158 PRBool compressing,
1159 PRUint16 *called, unsigned int *nCalled)
1160{
1161 PRUint8 buf[1024] = { 0 };
1162 const PRUint8 *p;
1163 unsigned int len = 0;
1164 PRBool willCompress;
1165
1166 PORT_Assert(extensionType != ssl_tls13_encrypted_client_hello_xtn)((extensionType != ssl_tls13_encrypted_client_hello_xtn)?((void
)0):PR_Assert("extensionType != ssl_tls13_encrypted_client_hello_xtn"
,"tls13ech.c",1166))
;
1167 sslCustomExtensionHooks *hook = ss->opt.callExtensionWriterOnEchInner
1168 ? ssl_FindCustomExtensionHooks(ss, extensionType)
1169 : NULL((void*)0);
1170 if (hook && hook->writer) {
1171 if (*nCalled >= MAX_EXTENSION_WRITERS32) {
1172 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); /* TODO new code? */
1173 return SECFailure;
1174 }
1175
1176 PRBool append = (*hook->writer)(ss->fd, ssl_hs_client_hello,
1177 buf, &len, sizeof(buf), hook->writerArg);
1178 called[(*nCalled)++] = extensionType;
1179 if (!append) {
1180 /* This extension is not going to appear in CHInner. */
1181 /* TODO: consider removing this extension from ss->xtnData.advertised.
1182 * The consequence of not removing it is that we won't complain
1183 * if the server accepts ECH and then includes this extension.
1184 * The cost is a complete reworking of ss->xtnData.advertised.
1185 */
1186 return SECSuccess;
1187 }
1188 /* It can be compressed if it is the same as the outer value. */
1189 willCompress = (len == extensionData->len &&
1190 NSS_SecureMemcmp(buf, extensionData->buf, len) == 0);
1191 p = buf;
1192 } else {
1193 /* Non-custom extensions are duplicated when compressing. */
1194 willCompress = PR_TRUE1;
1195 p = extensionData->buf;
1196 len = extensionData->len;
1197 }
1198
1199 /* Duplicated extensions all need to go together. */
1200 sslBuffer *dst = willCompress ? dupXtns : chInnerXtns;
1201 SECStatus rv = sslBuffer_AppendNumber(dst, extensionType, 2);
1202 if (rv != SECSuccess) {
1203 return SECFailure;
1204 }
1205 if (!willCompress || !compressing) {
1206 rv = sslBuffer_AppendVariable(dst, p, len, 2);
1207 if (rv != SECSuccess) {
1208 return SECFailure;
1209 }
1210 }
1211 /* As this function is called twice, we only want to update our state the second time. */
1212 if (compressing) {
1213 ss->xtnData.echAdvertised[ss->xtnData.echNumAdvertised++] = extensionType;
1214 SSL_TRC(50, ("Appending extension=%d to the Client Hello Inner. Compressed?=%d", extensionType, willCompress))if (ssl_trace >= (50)) ssl_Trace ("Appending extension=%d to the Client Hello Inner. Compressed?=%d"
, extensionType, willCompress)
;
1215 }
1216 return SECSuccess;
1217}
1218
1219/* Call any custom extension handlers that didn't want to be added to CHOuter. */
1220static SECStatus
1221tls13_ChInnerAdditionalExtensionWriters(sslSocket *ss, const PRUint16 *called,
1222 unsigned int nCalled, sslBuffer *chInnerXtns)
1223{
1224 if (!ss->opt.callExtensionWriterOnEchInner) {
1225 return SECSuccess;
1226 }
1227
1228 for (PRCList *cursor = PR_NEXT_LINK(&ss->extensionHooks)((&ss->extensionHooks)->next);
1229 cursor != &ss->extensionHooks;
1230 cursor = PR_NEXT_LINK(cursor)((cursor)->next)) {
1231 sslCustomExtensionHooks *hook = (sslCustomExtensionHooks *)cursor;
1232
1233 /* Skip if this hook was already called. */
1234 PRBool hookCalled = PR_FALSE0;
1235 for (unsigned int i = 0; i < nCalled; ++i) {
1236 if (called[i] == hook->type) {
1237 hookCalled = PR_TRUE1;
1238 break;
1239 }
1240 }
1241 if (hookCalled) {
1242 continue;
1243 }
1244
1245 /* This is a cut-down version of ssl_CallCustomExtensionSenders(). */
1246 PRUint8 buf[1024];
1247 unsigned int len = 0;
1248 PRBool append = (*hook->writer)(ss->fd, ssl_hs_client_hello,
1249 buf, &len, sizeof(buf), hook->writerArg);
1250 if (!append) {
1251 continue;
1252 }
1253
1254 SECStatus rv = sslBuffer_AppendNumber(chInnerXtns, hook->type, 2);
1255 if (rv != SECSuccess) {
1256 return SECFailure;
1257 }
1258 rv = sslBuffer_AppendVariable(chInnerXtns, buf, len, 2);
1259 if (rv != SECSuccess) {
1260 return SECFailure;
1261 }
1262 ss->xtnData.echAdvertised[ss->xtnData.echNumAdvertised++] = hook->type;
1263 }
1264 return SECSuccess;
1265}
1266
1267/* Take the PSK extension CHOuter and fill it with junk. */
1268static SECStatus
1269tls13_RandomizePsk(PRUint8 *buf, unsigned int len)
1270{
1271 sslReader rdr = SSL_READER(buf, len){ { buf, len }, 0 };
1272
1273 /* Read the length of identities. */
1274 PRUint64 outerLen = 0;
1275 SECStatus rv = sslRead_ReadNumber(&rdr, 2, &outerLen);
1276 if (rv != SECSuccess) {
1277 return SECFailure;
1278 }
1279 PORT_Assert(outerLen < len + 2)((outerLen < len + 2)?((void)0):PR_Assert("outerLen < len + 2"
,"tls13ech.c",1279))
;
1280
1281 /* Read the length of PskIdentity.identity */
1282 PRUint64 innerLen = 0;
1283 rv = sslRead_ReadNumber(&rdr, 2, &innerLen);
1284 if (rv != SECSuccess) {
1285 return SECFailure;
1286 }
1287 /* identities should contain just one identity. */
1288 PORT_Assert(outerLen == innerLen + 6)((outerLen == innerLen + 6)?((void)0):PR_Assert("outerLen == innerLen + 6"
,"tls13ech.c",1288))
;
1289
1290 /* Randomize PskIdentity.{identity,obfuscated_ticket_age}. */
1291 rv = PK11_GenerateRandom(buf + rdr.offset, innerLen + 4);
1292 if (rv != SECSuccess) {
1293 return SECFailure;
1294 }
1295 rdr.offset += innerLen + 4;
1296
1297 /* Read the length of binders. */
1298 rv = sslRead_ReadNumber(&rdr, 2, &outerLen);
1299 if (rv != SECSuccess) {
1300 return SECFailure;
1301 }
1302 PORT_Assert(outerLen + rdr.offset == len)((outerLen + rdr.offset == len)?((void)0):PR_Assert("outerLen + rdr.offset == len"
,"tls13ech.c",1302))
;
1303
1304 /* Read the length of the binder. */
1305 rv = sslRead_ReadNumber(&rdr, 1, &innerLen);
1306 if (rv != SECSuccess) {
1307 return SECFailure;
1308 }
1309 /* binders should contain just one binder. */
1310 PORT_Assert(outerLen == innerLen + 1)((outerLen == innerLen + 1)?((void)0):PR_Assert("outerLen == innerLen + 1"
,"tls13ech.c",1310))
;
1311
1312 /* Randomize the binder. */
1313 rv = PK11_GenerateRandom(buf + rdr.offset, innerLen);
1314 if (rv != SECSuccess) {
1315 return SECFailure;
1316 }
1317
1318 return SECSuccess;
1319}
1320
1321/* Given a buffer of extensions prepared for CHOuter, translate those extensions to a
1322 * buffer suitable for CHInner. This is intended to be called twice: once without
1323 * compression for the transcript hash and binders, and once with compression for
1324 * encoding the actual CHInner value.
1325 *
1326 * Compressed extensions are moved in both runs. When compressing, they are moved
1327 * to a single outer_extensions extension, which lists extensions from CHOuter.
1328 * When not compressing, this produces the ClientHello that will be reconstructed
1329 * from the compressed ClientHello (that is, what goes into the handshake transcript),
1330 * so all the compressed extensions need to appear in the same place that the
1331 * outer_extensions extension appears.
1332 *
1333 * On the first run, if |inOutPskXtn| and OuterXtnsBuf contains a PSK extension,
1334 * remove it and return in the outparam.he caller will compute the binder value
1335 * based on the uncompressed output. Next, if |compress|, consolidate duplicated
1336 * extensions (that would otherwise be copied) into a single outer_extensions
1337 * extension. If |inOutPskXtn|, the extension contains a binder, it is appended
1338 * after the deduplicated outer_extensions. In the case of GREASE ECH, one call
1339 * is made to estimate size (wiith compression, null inOutPskXtn).
1340 */
1341SECStatus
1342tls13_ConstructInnerExtensionsFromOuter(sslSocket *ss, sslBuffer *chOuterXtnsBuf,
1343 sslBuffer *chInnerXtns, sslBuffer *inOutPskXtn,
1344 PRBool shouldCompress)
1345{
1346 SECStatus rv;
1347 PRUint64 extensionType;
1348 sslReadBuffer extensionData;
1349 sslBuffer pskXtn = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
1350 sslBuffer dupXtns = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 }; /* Duplicated extensions, types-only if |compress|. */
1351 unsigned int tmpOffset;
1352 unsigned int tmpLen;
1353 unsigned int srcXtnBase; /* To truncate CHOuter and remove the PSK extension. */
1354
1355 PRUint16 called[MAX_EXTENSION_WRITERS32] = { 0 }; /* For tracking which has been called. */
1356 unsigned int nCalled = 0;
1357
1358 SSL_TRC(50, ("%d: TLS13[%d]: Constructing ECH inner extensions %s compression",if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: Constructing ECH inner extensions %s compression"
, getpid(), ss->fd, shouldCompress ? "with" : "without")
1359 SSL_GETPID(), ss->fd, shouldCompress ? "with" : "without"))if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: Constructing ECH inner extensions %s compression"
, getpid(), ss->fd, shouldCompress ? "with" : "without")
;
1360
1361 /* When offering the "encrypted_client_hello" extension in its
1362 * ClientHelloOuter, the client MUST also offer an empty
1363 * "encrypted_client_hello" extension in its ClientHelloInner. */
1364 rv = sslBuffer_AppendNumber(chInnerXtns, ssl_tls13_encrypted_client_hello_xtn, 2);
1365 if (rv != SECSuccess) {
1366 goto loser;
1367 }
1368 rv = sslBuffer_AppendNumber(chInnerXtns, 1, 2);
1369 if (rv != SECSuccess) {
1370 goto loser;
1371 }
1372 rv = sslBuffer_AppendNumber(chInnerXtns, ech_xtn_type_inner, 1);
1373 if (rv != SECSuccess) {
1374 goto loser;
1375 }
1376
1377 sslReader rdr = SSL_READER(chOuterXtnsBuf->buf, chOuterXtnsBuf->len){ { chOuterXtnsBuf->buf, chOuterXtnsBuf->len }, 0 };
1378 while (SSL_READER_REMAINING(&rdr)((&rdr)->buf.len - (&rdr)->offset)) {
1379 srcXtnBase = rdr.offset;
1380 rv = sslRead_ReadNumber(&rdr, 2, &extensionType);
1381 if (rv != SECSuccess) {
1382 goto loser;
1383 }
1384
1385 /* Get the extension data. */
1386 rv = sslRead_ReadVariable(&rdr, 2, &extensionData);
1387 if (rv != SECSuccess) {
1388 goto loser;
1389 }
1390
1391 /* Skip extensions that are TLS < 1.3 only, since CHInner MUST
1392 * negotiate TLS 1.3 or above.
1393 * If the extension is supported by default (sslSupported) but unknown
1394 * to TLS 1.3 it must be a TLS < 1.3 only extension. */
1395 SSLExtensionSupport sslSupported;
1396 (void)SSLExp_GetExtensionSupport(extensionType, &sslSupported);
1397 if (sslSupported != ssl_ext_none &&
1398 tls13_ExtensionStatus(extensionType, ssl_hs_client_hello) == tls13_extension_unknown) {
1399 continue;
1400 }
1401
1402 switch (extensionType) {
1403 case ssl_server_name_xtn:
1404 /* Write the real (private) SNI value. */
1405 rv = sslBuffer_AppendNumber(chInnerXtns, extensionType, 2);
1406 if (rv != SECSuccess) {
1407 goto loser;
1408 }
1409 rv = sslBuffer_Skip(chInnerXtns, 2, &tmpOffset);
1410 if (rv != SECSuccess) {
1411 goto loser;
1412 }
1413 tmpLen = SSL_BUFFER_LEN(chInnerXtns)((chInnerXtns)->len);
1414 rv = ssl3_ClientFormatServerNameXtn(ss, ss->url,
1415 strlen(ss->url),
1416 NULL((void*)0), chInnerXtns);
1417 if (rv != SECSuccess) {
1418 goto loser;
1419 }
1420 tmpLen = SSL_BUFFER_LEN(chInnerXtns)((chInnerXtns)->len) - tmpLen;
1421 rv = sslBuffer_InsertNumber(chInnerXtns, tmpOffset, tmpLen, 2);
1422 if (rv != SECSuccess) {
1423 goto loser;
1424 }
1425 /* Only update state on second invocation of this function */
1426 if (shouldCompress) {
1427 ss->xtnData.echAdvertised[ss->xtnData.echNumAdvertised++] = extensionType;
1428 }
1429 break;
1430 case ssl_tls13_supported_versions_xtn:
1431 /* Only TLS 1.3 and GREASE on CHInner. */
1432 rv = sslBuffer_AppendNumber(chInnerXtns, extensionType, 2);
1433 if (rv != SECSuccess) {
1434 goto loser;
1435 }
1436 /* Extension length. */
1437 tmpLen = (ss->opt.enableGrease) ? 5 : 3;
1438 rv = sslBuffer_AppendNumber(chInnerXtns, tmpLen, 2);
1439 if (rv != SECSuccess) {
1440 goto loser;
1441 }
1442 /* ProtocolVersion length */
1443 rv = sslBuffer_AppendNumber(chInnerXtns, tmpLen - 1, 1);
1444 if (rv != SECSuccess) {
1445 goto loser;
1446 }
1447 /* ProtocolVersion TLS 1.3 */
1448 rv = sslBuffer_AppendNumber(chInnerXtns, SSL_LIBRARY_VERSION_TLS_1_30x0304, 2);
1449 if (rv != SECSuccess) {
1450 goto loser;
1451 }
1452 /* ProtocolVersion GREASE */
1453 if (ss->opt.enableGrease) {
1454 rv = sslBuffer_AppendNumber(chInnerXtns, ss->ssl3.hs.grease->idx[grease_version], 2);
1455 if (rv != SECSuccess) {
1456 goto loser;
1457 }
1458 }
1459 /* Only update state on second invocation of this function */
1460 if (shouldCompress) {
1461 ss->xtnData.echAdvertised[ss->xtnData.echNumAdvertised++] = extensionType;
1462 }
1463 break;
1464 case ssl_tls13_pre_shared_key_xtn:
1465 if (inOutPskXtn && !shouldCompress) {
1466 rv = sslBuffer_AppendNumber(&pskXtn, extensionType, 2);
1467 if (rv != SECSuccess) {
1468 goto loser;
1469 }
1470 rv = sslBuffer_AppendVariable(&pskXtn, extensionData.buf,
1471 extensionData.len, 2);
1472 if (rv != SECSuccess) {
1473 goto loser;
1474 }
1475 /* This should be the last extension. */
1476 PORT_Assert(srcXtnBase == ss->xtnData.lastXtnOffset)((srcXtnBase == ss->xtnData.lastXtnOffset)?((void)0):PR_Assert
("srcXtnBase == ss->xtnData.lastXtnOffset","tls13ech.c",1476
))
;
1477 PORT_Assert(chOuterXtnsBuf->len - srcXtnBase == extensionData.len + 4)((chOuterXtnsBuf->len - srcXtnBase == extensionData.len + 4
)?((void)0):PR_Assert("chOuterXtnsBuf->len - srcXtnBase == extensionData.len + 4"
,"tls13ech.c",1477))
;
1478 rv = tls13_RandomizePsk(chOuterXtnsBuf->buf + srcXtnBase + 4,
1479 chOuterXtnsBuf->len - srcXtnBase - 4);
1480 if (rv != SECSuccess) {
1481 goto loser;
1482 }
1483 } else if (!inOutPskXtn) {
1484 /* When GREASEing, only the length is used.
1485 * Order doesn't matter, so just copy the extension. */
1486 rv = sslBuffer_AppendNumber(chInnerXtns, extensionType, 2);
1487 if (rv != SECSuccess) {
1488 goto loser;
1489 }
1490 rv = sslBuffer_AppendVariable(chInnerXtns, extensionData.buf,
1491 extensionData.len, 2);
1492 if (rv != SECSuccess) {
1493 goto loser;
1494 }
1495 }
1496 /* Only update state on second invocation of this function */
1497 if (shouldCompress) {
1498 ss->xtnData.echAdvertised[ss->xtnData.echNumAdvertised++] = extensionType;
1499 }
1500 break;
1501 default: {
1502 /* This is a regular extension. We can maybe compress these. */
1503 rv = tls13_ChInnerAppendExtension(ss, extensionType,
1504 &extensionData,
1505 &dupXtns, chInnerXtns,
1506 shouldCompress,
1507 called, &nCalled);
1508 if (rv != SECSuccess) {
1509 goto loser;
1510 }
1511 break;
1512 }
1513 }
1514 }
1515
1516 rv = tls13_WriteDupXtnsToChInner(shouldCompress, &dupXtns, chInnerXtns);
1517 if (rv != SECSuccess) {
1518 goto loser;
1519 }
1520
1521 /* Now call custom extension handlers that didn't choose to append anything to
1522 * the outer ClientHello. */
1523 rv = tls13_ChInnerAdditionalExtensionWriters(ss, called, nCalled, chInnerXtns);
1524 if (rv != SECSuccess) {
1525 goto loser;
1526 }
1527
1528 if (inOutPskXtn) {
1529 /* On the first, non-compress run, append the (bad) PSK binder.
1530 * On the second compression run, the caller is responsible for
1531 * providing an extension with a valid binder, so append that. */
1532 if (shouldCompress) {
1533 rv = sslBuffer_AppendBuffer(chInnerXtns, inOutPskXtn);
1534 } else {
1535 rv = sslBuffer_AppendBuffer(chInnerXtns, &pskXtn);
1536 *inOutPskXtn = pskXtn;
1537 }
1538 if (rv != SECSuccess) {
1539 goto loser;
1540 }
1541 }
1542
1543 return SECSuccess;
1544
1545loser:
1546 sslBuffer_Clear(&pskXtn);
1547 sslBuffer_Clear(&dupXtns);
1548 return SECFailure;
1549}
1550
1551static SECStatus
1552tls13_EncodeClientHelloInner(sslSocket *ss, const sslBuffer *chInner, const sslBuffer *chInnerXtns, sslBuffer *out)
1553{
1554 PORT_Assert(ss && chInner && chInnerXtns && out)((ss && chInner && chInnerXtns && out
)?((void)0):PR_Assert("ss && chInner && chInnerXtns && out"
,"tls13ech.c",1554))
;
1555 SECStatus rv;
1556 sslReadBuffer tmpReadBuf;
1557 sslReader chReader = SSL_READER(chInner->buf, chInner->len){ { chInner->buf, chInner->len }, 0 };
1558
1559 rv = sslRead_Read(&chReader, 4, &tmpReadBuf);
1560 if (rv != SECSuccess) {
1561 goto loser;
1562 }
1563
1564 rv = sslRead_Read(&chReader, 2 + SSL3_RANDOM_LENGTH32, &tmpReadBuf);
1565 if (rv != SECSuccess) {
1566 goto loser;
1567 }
1568 rv = sslBuffer_Append(out, tmpReadBuf.buf, tmpReadBuf.len);
1569 if (rv != SECSuccess) {
1570 goto loser;
1571 }
1572
1573 /* Skip the legacy_session_id */
1574 rv = sslRead_ReadVariable(&chReader, 1, &tmpReadBuf);
1575 if (rv != SECSuccess) {
1576 goto loser;
1577 }
1578 rv = sslBuffer_AppendNumber(out, 0, 1);
1579 if (rv != SECSuccess) {
1580 goto loser;
1581 }
1582
1583 /* cipher suites */
1584 rv = sslRead_ReadVariable(&chReader, 2, &tmpReadBuf);
1585 if (rv != SECSuccess) {
1586 goto loser;
1587 }
1588 rv = sslBuffer_AppendVariable(out, tmpReadBuf.buf, tmpReadBuf.len, 2);
1589 if (rv != SECSuccess) {
1590 goto loser;
1591 }
1592
1593 /* compression methods */
1594 rv = sslRead_ReadVariable(&chReader, 1, &tmpReadBuf);
1595 if (rv != SECSuccess) {
1596 goto loser;
1597 }
1598 rv = sslBuffer_AppendVariable(out, tmpReadBuf.buf, tmpReadBuf.len, 1);
1599 if (rv != SECSuccess) {
1600 goto loser;
1601 }
1602
1603 /* Append the extensions. */
1604 rv = sslBuffer_AppendBufferVariable(out, chInnerXtns, 2);
1605 if (rv != SECSuccess) {
1606 goto loser;
1607 }
1608 return SECSuccess;
1609
1610loser:
1611 sslBuffer_Clear(out);
1612 return SECFailure;
1613}
1614
1615SECStatus
1616tls13_PadChInner(sslBuffer *chInner, uint8_t maxNameLen, uint8_t serverNameLen)
1617{
1618 SECStatus rv;
1619 PORT_Assert(chInner)((chInner)?((void)0):PR_Assert("chInner","tls13ech.c",1619));
1620 PORT_Assert(serverNameLen > 0)((serverNameLen > 0)?((void)0):PR_Assert("serverNameLen > 0"
,"tls13ech.c",1620))
;
1621 static unsigned char padding[256 + 32] = { 0 };
1622 int16_t name_padding = (int16_t)maxNameLen - (int16_t)serverNameLen;
1623 if (name_padding < 0) {
1624 name_padding = 0;
1625 }
1626 unsigned int rounding_padding = 31 - ((SSL_BUFFER_LEN(chInner)((chInner)->len) + name_padding) % 32);
1627 unsigned int total_padding = name_padding + rounding_padding;
1628 PORT_Assert(total_padding < sizeof(padding))((total_padding < sizeof(padding))?((void)0):PR_Assert("total_padding < sizeof(padding)"
,"tls13ech.c",1628))
;
1629 SSL_TRC(100, ("computed ECH Inner Client Hello padding of size %u", total_padding))if (ssl_trace >= (100)) ssl_Trace ("computed ECH Inner Client Hello padding of size %u"
, total_padding)
;
1630 rv = sslBuffer_Append(chInner, padding, total_padding);
1631 if (rv != SECSuccess) {
1632 sslBuffer_Clear(chInner);
1633 return SECFailure;
1634 }
1635 return SECSuccess;
1636}
1637
1638/* Build an ECH Xtn body with a zeroed payload for the client hello inner
1639 *
1640 * enum { outer(0), inner(1) } ECHClientHelloType;
1641 *
1642 * struct {
1643 * ECHClientHelloType type;
1644 * select (ECHClientHello.type) {
1645 * case outer:
1646 * HpkeSymmetricCipherSuite cipher_suite;
1647 * uint8 config_id;
1648 * opaque enc<0..2^16-1>;
1649 * opaque payload<1..2^16-1>;
1650 * case inner:
1651 * Empty;
1652 * };
1653 * } ECHClientHello;
1654 *
1655 * payloadLen = Size of zeroed placeholder field for payload.
1656 * payloadOffset = Out parameter, start of payload field
1657 * echXtn = Out parameter, constructed ECH Xtn with zeroed placeholder field.
1658*/
1659SECStatus
1660tls13_BuildEchXtn(sslEchConfig *cfg, const SECItem *hpkeEnc, unsigned int payloadLen, PRUint16 *payloadOffset, sslBuffer *echXtn)
1661{
1662 SECStatus rv;
1663 /* Format the encrypted_client_hello extension. */
1664 rv = sslBuffer_AppendNumber(echXtn, ech_xtn_type_outer, 1);
1665 if (rv != SECSuccess) {
1666 goto loser;
1667 }
1668 rv = sslBuffer_AppendNumber(echXtn, cfg->contents.kdfId, 2);
1669 if (rv != SECSuccess) {
1670 goto loser;
1671 }
1672 rv = sslBuffer_AppendNumber(echXtn, cfg->contents.aeadId, 2);
1673 if (rv != SECSuccess) {
1674 goto loser;
1675 }
1676
1677 rv = sslBuffer_AppendNumber(echXtn, cfg->contents.configId, 1);
1678 if (rv != SECSuccess) {
1679 goto loser;
1680 }
1681 if (hpkeEnc) {
1682 /* Public Key */
1683 rv = sslBuffer_AppendVariable(echXtn, hpkeEnc->data, hpkeEnc->len, 2);
1684 if (rv != SECSuccess) {
1685 goto loser;
1686 }
1687 } else {
1688 /* |enc| is empty. */
1689 rv = sslBuffer_AppendNumber(echXtn, 0, 2);
1690 if (rv != SECSuccess) {
1691 goto loser;
1692 }
1693 }
1694 payloadLen += TLS13_ECH_AEAD_TAG_LEN16;
1695 rv = sslBuffer_AppendNumber(echXtn, payloadLen, 2);
1696 if (rv != SECSuccess) {
1697 goto loser;
1698 }
1699 *payloadOffset = echXtn->len;
1700 rv = sslBuffer_Fill(echXtn, 0, payloadLen);
1701 if (rv != SECSuccess) {
1702 goto loser;
1703 }
1704 PRINT_BUF(100, (NULL, "ECH Xtn with Placeholder:", echXtn->buf, echXtn->len))if (ssl_trace >= (100)) ssl_PrintBuf (((void*)0), "ECH Xtn with Placeholder:"
, echXtn->buf, echXtn->len)
;
1705 return SECSuccess;
1706loser:
1707 sslBuffer_Clear(echXtn);
1708 return SECFailure;
1709}
1710
1711SECStatus
1712tls13_ConstructClientHelloWithEch(sslSocket *ss, const sslSessionID *sid, PRBool freshSid,
1713 sslBuffer *chOuter, sslBuffer *chOuterXtnsBuf)
1714{
1715 SECStatus rv;
1716 sslBuffer chInner = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
1717 sslBuffer encodedChInner = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
1718 sslBuffer paddingChInner = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
1719 sslBuffer chInnerXtns = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
1720 sslBuffer pskXtn = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
1721 unsigned int preambleLen;
1722
1723 SSL_TRC(50, ("%d: TLS13[%d]: Constructing ECH inner", SSL_GETPID(), ss->fd))if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: Constructing ECH inner"
, getpid(), ss->fd)
;
1724
1725 /* Create the full (uncompressed) inner extensions and steal any PSK extension.
1726 * NB: Neither chOuterXtnsBuf nor chInnerXtns are length-prefixed. */
1727 rv = tls13_ConstructInnerExtensionsFromOuter(ss, chOuterXtnsBuf, &chInnerXtns,
1728 &pskXtn, PR_FALSE0);
1729 if (rv != SECSuccess) {
1730 goto loser; /* code set */
1731 }
1732
1733 rv = ssl3_CreateClientHelloPreamble(ss, sid, PR_FALSE0, SSL_LIBRARY_VERSION_TLS_1_30x0304,
1734 PR_TRUE1, &chInnerXtns, &chInner);
1735 if (rv != SECSuccess) {
1736 goto loser; /* code set */
1737 }
1738 preambleLen = SSL_BUFFER_LEN(&chInner)((&chInner)->len);
1739
1740 /* Write handshake header length. tls13_EncryptClientHello will
1741 * remove this upon encoding, but the transcript needs it. This assumes
1742 * the 4B stream-variant header. */
1743 PORT_Assert(!IS_DTLS(ss))((!(ss->protocolVariant == ssl_variant_datagram))?((void)0
):PR_Assert("!IS_DTLS(ss)","tls13ech.c",1743))
;
1744 rv = sslBuffer_InsertNumber(&chInner, 1,
1745 chInner.len + 2 + chInnerXtns.len - 4, 3);
1746 if (rv != SECSuccess) {
1747 goto loser;
1748 }
1749
1750 if (pskXtn.len) {
1751 PORT_Assert(ssl3_ExtensionAdvertised(ss, ssl_tls13_pre_shared_key_xtn))((ssl3_ExtensionAdvertised(ss, ssl_tls13_pre_shared_key_xtn))
?((void)0):PR_Assert("ssl3_ExtensionAdvertised(ss, ssl_tls13_pre_shared_key_xtn)"
,"tls13ech.c",1751))
;
1752 rv = tls13_WriteExtensionsWithBinder(ss, &chInnerXtns, &chInner);
1753 /* Update the stolen PSK extension with the binder value. */
1754 PORT_Memcpymemcpy(pskXtn.buf, &chInnerXtns.buf[chInnerXtns.len - pskXtn.len], pskXtn.len);
1755 } else {
1756 rv = sslBuffer_AppendBufferVariable(&chInner, &chInnerXtns, 2);
1757 }
1758 if (rv != SECSuccess) {
1759 goto loser;
1760 }
1761
1762 PRINT_BUF(50, (ss, "Uncompressed CHInner", chInner.buf, chInner.len))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "Uncompressed CHInner"
, chInner.buf, chInner.len)
;
1763 rv = ssl3_UpdateHandshakeHashesInt(ss, chInner.buf, chInner.len,
1764 &ss->ssl3.hs.echInnerMessages);
1765 if (rv != SECSuccess) {
1766 goto loser; /* code set */
1767 }
1768
1769 /* Un-append the extensions, then append compressed via Encoded. */
1770 SSL_BUFFER_LEN(&chInner)((&chInner)->len) = preambleLen;
1771 sslBuffer_Clear(&chInnerXtns);
1772 rv = tls13_ConstructInnerExtensionsFromOuter(ss, chOuterXtnsBuf,
1773 &chInnerXtns, &pskXtn, PR_TRUE1);
1774 if (rv != SECSuccess) {
1775 goto loser;
1776 }
1777
1778 rv = tls13_EncodeClientHelloInner(ss, &chInner, &chInnerXtns, &encodedChInner);
1779 if (rv != SECSuccess) {
1780 goto loser;
1781 }
1782 PRINT_BUF(50, (ss, "Compressed CHInner", encodedChInner.buf, encodedChInner.len))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "Compressed CHInner"
, encodedChInner.buf, encodedChInner.len)
;
1783
1784 PORT_Assert(!PR_CLIST_IS_EMPTY(&ss->echConfigs))((!((&ss->echConfigs)->next == (&ss->echConfigs
)))?((void)0):PR_Assert("!PR_CLIST_IS_EMPTY(&ss->echConfigs)"
,"tls13ech.c",1784))
;
1785 sslEchConfig *cfg = (sslEchConfig *)PR_LIST_HEAD(&ss->echConfigs)(&ss->echConfigs)->next;
1786
1787 /* We are using ECH so SNI must have been included */
1788 rv = tls13_PadChInner(&encodedChInner, cfg->contents.maxNameLen, strlen(ss->url));
1789 if (rv != SECSuccess) {
1790 goto loser;
1791 }
1792
1793 /* Build the ECH Xtn with placeholder and put it in chOuterXtnsBuf */
1794 sslBuffer echXtn = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
1795 const SECItem *hpkeEnc = NULL((void*)0);
1796 if (!ss->ssl3.hs.helloRetry) {
1797 hpkeEnc = PK11_HPKE_GetEncapPubKey(ss->ssl3.hs.echHpkeCtx);
1798 if (!hpkeEnc) {
1799 FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error)do { do { if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)"
, getpid(), ss->fd, SEC_ERROR_LIBRARY_FAILURE, __func__, "tls13ech.c"
, 1799); PORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); } while
(0); tls13_FatalError(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error
); } while (0)
;
1800 goto loser;
1801 }
1802 }
1803 PRUint16 echXtnPayloadOffset; /* Offset from start of ECH Xtn to ECH Payload */
1804 rv = tls13_BuildEchXtn(cfg, hpkeEnc, encodedChInner.len, &echXtnPayloadOffset, &echXtn);
1805 if (rv != SECSuccess) {
1806 goto loser;
1807 }
1808 ss->xtnData.echAdvertised[ss->xtnData.echNumAdvertised++] = ssl_tls13_encrypted_client_hello_xtn;
1809 rv = ssl3_EmplaceExtension(ss, chOuterXtnsBuf, ssl_tls13_encrypted_client_hello_xtn,
1810 echXtn.buf, echXtn.len, PR_TRUE1);
1811 if (rv != SECSuccess) {
1812 goto loser;
1813 }
1814
1815 /* Add the padding */
1816 rv = ssl_InsertPaddingExtension(ss, chOuter->len, chOuterXtnsBuf);
1817 if (rv != SECSuccess) {
1818 goto loser;
1819 }
1820
1821 /* Finish the CHO with the ECH Xtn payload zeroed */
1822 rv = ssl3_InsertChHeaderSize(ss, chOuter, chOuterXtnsBuf);
1823 if (rv != SECSuccess) {
1824 goto loser;
1825 }
1826 unsigned int chOuterXtnsOffset = chOuter->len + 2; /* From Start of CHO to Extensions list */
1827 rv = sslBuffer_AppendBufferVariable(chOuter, chOuterXtnsBuf, 2);
1828 if (rv != SECSuccess) {
1829 goto loser;
1830 }
1831
1832 /* AAD consists of entire CHO, minus the 4 byte handshake header */
1833 SECItem aadItem = { siBuffer, chOuter->buf + 4, chOuter->len - 4 };
1834 /* ECH Payload begins after CHO Header, after ECH Xtn start, after ECH Xtn header */
1835 PRUint8 *echPayload = chOuter->buf + chOuterXtnsOffset + ss->xtnData.echXtnOffset + 4 + echXtnPayloadOffset;
1836 /* Insert the encrypted_client_hello xtn and coalesce. */
1837 rv = tls13_EncryptClientHello(ss, &aadItem, &encodedChInner, echPayload);
1838 if (rv != SECSuccess) {
1839 goto loser;
1840 }
1841
1842 sslBuffer_Clear(&echXtn);
1843 sslBuffer_Clear(&chInner);
1844 sslBuffer_Clear(&encodedChInner);
1845 sslBuffer_Clear(&paddingChInner);
1846 sslBuffer_Clear(&chInnerXtns);
1847 sslBuffer_Clear(&pskXtn);
1848 return SECSuccess;
1849
1850loser:
1851 sslBuffer_Clear(&chInner);
1852 sslBuffer_Clear(&encodedChInner);
1853 sslBuffer_Clear(&paddingChInner);
1854 sslBuffer_Clear(&chInnerXtns);
1855 sslBuffer_Clear(&pskXtn);
1856 PORT_Assert(PORT_GetError() != 0)((PORT_GetError_Util() != 0)?((void)0):PR_Assert("PORT_GetError() != 0"
,"tls13ech.c",1856))
;
1857 return SECFailure;
1858}
1859
1860static SECStatus
1861tls13_ComputeEchHelloRetryTranscript(sslSocket *ss, const PRUint8 *sh, unsigned int shLen, sslBuffer *out)
1862{
1863 SECStatus rv;
1864 PRUint8 zeroedEchSignal[TLS13_ECH_SIGNAL_LEN8] = { 0 };
1865 sslBuffer *previousTranscript;
1866
1867 if (ss->sec.isServer) {
1868 previousTranscript = &(ss->ssl3.hs.messages);
1869 } else {
1870 previousTranscript = &(ss->ssl3.hs.echInnerMessages);
1871 }
1872 /*
1873 * This segment calculates the hash of the Client Hello
1874 * TODO(djackson@mozilla.com) - Replace with existing function?
1875 * e.g. tls13_ReinjectHandshakeTranscript
1876 * TODO(djackson@mozilla.com) - Replace with streaming version
1877 */
1878 if (!ss->ssl3.hs.helloRetry || !ss->sec.isServer) {
1879 /*
1880 * This function can be called in three situations:
1881 * - By the server, prior to sending the HRR, when ECH was accepted
1882 * - By the client, after receiving the HRR, but before it knows whether ECH was accepted
1883 * - By the server, after accepting ECH and receiving CH2 when it needs to reconstruct the HRR
1884 * In the first two situations, we need to include the message hash of inner ClientHello1 but don't
1885 * want to alter the buffer containing the current transcript.
1886 * In the last, the buffer already contains the message hash of inner ClientHello1.
1887 */
1888 SSL3Hashes hashes;
1889 rv = tls13_ComputeHash(ss, &hashes, previousTranscript->buf, previousTranscript->len, tls13_GetHash(ss));
1890 if (rv != SECSuccess) {
1891 goto loser;
1892 }
1893 rv = sslBuffer_AppendNumber(out, ssl_hs_message_hash, 1);
1894 if (rv != SECSuccess) {
1895 goto loser;
1896 }
1897 rv = sslBuffer_AppendNumber(out, hashes.len, 3);
1898 if (rv != SECSuccess) {
1899 goto loser;
1900 }
1901 rv = sslBuffer_Append(out, hashes.u.raw, hashes.len);
1902 if (rv != SECSuccess) {
1903 goto loser;
1904 }
1905 } else {
1906 rv = sslBuffer_AppendBuffer(out, previousTranscript);
1907 if (rv != SECSuccess) {
1908 goto loser;
1909 }
1910 }
1911 /* Ensure the first ClientHello has been hashed. */
1912 PR_ASSERT(out->len == tls13_GetHashSize(ss) + 4)((out->len == tls13_GetHashSize(ss) + 4)?((void)0):PR_Assert
("out->len == tls13_GetHashSize(ss) + 4","tls13ech.c",1912
))
;
1913 PRINT_BUF(100, (ss, "ECH Client Hello Message Hash", out->buf, out->len))if (ssl_trace >= (100)) ssl_PrintBuf (ss, "ECH Client Hello Message Hash"
, out->buf, out->len)
;
1914 /* Message Header */
1915 rv = sslBuffer_AppendNumber(out, ssl_hs_server_hello, 1);
1916 if (rv != SECSuccess) {
1917 goto loser;
1918 }
1919 /* Message Size */
1920 rv = sslBuffer_AppendNumber(out, shLen, 3);
1921 if (rv != SECSuccess) {
1922 goto loser;
1923 }
1924 /* Calculate where the HRR ECH Xtn Signal begins */
1925 unsigned int absEchOffset;
1926 if (ss->sec.isServer) {
1927 /* We know the ECH HRR Xtn is last */
1928 PORT_Assert(shLen >= TLS13_ECH_SIGNAL_LEN)((shLen >= 8)?((void)0):PR_Assert("shLen >= TLS13_ECH_SIGNAL_LEN"
,"tls13ech.c",1928))
;
1929 absEchOffset = shLen - TLS13_ECH_SIGNAL_LEN8;
1930 } else {
1931 /* We parsed the offset earlier */
1932 /* The result of pointer comparision is unspecified
1933 * (and pointer arithemtic is undefined) if the pointers
1934 * do not point to the same array or struct. That means these
1935 * asserts cannot be relied on for correctness in compiled code,
1936 * but may help the reader understand the requirements.
1937 */
1938 PORT_Assert(ss->xtnData.ech->hrrConfirmation > sh)((ss->xtnData.ech->hrrConfirmation > sh)?((void)0):PR_Assert
("ss->xtnData.ech->hrrConfirmation > sh","tls13ech.c"
,1938))
;
1939 PORT_Assert(ss->xtnData.ech->hrrConfirmation < sh + shLen)((ss->xtnData.ech->hrrConfirmation < sh + shLen)?((void
)0):PR_Assert("ss->xtnData.ech->hrrConfirmation < sh + shLen"
,"tls13ech.c",1939))
;
1940 absEchOffset = ss->xtnData.ech->hrrConfirmation - sh;
1941 }
1942 PR_ASSERT(tls13_Debug_CheckXtnBegins(sh + absEchOffset - 4, ssl_tls13_encrypted_client_hello_xtn))((tls13_Debug_CheckXtnBegins(sh + absEchOffset - 4, ssl_tls13_encrypted_client_hello_xtn
))?((void)0):PR_Assert("tls13_Debug_CheckXtnBegins(sh + absEchOffset - 4, ssl_tls13_encrypted_client_hello_xtn)"
,"tls13ech.c",1942))
;
1943 /* The HRR up to the ECH Xtn signal */
1944 rv = sslBuffer_Append(out, sh, absEchOffset);
1945 if (rv != SECSuccess) {
1946 goto loser;
1947 }
1948 rv = sslBuffer_Append(out, zeroedEchSignal, sizeof(zeroedEchSignal));
1949 if (rv != SECSuccess) {
1950 goto loser;
1951 }
1952 PR_ASSERT(absEchOffset + TLS13_ECH_SIGNAL_LEN <= shLen)((absEchOffset + 8 <= shLen)?((void)0):PR_Assert("absEchOffset + TLS13_ECH_SIGNAL_LEN <= shLen"
,"tls13ech.c",1952))
;
1953 /* The remainder of the HRR */
1954 rv = sslBuffer_Append(out, sh + absEchOffset + TLS13_ECH_SIGNAL_LEN8, shLen - absEchOffset - TLS13_ECH_SIGNAL_LEN8);
1955 if (rv != SECSuccess) {
1956 goto loser;
1957 }
1958 PR_ASSERT(out->len == tls13_GetHashSize(ss) + 4 + shLen + 4)((out->len == tls13_GetHashSize(ss) + 4 + shLen + 4)?((void
)0):PR_Assert("out->len == tls13_GetHashSize(ss) + 4 + shLen + 4"
,"tls13ech.c",1958))
;
1959 return SECSuccess;
1960loser:
1961 sslBuffer_Clear(out);
1962 return SECFailure;
1963}
1964
1965static SECStatus
1966tls13_ComputeEchServerHelloTranscript(sslSocket *ss, const PRUint8 *sh, unsigned int shLen, sslBuffer *out)
1967{
1968 SECStatus rv;
1969 sslBuffer *chSource = ss->sec.isServer ? &ss->ssl3.hs.messages : &ss->ssl3.hs.echInnerMessages;
1970 unsigned int offset = sizeof(SSL3ProtocolVersion) +
1971 SSL3_RANDOM_LENGTH32 - TLS13_ECH_SIGNAL_LEN8;
1972 PORT_Assert(sh && shLen > offset)((sh && shLen > offset)?((void)0):PR_Assert("sh && shLen > offset"
,"tls13ech.c",1972))
;
1973 PORT_Assert(TLS13_ECH_SIGNAL_LEN <= SSL3_RANDOM_LENGTH)((8 <= 32)?((void)0):PR_Assert("TLS13_ECH_SIGNAL_LEN <= SSL3_RANDOM_LENGTH"
,"tls13ech.c",1973))
;
1974
1975 /* TODO(djackson@mozilla.com) - Replace with streaming version */
1976
1977 rv = sslBuffer_AppendBuffer(out, chSource);
1978 if (rv != SECSuccess) {
1979 goto loser;
1980 }
1981
1982 /* Re-create the message header. */
1983 rv = sslBuffer_AppendNumber(out, ssl_hs_server_hello, 1);
1984 if (rv != SECSuccess) {
1985 goto loser;
1986 }
1987
1988 rv = sslBuffer_AppendNumber(out, shLen, 3);
1989 if (rv != SECSuccess) {
1990 goto loser;
1991 }
1992
1993 /* Copy the version and 24B of server_random. */
1994 rv = sslBuffer_Append(out, sh, offset);
1995 if (rv != SECSuccess) {
1996 goto loser;
1997 }
1998
1999 /* Zero the signal placeholder. */
2000 rv = sslBuffer_AppendNumber(out, 0, TLS13_ECH_SIGNAL_LEN8);
2001 if (rv != SECSuccess) {
2002 goto loser;
2003 }
2004 offset += TLS13_ECH_SIGNAL_LEN8;
2005
2006 /* Use the remainder of SH. */
2007 rv = sslBuffer_Append(out, &sh[offset], shLen - offset);
2008 if (rv != SECSuccess) {
2009 goto loser;
2010 }
2011 sslBuffer_Clear(&ss->ssl3.hs.messages);
2012 sslBuffer_Clear(&ss->ssl3.hs.echInnerMessages);
2013 return SECSuccess;
2014loser:
2015 sslBuffer_Clear(&ss->ssl3.hs.messages);
2016 sslBuffer_Clear(&ss->ssl3.hs.echInnerMessages);
2017 sslBuffer_Clear(out);
2018 return SECFailure;
2019}
2020
2021/* Compute the ECH signal using the transcript (up to, including)
2022 * ServerHello. The server sources this transcript prefix from
2023 * ss->ssl3.hs.messages, as it never uses ss->ssl3.hs.echInnerMessages.
2024 * The client uses the inner transcript, echInnerMessages. */
2025SECStatus
2026tls13_ComputeEchSignal(sslSocket *ss, PRBool isHrr, const PRUint8 *sh, unsigned int shLen, PRUint8 *out)
2027{
2028 SECStatus rv;
2029 sslBuffer confMsgs = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
2030 SSL3Hashes hashes;
2031 PK11SymKey *echSecret = NULL((void*)0);
2032
2033 const char *hkdfInfo = isHrr ? kHkdfInfoEchHrrConfirm : kHkdfInfoEchConfirm;
2034 const size_t hkdfInfoLen = strlen(hkdfInfo);
2035
2036 PRINT_BUF(100, (ss, "ECH Server Hello", sh, shLen))if (ssl_trace >= (100)) ssl_PrintBuf (ss, "ECH Server Hello"
, sh, shLen)
;
2037
2038 if (isHrr) {
2039 rv = tls13_ComputeEchHelloRetryTranscript(ss, sh, shLen, &confMsgs);
2040 } else {
2041 rv = tls13_ComputeEchServerHelloTranscript(ss, sh, shLen, &confMsgs);
2042 }
2043 if (rv != SECSuccess) {
2044 goto loser;
2045 }
2046 PRINT_BUF(100, (ss, "ECH Transcript", confMsgs.buf, confMsgs.len))if (ssl_trace >= (100)) ssl_PrintBuf (ss, "ECH Transcript"
, confMsgs.buf, confMsgs.len)
;
2047 rv = tls13_ComputeHash(ss, &hashes, confMsgs.buf, confMsgs.len,
2048 tls13_GetHash(ss));
2049 if (rv != SECSuccess) {
2050 goto loser;
2051 }
2052 PRINT_BUF(100, (ss, "ECH Transcript Hash", &hashes.u, hashes.len))if (ssl_trace >= (100)) ssl_PrintBuf (ss, "ECH Transcript Hash"
, &hashes.u, hashes.len)
;
2053 rv = tls13_DeriveEchSecret(ss, &echSecret);
2054 if (rv != SECSuccess) {
2055 return SECFailure;
2056 }
2057 rv = tls13_HkdfExpandLabelRaw(echSecret, tls13_GetHash(ss), hashes.u.raw,
2058 hashes.len, hkdfInfo, hkdfInfoLen, ss->protocolVariant,
2059 out, TLS13_ECH_SIGNAL_LEN8);
2060 if (rv != SECSuccess) {
2061 return SECFailure;
2062 }
2063 SSL_TRC(50, ("%d: TLS13[%d]: %s computed ECH signal", SSL_GETPID(), ss->fd, SSL_ROLE(ss)))if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: %s computed ECH signal"
, getpid(), ss->fd, (ss->sec.isServer ? "server" : "client"
))
;
2064 PRINT_BUF(50, (ss, "Computed ECH Signal", out, TLS13_ECH_SIGNAL_LEN))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "Computed ECH Signal"
, out, 8)
;
2065 PK11_FreeSymKey(echSecret);
2066 sslBuffer_Clear(&confMsgs);
2067 return SECSuccess;
2068
2069loser:
2070 PK11_FreeSymKey(echSecret);
2071 sslBuffer_Clear(&confMsgs);
2072 return SECFailure;
2073}
2074
2075/* Ech Secret is HKDF-Extract(0, ClientHelloInner.random) where
2076 "0" is a string of Hash.len bytes of value 0. */
2077SECStatus
2078tls13_DeriveEchSecret(const sslSocket *ss, PK11SymKey **output)
2079{
2080 SECStatus rv;
2081 PK11SlotInfo *slot = NULL((void*)0);
2082 PK11SymKey *crKey = NULL((void*)0);
2083 SECItem rawKey;
2084 const unsigned char *client_random = ss->sec.isServer ? ss->ssl3.hs.client_random : ss->ssl3.hs.client_inner_random;
2085 PRINT_BUF(50, (ss, "Client Random for ECH", client_random, SSL3_RANDOM_LENGTH))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "Client Random for ECH"
, client_random, 32)
;
2086 /* We need a SECItem */
2087 rv = SECITEM_MakeItem(NULL((void*)0), &rawKey, client_random, SSL3_RANDOM_LENGTH32);
2088 if (rv != SECSuccess) {
2089 goto cleanup;
2090 }
2091 /* We need a slot*/
2092 slot = PK11_GetBestSlot(CKM_HKDF_DERIVE0x0000402aUL, NULL((void*)0));
2093 if (!slot) {
2094 rv = SECFailure;
2095 goto cleanup;
2096 }
2097 /* We import the key */
2098 crKey = PK11_ImportDataKey(slot, CKM_HKDF_DERIVE0x0000402aUL, PK11_OriginUnwrap,
2099 CKA_DERIVE0x0000010CUL, &rawKey, NULL((void*)0));
2100 if (crKey == NULL((void*)0)) {
2101 rv = SECFailure;
2102 goto cleanup;
2103 }
2104 /* NULL will be expanded to 0s of hash length */
2105 rv = tls13_HkdfExtract(NULL((void*)0), crKey, tls13_GetHash(ss), output);
2106 if (rv != SECSuccess) {
2107 goto cleanup;
2108 }
2109 SSL_TRC(50, ("%d: TLS13[%d]: ECH Confirmation Key Derived.",if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: ECH Confirmation Key Derived."
, getpid(), ss->fd)
2110 SSL_GETPID(), ss->fd))if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: ECH Confirmation Key Derived."
, getpid(), ss->fd)
;
2111 PRINT_KEY(50, (NULL, "ECH Confirmation Key", *output))if (ssl_trace >= (50)) ssl_PrintKey (((void*)0), "ECH Confirmation Key"
, *output)
;
2112cleanup:
2113 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&rawKey, PR_FALSE0);
2114 if (slot) {
2115 PK11_FreeSlot(slot);
2116 }
2117 if (crKey) {
2118 PK11_FreeSymKey(crKey);
2119 }
2120 if (rv != SECSuccess && *output) {
2121 PK11_FreeSymKey(*output);
2122 *output = NULL((void*)0);
2123 }
2124 return rv;
2125}
2126
2127/* Called just prior to padding the CH. Use the size of the CH to estimate
2128 * the size of a corresponding ECH extension, then add it to the buffer. */
2129SECStatus
2130tls13_MaybeGreaseEch(sslSocket *ss, const sslBuffer *preamble, sslBuffer *buf)
2131{
2132 SECStatus rv;
2133 sslBuffer chInnerXtns = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
2134 sslBuffer encodedCh = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
2135 sslBuffer greaseBuf = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
2136 unsigned int payloadLen;
2137 HpkeAeadId aead;
2138 PK11SlotInfo *slot = NULL((void*)0);
2139 PK11SymKey *hmacPrk = NULL((void*)0);
2140 PK11SymKey *derivedData = NULL((void*)0);
2141 SECItem *rawData;
2142 CK_HKDF_PARAMS params;
2143 SECItem paramsi;
2144 /* 1B aead determinant (don't send), 1B config_id, 32B enc, payload */
2145 PR_ASSERT(!ss->sec.isServer)((!ss->sec.isServer)?((void)0):PR_Assert("!ss->sec.isServer"
,"tls13ech.c",2145))
;
2146 const int kNonPayloadLen = 34;
2147
2148 if (!ss->opt.enableTls13GreaseEch || ss->ssl3.hs.echHpkeCtx) {
2149 return SECSuccess;
2150 }
2151
2152 if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_30x0304 ||
2153 IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) {
2154 return SECSuccess;
2155 }
2156
2157 /* In draft-09, CH2 sends exactly the same GREASE ECH extension. */
2158 if (ss->ssl3.hs.helloRetry) {
2159 return ssl3_EmplaceExtension(ss, buf, ssl_tls13_encrypted_client_hello_xtn,
2160 ss->ssl3.hs.greaseEchBuf.buf,
2161 ss->ssl3.hs.greaseEchBuf.len, PR_TRUE1);
2162 }
2163
2164 /* Compress the extensions for payload length. */
2165 rv = tls13_ConstructInnerExtensionsFromOuter(ss, buf, &chInnerXtns,
2166 NULL((void*)0), PR_TRUE1);
2167 if (rv != SECSuccess) {
2168 goto loser; /* Code set */
2169 }
2170 rv = tls13_EncodeClientHelloInner(ss, preamble, &chInnerXtns, &encodedCh);
2171 if (rv != SECSuccess) {
2172 goto loser; /* Code set */
2173 }
2174 rv = tls13_PadChInner(&encodedCh, ss->ssl3.hs.greaseEchSize, strlen(ss->url));
Value stored to 'rv' is never read
2175
2176 payloadLen = encodedCh.len;
2177 payloadLen += TLS13_ECH_AEAD_TAG_LEN16; /* Aead tag */
2178
2179 /* HMAC-Expand to get something that will pass for ciphertext. */
2180 slot = PK11_GetBestSlot(CKM_HKDF_DERIVE0x0000402aUL, NULL((void*)0));
2181 if (!slot) {
2182 goto loser;
2183 }
2184
2185 hmacPrk = PK11_KeyGen(slot, CKM_HKDF_DATA0x0000402bUL, NULL((void*)0), SHA256_LENGTH32, NULL((void*)0));
2186 if (!hmacPrk) {
2187 goto loser;
2188 }
2189
2190 params.bExtract = CK_FALSE0;
2191 params.bExpand = CK_TRUE1;
2192 params.prfHashMechanism = CKM_SHA2560x00000250UL;
2193 params.pInfo = NULL((void*)0);
2194 params.ulInfoLen = 0;
2195 paramsi.data = (unsigned char *)&params;
2196 paramsi.len = sizeof(params);
2197 derivedData = PK11_DeriveWithFlags(hmacPrk, CKM_HKDF_DATA0x0000402bUL,
2198 &paramsi, CKM_HKDF_DATA0x0000402bUL,
2199 CKA_DERIVE0x0000010CUL, kNonPayloadLen + payloadLen,
2200 CKF_VERIFY0x00002000);
2201 if (!derivedData) {
2202 goto loser;
2203 }
2204
2205 rv = PK11_ExtractKeyValue(derivedData);
2206 if (rv != SECSuccess) {
2207 goto loser;
2208 }
2209
2210 rawData = PK11_GetKeyData(derivedData);
2211 if (!rawData) {
2212 goto loser;
2213 }
2214 PORT_Assert(rawData->len == kNonPayloadLen + payloadLen)((rawData->len == kNonPayloadLen + payloadLen)?((void)0):PR_Assert
("rawData->len == kNonPayloadLen + payloadLen","tls13ech.c"
,2214))
;
2215
2216 /* struct {
2217 HpkeSymmetricCipherSuite cipher_suite; // kdf_id, aead_id
2218 PRUint8 config_id;
2219 opaque enc<1..2^16-1>;
2220 opaque payload<1..2^16-1>;
2221 } ClientECH; */
2222
2223 rv = sslBuffer_AppendNumber(&greaseBuf, ech_xtn_type_outer, 1);
2224 if (rv != SECSuccess) {
2225 goto loser;
2226 }
2227 /* Only support SHA256. */
2228 rv = sslBuffer_AppendNumber(&greaseBuf, HpkeKdfHkdfSha256, 2);
2229 if (rv != SECSuccess) {
2230 goto loser;
2231 }
2232
2233 /* HpkeAeadAes128Gcm = 1, HpkeAeadChaCha20Poly1305 = 3, */
2234 aead = (rawData->data[0] & 1) ? HpkeAeadAes128Gcm : HpkeAeadChaCha20Poly1305;
2235 rv = sslBuffer_AppendNumber(&greaseBuf, aead, 2);
2236 if (rv != SECSuccess) {
2237 goto loser;
2238 }
2239
2240 /* config_id */
2241 rv = sslBuffer_AppendNumber(&greaseBuf, rawData->data[1], 1);
2242 if (rv != SECSuccess) {
2243 goto loser;
2244 }
2245
2246 /* enc len is fixed 32B for X25519. */
2247 rv = sslBuffer_AppendVariable(&greaseBuf, &rawData->data[2], 32, 2);
2248 if (rv != SECSuccess) {
2249 goto loser;
2250 }
2251
2252 rv = sslBuffer_AppendVariable(&greaseBuf, &rawData->data[kNonPayloadLen], payloadLen, 2);
2253 if (rv != SECSuccess) {
2254 goto loser;
2255 }
2256
2257 /* Mark ECH as advertised so that we can validate any response.
2258 * We'll use echHpkeCtx to determine if we sent real or GREASE ECH. */
2259 rv = ssl3_EmplaceExtension(ss, buf, ssl_tls13_encrypted_client_hello_xtn,
2260 greaseBuf.buf, greaseBuf.len, PR_TRUE1);
2261 if (rv != SECSuccess) {
2262 goto loser;
2263 }
2264
2265 /* Stash the GREASE ECH extension - in the case of HRR, CH2 must echo it. */
2266 ss->ssl3.hs.greaseEchBuf = greaseBuf;
2267
2268 sslBuffer_Clear(&chInnerXtns);
2269 sslBuffer_Clear(&encodedCh);
2270 PK11_FreeSymKey(hmacPrk);
2271 PK11_FreeSymKey(derivedData);
2272 PK11_FreeSlot(slot);
2273 return SECSuccess;
2274
2275loser:
2276 sslBuffer_Clear(&chInnerXtns);
2277 sslBuffer_Clear(&encodedCh);
2278 PK11_FreeSymKey(hmacPrk);
2279 PK11_FreeSymKey(derivedData);
2280 if (slot) {
2281 PK11_FreeSlot(slot);
2282 }
2283 return SECFailure;
2284}
2285
2286SECStatus
2287tls13_MaybeHandleEch(sslSocket *ss, const PRUint8 *msg, PRUint32 msgLen, SECItem *sidBytes,
2288 SECItem *comps, SECItem *cookieBytes, SECItem *suites, SECItem **echInner)
2289{
2290 SECStatus rv;
2291 SECItem *tmpEchInner = NULL((void*)0);
2292 PRUint8 *b;
2293 PRUint32 length;
2294 TLSExtension *echExtension;
2295 TLSExtension *versionExtension;
2296 PORT_Assert(!ss->ssl3.hs.echAccepted)((!ss->ssl3.hs.echAccepted)?((void)0):PR_Assert("!ss->ssl3.hs.echAccepted"
,"tls13ech.c",2296))
;
2297 SECItem tmpSid = { siBuffer, NULL((void*)0), 0 };
2298 SECItem tmpCookie = { siBuffer, NULL((void*)0), 0 };
2299 SECItem tmpSuites = { siBuffer, NULL((void*)0), 0 };
2300 SECItem tmpComps = { siBuffer, NULL((void*)0), 0 };
2301
2302 echExtension = ssl3_FindExtension(ss, ssl_tls13_encrypted_client_hello_xtn);
2303 if (echExtension) {
2304 rv = tls13_ServerHandleOuterEchXtn(ss, &ss->xtnData, &echExtension->data);
2305 if (rv != SECSuccess) {
2306 goto loser; /* code set, alert sent. */
2307 }
2308 rv = tls13_MaybeAcceptEch(ss, sidBytes, msg, msgLen, &tmpEchInner);
2309 if (rv != SECSuccess) {
2310 goto loser; /* code set, alert sent. */
2311 }
2312 }
2313 ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_ech(1U << 4);
2314
2315 if (ss->ssl3.hs.echAccepted) {
2316 PORT_Assert(tmpEchInner)((tmpEchInner)?((void)0):PR_Assert("tmpEchInner","tls13ech.c"
,2316))
;
2317 PORT_Assert(!PR_CLIST_IS_EMPTY(&ss->ssl3.hs.remoteExtensions))((!((&ss->ssl3.hs.remoteExtensions)->next == (&
ss->ssl3.hs.remoteExtensions)))?((void)0):PR_Assert("!PR_CLIST_IS_EMPTY(&ss->ssl3.hs.remoteExtensions)"
,"tls13ech.c",2317))
;
2318
2319 /* Start over on ECHInner */
2320 b = tmpEchInner->data;
2321 length = tmpEchInner->len;
2322 rv = ssl3_HandleClientHelloPreamble(ss, &b, &length, &tmpSid,
2323 &tmpCookie, &tmpSuites, &tmpComps);
2324 if (rv != SECSuccess) {
2325 goto loser; /* code set, alert sent. */
2326 }
2327
2328 versionExtension = ssl3_FindExtension(ss, ssl_tls13_supported_versions_xtn);
2329 if (!versionExtension) {
2330 FATAL_ERROR(ss, SSL_ERROR_UNSUPPORTED_VERSION, illegal_parameter)do { do { if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)"
, getpid(), ss->fd, SSL_ERROR_UNSUPPORTED_VERSION, __func__
, "tls13ech.c", 2330); PORT_SetError_Util(SSL_ERROR_UNSUPPORTED_VERSION
); } while (0); tls13_FatalError(ss, SSL_ERROR_UNSUPPORTED_VERSION
, illegal_parameter); } while (0)
;
2331 goto loser;
2332 }
2333 rv = tls13_NegotiateVersion(ss, versionExtension);
2334 if (rv != SECSuccess) {
2335 /* code and alert set by tls13_NegotiateVersion */
2336 goto loser;
2337 }
2338
2339 *comps = tmpComps;
2340 *cookieBytes = tmpCookie;
2341 *sidBytes = tmpSid;
2342 *suites = tmpSuites;
2343 *echInner = tmpEchInner;
2344 }
2345 return SECSuccess;
2346
2347loser:
2348 SECITEM_FreeItemSECITEM_FreeItem_Util(tmpEchInner, PR_TRUE1);
2349 PORT_Assert(PORT_GetError() != 0)((PORT_GetError_Util() != 0)?((void)0):PR_Assert("PORT_GetError() != 0"
,"tls13ech.c",2349))
;
2350 return SECFailure;
2351}
2352
2353SECStatus
2354tls13_MaybeHandleEchSignal(sslSocket *ss, const PRUint8 *sh, PRUint32 shLen, PRBool isHrr)
2355{
2356 SECStatus rv;
2357 PRUint8 computed[TLS13_ECH_SIGNAL_LEN8];
2358 const PRUint8 *signal;
2359 PORT_Assert(!ss->sec.isServer)((!ss->sec.isServer)?((void)0):PR_Assert("!ss->sec.isServer"
,"tls13ech.c",2359))
;
2360
2361 /* If !echHpkeCtx, we either didn't advertise or sent GREASE ECH. */
2362 if (!ss->ssl3.hs.echHpkeCtx) {
2363 SSL_TRC(50, ("%d: TLS13[%d]: client only sent GREASE ECH",if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: client only sent GREASE ECH"
, getpid(), ss->fd)
2364 SSL_GETPID(), ss->fd))if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: client only sent GREASE ECH"
, getpid(), ss->fd)
;
2365 ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_ech(1U << 4);
2366 return SECSuccess;
2367 }
2368
2369 PORT_Assert(!IS_DTLS(ss))((!(ss->protocolVariant == ssl_variant_datagram))?((void)0
):PR_Assert("!IS_DTLS(ss)","tls13ech.c",2369))
;
2370
2371 if (isHrr) {
2372 if (ss->xtnData.ech) {
2373 signal = ss->xtnData.ech->hrrConfirmation;
2374 } else {
2375 SSL_TRC(50, ("%d: TLS13[%d]: client did not receive ECH Xtn from Server HRR",if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: client did not receive ECH Xtn from Server HRR"
, getpid(), ss->fd)
2376 SSL_GETPID(), ss->fd))if (ssl_trace >= (50)) ssl_Trace ("%d: TLS13[%d]: client did not receive ECH Xtn from Server HRR"
, getpid(), ss->fd)
;
2377 signal = NULL((void*)0);
2378 ss->ssl3.hs.echAccepted = PR_FALSE0;
2379 ss->ssl3.hs.echDecided = PR_TRUE1;
2380 }
2381 } else {
2382 signal = &ss->ssl3.hs.server_random[SSL3_RANDOM_LENGTH32 - TLS13_ECH_SIGNAL_LEN8];
2383 }
2384
2385 PORT_Assert(ssl3_ExtensionAdvertised(ss, ssl_tls13_encrypted_client_hello_xtn))((ssl3_ExtensionAdvertised(ss, ssl_tls13_encrypted_client_hello_xtn
))?((void)0):PR_Assert("ssl3_ExtensionAdvertised(ss, ssl_tls13_encrypted_client_hello_xtn)"
,"tls13ech.c",2385))
;
2386
2387 /* Check ECH Confirmation for HRR ECH Xtn or ServerHello Random */
2388 if (signal) {
2389 rv = tls13_ComputeEchSignal(ss, isHrr, sh, shLen, computed);
2390 if (rv != SECSuccess) {
2391 return SECFailure;
2392 }
2393 PRINT_BUF(100, (ss, "Server Signal", signal, TLS13_ECH_SIGNAL_LEN))if (ssl_trace >= (100)) ssl_PrintBuf (ss, "Server Signal",
signal, 8)
;
2394 PRBool new_decision = !NSS_SecureMemcmp(computed, signal, TLS13_ECH_SIGNAL_LEN8);
2395 /* Server can't change its mind on whether to accept ECH */
2396 if (ss->ssl3.hs.echDecided && new_decision != ss->ssl3.hs.echAccepted) {
2397 FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_SERVER_HELLO, illegal_parameter)do { do { if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)"
, getpid(), ss->fd, SSL_ERROR_RX_MALFORMED_SERVER_HELLO, __func__
, "tls13ech.c", 2397); PORT_SetError_Util(SSL_ERROR_RX_MALFORMED_SERVER_HELLO
); } while (0); tls13_FatalError(ss, SSL_ERROR_RX_MALFORMED_SERVER_HELLO
, illegal_parameter); } while (0)
;
2398 return SECFailure;
2399 }
2400 ss->ssl3.hs.echAccepted = new_decision;
2401 ss->ssl3.hs.echDecided = PR_TRUE1;
2402 }
2403
2404 ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_ech(1U << 4);
2405 if (ss->ssl3.hs.echAccepted) {
2406 if (ss->version < SSL_LIBRARY_VERSION_TLS_1_30x0304) {
2407 FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_SERVER_HELLO, illegal_parameter)do { do { if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)"
, getpid(), ss->fd, SSL_ERROR_RX_MALFORMED_SERVER_HELLO, __func__
, "tls13ech.c", 2407); PORT_SetError_Util(SSL_ERROR_RX_MALFORMED_SERVER_HELLO
); } while (0); tls13_FatalError(ss, SSL_ERROR_RX_MALFORMED_SERVER_HELLO
, illegal_parameter); } while (0)
;
2408 return SECFailure;
2409 }
2410 /* Server accepted, but sent an extension which was only advertised in the ClientHelloOuter */
2411 if (ss->ssl3.hs.echInvalidExtension) {
2412 (void)SSL3_SendAlert(ss, alert_fatal, unsupported_extension);
2413 PORT_SetErrorPORT_SetError_Util(SSL_ERROR_RX_UNEXPECTED_EXTENSION);
2414 return SECFailure;
2415 }
2416
2417 /* Swap the advertised lists as we've accepted ECH. */
2418 PRUint16 *tempArray = ss->xtnData.advertised;
2419 PRUint16 tempNum = ss->xtnData.numAdvertised;
2420
2421 ss->xtnData.advertised = ss->xtnData.echAdvertised;
2422 ss->xtnData.numAdvertised = ss->xtnData.echNumAdvertised;
2423
2424 ss->xtnData.echAdvertised = tempArray;
2425 ss->xtnData.echNumAdvertised = tempNum;
2426
2427 /* |enc| must not be included in CH2.ClientECH. */
2428 if (ss->ssl3.hs.helloRetry && ss->sec.isServer &&
2429 ss->xtnData.ech->senderPubKey.len) {
2430 ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
2431 PORT_SetErrorPORT_SetError_Util(SSL_ERROR_BAD_2ND_CLIENT_HELLO);
2432 return SECFailure;
2433 }
2434 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_tls13_encrypted_client_hello_xtn;
2435
2436 /* Only overwrite client_random with client_inner_random if CHInner was
2437 * succesfully used for handshake (NOT if HRR is received). */
2438 if (!isHrr) {
2439 PORT_Memcpymemcpy(ss->ssl3.hs.client_random, ss->ssl3.hs.client_inner_random, SSL3_RANDOM_LENGTH32);
2440 }
2441 }
2442 /* If rejected, leave echHpkeCtx and echPublicName for rejection paths. */
2443 ssl3_CoalesceEchHandshakeHashes(ss);
2444 SSL_TRC(3, ("%d: TLS13[%d]: ECH %s accepted by server",if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: ECH %s accepted by server"
, getpid(), ss->fd, ss->ssl3.hs.echAccepted ? "is" : "is not"
)
2445 SSL_GETPID(), ss->fd, ss->ssl3.hs.echAccepted ? "is" : "is not"))if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: ECH %s accepted by server"
, getpid(), ss->fd, ss->ssl3.hs.echAccepted ? "is" : "is not"
)
;
2446 return SECSuccess;
2447}
2448
2449static SECStatus
2450tls13_UnencodeChInner(sslSocket *ss, const SECItem *sidBytes, SECItem **echInner)
2451{
2452 SECStatus rv;
2453 sslReadBuffer outerExtensionsList;
2454 sslReadBuffer tmpReadBuf;
2455 sslBuffer unencodedChInner = SSL_BUFFER_EMPTY{ ((void*)0), 0, 0, 0 };
2456 PRCList *outerCursor;
2457 PRCList *innerCursor;
2458 PRBool outerFound;
2459 PRUint32 xtnsOffset;
2460 PRUint64 tmp;
2461 PRUint8 *tmpB;
2462 PRUint32 tmpLength;
2463 sslReader chReader = SSL_READER((*echInner)->data, (*echInner)->len){ { (*echInner)->data, (*echInner)->len }, 0 };
2464 PORT_Assert(!PR_CLIST_IS_EMPTY(&ss->ssl3.hs.echOuterExtensions))((!((&ss->ssl3.hs.echOuterExtensions)->next == (&
ss->ssl3.hs.echOuterExtensions)))?((void)0):PR_Assert("!PR_CLIST_IS_EMPTY(&ss->ssl3.hs.echOuterExtensions)"
,"tls13ech.c",2464))
;
2465 PORT_Assert(PR_CLIST_IS_EMPTY(&ss->ssl3.hs.remoteExtensions))((((&ss->ssl3.hs.remoteExtensions)->next == (&ss
->ssl3.hs.remoteExtensions)))?((void)0):PR_Assert("PR_CLIST_IS_EMPTY(&ss->ssl3.hs.remoteExtensions)"
,"tls13ech.c",2465))
;
2466 TLSExtension *echExtension;
2467 int error = SSL_ERROR_INTERNAL_ERROR_ALERT;
2468 int errDesc = internal_error;
2469
2470 PRINT_BUF(100, (ss, "ECH Inner", chReader.buf.buf, chReader.buf.len))if (ssl_trace >= (100)) ssl_PrintBuf (ss, "ECH Inner", chReader
.buf.buf, chReader.buf.len)
;
2471
2472 /* unencodedChInner := preamble, tmpReadBuf := encoded extensions. */
2473 rv = tls13_CopyChPreamble(ss, &chReader, sidBytes, &unencodedChInner, &tmpReadBuf);
2474 if (rv != SECSuccess) {
2475 goto loser; /* code set */
2476 }
2477
2478 /* Parse inner extensions into ss->ssl3.hs.remoteExtensions. */
2479 tmpB = CONST_CAST(PRUint8, tmpReadBuf.buf)((PRUint8 *)(tmpReadBuf.buf));
2480 rv = ssl3_ParseExtensions(ss, &tmpB, &tmpReadBuf.len);
2481 if (rv != SECSuccess) {
2482 goto loser; /* malformed, alert sent. */
2483 }
2484
2485 echExtension = ssl3_FindExtension(ss, ssl_tls13_encrypted_client_hello_xtn);
2486 if (!echExtension) {
2487 error = SSL_ERROR_MISSING_ECH_EXTENSIONSSL_ERROR_MISSING_ESNI_EXTENSION;
2488 errDesc = illegal_parameter;
2489 goto alert_loser; /* Must have an inner Extension */
2490 }
2491 rv = tls13_ServerHandleInnerEchXtn(ss, &ss->xtnData, &echExtension->data);
2492 if (rv != SECSuccess) {
2493 goto loser; /* code set, alert sent. */
2494 }
2495
2496 /* Exit early if there are no outer_extensions to decompress. */
2497 if (!ssl3_FindExtension(ss, ssl_tls13_outer_extensions_xtn)) {
2498 rv = sslBuffer_AppendVariable(&unencodedChInner, tmpReadBuf.buf, tmpReadBuf.len, 2);
2499 if (rv != SECSuccess) {
2500 goto loser;
2501 }
2502 sslBuffer_Clear(&unencodedChInner);
2503 return SECSuccess;
2504 }
2505
2506 /* Save room for uncompressed length. */
2507 rv = sslBuffer_Skip(&unencodedChInner, 2, &xtnsOffset);
2508 if (rv != SECSuccess) {
2509 goto loser;
2510 }
2511
2512 /* For each inner extension: If not outer_extensions, copy it to the output.
2513 * Else if outer_extensions, iterate the compressed extension list and append
2514 * each full extension as contained in CHOuter. Compressed extensions must be
2515 * contiguous, so decompress at the point at which outer_extensions appears. */
2516 for (innerCursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions)((&ss->ssl3.hs.remoteExtensions)->next);
2517 innerCursor != &ss->ssl3.hs.remoteExtensions;
2518 innerCursor = PR_NEXT_LINK(innerCursor)((innerCursor)->next)) {
2519 TLSExtension *innerExtension = (TLSExtension *)innerCursor;
2520 if (innerExtension->type != ssl_tls13_outer_extensions_xtn) {
2521 SSL_TRC(10, ("%d: SSL3[%d]: copying inner extension of type %d and size %d directly", SSL_GETPID(),if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: copying inner extension of type %d and size %d directly"
, getpid(), ss->fd, innerExtension->type, innerExtension
->data.len)
2522 ss->fd, innerExtension->type, innerExtension->data.len))if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: copying inner extension of type %d and size %d directly"
, getpid(), ss->fd, innerExtension->type, innerExtension
->data.len)
;
2523 rv = sslBuffer_AppendNumber(&unencodedChInner,
2524 innerExtension->type, 2);
2525 if (rv != SECSuccess) {
2526 goto loser;
2527 }
2528 rv = sslBuffer_AppendVariable(&unencodedChInner,
2529 innerExtension->data.data,
2530 innerExtension->data.len, 2);
2531 if (rv != SECSuccess) {
2532 goto loser;
2533 }
2534 continue;
2535 }
2536
2537 /* Decompress */
2538 sslReader extensionRdr = SSL_READER(innerExtension->data.data,{ { innerExtension->data.data, innerExtension->data.len
}, 0 }
2539 innerExtension->data.len){ { innerExtension->data.data, innerExtension->data.len
}, 0 }
;
2540 rv = sslRead_ReadVariable(&extensionRdr, 1, &outerExtensionsList);
2541 if (rv != SECSuccess) {
2542 SSL_TRC(10, ("%d: SSL3[%d]: ECH Outer Extensions has invalid size.",if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: ECH Outer Extensions has invalid size."
, getpid(), ss->fd)
2543 SSL_GETPID(), ss->fd))if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: ECH Outer Extensions has invalid size."
, getpid(), ss->fd)
;
2544 error = SSL_ERROR_RX_MALFORMED_ECH_EXTENSIONSSL_ERROR_RX_MALFORMED_ESNI_EXTENSION;
2545 errDesc = illegal_parameter;
2546 goto alert_loser;
2547 }
2548 if (SSL_READER_REMAINING(&extensionRdr)((&extensionRdr)->buf.len - (&extensionRdr)->offset
)
|| (outerExtensionsList.len % 2) != 0 || !outerExtensionsList.len) {
2549 SSL_TRC(10, ("%d: SSL3[%d]: ECH Outer Extensions has invalid size.",if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: ECH Outer Extensions has invalid size."
, getpid(), ss->fd)
2550 SSL_GETPID(), ss->fd))if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: ECH Outer Extensions has invalid size."
, getpid(), ss->fd)
;
2551 error = SSL_ERROR_RX_MALFORMED_ECH_EXTENSIONSSL_ERROR_RX_MALFORMED_ESNI_EXTENSION;
2552 errDesc = illegal_parameter;
2553 goto alert_loser;
2554 }
2555
2556 outerCursor = &ss->ssl3.hs.echOuterExtensions;
2557 sslReader compressedTypes = SSL_READER(outerExtensionsList.buf, outerExtensionsList.len){ { outerExtensionsList.buf, outerExtensionsList.len }, 0 };
2558 while (SSL_READER_REMAINING(&compressedTypes)((&compressedTypes)->buf.len - (&compressedTypes)->
offset)
) {
2559 outerFound = PR_FALSE0;
2560 rv = sslRead_ReadNumber(&compressedTypes, 2, &tmp);
2561 if (rv != SECSuccess) {
2562 SSL_TRC(10, ("%d: SSL3[%d]: ECH Outer Extensions has invalid contents.",if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: ECH Outer Extensions has invalid contents."
, getpid(), ss->fd)
2563 SSL_GETPID(), ss->fd))if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: ECH Outer Extensions has invalid contents."
, getpid(), ss->fd)
;
2564 error = SSL_ERROR_RX_MALFORMED_ECH_EXTENSIONSSL_ERROR_RX_MALFORMED_ESNI_EXTENSION;
2565 errDesc = illegal_parameter;
2566 goto alert_loser;
2567 }
2568 if (tmp == ssl_tls13_encrypted_client_hello_xtn ||
2569 tmp == ssl_tls13_outer_extensions_xtn) {
2570 SSL_TRC(10, ("%d: SSL3[%d]: ECH Outer Extensions contains an invalid reference.",if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: ECH Outer Extensions contains an invalid reference."
, getpid(), ss->fd)
2571 SSL_GETPID(), ss->fd))if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: ECH Outer Extensions contains an invalid reference."
, getpid(), ss->fd)
;
2572 error = SSL_ERROR_RX_MALFORMED_ECH_EXTENSIONSSL_ERROR_RX_MALFORMED_ESNI_EXTENSION;
2573 errDesc = illegal_parameter;
2574 goto alert_loser;
2575 }
2576 do {
2577 const TLSExtension *candidate = (TLSExtension *)outerCursor;
2578 /* Advance the outerCursor, we never consider the same xtn twice. */
2579 outerCursor = PR_NEXT_LINK(outerCursor)((outerCursor)->next);
2580 if (candidate->type == tmp) {
2581 outerFound = PR_TRUE1;
2582 SSL_TRC(100, ("%d: SSL3[%d]: Decompressing ECH Inner Extension of type %d",if (ssl_trace >= (100)) ssl_Trace ("%d: SSL3[%d]: Decompressing ECH Inner Extension of type %d"
, getpid(), ss->fd, tmp)
2583 SSL_GETPID(), ss->fd, tmp))if (ssl_trace >= (100)) ssl_Trace ("%d: SSL3[%d]: Decompressing ECH Inner Extension of type %d"
, getpid(), ss->fd, tmp)
;
2584 rv = sslBuffer_AppendNumber(&unencodedChInner,
2585 candidate->type, 2);
2586 if (rv != SECSuccess) {
2587 goto loser;
2588 }
2589 rv = sslBuffer_AppendVariable(&unencodedChInner,
2590 candidate->data.data,
2591 candidate->data.len, 2);
2592 if (rv != SECSuccess) {
2593 goto loser;
2594 }
2595 break;
2596 }
2597 } while (outerCursor != &ss->ssl3.hs.echOuterExtensions);
2598 if (!outerFound) {
2599 SSL_TRC(10, ("%d: SSL3[%d]: ECH Outer Extensions has missing,"if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: ECH Outer Extensions has missing,"
" out of order or duplicate references.", getpid(), ss->fd
)
2600 " out of order or duplicate references.",if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: ECH Outer Extensions has missing,"
" out of order or duplicate references.", getpid(), ss->fd
)
2601 SSL_GETPID(), ss->fd))if (ssl_trace >= (10)) ssl_Trace ("%d: SSL3[%d]: ECH Outer Extensions has missing,"
" out of order or duplicate references.", getpid(), ss->fd
)
;
2602 error = SSL_ERROR_RX_MALFORMED_ECH_EXTENSIONSSL_ERROR_RX_MALFORMED_ESNI_EXTENSION;
2603 errDesc = illegal_parameter;
2604 goto alert_loser;
2605 }
2606 }
2607 }
2608 ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.echOuterExtensions);
2609 ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);
2610
2611 /* Correct the message and extensions sizes. */
2612 rv = sslBuffer_InsertNumber(&unencodedChInner, xtnsOffset,
2613 unencodedChInner.len - xtnsOffset - 2, 2);
2614 if (rv != SECSuccess) {
2615 goto loser;
2616 }
2617
2618 tmpB = &unencodedChInner.buf[xtnsOffset];
2619 tmpLength = unencodedChInner.len - xtnsOffset;
2620 rv = ssl3_ConsumeHandshakeNumber64(ss, &tmp, 2, &tmpB, &tmpLength);
2621 if (rv != SECSuccess || tmpLength != tmp) {
2622 error = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
2623 errDesc = internal_error;
2624 goto alert_loser;
2625 }
2626
2627 rv = ssl3_ParseExtensions(ss, &tmpB, &tmpLength);
2628 if (rv != SECSuccess) {
2629 goto loser; /* Error set and alert already sent */
2630 }
2631
2632 SECITEM_FreeItemSECITEM_FreeItem_Util(*echInner, PR_FALSE0);
2633 (*echInner)->data = unencodedChInner.buf;
2634 (*echInner)->len = unencodedChInner.len;
2635 return SECSuccess;
2636alert_loser:
2637 FATAL_ERROR(ss, error, errDesc)do { do { if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)"
, getpid(), ss->fd, error, __func__, "tls13ech.c", 2637); PORT_SetError_Util
(error); } while (0); tls13_FatalError(ss, error, errDesc); }
while (0)
;
2638loser:
2639 sslBuffer_Clear(&unencodedChInner);
2640 return SECFailure;
2641}
2642
2643SECStatus
2644tls13_MaybeAcceptEch(sslSocket *ss, const SECItem *sidBytes, const PRUint8 *chOuter,
2645 unsigned int chOuterLen, SECItem **chInner)
2646{
2647 SECStatus rv;
2648 SECItem outer = { siBuffer, CONST_CAST(PRUint8, chOuter)((PRUint8 *)(chOuter)), chOuterLen };
2649 SECItem *decryptedChInner = NULL((void*)0);
2650 SECItem outerAAD = { siBuffer, NULL((void*)0), 0 };
2651 SECItem cookieData = { siBuffer, NULL((void*)0), 0 };
2652 sslEchCookieData echData;
2653 sslEchConfig *candidate = NULL((void*)0); /* non-owning */
2654 TLSExtension *hrrXtn;
2655 PRBool previouslyOfferedEch;
2656
2657 if (!ss->xtnData.ech || ss->xtnData.ech->receivedInnerXtn || IS_DTLS(ss)(ss->protocolVariant == ssl_variant_datagram)) {
2658 ss->ssl3.hs.echDecided = PR_TRUE1;
2659 return SECSuccess;
2660 }
2661
2662 PORT_Assert(ss->xtnData.ech->innerCh.data)((ss->xtnData.ech->innerCh.data)?((void)0):PR_Assert("ss->xtnData.ech->innerCh.data"
,"tls13ech.c",2662))
;
2663
2664 if (ss->ssl3.hs.helloRetry) {
2665 ss->ssl3.hs.echDecided = PR_TRUE1;
2666 PORT_Assert(!ss->ssl3.hs.echHpkeCtx)((!ss->ssl3.hs.echHpkeCtx)?((void)0):PR_Assert("!ss->ssl3.hs.echHpkeCtx"
,"tls13ech.c",2666))
;
2667 hrrXtn = ssl3_FindExtension(ss, ssl_tls13_cookie_xtn);
2668 if (!hrrXtn) {
2669 /* If the client doesn't echo cookie, we can't decrypt. */
2670 return SECSuccess;
2671 }
2672
2673 PORT_Assert(!ss->ssl3.hs.echHpkeCtx)((!ss->ssl3.hs.echHpkeCtx)?((void)0):PR_Assert("!ss->ssl3.hs.echHpkeCtx"
,"tls13ech.c",2673))
;
2674
2675 PRUint8 *tmp = hrrXtn->data.data;
2676 PRUint32 len = hrrXtn->data.len;
2677 rv = ssl3_ExtConsumeHandshakeVariable(ss, &cookieData, 2,
2678 &tmp, &len);
2679 if (rv != SECSuccess) {
2680 return SECFailure;
2681 }
2682
2683 /* Extract ECH info without restoring hash state. If there's
2684 * something wrong with the cookie, continue without ECH
2685 * and let HRR code handle the problem. */
2686 rv = tls13_HandleHrrCookie(ss, cookieData.data, cookieData.len,
2687 NULL((void*)0), NULL((void*)0), &previouslyOfferedEch, &echData, PR_FALSE0);
2688 if (rv != SECSuccess) {
2689 return SECSuccess;
2690 }
2691
2692 ss->ssl3.hs.echHpkeCtx = echData.hpkeCtx;
2693
2694 const PRUint8 greaseConstant[TLS13_ECH_SIGNAL_LEN8] = { 0 };
2695 ss->ssl3.hs.echAccepted = previouslyOfferedEch &&
2696 !NSS_SecureMemcmp(greaseConstant, echData.signal, TLS13_ECH_SIGNAL_LEN8);
2697
2698 if (echData.configId != ss->xtnData.ech->configId ||
2699 echData.kdfId != ss->xtnData.ech->kdfId ||
2700 echData.aeadId != ss->xtnData.ech->aeadId) {
2701 FATAL_ERROR(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO,do { do { if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)"
, getpid(), ss->fd, SSL_ERROR_BAD_2ND_CLIENT_HELLO, __func__
, "tls13ech.c", 2702); PORT_SetError_Util(SSL_ERROR_BAD_2ND_CLIENT_HELLO
); } while (0); tls13_FatalError(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO
, illegal_parameter); } while (0)
2702 illegal_parameter)do { do { if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)"
, getpid(), ss->fd, SSL_ERROR_BAD_2ND_CLIENT_HELLO, __func__
, "tls13ech.c", 2702); PORT_SetError_Util(SSL_ERROR_BAD_2ND_CLIENT_HELLO
); } while (0); tls13_FatalError(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO
, illegal_parameter); } while (0)
;
2703 return SECFailure;
2704 }
2705
2706 if (!ss->ssl3.hs.echHpkeCtx) {
2707 return SECSuccess;
2708 }
2709 }
2710
2711 if (ss->ssl3.hs.echDecided && !ss->ssl3.hs.echAccepted) {
2712 /* We don't change our mind */
2713 return SECSuccess;
2714 }
2715 /* Regardless of where we return, the outcome is decided */
2716 ss->ssl3.hs.echDecided = PR_TRUE1;
2717
2718 /* Cookie data was good, proceed with ECH. */
2719 rv = tls13_GetMatchingEchConfigs(ss, ss->xtnData.ech->kdfId, ss->xtnData.ech->aeadId,
2720 ss->xtnData.ech->configId, candidate, &candidate);
2721 if (rv != SECSuccess) {
2722 FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error)do { do { if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)"
, getpid(), ss->fd, SEC_ERROR_LIBRARY_FAILURE, __func__, "tls13ech.c"
, 2722); PORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); } while
(0); tls13_FatalError(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error
); } while (0)
;
2723 return SECFailure;
2724 }
2725
2726 if (candidate) {
2727 rv = tls13_ServerMakeChOuterAAD(ss, chOuter, chOuterLen, &outerAAD);
2728 if (rv != SECSuccess) {
2729 return SECFailure;
2730 }
2731 }
2732
2733 while (candidate) {
2734 rv = tls13_OpenClientHelloInner(ss, &outer, &outerAAD, candidate, &decryptedChInner);
2735 if (rv != SECSuccess) {
2736 /* Get the next matching config */
2737 rv = tls13_GetMatchingEchConfigs(ss, ss->xtnData.ech->kdfId, ss->xtnData.ech->aeadId,
2738 ss->xtnData.ech->configId, candidate, &candidate);
2739 if (rv != SECSuccess) {
2740 FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error)do { do { if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)"
, getpid(), ss->fd, SEC_ERROR_LIBRARY_FAILURE, __func__, "tls13ech.c"
, 2740); PORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE); } while
(0); tls13_FatalError(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error
); } while (0)
;
2741 SECITEM_FreeItemSECITEM_FreeItem_Util(&outerAAD, PR_FALSE0);
2742 return SECFailure;
2743 }
2744 continue;
2745 }
2746 break;
2747 }
2748 SECITEM_FreeItemSECITEM_FreeItem_Util(&outerAAD, PR_FALSE0);
2749
2750 if (rv != SECSuccess || !decryptedChInner) {
2751 if (ss->ssl3.hs.helloRetry) {
2752 FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_ECH_EXTENSION, decrypt_error)do { do { if (ssl_trace >= (3)) ssl_Trace ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)"
, getpid(), ss->fd, SSL_ERROR_RX_MALFORMED_ESNI_EXTENSION,
__func__, "tls13ech.c", 2752); PORT_SetError_Util(SSL_ERROR_RX_MALFORMED_ESNI_EXTENSION
); } while (0); tls13_FatalError(ss, SSL_ERROR_RX_MALFORMED_ESNI_EXTENSION
, decrypt_error); } while (0)
;
2753 return SECFailure;
2754 } else {
2755 /* Send retry_configs (if we have any) when we fail to decrypt or
2756 * found no candidates. This does *not* count as negotiating ECH. */
2757 return ssl3_RegisterExtensionSender(ss, &ss->xtnData,
2758 ssl_tls13_encrypted_client_hello_xtn,
2759 tls13_ServerSendEchXtn);
2760 }
2761 }
2762
2763 SSL_TRC(20, ("%d: TLS13[%d]: Successfully opened ECH inner CH",if (ssl_trace >= (20)) ssl_Trace ("%d: TLS13[%d]: Successfully opened ECH inner CH"
, getpid(), ss->fd)
2764 SSL_GETPID(), ss->fd))if (ssl_trace >= (20)) ssl_Trace ("%d: TLS13[%d]: Successfully opened ECH inner CH"
, getpid(), ss->fd)
;
2765 PRINT_BUF(50, (ss, "Compressed CHInner", decryptedChInner->data,if (ssl_trace >= (50)) ssl_PrintBuf (ss, "Compressed CHInner"
, decryptedChInner->data, decryptedChInner->len)
2766 decryptedChInner->len))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "Compressed CHInner"
, decryptedChInner->data, decryptedChInner->len)
;
2767
2768 ss->ssl3.hs.echAccepted = PR_TRUE1;
2769
2770 /* Stash the CHOuter extensions. They're not yet handled (only parsed). If
2771 * the CHInner contains outer_extensions_xtn, we'll need to reference them. */
2772 ssl3_MoveRemoteExtensions(&ss->ssl3.hs.echOuterExtensions, &ss->ssl3.hs.remoteExtensions);
2773
2774 rv = tls13_UnencodeChInner(ss, sidBytes, &decryptedChInner);
2775 if (rv != SECSuccess) {
2776 SECITEM_FreeItemSECITEM_FreeItem_Util(decryptedChInner, PR_TRUE1);
2777 return SECFailure; /* code set */
2778 }
2779 PRINT_BUF(50, (ss, "Uncompressed CHInner", decryptedChInner->data,if (ssl_trace >= (50)) ssl_PrintBuf (ss, "Uncompressed CHInner"
, decryptedChInner->data, decryptedChInner->len)
2780 decryptedChInner->len))if (ssl_trace >= (50)) ssl_PrintBuf (ss, "Uncompressed CHInner"
, decryptedChInner->data, decryptedChInner->len)
;
2781 *chInner = decryptedChInner;
2782 return SECSuccess;
2783}
2784
2785SECStatus
2786tls13_WriteServerEchSignal(sslSocket *ss, PRUint8 *sh, unsigned int shLen)
2787{
2788 SECStatus rv;
2789 PRUint8 signal[TLS13_ECH_SIGNAL_LEN8];
2790 PRUint8 *msg_random = &sh[sizeof(SSL3ProtocolVersion)];
2791
2792 PORT_Assert(shLen > sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH)((shLen > sizeof(SSL3ProtocolVersion) + 32)?((void)0):PR_Assert
("shLen > sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH"
,"tls13ech.c",2792))
;
2793 PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3)((ss->version >= 0x0304)?((void)0):PR_Assert("ss->version >= SSL_LIBRARY_VERSION_TLS_1_3"
,"tls13ech.c",2793))
;
2794
2795 rv = tls13_ComputeEchSignal(ss, PR_FALSE0, sh, shLen, signal);
2796 if (rv != SECSuccess) {
2797 return SECFailure;
2798 }
2799 PRUint8 *dest = &msg_random[SSL3_RANDOM_LENGTH32 - TLS13_ECH_SIGNAL_LEN8];
2800 PORT_Memcpymemcpy(dest, signal, TLS13_ECH_SIGNAL_LEN8);
2801
2802 /* Keep the socket copy consistent. */
2803 PORT_Assert(0 == memcmp(msg_random, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH - TLS13_ECH_SIGNAL_LEN))((0 == memcmp(msg_random, &ss->ssl3.hs.server_random, 32
- 8))?((void)0):PR_Assert("0 == memcmp(msg_random, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH - TLS13_ECH_SIGNAL_LEN)"
,"tls13ech.c",2803))
;
2804 dest = &ss->ssl3.hs.server_random[SSL3_RANDOM_LENGTH32 - TLS13_ECH_SIGNAL_LEN8];
2805 PORT_Memcpymemcpy(dest, signal, TLS13_ECH_SIGNAL_LEN8);
2806
2807 return SECSuccess;
2808}
2809
2810SECStatus
2811tls13_WriteServerEchHrrSignal(sslSocket *ss, PRUint8 *sh, unsigned int shLen)
2812{
2813 SECStatus rv;
2814 PR_ASSERT(shLen >= 4 + TLS13_ECH_SIGNAL_LEN)((shLen >= 4 + 8)?((void)0):PR_Assert("shLen >= 4 + TLS13_ECH_SIGNAL_LEN"
,"tls13ech.c",2814))
;
2815 /* We put the HRR ECH extension last. */
2816 PRUint8 *placeholder_location = sh + shLen - TLS13_ECH_SIGNAL_LEN8;
2817 /* Defensive check that we are overwriting the contents of the right extension */
2818 PR_ASSERT(tls13_Debug_CheckXtnBegins(placeholder_location - 4, ssl_tls13_encrypted_client_hello_xtn))((tls13_Debug_CheckXtnBegins(placeholder_location - 4, ssl_tls13_encrypted_client_hello_xtn
))?((void)0):PR_Assert("tls13_Debug_CheckXtnBegins(placeholder_location - 4, ssl_tls13_encrypted_client_hello_xtn)"
,"tls13ech.c",2818))
;
2819 /* Calculate signal and overwrite */
2820 rv = tls13_ComputeEchSignal(ss, PR_TRUE1, sh, shLen, placeholder_location);
2821 if (rv != SECSuccess) {
2822 return SECFailure;
2823 }
2824 /* Free HRR GREASE/accept_confirmation value, it MUST be restored from
2825 * cookie when handling CH2 after HRR. */
2826 sslBuffer_Clear(&ss->ssl3.hs.greaseEchBuf);
2827 return SECSuccess;
2828}