Coverage Report

Created: 2026-03-09 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/ssl/ech/ech_internal.c
Line
Count
Source
1
/*
2
 * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the OpenSSL license (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
#include <openssl/ssl.h>
11
#include <openssl/ech.h>
12
#include <openssl/rand.h>
13
#include <openssl/kdf.h>
14
#include "internal/ech_helpers.h"
15
#include "internal/ssl_unwrap.h"
16
#include "../ssl_local.h"
17
#include "../statem/statem_local.h"
18
#include "ech_local.h"
19
20
#ifndef OPENSSL_NO_ECH
21
22
/*
23
 * Strings used in ECH crypto derivations (odd format for EBCDIC goodness)
24
 */
25
/* "ech accept confirmation" */
26
static const char OSSL_ECH_ACCEPT_CONFIRM_STRING[] = "\x65\x63\x68\x20\x61\x63\x63\x65\x70\x74\x20\x63\x6f\x6e\x66\x69\x72\x6d\x61\x74\x69\x6f\x6e";
27
/* "hrr ech accept confirmation" */
28
static const char OSSL_ECH_HRR_CONFIRM_STRING[] = "\x68\x72\x72\x20\x65\x63\x68\x20\x61\x63\x63\x65\x70\x74\x20\x63\x6f\x6e\x66\x69\x72\x6d\x61\x74\x69\x6f\x6e";
29
30
/* ECH internal API functions */
31
32
#ifdef OSSL_ECH_SUPERVERBOSE
33
/* ascii-hex print a buffer nicely for debug/interop purposes */
34
void ossl_ech_pbuf(const char *msg, const unsigned char *buf, const size_t blen)
35
0
{
36
0
    OSSL_TRACE_BEGIN(TLS)
37
0
    {
38
0
        if (msg == NULL) {
39
0
            BIO_printf(trc_out, "msg is NULL\n");
40
0
        } else if (buf == NULL || blen == 0) {
41
0
            BIO_printf(trc_out, "%s: buf is %p\n", msg, (void *)buf);
42
0
            BIO_printf(trc_out, "%s: blen is %lu\n", msg, (unsigned long)blen);
43
0
        } else {
44
0
            BIO_printf(trc_out, "%s (%lu)\n", msg, (unsigned long)blen);
45
0
            BIO_dump_indent(trc_out, buf, (int)blen, 4);
46
0
        }
47
0
    }
48
0
    OSSL_TRACE_END(TLS);
49
0
    return;
50
0
}
51
52
/* trace out transcript */
53
static void ossl_ech_ptranscript(SSL_CONNECTION *s, const char *msg)
54
0
{
55
0
    size_t hdatalen = 0;
56
0
    unsigned char *hdata = NULL;
57
0
    unsigned char ddata[EVP_MAX_MD_SIZE];
58
0
    size_t ddatalen;
59
60
0
    if (s == NULL)
61
0
        return;
62
0
    hdatalen = BIO_get_mem_data(s->s3.handshake_buffer, &hdata);
63
0
    ossl_ech_pbuf(msg, hdata, hdatalen);
64
0
    if (s->s3.handshake_dgst != NULL) {
65
0
        if (ssl_handshake_hash(s, ddata, sizeof(ddata), &ddatalen) == 0) {
66
0
            OSSL_TRACE(TLS, "ssl_handshake_hash failed\n");
67
0
            ossl_ech_pbuf(msg, ddata, ddatalen);
68
0
        }
69
0
    }
70
0
    OSSL_TRACE(TLS, "new transbuf:\n");
71
0
    ossl_ech_pbuf(msg, s->ext.ech.transbuf, s->ext.ech.transbuf_len);
72
0
    return;
73
0
}
74
#endif
75
76
static OSSL_ECHSTORE_ENTRY *ossl_echstore_entry_dup(const OSSL_ECHSTORE_ENTRY *orig)
77
0
{
78
0
    OSSL_ECHSTORE_ENTRY *ret = NULL;
79
80
0
    if (orig == NULL)
81
0
        return NULL;
82
0
    ret = OPENSSL_zalloc(sizeof(*ret));
83
0
    if (ret == NULL)
84
0
        return NULL;
85
0
    ret->version = orig->version;
86
0
    if (orig->public_name != NULL) {
87
0
        ret->public_name = OPENSSL_strdup(orig->public_name);
88
0
        if (ret->public_name == NULL)
89
0
            goto err;
90
0
    }
91
0
    ret->pub_len = orig->pub_len;
92
0
    if (orig->pub != NULL) {
93
0
        ret->pub = OPENSSL_memdup(orig->pub, orig->pub_len);
94
0
        if (ret->pub == NULL)
95
0
            goto err;
96
0
    }
97
0
    ret->nsuites = orig->nsuites;
98
0
    ret->suites = OPENSSL_memdup(orig->suites, sizeof(OSSL_HPKE_SUITE) * ret->nsuites);
99
0
    if (ret->suites == NULL)
100
0
        goto err;
101
0
    ret->max_name_length = orig->max_name_length;
102
0
    ret->config_id = orig->config_id;
103
0
    if (orig->exts != NULL) {
104
0
        ret->exts = sk_OSSL_ECHEXT_deep_copy(orig->exts, ossl_echext_dup,
105
0
            ossl_echext_free);
106
0
        if (ret->exts == NULL)
107
0
            goto err;
108
0
    }
109
0
    ret->loadtime = orig->loadtime;
110
0
    if (orig->keyshare != NULL) {
111
0
        if (!EVP_PKEY_up_ref(orig->keyshare))
112
0
            goto err;
113
0
        ret->keyshare = orig->keyshare;
114
0
    }
115
0
    ret->for_retry = orig->for_retry;
116
0
    if (orig->encoded != NULL) {
117
0
        ret->encoded_len = orig->encoded_len;
118
0
        ret->encoded = OPENSSL_memdup(orig->encoded, ret->encoded_len);
119
0
        if (ret->encoded == NULL)
120
0
            goto err;
121
0
    }
122
0
    return ret;
123
0
err:
124
0
    ossl_echstore_entry_free(ret);
125
0
    return NULL;
126
0
}
127
128
/* duplicate an OSSL_ECHSTORE as needed */
129
OSSL_ECHSTORE *ossl_echstore_dup(const OSSL_ECHSTORE *old)
130
0
{
131
0
    OSSL_ECHSTORE *cp = NULL;
132
133
0
    if (old == NULL)
134
0
        return NULL;
135
0
    cp = OPENSSL_zalloc(sizeof(*cp));
136
0
    if (cp == NULL)
137
0
        return NULL;
138
0
    cp->libctx = old->libctx;
139
0
    if (old->propq != NULL) {
140
0
        cp->propq = OPENSSL_strdup(old->propq);
141
0
        if (cp->propq == NULL)
142
0
            goto err;
143
0
    }
144
0
    if (old->entries != NULL) {
145
0
        cp->entries = sk_OSSL_ECHSTORE_ENTRY_deep_copy(old->entries,
146
0
            ossl_echstore_entry_dup,
147
0
            ossl_echstore_entry_free);
148
0
        if (cp->entries == NULL)
149
0
            goto err;
150
0
    }
151
0
    return cp;
152
0
err:
153
0
    OSSL_ECHSTORE_free(cp);
154
0
    return NULL;
155
0
}
156
157
void ossl_ech_ctx_clear(OSSL_ECH_CTX *ce)
158
0
{
159
0
    if (ce == NULL)
160
0
        return;
161
0
    OSSL_ECHSTORE_free(ce->es);
162
0
    OPENSSL_free(ce->alpn_outer);
163
0
    return;
164
0
}
165
166
static void ech_free_stashed_key_shares(OSSL_ECH_CONN *ec)
167
0
{
168
0
    size_t i;
169
170
0
    if (ec == NULL)
171
0
        return;
172
0
    for (i = 0; i != ec->num_ks_pkey; i++) {
173
0
        EVP_PKEY_free(ec->ks_pkey[i]);
174
0
        ec->ks_pkey[i] = NULL;
175
0
    }
176
0
    ec->num_ks_pkey = 0;
177
0
    return;
178
0
}
179
180
void ossl_ech_conn_clear(OSSL_ECH_CONN *ec)
181
0
{
182
0
    if (ec == NULL)
183
0
        return;
184
0
    OSSL_ECHSTORE_free(ec->es);
185
0
    OPENSSL_free(ec->outer_hostname);
186
0
    OPENSSL_free(ec->alpn_outer);
187
0
    OPENSSL_free(ec->former_inner);
188
0
    OPENSSL_free(ec->transbuf);
189
0
    OPENSSL_free(ec->innerch);
190
0
    OPENSSL_free(ec->grease_suite);
191
0
    OPENSSL_free(ec->sent);
192
0
    OPENSSL_free(ec->returned);
193
0
    OPENSSL_free(ec->pub);
194
0
    OSSL_HPKE_CTX_free(ec->hpke_ctx);
195
0
    OPENSSL_free(ec->encoded_inner);
196
0
    ech_free_stashed_key_shares(ec);
197
0
    return;
198
0
}
199
200
/* called from ssl/ssl_lib.c: ossl_ssl_connection_new_int */
201
int ossl_ech_conn_init(SSL_CONNECTION *s, SSL_CTX *ctx,
202
    const SSL_METHOD *method)
203
0
{
204
0
    memset(&s->ext.ech, 0, sizeof(s->ext.ech));
205
0
    if (ctx->ext.ech.es != NULL
206
0
        && (s->ext.ech.es = ossl_echstore_dup(ctx->ext.ech.es)) == NULL)
207
0
        goto err;
208
0
    s->ext.ech.cb = ctx->ext.ech.cb;
209
0
    if (ctx->ext.ech.alpn_outer != NULL) {
210
0
        s->ext.ech.alpn_outer = OPENSSL_memdup(ctx->ext.ech.alpn_outer,
211
0
            ctx->ext.ech.alpn_outer_len);
212
0
        if (s->ext.ech.alpn_outer == NULL)
213
0
            goto err;
214
0
        s->ext.ech.alpn_outer_len = ctx->ext.ech.alpn_outer_len;
215
0
    }
216
    /* initialise type/cid to unknown */
217
0
    s->ext.ech.attempted_type = OSSL_ECH_type_unknown;
218
0
    s->ext.ech.attempted_cid = OSSL_ECH_config_id_unset;
219
0
    if (s->ext.ech.es != NULL)
220
0
        s->ext.ech.attempted = 1;
221
0
    if ((ctx->options & SSL_OP_ECH_GREASE) != 0)
222
0
        s->options |= SSL_OP_ECH_GREASE;
223
0
    return 1;
224
0
err:
225
0
    OSSL_ECHSTORE_free(s->ext.ech.es);
226
0
    s->ext.ech.es = NULL;
227
0
    OPENSSL_free(s->ext.ech.alpn_outer);
228
0
    s->ext.ech.alpn_outer = NULL;
229
0
    s->ext.ech.alpn_outer_len = 0;
230
0
    return 0;
231
0
}
232
233
/*
234
 * Assemble the set of ECHConfig values to return as retry-configs.
235
 * The caller (stoc ECH extension handler) needs to OPENSSL_free the rcfgs
236
 * The rcfgs itself is missing the outer length to make it an ECHConfigList
237
 * so the caller adds that using WPACKET functions
238
 */
239
int ossl_ech_get_retry_configs(SSL_CONNECTION *s, unsigned char **rcfgs,
240
    size_t *rcfgslen)
241
0
{
242
0
    OSSL_ECHSTORE *es = NULL;
243
0
    OSSL_ECHSTORE_ENTRY *ee = NULL;
244
0
    int i, num = 0;
245
0
    size_t retslen = 0;
246
0
    unsigned char *tmp = NULL, *rets = NULL;
247
248
0
    if (s == NULL || rcfgs == NULL || rcfgslen == NULL)
249
0
        return 0;
250
0
    es = s->ext.ech.es;
251
0
    if (es != NULL && es->entries != NULL)
252
0
        num = sk_OSSL_ECHSTORE_ENTRY_num(es->entries);
253
0
    for (i = 0; i != num; i++) {
254
0
        ee = sk_OSSL_ECHSTORE_ENTRY_value(es->entries, i);
255
0
        if (ee != NULL && ee->for_retry == OSSL_ECH_FOR_RETRY) {
256
0
            if (ee->encoded_len > SIZE_MAX - retslen)
257
0
                goto err;
258
0
            tmp = (unsigned char *)OPENSSL_realloc(rets,
259
0
                retslen + ee->encoded_len);
260
0
            if (tmp == NULL)
261
0
                goto err;
262
0
            rets = tmp;
263
0
            memcpy(rets + retslen, ee->encoded, ee->encoded_len);
264
0
            retslen += ee->encoded_len;
265
0
        }
266
0
    }
267
0
    *rcfgs = rets;
268
0
    *rcfgslen = retslen;
269
0
    return 1;
270
0
err:
271
0
    OPENSSL_free(rets);
272
0
    *rcfgs = NULL;
273
0
    *rcfgslen = 0;
274
0
    return 0;
275
0
}
276
277
/* GREASEy constants */
278
0
#define OSSL_ECH_MAX_GREASE_PUB 0x100 /* buffer size for 'enc' values */
279
#define OSSL_ECH_MAX_GREASE_CT 0x200 /* max GREASEy ciphertext we'll emit */
280
281
/*
282
 * Send a random value that looks like a real ECH.
283
 *
284
 * We do GREASEing as follows:
285
 *   - always HKDF-SHA256
286
 *   - always AES-128-GCM
287
 *   - random config ID, even for requests to same server in same session
288
 *   - random enc
289
 *   - random looking payload, randomly 144, 176, 208, 240 bytes, no correlation with server
290
 */
291
int ossl_ech_send_grease(SSL_CONNECTION *s, WPACKET *pkt)
292
0
{
293
0
    OSSL_HPKE_SUITE hpke_suite_in = OSSL_HPKE_SUITE_DEFAULT;
294
0
    OSSL_HPKE_SUITE *hpke_suite_in_p = NULL;
295
0
    OSSL_HPKE_SUITE hpke_suite = OSSL_HPKE_SUITE_DEFAULT;
296
0
    size_t pp_at_start = 0, pp_at_end = 0;
297
0
    size_t senderpub_len = OSSL_ECH_MAX_GREASE_PUB;
298
0
    size_t cipher_len = 0, cipher_len_jitter = 0;
299
0
    unsigned char cid, senderpub[OSSL_ECH_MAX_GREASE_PUB];
300
0
    unsigned char cipher[OSSL_ECH_MAX_GREASE_CT];
301
0
    SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
302
303
0
    if (!WPACKET_get_total_written(pkt, &pp_at_start)) {
304
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
305
0
        return 0;
306
0
    }
307
    /* randomly select cipher_len to be one of 144, 176, 208, 244 */
308
0
    if (RAND_bytes_ex(sctx->libctx, &cid, 1, 0) <= 0) {
309
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
310
0
        return 0;
311
0
    }
312
0
    cipher_len_jitter = cid % 4;
313
0
    cipher_len = 144;
314
0
    cipher_len += 32 * cipher_len_jitter;
315
    /* generate a random (1 octet) client id */
316
0
    if (RAND_bytes_ex(sctx->libctx, &cid, 1, 0) <= 0) {
317
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
318
0
        return 0;
319
0
    }
320
0
    s->ext.ech.attempted_cid = cid;
321
0
    hpke_suite_in_p = &hpke_suite;
322
0
    if (s->ext.ech.grease_suite != NULL) {
323
0
        if (OSSL_HPKE_str2suite(s->ext.ech.grease_suite, &hpke_suite_in) != 1) {
324
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
325
0
            return 0;
326
0
        }
327
0
        hpke_suite_in_p = &hpke_suite_in;
328
0
    }
329
0
    if (OSSL_HPKE_get_grease_value(hpke_suite_in_p, &hpke_suite,
330
0
            senderpub, &senderpub_len,
331
0
            cipher, cipher_len,
332
0
            sctx->libctx, sctx->propq)
333
0
        != 1) {
334
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
335
0
        return 0;
336
0
    }
337
0
    if (!WPACKET_put_bytes_u16(pkt, s->ext.ech.attempted_type)
338
0
        || !WPACKET_start_sub_packet_u16(pkt)
339
0
        || !WPACKET_put_bytes_u8(pkt, OSSL_ECH_OUTER_CH_TYPE)
340
0
        || !WPACKET_put_bytes_u16(pkt, hpke_suite.kdf_id)
341
0
        || !WPACKET_put_bytes_u16(pkt, hpke_suite.aead_id)
342
0
        || !WPACKET_put_bytes_u8(pkt, cid)
343
0
        || !WPACKET_sub_memcpy_u16(pkt, senderpub, senderpub_len)
344
0
        || !WPACKET_sub_memcpy_u16(pkt, cipher, cipher_len)
345
0
        || !WPACKET_close(pkt)) {
346
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
347
0
        return 0;
348
0
    }
349
    /* record the ECH sent so we can re-tx same if we hit an HRR */
350
0
    OPENSSL_free(s->ext.ech.sent);
351
0
    if (!WPACKET_get_total_written(pkt, &pp_at_end)) {
352
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
353
0
        return 0;
354
0
    }
355
0
    s->ext.ech.sent_len = pp_at_end - pp_at_start;
356
0
    s->ext.ech.sent = OPENSSL_malloc(s->ext.ech.sent_len);
357
0
    if (s->ext.ech.sent == NULL) {
358
0
        s->ext.ech.sent_len = 0;
359
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
360
0
        return 0;
361
0
    }
362
0
    memcpy(s->ext.ech.sent, WPACKET_get_curr(pkt) - s->ext.ech.sent_len,
363
0
        s->ext.ech.sent_len);
364
0
    s->ext.ech.grease = OSSL_ECH_IS_GREASE;
365
0
    OSSL_TRACE_BEGIN(TLS)
366
0
    {
367
0
        BIO_printf(trc_out, "ECH - sending GREASE\n");
368
0
    }
369
0
    OSSL_TRACE_END(TLS);
370
0
    return 1;
371
0
}
372
373
/*
374
 * Search the ECH store for one that's a match. If no outer_name was set via
375
 * API then we just take the 1st match where we locally support the HPKE suite.
376
 * If OTOH, an outer_name was provided via API then we prefer the first that
377
 * matches that. Name comparison is via case-insensitive exact matches.
378
 */
379
int ossl_ech_pick_matching_cfg(SSL_CONNECTION *s, OSSL_ECHSTORE_ENTRY **ee,
380
    OSSL_HPKE_SUITE *suite)
381
0
{
382
0
    int namematch = 0, nameoverride = 0, suitematch = 0, num, cind = 0;
383
0
    unsigned int csuite = 0, tsuite = 0;
384
0
    size_t hnlen = 0;
385
0
    OSSL_ECHSTORE_ENTRY *lee = NULL, *tee = NULL;
386
0
    OSSL_ECHSTORE *es = NULL;
387
0
    char *hn = NULL;
388
389
0
    if (s == NULL || s->ext.ech.es == NULL || ee == NULL || suite == NULL)
390
0
        return 0;
391
0
    *ee = NULL;
392
0
    es = s->ext.ech.es;
393
0
    if (es->entries == NULL)
394
0
        return 0;
395
0
    num = sk_OSSL_ECHSTORE_ENTRY_num(es->entries);
396
    /* allow API-set pref to override */
397
0
    hn = s->ext.ech.outer_hostname;
398
0
    hnlen = (hn == NULL ? 0 : (unsigned int)strlen(hn));
399
0
    if (hnlen != 0)
400
0
        nameoverride = 1;
401
0
    if (s->ext.ech.no_outer == 1) {
402
0
        hn = NULL;
403
0
        hnlen = 0;
404
0
        nameoverride = 1;
405
0
    }
406
0
    for (cind = 0; cind < num && (suitematch == 0 || namematch == 0); cind++) {
407
0
        lee = sk_OSSL_ECHSTORE_ENTRY_value(es->entries, cind);
408
0
        if (lee == NULL || lee->version != OSSL_ECH_RFC9849_VERSION)
409
0
            continue;
410
0
        if (nameoverride == 1 && hnlen == 0) {
411
0
            namematch = 1;
412
0
        } else {
413
0
            namematch = 0;
414
0
            if (hnlen == 0
415
0
                || (lee->public_name != NULL
416
0
                    && strlen(lee->public_name) == hnlen
417
0
                    && OPENSSL_strncasecmp(hn, (char *)lee->public_name,
418
0
                           hnlen)
419
0
                        == 0))
420
0
                namematch = 1;
421
0
        }
422
0
        suitematch = 0;
423
0
        for (csuite = 0; csuite != lee->nsuites && suitematch == 0; csuite++) {
424
0
            if (OSSL_HPKE_suite_check(lee->suites[csuite]) == 1) {
425
0
                if (tee == NULL) { /* remember 1st suite match for override */
426
0
                    tee = lee;
427
0
                    tsuite = csuite;
428
0
                }
429
0
                suitematch = 1;
430
0
                if (namematch == 1) { /* pick this one if both "fit" */
431
0
                    *suite = lee->suites[csuite];
432
0
                    *ee = lee;
433
0
                    break;
434
0
                }
435
0
            }
436
0
        }
437
0
    }
438
0
    if (tee != NULL && nameoverride == 1
439
0
        && (namematch == 0 || suitematch == 0)) {
440
0
        *suite = tee->suites[tsuite];
441
0
        *ee = tee;
442
0
    } else if (namematch == 0 || suitematch == 0) {
443
        /* no joy */
444
0
        return 0;
445
0
    }
446
0
    if (*ee == NULL || (*ee)->pub_len == 0 || (*ee)->pub == NULL)
447
0
        return 0;
448
0
    return 1;
449
0
}
450
451
/* Make up the ClientHelloInner and EncodedClientHelloInner buffers */
452
int ossl_ech_encode_inner(SSL_CONNECTION *s, unsigned char **encoded,
453
    size_t *encoded_len)
454
0
{
455
0
    int rv = 0;
456
0
    size_t nraws = 0, ind = 0, innerlen = 0;
457
0
    WPACKET inner = { 0 }; /* "fake" pkt for inner */
458
0
    BUF_MEM *inner_mem = NULL;
459
0
    RAW_EXTENSION *raws = NULL;
460
461
    /* basic checks */
462
0
    if (s == NULL)
463
0
        return 0;
464
0
    if (s->ext.ech.es == NULL || s->clienthello == NULL) {
465
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
466
0
        return 0;
467
0
    }
468
0
    if ((inner_mem = BUF_MEM_new()) == NULL
469
0
        || !WPACKET_init(&inner, inner_mem)
470
        /* We don't add the type and 3-octet header as usually done */
471
        /* Add ver/rnd/sess-id/suites to buffer */
472
0
        || !WPACKET_put_bytes_u16(&inner, s->client_version)
473
0
        || !WPACKET_memcpy(&inner, s->ext.ech.client_random, SSL3_RANDOM_SIZE)
474
        /* Session ID is forced to zero in the encoded inner */
475
0
        || !WPACKET_sub_memcpy_u8(&inner, NULL, 0)
476
        /* Ciphers supported */
477
0
        || !WPACKET_start_sub_packet_u16(&inner)
478
0
        || !ssl_cipher_list_to_bytes(s, SSL_get_ciphers(&s->ssl), &inner)
479
0
        || !WPACKET_close(&inner)
480
        /* COMPRESSION */
481
0
        || !WPACKET_start_sub_packet_u8(&inner)
482
        /* Add the NULL compression method */
483
0
        || !WPACKET_put_bytes_u8(&inner, 0)
484
0
        || !WPACKET_close(&inner)) {
485
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
486
0
        goto err;
487
0
    }
488
    /* Now handle extensions */
489
0
    if (!WPACKET_start_sub_packet_u16(&inner)) {
490
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
491
0
        goto err;
492
0
    }
493
    /* Grab a pointer to the already constructed extensions */
494
0
    raws = s->clienthello->pre_proc_exts;
495
0
    nraws = s->clienthello->pre_proc_exts_len;
496
0
    if (raws == NULL || nraws < TLSEXT_IDX_num_builtins) {
497
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
498
0
        goto err;
499
0
    }
500
    /*  We put ECH-compressed stuff first (if any), because we can */
501
0
    if (s->ext.ech.n_outer_only > 0) {
502
0
        if (!WPACKET_put_bytes_u16(&inner, TLSEXT_TYPE_outer_extensions)
503
0
            || !WPACKET_start_sub_packet_u16(&inner)
504
            /* redundant encoding of more-or-less the same thing */
505
0
            || !WPACKET_start_sub_packet_u8(&inner)) {
506
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
507
0
            goto err;
508
0
        }
509
        /* add the types for each of the compressed extensions now */
510
0
        for (ind = 0; ind != s->ext.ech.n_outer_only; ind++) {
511
0
            if (!WPACKET_put_bytes_u16(&inner, s->ext.ech.outer_only[ind])) {
512
0
                SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
513
0
                goto err;
514
0
            }
515
0
        }
516
        /* close the 2 sub-packets with the compressed types */
517
0
        if (!WPACKET_close(&inner) || !WPACKET_close(&inner)) {
518
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
519
0
            goto err;
520
0
        }
521
0
    }
522
    /* now copy the rest, as "proper" exts, into encoded inner */
523
0
    for (ind = 0; ind < TLSEXT_IDX_num_builtins; ind++) {
524
0
        if (raws[ind].present == 0 || ossl_ech_2bcompressed((int)ind) == 1)
525
0
            continue;
526
0
        if (!WPACKET_put_bytes_u16(&inner, raws[ind].type)
527
0
            || !WPACKET_sub_memcpy_u16(&inner, PACKET_data(&raws[ind].data),
528
0
                PACKET_remaining(&raws[ind].data))) {
529
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
530
0
            goto err;
531
0
        }
532
0
    }
533
0
    if (!WPACKET_close(&inner) /* close the encoded inner packet */
534
0
        || !WPACKET_get_length(&inner, &innerlen)) { /* len for inner CH */
535
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
536
0
        goto err;
537
0
    }
538
0
    *encoded = (unsigned char *)inner_mem->data;
539
0
    inner_mem->data = NULL; /* keep BUF_MEM_free happy */
540
0
    *encoded_len = innerlen;
541
    /* and clean up */
542
0
    rv = 1;
543
0
err:
544
0
    WPACKET_cleanup(&inner);
545
0
    BUF_MEM_free(inner_mem);
546
0
    return rv;
547
0
}
548
549
/*
550
 * Find ECH acceptance signal in a SH
551
 * hrr is 1 if this is for an HRR, otherwise for SH
552
 * acbuf is (a preallocated) 8 octet buffer
553
 * shbuf is a pointer to the SH buffer
554
 * shlen is the length of the SH buf
555
 * return: 1 for success, 0 otherwise
556
 */
557
int ossl_ech_find_confirm(SSL_CONNECTION *s, int hrr,
558
    unsigned char acbuf[OSSL_ECH_SIGNAL_LEN])
559
0
{
560
0
    unsigned char *acp = NULL;
561
562
0
    if (hrr == 0) {
563
0
        acp = s->s3.server_random + SSL3_RANDOM_SIZE - OSSL_ECH_SIGNAL_LEN;
564
0
    } else { /* was set in extension handler */
565
0
        if (s->ext.ech.hrrsignal_p == NULL)
566
0
            return 0;
567
0
        acp = s->ext.ech.hrrsignal;
568
0
    }
569
0
    memcpy(acbuf, acp, OSSL_ECH_SIGNAL_LEN);
570
0
    return 1;
571
0
}
572
573
/*
574
 * reset the handshake buffer for transcript after ECH is good
575
 * buf is the data to put into the transcript (inner CH if no HRR)
576
 * blen is the length of buf
577
 * return 1 for success
578
 */
579
int ossl_ech_reset_hs_buffer(SSL_CONNECTION *s, const unsigned char *buf,
580
    size_t blen)
581
0
{
582
0
#ifdef OSSL_ECH_SUPERVERBOSE
583
0
    ossl_ech_pbuf("RESET transcript to", buf, blen);
584
0
#endif
585
0
    if (s->s3.handshake_buffer != NULL) {
586
0
        if (BIO_reset(s->s3.handshake_buffer) < 0)
587
0
            return 0;
588
0
    } else {
589
0
        s->s3.handshake_buffer = BIO_new(BIO_s_mem());
590
0
        if (s->s3.handshake_buffer == NULL)
591
0
            return 0;
592
0
        (void)BIO_set_close(s->s3.handshake_buffer, BIO_CLOSE);
593
0
    }
594
0
    EVP_MD_CTX_free(s->s3.handshake_dgst);
595
0
    s->s3.handshake_dgst = NULL;
596
    /* providing nothing at all is a real use (mid-HRR) */
597
0
    if (buf != NULL && blen > 0)
598
0
        BIO_write(s->s3.handshake_buffer, (void *)buf, (int)blen);
599
0
    return 1;
600
0
}
601
602
/*
603
 * To control the number of zeros added after an EncodedClientHello - we pad
604
 * to a target number of octets or, if there are naturally more, to a number
605
 * divisible by the defined increment (we also do the spec-recommended SNI
606
 * padding thing first)
607
 */
608
0
#define OSSL_ECH_PADDING_TARGET 128 /* ECH cleartext padded to at least this */
609
0
#define OSSL_ECH_PADDING_INCREMENT 32 /* ECH padded to a multiple of this */
610
611
/*
612
 * figure out how much padding for cleartext (on client)
613
 * ee is the chosen ECHConfig
614
 * return overall length to use including padding or zero on error
615
 *
616
 * "Recommended" inner SNI padding scheme as per spec (section 6.1.3)
617
 * Might remove the mnl stuff later - overall message padding seems
618
 * better really, BUT... we might want to keep this if others (e.g.
619
 * browsers) do it so as to not stand out compared to them.
620
 *
621
 * The "+ 9" constant below is from the specification and is the
622
 * expansion comparing a string length to an encoded SNI extension.
623
 * Same is true of the 31/32 formula below.
624
 *
625
 * Note that the AEAD tag will be added later, so if we e.g. have
626
 * a padded cleartext of 128 octets, the ciphertext will be 144
627
 * octets.
628
 */
629
size_t ossl_ech_calc_padding(SSL_CONNECTION *s, OSSL_ECHSTORE_ENTRY *ee,
630
    size_t encoded_len)
631
0
{
632
0
    size_t length_of_padding = 0, length_with_snipadding = 0;
633
0
    size_t innersnipadding = 0, length_with_padding = 0;
634
0
    size_t mnl = 0, isnilen = 0;
635
636
0
    if (s == NULL || ee == NULL)
637
0
        return 0;
638
0
    mnl = ee->max_name_length;
639
0
    if (mnl != 0) {
640
        /* do weirder padding if SNI present in inner */
641
0
        if (s->ext.hostname != NULL) {
642
0
            isnilen = strlen(s->ext.hostname) + 9;
643
0
            innersnipadding = (mnl > isnilen) ? (int)(mnl - isnilen) : 0;
644
0
        } else {
645
0
            innersnipadding = (int)mnl + 9;
646
0
        }
647
0
    }
648
    /* padding is after the inner client hello has been encoded */
649
0
    length_with_snipadding = innersnipadding + (int)encoded_len;
650
0
    length_of_padding = 31 - ((length_with_snipadding - 1) % 32);
651
0
    length_with_padding = (int)encoded_len + length_of_padding
652
0
        + innersnipadding;
653
    /*
654
     * Finally - make sure final result is longer than padding target
655
     * and a multiple of our padding increment.
656
     * This is a local addition - we might want to take it out if it makes
657
     * us stick out; or if we take out the above more (uselessly:-)
658
     * complicated scheme above, we may only need this in the end.
659
     */
660
0
    if ((length_with_padding % OSSL_ECH_PADDING_INCREMENT) != 0)
661
0
        length_with_padding += OSSL_ECH_PADDING_INCREMENT
662
0
            - (length_with_padding % OSSL_ECH_PADDING_INCREMENT);
663
0
    while (length_with_padding < OSSL_ECH_PADDING_TARGET)
664
0
        length_with_padding += OSSL_ECH_PADDING_INCREMENT;
665
0
    OSSL_TRACE_BEGIN(TLS)
666
0
    {
667
0
        BIO_printf(trc_out, "EAAE: padding: mnl: %zu, lws: %zu "
668
0
                            "lop: %zu, clear_len (len with padding): %zu, orig: %zu\n",
669
0
            mnl, length_with_snipadding, length_of_padding,
670
0
            length_with_padding, encoded_len);
671
0
    }
672
0
    OSSL_TRACE_END(TLS);
673
0
    return length_with_padding;
674
0
}
675
676
/*
677
 * Calculate AAD and do ECH encryption
678
 * pkt is the packet to send
679
 * return 1 for success, other otherwise
680
 *
681
 * 1. Make up the AAD: the encoded outer, with ECH ciphertext octets zero'd
682
 * 2. Do the encryption
683
 * 3. Put the ECH back into the encoding
684
 * 4. Encode the outer (again!)
685
 */
686
int ossl_ech_aad_and_encrypt(SSL_CONNECTION *s, WPACKET *pkt)
687
0
{
688
0
    int rv = 0;
689
0
    size_t cipherlen = 0, aad_len = 0, mypub_len = 0, clear_len = 0;
690
0
    size_t encoded_inner_len = 0;
691
0
    unsigned char *clear = NULL, *aad = NULL, *mypub = NULL;
692
0
    unsigned char *encoded_inner = NULL, *cipher_loc = NULL;
693
694
0
    if (s == NULL)
695
0
        return 0;
696
0
    if (s->ext.ech.es == NULL || s->ext.ech.es->entries == NULL
697
0
        || pkt == NULL || s->ssl.ctx == NULL) {
698
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
699
0
        goto err;
700
0
    }
701
    /* values calculated in tls_construct_ctos_ech */
702
0
    encoded_inner = s->ext.ech.encoded_inner;
703
0
    encoded_inner_len = s->ext.ech.encoded_inner_len;
704
0
    clear_len = s->ext.ech.clearlen;
705
0
    cipherlen = s->ext.ech.cipherlen;
706
0
    if (!WPACKET_get_total_written(pkt, &aad_len) || aad_len < 4) {
707
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
708
0
        goto err;
709
0
    }
710
0
    aad_len -= 4; /* ECH/HPKE aad starts after type + 3-octet len */
711
0
    aad = WPACKET_get_curr(pkt) - aad_len;
712
    /* where we'll replace zeros with ciphertext */
713
0
    cipher_loc = aad + s->ext.ech.cipher_offset;
714
    /*
715
     * close the extensions of the CH - we skipped doing this
716
     * earlier when encoding extensions, to allow for adding the
717
     * ECH here (when doing ECH) - see tls_construct_extensions()
718
     * towards the end
719
     */
720
0
    if (!WPACKET_close(pkt)) {
721
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
722
0
        goto err;
723
0
    }
724
0
#ifdef OSSL_ECH_SUPERVERBOSE
725
0
    ossl_ech_pbuf("EAAE: aad", aad, aad_len);
726
0
#endif
727
0
    clear = OPENSSL_zalloc(clear_len); /* zeros incl. padding */
728
0
    if (clear == NULL) {
729
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
730
0
        goto err;
731
0
    }
732
0
    memcpy(clear, encoded_inner, encoded_inner_len);
733
0
#ifdef OSSL_ECH_SUPERVERBOSE
734
0
    ossl_ech_pbuf("EAAE: padded clear", clear, clear_len);
735
0
#endif
736
    /* we're done with this now */
737
0
    OPENSSL_free(s->ext.ech.encoded_inner);
738
0
    s->ext.ech.encoded_inner = NULL;
739
0
    rv = OSSL_HPKE_seal(s->ext.ech.hpke_ctx, cipher_loc,
740
0
        &cipherlen, aad, aad_len, clear, clear_len);
741
0
    OPENSSL_free(clear);
742
0
    if (rv != 1) {
743
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
744
0
        goto err;
745
0
    }
746
0
#ifdef OSSL_ECH_SUPERVERBOSE
747
0
    ossl_ech_pbuf("EAAE: cipher", cipher_loc, cipherlen);
748
0
    ossl_ech_pbuf("EAAE: hpke mypub", mypub, mypub_len);
749
    /* re-use aad_len for tracing */
750
0
    WPACKET_get_total_written(pkt, &aad_len);
751
0
    ossl_ech_pbuf("EAAE pkt aftr", WPACKET_get_curr(pkt) - aad_len, aad_len);
752
0
#endif
753
0
    return 1;
754
0
err:
755
0
    return 0;
756
0
}
757
758
/*
759
 * print info about the ECH-status of an SSL connection
760
 * out is the BIO to use (e.g. stdout/whatever)
761
 * selector OSSL_ECH_SELECT_ALL or just one of the SSL_ECH values
762
 */
763
void ossl_ech_status_print(BIO *out, SSL_CONNECTION *s, int selector)
764
0
{
765
0
    int num = 0, i, has_priv, for_retry;
766
0
    size_t j;
767
0
    time_t secs = 0;
768
0
    char *pn = NULL, *ec = NULL;
769
0
    OSSL_ECHSTORE *es = NULL;
770
771
0
#ifdef OSSL_ECH_SUPERVERBOSE
772
0
    BIO_printf(out, "ech_status_print\n");
773
0
    BIO_printf(out, "s=%p\n", (void *)s);
774
0
#endif
775
0
    BIO_printf(out, "ech_attempted=%d\n", s->ext.ech.attempted);
776
0
    BIO_printf(out, "ech_attempted_type=0x%4x\n",
777
0
        s->ext.ech.attempted_type);
778
0
    if (s->ext.ech.attempted_cid == OSSL_ECH_config_id_unset)
779
0
        BIO_printf(out, "ech_atttempted_cid is unset\n");
780
0
    else
781
0
        BIO_printf(out, "ech_atttempted_cid=0x%02x\n",
782
0
            s->ext.ech.attempted_cid);
783
0
    BIO_printf(out, "ech_done=%d\n", s->ext.ech.done);
784
0
    BIO_printf(out, "ech_grease=%d\n", s->ext.ech.grease);
785
0
#ifdef OSSL_ECH_SUPERVERBOSE
786
0
    BIO_printf(out, "HRR=%d\n", s->hello_retry_request);
787
0
#endif
788
0
    BIO_printf(out, "ech_backend=%d\n", s->ext.ech.backend);
789
0
    BIO_printf(out, "ech_success=%d\n", s->ext.ech.success);
790
0
    es = s->ext.ech.es;
791
0
    if (es == NULL || es->entries == NULL) {
792
0
        BIO_printf(out, "ECH cfg=NONE\n");
793
0
    } else {
794
0
        num = sk_OSSL_ECHSTORE_ENTRY_num(es->entries);
795
0
        BIO_printf(out, "%d ECHConfig values loaded\n", num);
796
0
        for (i = 0; i != num; i++) {
797
0
            if (selector != OSSL_ECHSTORE_ALL && selector != i)
798
0
                continue;
799
0
            BIO_printf(out, "cfg(%d): ", i);
800
0
            if (OSSL_ECHSTORE_get1_info(es, i, &secs, &pn, &ec,
801
0
                    &has_priv, &for_retry)
802
0
                != 1) {
803
0
                OPENSSL_free(pn); /* just in case */
804
0
                OPENSSL_free(ec);
805
0
                continue;
806
0
            }
807
0
            BIO_printf(out, "ECH entry: %d public_name: %s age: %lld%s\n",
808
0
                i, pn, (long long)secs, has_priv ? " (has private key)" : "");
809
0
            BIO_printf(out, "\t%s\n", ec);
810
0
            OPENSSL_free(pn);
811
0
            OPENSSL_free(ec);
812
0
        }
813
0
    }
814
0
    if (s->ext.ech.returned) {
815
0
        BIO_printf(out, "ret=");
816
0
        for (j = 0; j != s->ext.ech.returned_len; j++) {
817
0
            if (j != 0 && j % 16 == 0)
818
0
                BIO_printf(out, "\n    ");
819
0
            BIO_printf(out, "%02x:", (unsigned)(s->ext.ech.returned[j]));
820
0
        }
821
0
        BIO_printf(out, "\n");
822
0
    }
823
0
    return;
824
0
}
825
826
/*
827
 * Swap the inner and outer after ECH success on the client
828
 * return 0 for error, 1 for success
829
 */
830
int ossl_ech_swaperoo(SSL_CONNECTION *s)
831
0
{
832
0
    unsigned char *curr_buf = NULL;
833
0
    size_t curr_buflen = 0;
834
835
0
    if (s == NULL)
836
0
        return 0;
837
0
#ifdef OSSL_ECH_SUPERVERBOSE
838
0
    ossl_ech_ptranscript(s, "ech_swaperoo, b4");
839
0
#endif
840
    /* un-stash inner key share(s) */
841
0
    if (ossl_ech_unstash_keyshares(s) != 1) {
842
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
843
0
        return 0;
844
0
    }
845
    /*
846
     * When not doing HRR... fix up the transcript to reflect the inner CH.
847
     * If there's a client hello at the start of the buffer, then that's
848
     * the outer CH and we want to replace that with the inner. We need to
849
     * be careful that there could be early data or a server hello following
850
     * and we can't lose that.
851
     *
852
     * For HRR... HRR processing code has already done the necessary.
853
     */
854
0
    if (s->hello_retry_request == SSL_HRR_NONE) {
855
0
        BIO *handbuf = s->s3.handshake_buffer;
856
0
        PACKET pkt, subpkt;
857
0
        unsigned int mt;
858
859
0
        s->s3.handshake_buffer = NULL;
860
0
        if (ssl3_init_finished_mac(s) == 0) {
861
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
862
0
            BIO_free(handbuf);
863
0
            return 0;
864
0
        }
865
0
        if (ssl3_finish_mac(s, s->ext.ech.innerch, s->ext.ech.innerch_len) == 0) {
866
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
867
0
            BIO_free(handbuf);
868
0
            return 0;
869
0
        }
870
0
        curr_buflen = BIO_get_mem_data(handbuf, &curr_buf);
871
0
        if (PACKET_buf_init(&pkt, curr_buf, curr_buflen)
872
0
            && PACKET_get_1(&pkt, &mt)
873
0
            && mt == SSL3_MT_CLIENT_HELLO
874
0
            && PACKET_remaining(&pkt) >= 3) {
875
0
            if (!PACKET_get_length_prefixed_3(&pkt, &subpkt)) {
876
0
                SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
877
0
                BIO_free(handbuf);
878
0
                return 0;
879
0
            }
880
0
            if (PACKET_remaining(&pkt) > 0) {
881
0
                if (ssl3_finish_mac(s, PACKET_data(&pkt), PACKET_remaining(&pkt)) == 0) {
882
0
                    SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
883
0
                    BIO_free(handbuf);
884
0
                    return 0;
885
0
                }
886
0
            }
887
0
            BIO_free(handbuf);
888
0
        }
889
0
    }
890
0
#ifdef OSSL_ECH_SUPERVERBOSE
891
0
    ossl_ech_ptranscript(s, "ech_swaperoo, after");
892
0
#endif
893
    /* Declare victory! */
894
0
    s->ext.ech.attempted = 1;
895
0
    s->ext.ech.success = 1;
896
0
    s->ext.ech.done = 1;
897
0
    s->ext.ech.grease = OSSL_ECH_NOT_GREASE;
898
    /* time to call an ECH callback, if there's one */
899
0
    if (s->ext.ech.es != NULL && s->ext.ech.done == 1
900
0
        && s->hello_retry_request != SSL_HRR_PENDING
901
0
        && s->ext.ech.cb != NULL) {
902
0
        char pstr[OSSL_ECH_PBUF_SIZE + 1] = { 0 };
903
0
        BIO *biom = BIO_new(BIO_s_mem());
904
0
        unsigned int cbrv = 0;
905
906
0
        if (biom == NULL) {
907
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
908
0
            return 0;
909
0
        }
910
0
        ossl_ech_status_print(biom, s, OSSL_ECHSTORE_ALL);
911
0
        BIO_read(biom, pstr, OSSL_ECH_PBUF_SIZE);
912
0
        cbrv = s->ext.ech.cb(&s->ssl, pstr);
913
0
        BIO_free(biom);
914
0
        if (cbrv != 1) {
915
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
916
0
            return 0;
917
0
        }
918
0
    }
919
0
    return 1;
920
0
}
921
922
/*
923
 * do the HKDF for ECH acceptance checking
924
 * md is the h/s hash
925
 * for_hrr is 1 if we're doing a HRR
926
 * hashval/hashlen is the transcript hash
927
 * hoval is the output, with the ECH acceptance signal
928
 * return 1 for good, 0 for error
929
 */
930
static int ech_hkdf_extract_wrap(SSL_CONNECTION *s, EVP_MD *md, int for_hrr,
931
    unsigned char *hashval, size_t hashlen,
932
    unsigned char hoval[OSSL_ECH_SIGNAL_LEN])
933
0
{
934
0
    int rv = 0;
935
0
    unsigned char notsecret[EVP_MAX_MD_SIZE], zeros[EVP_MAX_MD_SIZE];
936
0
    size_t retlen = 0, labellen = 0;
937
0
    EVP_PKEY_CTX *pctx = NULL;
938
0
    const char *label = NULL;
939
0
    unsigned char *p = NULL;
940
941
0
    if (for_hrr == 1) {
942
0
        label = OSSL_ECH_HRR_CONFIRM_STRING;
943
0
        labellen = sizeof(OSSL_ECH_HRR_CONFIRM_STRING) - 1;
944
0
    } else {
945
0
        label = OSSL_ECH_ACCEPT_CONFIRM_STRING;
946
0
        labellen = sizeof(OSSL_ECH_ACCEPT_CONFIRM_STRING) - 1;
947
0
    }
948
0
#ifdef OSSL_ECH_SUPERVERBOSE
949
0
    ossl_ech_pbuf("cc: label", (unsigned char *)label, labellen);
950
0
#endif
951
0
    memset(zeros, 0, EVP_MAX_MD_SIZE);
952
    /* We don't seem to have an hkdf-extract that's exposed by libcrypto */
953
0
    pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
954
0
    if (pctx == NULL
955
0
        || EVP_PKEY_derive_init(pctx) != 1
956
0
        || EVP_PKEY_CTX_hkdf_mode(pctx,
957
0
               EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY)
958
0
            != 1
959
0
        || EVP_PKEY_CTX_set_hkdf_md(pctx, md) != 1) {
960
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
961
0
        goto err;
962
0
    }
963
    /* pick correct client_random */
964
0
    if (s->server)
965
0
        p = s->s3.client_random;
966
0
    else
967
0
        p = s->ext.ech.client_random;
968
0
#ifdef OSSL_ECH_SUPERVERBOSE
969
0
    ossl_ech_pbuf("cc: client_random", p, SSL3_RANDOM_SIZE);
970
0
#endif
971
0
    if (EVP_PKEY_CTX_set1_hkdf_key(pctx, p, SSL3_RANDOM_SIZE) != 1
972
0
        || EVP_PKEY_CTX_set1_hkdf_salt(pctx, zeros, (int)hashlen) != 1
973
0
        || EVP_PKEY_derive(pctx, NULL, &retlen) != 1
974
0
        || hashlen != retlen
975
0
        || EVP_PKEY_derive(pctx, notsecret, &retlen) != 1) {
976
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
977
0
        goto err;
978
0
    }
979
0
#ifdef OSSL_ECH_SUPERVERBOSE
980
0
    ossl_ech_pbuf("cc: notsecret", notsecret, hashlen);
981
0
#endif
982
0
    if (hashlen < OSSL_ECH_SIGNAL_LEN
983
0
        || !tls13_hkdf_expand(s, md, notsecret,
984
0
            (const unsigned char *)label, labellen,
985
0
            hashval, hashlen, hoval,
986
0
            OSSL_ECH_SIGNAL_LEN, 1)) {
987
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
988
0
        goto err;
989
0
    }
990
0
    rv = 1;
991
0
err:
992
0
    EVP_PKEY_CTX_free(pctx);
993
0
    return rv;
994
0
}
995
996
/*
997
 * ECH accept_confirmation calculation
998
 * for_hrr is 1 if this is for an HRR, otherwise for SH
999
 * acbuf is an 8 octet buffer for the confirmation value
1000
 * shlen is the server hello length
1001
 * return: 1 for success, 0 otherwise
1002
 *
1003
 * This is a magic value in the ServerHello.random lower 8 octets
1004
 * that is used to signal that the inner worked.
1005
 *
1006
 * As per spec:
1007
 *
1008
 * accept_confirmation = HKDF-Expand-Label(
1009
 *         HKDF-Extract(0, ClientHelloInner.random),
1010
 *         "ech accept confirmation",
1011
 *         transcript_ech_conf,
1012
 *         8)
1013
 *
1014
 * transcript_ech_conf = ClientHelloInner..ServerHello
1015
 *         with last 8 octets of ServerHello.random==0x00
1016
 *
1017
 * and with differences due to HRR
1018
 */
1019
int ossl_ech_calc_confirm(SSL_CONNECTION *s, int for_hrr,
1020
    unsigned char acbuf[OSSL_ECH_SIGNAL_LEN],
1021
    const size_t shlen)
1022
0
{
1023
0
    int rv = 0;
1024
0
    EVP_MD_CTX *ctx = NULL;
1025
0
    EVP_MD *md = NULL;
1026
0
    unsigned char *tbuf = NULL, *conf_loc = NULL;
1027
0
    unsigned char *fixedshbuf = NULL;
1028
0
    size_t fixedshbuf_len = 0, tlen = 0, chend = 0;
1029
    /* shoffset is: 4 + 2 + 32 - 8 */
1030
0
    size_t shoffset = SSL3_HM_HEADER_LENGTH + sizeof(uint16_t)
1031
0
        + SSL3_RANDOM_SIZE - OSSL_ECH_SIGNAL_LEN;
1032
0
    unsigned int hashlen = 0;
1033
0
    unsigned char hashval[EVP_MAX_MD_SIZE];
1034
0
    SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
1035
1036
0
    if ((md = (EVP_MD *)ssl_handshake_md(s)) == NULL) {
1037
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_ECH_REQUIRED);
1038
0
        goto end;
1039
0
    }
1040
0
    if (ossl_ech_intbuf_fetch(s, &tbuf, &tlen) != 1) {
1041
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_ECH_REQUIRED);
1042
0
        goto end;
1043
0
    }
1044
0
    chend = tlen - shlen - 4;
1045
0
    fixedshbuf_len = shlen + 4;
1046
0
    if (s->server) {
1047
0
        chend = tlen - shlen;
1048
0
        fixedshbuf_len = shlen;
1049
0
    }
1050
0
#ifdef OSSL_ECH_SUPERVERBOSE
1051
0
    ossl_ech_pbuf("cx: tbuf b4-b4", tbuf, tlen);
1052
0
#endif
1053
    /* put zeros in correct place */
1054
0
    if (for_hrr == 0) { /* zap magic octets at fixed place for SH */
1055
0
        conf_loc = tbuf + chend + shoffset;
1056
0
    } else {
1057
0
        if (s->server == 1) { /* we get to say where we put ECH:-) */
1058
0
            conf_loc = tbuf + tlen - OSSL_ECH_SIGNAL_LEN;
1059
0
        } else {
1060
0
            if (s->ext.ech.hrrsignal_p == NULL) {
1061
                /* No ECH found so we'll exit, but set random output */
1062
0
                if (RAND_bytes_ex(sctx->libctx, acbuf,
1063
0
                        OSSL_ECH_SIGNAL_LEN, 0)
1064
0
                    <= 0) {
1065
0
                    SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_ECH_REQUIRED);
1066
0
                    goto end;
1067
0
                }
1068
0
                rv = 1;
1069
0
                goto end;
1070
0
            }
1071
0
            conf_loc = s->ext.ech.hrrsignal_p;
1072
0
        }
1073
0
    }
1074
0
    memset(conf_loc, 0, OSSL_ECH_SIGNAL_LEN);
1075
0
#ifdef OSSL_ECH_SUPERVERBOSE
1076
0
    ossl_ech_pbuf("cx: tbuf after", tbuf, tlen);
1077
0
#endif
1078
0
    if ((ctx = EVP_MD_CTX_new()) == NULL
1079
0
        || EVP_DigestInit_ex(ctx, md, NULL) <= 0
1080
0
        || EVP_DigestUpdate(ctx, tbuf, tlen) <= 0
1081
0
        || EVP_DigestFinal_ex(ctx, hashval, &hashlen) <= 0) {
1082
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
1083
0
        goto end;
1084
0
    }
1085
0
    EVP_MD_CTX_free(ctx);
1086
0
    ctx = NULL;
1087
0
#ifdef OSSL_ECH_SUPERVERBOSE
1088
0
    ossl_ech_pbuf("cx: hashval", hashval, hashlen);
1089
0
#endif
1090
    /* calculate and set the final output */
1091
0
    if (ech_hkdf_extract_wrap(s, md, for_hrr, hashval, hashlen, acbuf) != 1) {
1092
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
1093
0
        goto end;
1094
0
    }
1095
0
#ifdef OSSL_ECH_SUPERVERBOSE
1096
0
    ossl_ech_pbuf("cx: result", acbuf, OSSL_ECH_SIGNAL_LEN);
1097
0
#endif
1098
    /* put confirm value back into transcript */
1099
0
    memcpy(conf_loc, acbuf, OSSL_ECH_SIGNAL_LEN);
1100
    /* on a server, we need to reset the hs buffer now */
1101
0
    if (s->server && s->hello_retry_request == SSL_HRR_NONE)
1102
0
        ossl_ech_reset_hs_buffer(s, s->ext.ech.innerch, s->ext.ech.innerch_len);
1103
0
    if (s->server && s->hello_retry_request == SSL_HRR_COMPLETE)
1104
0
        ossl_ech_reset_hs_buffer(s, tbuf, tlen - fixedshbuf_len);
1105
0
    rv = 1;
1106
0
end:
1107
0
    OPENSSL_free(fixedshbuf);
1108
0
    EVP_MD_CTX_free(ctx);
1109
0
    return rv;
1110
0
}
1111
1112
/*!
1113
 * Given a CH find the offsets of the session id, extensions and ECH
1114
 * pkt is the CH
1115
 * sessid_off points to offset of session_id length
1116
 * exts_off points to offset of extensions
1117
 * ech_off points to offset of ECH
1118
 * echtype points to the ext type of the ECH
1119
 * inner 1 if the ECH is marked as an inner, 0 for outer
1120
 * sni_off points to offset of (outer) SNI
1121
 * return 1 for success, other otherwise
1122
 *
1123
 * Offsets are set to zero if relevant thing not found.
1124
 * Offsets are returned to the type or length field in question.
1125
 *
1126
 * Note: input here is untrusted!
1127
 */
1128
int ossl_ech_get_ch_offsets(SSL_CONNECTION *s, PACKET *pkt, size_t *sessid_off,
1129
    size_t *exts_off, size_t *ech_off, uint16_t *echtype,
1130
    int *inner, size_t *sni_off)
1131
0
{
1132
0
    const unsigned char *ch = NULL;
1133
0
    size_t ch_len = 0, exts_len = 0, sni_len = 0, ech_len = 0;
1134
1135
0
    if (s == NULL)
1136
0
        return 0;
1137
0
    if (pkt == NULL || sessid_off == NULL || exts_off == NULL
1138
0
        || ech_off == NULL || echtype == NULL || inner == NULL
1139
0
        || sni_off == NULL) {
1140
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1141
0
        return 0;
1142
0
    }
1143
    /* check if we've already done the work */
1144
0
    if (s->ext.ech.ch_offsets_done == 1) {
1145
0
        *sessid_off = s->ext.ech.sessid_off;
1146
0
        *exts_off = s->ext.ech.exts_off;
1147
0
        *ech_off = s->ext.ech.ech_off;
1148
0
        *echtype = s->ext.ech.echtype;
1149
0
        *inner = s->ext.ech.inner;
1150
0
        *sni_off = s->ext.ech.sni_off;
1151
0
        return 1;
1152
0
    }
1153
0
    *sessid_off = 0;
1154
0
    *exts_off = 0;
1155
0
    *ech_off = 0;
1156
0
    *echtype = OSSL_ECH_type_unknown;
1157
0
    *sni_off = 0;
1158
    /* do the work */
1159
0
    ch_len = PACKET_remaining(pkt);
1160
0
    if (PACKET_peek_bytes(pkt, &ch, ch_len) != 1) {
1161
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1162
0
        return 0;
1163
0
    }
1164
0
    if (ossl_ech_helper_get_ch_offsets(ch, ch_len, sessid_off, exts_off,
1165
0
            &exts_len, ech_off, echtype, &ech_len,
1166
0
            sni_off, &sni_len, inner)
1167
0
        != 1) {
1168
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1169
0
        return 0;
1170
0
    }
1171
0
#ifdef OSSL_ECH_SUPERVERBOSE
1172
0
    OSSL_TRACE_BEGIN(TLS)
1173
0
    {
1174
0
        BIO_printf(trc_out, "orig CH/ECH type: %4x\n", *echtype);
1175
0
    }
1176
0
    OSSL_TRACE_END(TLS);
1177
0
    ossl_ech_pbuf("orig CH", (unsigned char *)ch, ch_len);
1178
0
    ossl_ech_pbuf("orig CH exts", (unsigned char *)ch + *exts_off, exts_len);
1179
0
    ossl_ech_pbuf("orig CH/ECH", (unsigned char *)ch + *ech_off, ech_len);
1180
0
    ossl_ech_pbuf("orig CH SNI", (unsigned char *)ch + *sni_off, sni_len);
1181
0
#endif
1182
0
    s->ext.ech.sessid_off = *sessid_off;
1183
0
    s->ext.ech.exts_off = *exts_off;
1184
0
    s->ext.ech.ech_off = *ech_off;
1185
0
    s->ext.ech.echtype = *echtype;
1186
0
    s->ext.ech.inner = *inner;
1187
0
    s->ext.ech.sni_off = *sni_off;
1188
0
    s->ext.ech.ch_offsets_done = 1;
1189
0
    return 1;
1190
0
}
1191
1192
static void ossl_ech_encch_free(OSSL_ECH_ENCCH *tbf)
1193
0
{
1194
0
    if (tbf == NULL)
1195
0
        return;
1196
0
    OPENSSL_free(tbf->enc);
1197
0
    OPENSSL_free(tbf->payload);
1198
0
    return;
1199
0
}
1200
1201
/*
1202
 * decode outer sni value so we can trace it
1203
 * osni_str is the string-form of the SNI
1204
 * opd is the outer CH buffer
1205
 * opl is the length of the above
1206
 * snioffset is where we find the outer SNI
1207
 *
1208
 * The caller doesn't have to free the osni_str.
1209
 */
1210
static int ech_get_outer_sni(SSL_CONNECTION *s, char **osni_str,
1211
    const unsigned char *opd, size_t opl,
1212
    size_t snioffset)
1213
0
{
1214
0
    PACKET wrap, osni;
1215
0
    unsigned int type, osnilen;
1216
1217
0
    if (snioffset >= opl
1218
0
        || !PACKET_buf_init(&wrap, opd + snioffset, opl - snioffset)
1219
0
        || !PACKET_get_net_2(&wrap, &type)
1220
0
        || type != 0
1221
0
        || !PACKET_get_net_2(&wrap, &osnilen)
1222
0
        || !PACKET_get_sub_packet(&wrap, &osni, osnilen)
1223
0
        || tls_parse_ctos_server_name(s, &osni, 0, NULL, 0) != 1)
1224
0
        return 0;
1225
0
    OPENSSL_free(s->ext.ech.outer_hostname);
1226
0
    *osni_str = s->ext.ech.outer_hostname = s->ext.hostname;
1227
    /* clean up what the ECH-unaware parse func above left behind */
1228
0
    s->ext.hostname = NULL;
1229
0
    s->servername_done = 0;
1230
0
    return 1;
1231
0
}
1232
1233
/*
1234
 * decode EncryptedClientHello extension value
1235
 * pkt contains the ECH value as a PACKET
1236
 * retext is the returned decoded structure
1237
 * payload_offset is the offset to the ciphertext
1238
 * return 1 for good, 0 for bad
1239
 *
1240
 * SSLfatal called from inside, as needed
1241
 */
1242
static int ech_decode_inbound_ech(SSL_CONNECTION *s, PACKET *pkt,
1243
    OSSL_ECH_ENCCH **retext,
1244
    size_t *payload_offset)
1245
0
{
1246
0
    unsigned int innerorouter = 0xff;
1247
0
    unsigned int pval_tmp; /* tmp placeholder of value from packet */
1248
0
    OSSL_ECH_ENCCH *extval = NULL;
1249
0
    const unsigned char *startofech = NULL;
1250
1251
    /*
1252
     * Decode the inbound ECH value.
1253
     *  enum { outer(0), inner(1) } ECHClientHelloType;
1254
     *  struct {
1255
     *     ECHClientHelloType type;
1256
     *     select (ECHClientHello.type) {
1257
     *         case outer:
1258
     *             HpkeSymmetricCipherSuite cipher_suite;
1259
     *             uint8 config_id;
1260
     *             opaque enc<0..2^16-1>;
1261
     *             opaque payload<1..2^16-1>;
1262
     *         case inner:
1263
     *             Empty;
1264
     *     };
1265
     *  } ECHClientHello;
1266
     */
1267
0
    startofech = PACKET_data(pkt);
1268
0
    extval = OPENSSL_zalloc(sizeof(OSSL_ECH_ENCCH));
1269
0
    if (extval == NULL)
1270
0
        goto err;
1271
0
    if (!PACKET_get_1(pkt, &innerorouter)) {
1272
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1273
0
        goto err;
1274
0
    }
1275
0
    if (innerorouter != OSSL_ECH_OUTER_CH_TYPE) {
1276
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1277
0
        goto err;
1278
0
    }
1279
0
    if (!PACKET_get_net_2(pkt, &pval_tmp)) {
1280
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1281
0
        goto err;
1282
0
    }
1283
0
    extval->kdf_id = pval_tmp & 0xffff;
1284
0
    if (!PACKET_get_net_2(pkt, &pval_tmp)) {
1285
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1286
0
        goto err;
1287
0
    }
1288
0
    extval->aead_id = pval_tmp & 0xffff;
1289
    /* config id */
1290
0
    if (!PACKET_copy_bytes(pkt, &extval->config_id, 1)) {
1291
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1292
0
        goto err;
1293
0
    }
1294
0
#ifdef OSSL_ECH_SUPERVERBOSE
1295
0
    ossl_ech_pbuf("EARLY config id", &extval->config_id, 1);
1296
0
#endif
1297
0
    s->ext.ech.attempted_cid = extval->config_id;
1298
    /* enc - the client's public share */
1299
0
    if (!PACKET_get_net_2(pkt, &pval_tmp)) {
1300
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1301
0
        goto err;
1302
0
    }
1303
0
    if (pval_tmp > OSSL_ECH_MAX_GREASE_PUB) {
1304
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1305
0
        goto err;
1306
0
    }
1307
0
    if (pval_tmp > PACKET_remaining(pkt)) {
1308
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1309
0
        goto err;
1310
0
    }
1311
0
    if (pval_tmp == 0 && s->hello_retry_request != SSL_HRR_PENDING) {
1312
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1313
0
        goto err;
1314
0
    } else if (pval_tmp > 0 && s->hello_retry_request == SSL_HRR_PENDING) {
1315
0
        unsigned char *tmpenc = NULL;
1316
1317
        /*
1318
         * if doing HRR, client should only send this when GREASEing
1319
         * and it should be the same value as 1st time, so we'll check
1320
         * that
1321
         */
1322
0
        if (s->ext.ech.pub == NULL || s->ext.ech.pub_len == 0) {
1323
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1324
0
            goto err;
1325
0
        }
1326
0
        if (pval_tmp != s->ext.ech.pub_len) {
1327
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1328
0
            goto err;
1329
0
        }
1330
0
        tmpenc = OPENSSL_malloc(pval_tmp);
1331
0
        if (tmpenc == NULL)
1332
0
            goto err;
1333
0
        if (!PACKET_copy_bytes(pkt, tmpenc, pval_tmp)) {
1334
0
            OPENSSL_free(tmpenc);
1335
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1336
0
            goto err;
1337
0
        }
1338
0
        if (memcmp(tmpenc, s->ext.ech.pub, pval_tmp) != 0) {
1339
0
            OPENSSL_free(tmpenc);
1340
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1341
0
            goto err;
1342
0
        }
1343
0
        OPENSSL_free(tmpenc);
1344
0
    } else if (pval_tmp == 0 && s->hello_retry_request == SSL_HRR_PENDING) {
1345
0
        if (s->ext.ech.pub == NULL || s->ext.ech.pub_len == 0) {
1346
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1347
0
            goto err;
1348
0
        }
1349
0
        extval->enc_len = s->ext.ech.pub_len;
1350
0
        extval->enc = OPENSSL_malloc(extval->enc_len);
1351
0
        if (extval->enc == NULL)
1352
0
            goto err;
1353
0
        memcpy(extval->enc, s->ext.ech.pub, extval->enc_len);
1354
0
    } else {
1355
0
        extval->enc_len = pval_tmp;
1356
0
        extval->enc = OPENSSL_malloc(pval_tmp);
1357
0
        if (extval->enc == NULL)
1358
0
            goto err;
1359
0
        if (!PACKET_copy_bytes(pkt, extval->enc, pval_tmp)) {
1360
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1361
0
            goto err;
1362
0
        }
1363
        /* squirrel away that value in case of future HRR */
1364
0
        OPENSSL_free(s->ext.ech.pub);
1365
0
        s->ext.ech.pub_len = extval->enc_len;
1366
0
        s->ext.ech.pub = OPENSSL_malloc(extval->enc_len);
1367
0
        if (s->ext.ech.pub == NULL)
1368
0
            goto err;
1369
0
        memcpy(s->ext.ech.pub, extval->enc, extval->enc_len);
1370
0
    }
1371
    /* payload - the encrypted CH */
1372
0
    *payload_offset = PACKET_data(pkt) - startofech;
1373
0
    if (!PACKET_get_net_2(pkt, &pval_tmp)) {
1374
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1375
0
        goto err;
1376
0
    }
1377
0
    if (pval_tmp > OSSL_ECH_MAX_PAYLOAD_LEN) {
1378
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1379
0
        goto err;
1380
0
    }
1381
0
    if (pval_tmp == 0 || pval_tmp > PACKET_remaining(pkt)) {
1382
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1383
0
        goto err;
1384
0
    }
1385
0
    extval->payload_len = pval_tmp;
1386
0
    extval->payload = OPENSSL_malloc(pval_tmp);
1387
0
    if (extval->payload == NULL)
1388
0
        goto err;
1389
0
    if (!PACKET_copy_bytes(pkt, extval->payload, pval_tmp)) {
1390
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1391
0
        goto err;
1392
0
    }
1393
0
    *retext = extval;
1394
0
    return 1;
1395
0
err:
1396
0
    if (extval != NULL) {
1397
0
        ossl_ech_encch_free(extval);
1398
0
        OPENSSL_free(extval);
1399
0
        extval = NULL;
1400
0
    }
1401
0
    return 0;
1402
0
}
1403
1404
/*
1405
 * find outers if any, and do initial checks
1406
 * pkt is the encoded inner
1407
 * outers is the array of outer ext types
1408
 * n_outers is the number of outers found
1409
 * return 1 for good, 0 for error
1410
 *
1411
 * recall we're dealing with recovered ECH plaintext here so
1412
 * the content must be a TLSv1.3 ECH encoded inner
1413
 */
1414
static int ech_find_outers(SSL_CONNECTION *s, PACKET *pkt,
1415
    uint16_t *outers, size_t *n_outers)
1416
0
{
1417
0
    const unsigned char *pp_tmp;
1418
0
    unsigned int pi_tmp, extlens, etype, elen, olen;
1419
0
    int outers_found = 0;
1420
0
    size_t i;
1421
0
    PACKET op;
1422
1423
0
    PACKET_null_init(&op);
1424
    /* chew up the packet to extensions */
1425
0
    if (!PACKET_get_net_2(pkt, &pi_tmp)
1426
0
        || pi_tmp != TLS1_2_VERSION
1427
0
        || !PACKET_get_bytes(pkt, &pp_tmp, SSL3_RANDOM_SIZE)
1428
0
        || !PACKET_get_1(pkt, &pi_tmp)
1429
0
        || pi_tmp != 0x00 /* zero'd session id */
1430
0
        || !PACKET_get_net_2(pkt, &pi_tmp) /* ciphersuite len */
1431
0
        || !PACKET_get_bytes(pkt, &pp_tmp, pi_tmp) /* suites */
1432
0
        || !PACKET_get_1(pkt, &pi_tmp) /* compression meths */
1433
0
        || pi_tmp != 0x01 /* 1 octet of comressions */
1434
0
        || !PACKET_get_1(pkt, &pi_tmp) /* compression meths */
1435
0
        || pi_tmp != 0x00 /* 1 octet of no comressions */
1436
0
        || !PACKET_get_net_2(pkt, &extlens) /* len(extensions) */
1437
0
        || extlens == 0) { /* no extensions! */
1438
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1439
0
        goto err;
1440
0
    }
1441
0
    while (PACKET_remaining(pkt) > 0 && outers_found == 0) {
1442
0
        if (!PACKET_get_net_2(pkt, &etype)) {
1443
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1444
0
            goto err;
1445
0
        }
1446
0
        if (etype == TLSEXT_TYPE_outer_extensions) {
1447
0
            outers_found = 1;
1448
0
            if (!PACKET_get_length_prefixed_2(pkt, &op)) {
1449
0
                SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1450
0
                goto err;
1451
0
            }
1452
0
        } else { /* skip over */
1453
0
            if (!PACKET_get_net_2(pkt, &elen)
1454
0
                || !PACKET_get_bytes(pkt, &pp_tmp, elen)) {
1455
0
                SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1456
0
                goto err;
1457
0
            }
1458
0
        }
1459
0
    }
1460
1461
0
    if (outers_found == 0) { /* which is fine! */
1462
0
        *n_outers = 0;
1463
0
        return 1;
1464
0
    }
1465
    /*
1466
     * outers has a silly internal length as well and that better
1467
     * be one less than the extension length and an even number
1468
     * and we only support a certain max of outers
1469
     */
1470
0
    if (!PACKET_get_1(&op, &olen)
1471
0
        || olen % 2 == 1
1472
0
        || olen / 2 > OSSL_ECH_OUTERS_MAX) {
1473
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1474
0
        goto err;
1475
0
    }
1476
0
    *n_outers = olen / 2;
1477
0
    for (i = 0; i != *n_outers; i++) {
1478
0
        if (!PACKET_get_net_2(&op, &pi_tmp)
1479
0
            || pi_tmp == TLSEXT_TYPE_outer_extensions) {
1480
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1481
0
            goto err;
1482
0
        }
1483
0
        outers[i] = (uint16_t)pi_tmp;
1484
0
    }
1485
0
    return 1;
1486
0
err:
1487
0
    return 0;
1488
0
}
1489
1490
/*
1491
 * copy one extension from outer to inner
1492
 * di is the reconstituted inner CH
1493
 * type2copy is the outer type to copy
1494
 * extsbuf is the outer extensions buffer
1495
 * extslen is the outer extensions buffer length
1496
 * return 1 for good 0 for error
1497
 */
1498
static int ech_copy_ext(SSL_CONNECTION *s, WPACKET *di, uint16_t type2copy,
1499
    const unsigned char *extsbuf, size_t extslen)
1500
0
{
1501
0
    PACKET exts;
1502
0
    unsigned int etype, elen;
1503
0
    const unsigned char *eval;
1504
1505
0
    if (PACKET_buf_init(&exts, extsbuf, extslen) != 1) {
1506
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
1507
0
        goto err;
1508
0
    }
1509
0
    while (PACKET_remaining(&exts) > 0) {
1510
0
        if (!PACKET_get_net_2(&exts, &etype)
1511
0
            || !PACKET_get_net_2(&exts, &elen)
1512
0
            || !PACKET_get_bytes(&exts, &eval, elen)) {
1513
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1514
0
            goto err;
1515
0
        }
1516
0
        if (etype == type2copy) {
1517
0
            if (!WPACKET_put_bytes_u16(di, etype)
1518
0
                || !WPACKET_put_bytes_u16(di, elen)
1519
0
                || !WPACKET_memcpy(di, eval, elen)) {
1520
0
                SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1521
0
                goto err;
1522
0
            }
1523
0
            return 1;
1524
0
        }
1525
0
    }
1526
    /* we didn't find such an extension - that's an error */
1527
0
    SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1528
0
err:
1529
0
    return 0;
1530
0
}
1531
1532
/*
1533
 * reconstitute the inner CH from encoded inner and outers
1534
 * di is the reconstituted inner CH
1535
 * ei is the encoded inner
1536
 * ob is the outer CH as a buffer
1537
 * ob_len is the size of the above
1538
 * outers is the array of outer ext types
1539
 * n_outers is the number of outers found
1540
 * return 1 for good, 0 for error
1541
 */
1542
static int ech_reconstitute_inner(SSL_CONNECTION *s, WPACKET *di, PACKET *ei,
1543
    const unsigned char *ob, size_t ob_len,
1544
    uint16_t *outers, size_t n_outers)
1545
0
{
1546
0
    const unsigned char *pp_tmp, *eval, *outer_exts;
1547
0
    unsigned int pi_tmp, etype, elen, outer_extslen;
1548
0
    PACKET outer, session_id;
1549
0
    size_t i;
1550
1551
0
    if (PACKET_buf_init(&outer, ob, ob_len) != 1) {
1552
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
1553
0
        goto err;
1554
0
    }
1555
    /* read/write from encoded inner to decoded inner with help from outer */
1556
0
    if (/* version */
1557
0
        !PACKET_get_net_2(&outer, &pi_tmp)
1558
0
        || !PACKET_get_net_2(ei, &pi_tmp)
1559
0
        || !WPACKET_put_bytes_u16(di, pi_tmp)
1560
1561
        /* client random */
1562
0
        || !PACKET_get_bytes(&outer, &pp_tmp, SSL3_RANDOM_SIZE)
1563
0
        || !PACKET_get_bytes(ei, &pp_tmp, SSL3_RANDOM_SIZE)
1564
0
        || !WPACKET_memcpy(di, pp_tmp, SSL3_RANDOM_SIZE)
1565
1566
        /* session ID */
1567
0
        || !PACKET_get_1(ei, &pi_tmp)
1568
0
        || !PACKET_get_length_prefixed_1(&outer, &session_id)
1569
0
        || !WPACKET_start_sub_packet_u8(di)
1570
0
        || (PACKET_remaining(&session_id) != 0
1571
0
            && !WPACKET_memcpy(di, PACKET_data(&session_id),
1572
0
                PACKET_remaining(&session_id)))
1573
0
        || !WPACKET_close(di)
1574
1575
        /* ciphersuites */
1576
0
        || !PACKET_get_net_2(&outer, &pi_tmp) /* ciphersuite len */
1577
0
        || !PACKET_get_bytes(&outer, &pp_tmp, pi_tmp) /* suites */
1578
0
        || !PACKET_get_net_2(ei, &pi_tmp) /* ciphersuite len */
1579
0
        || !PACKET_get_bytes(ei, &pp_tmp, pi_tmp) /* suites */
1580
0
        || !WPACKET_put_bytes_u16(di, pi_tmp)
1581
0
        || !WPACKET_memcpy(di, pp_tmp, pi_tmp)
1582
1583
        /* compression len & meth */
1584
0
        || !PACKET_get_net_2(ei, &pi_tmp)
1585
0
        || !PACKET_get_net_2(&outer, &pi_tmp)
1586
0
        || !WPACKET_put_bytes_u16(di, pi_tmp)) {
1587
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1588
0
        goto err;
1589
0
    }
1590
    /* handle simple, but unlikely, case first */
1591
0
    if (n_outers == 0) {
1592
0
        if (PACKET_remaining(ei) == 0)
1593
0
            return 1; /* no exts is theoretically possible */
1594
0
        if (!PACKET_get_net_2(ei, &pi_tmp) /* len(extensions) */
1595
0
            || !PACKET_get_bytes(ei, &pp_tmp, pi_tmp)
1596
0
            || !WPACKET_put_bytes_u16(di, pi_tmp)
1597
0
            || !WPACKET_memcpy(di, pp_tmp, pi_tmp)) {
1598
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1599
0
            goto err;
1600
0
        }
1601
0
        WPACKET_close(di);
1602
0
        return 1;
1603
0
    }
1604
    /*
1605
     * general case, copy one by one from inner, 'till we hit
1606
     * the outers extension, then copy one by one from outer
1607
     */
1608
0
    if (!PACKET_get_net_2(ei, &pi_tmp) /* len(extensions) */
1609
0
        || !PACKET_get_net_2(&outer, &outer_extslen)
1610
0
        || !PACKET_get_bytes(&outer, &outer_exts, outer_extslen)
1611
0
        || !WPACKET_start_sub_packet_u16(di)) {
1612
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1613
0
        goto err;
1614
0
    }
1615
0
    while (PACKET_remaining(ei) > 0) {
1616
0
        if (!PACKET_get_net_2(ei, &etype)
1617
0
            || !PACKET_get_net_2(ei, &elen)
1618
0
            || !PACKET_get_bytes(ei, &eval, elen)) {
1619
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1620
0
            goto err;
1621
0
        }
1622
0
        if (etype == TLSEXT_TYPE_outer_extensions) {
1623
0
            for (i = 0; i != n_outers; i++) {
1624
0
                if (ech_copy_ext(s, di, outers[i],
1625
0
                        outer_exts, outer_extslen)
1626
0
                    != 1)
1627
                    /* SSLfatal called already */
1628
0
                    goto err;
1629
0
            }
1630
0
        } else {
1631
0
            if (!WPACKET_put_bytes_u16(di, etype)
1632
0
                || !WPACKET_put_bytes_u16(di, elen)
1633
0
                || !WPACKET_memcpy(di, eval, elen)) {
1634
0
                SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1635
0
                goto err;
1636
0
            }
1637
0
        }
1638
0
    }
1639
0
    WPACKET_close(di);
1640
0
    return 1;
1641
0
err:
1642
0
    WPACKET_cleanup(di);
1643
0
    return 0;
1644
0
}
1645
1646
/*
1647
 * After successful ECH decrypt, we decode, decompress etc.
1648
 * ob is the outer CH as a buffer
1649
 * ob_len is the size of the above
1650
 * return 1 for success, error otherwise
1651
 *
1652
 * We need the outer CH as a buffer (ob, below) so we can
1653
 * ECH-decompress.
1654
 * The plaintext we start from is in encoded_innerch
1655
 * and our final decoded, decompressed buffer will end up
1656
 * in innerch (which'll then be further processed).
1657
 * That further processing includes all existing decoding
1658
 * checks so we should be fine wrt fuzzing without having
1659
 * to make all checks here (e.g. we can assume that the
1660
 * protocol version, NULL compression etc are correct here -
1661
 * if not, those'll be caught later).
1662
 * Note: there are a lot of literal values here, but it's
1663
 * not clear that changing those to #define'd symbols will
1664
 * help much - a change to the length of a type or from a
1665
 * 2 octet length to longer would seem unlikely.
1666
 */
1667
static int ech_decode_inner(SSL_CONNECTION *s, const unsigned char *ob,
1668
    size_t ob_len, unsigned char *encoded_inner,
1669
    size_t encoded_inner_len)
1670
0
{
1671
0
    int rv = 0;
1672
0
    PACKET ei; /* encoded inner */
1673
0
    BUF_MEM *di_mem = NULL;
1674
0
    uint16_t outers[OSSL_ECH_OUTERS_MAX]; /* compressed extension types */
1675
0
    size_t n_outers = 0;
1676
0
    WPACKET di = { 0 }; /* "fake" pkt for inner */
1677
1678
0
    if (encoded_inner == NULL || ob == NULL || ob_len == 0) {
1679
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
1680
0
        return 0;
1681
0
    }
1682
0
    if ((di_mem = BUF_MEM_new()) == NULL
1683
0
        || !BUF_MEM_grow(di_mem, SSL3_RT_MAX_PLAIN_LENGTH)
1684
0
        || !WPACKET_init(&di, di_mem)
1685
0
        || !WPACKET_put_bytes_u8(&di, SSL3_MT_CLIENT_HELLO)
1686
0
        || !WPACKET_start_sub_packet_u24(&di)
1687
0
        || !PACKET_buf_init(&ei, encoded_inner, encoded_inner_len)) {
1688
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
1689
0
        goto err;
1690
0
    }
1691
0
#ifdef OSSL_ECH_SUPERVERBOSE
1692
0
    memset(outers, -1, sizeof(outers)); /* fill with known values for debug */
1693
0
#endif
1694
1695
    /* 1. check for outers and make initial checks of those */
1696
0
    if (ech_find_outers(s, &ei, outers, &n_outers) != 1)
1697
0
        goto err; /* SSLfatal called already */
1698
1699
    /* 2. reconstitute inner CH */
1700
    /* reset ei */
1701
0
    if (PACKET_buf_init(&ei, encoded_inner, encoded_inner_len) != 1) {
1702
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
1703
0
        goto err;
1704
0
    }
1705
0
    if (ech_reconstitute_inner(s, &di, &ei, ob, ob_len, outers, n_outers) != 1)
1706
0
        goto err; /* SSLfatal called already */
1707
    /* 3. store final inner CH in connection */
1708
0
    WPACKET_close(&di);
1709
0
    if (!WPACKET_get_length(&di, &s->ext.ech.innerch_len)) {
1710
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
1711
0
        goto err;
1712
0
    }
1713
0
    OPENSSL_free(s->ext.ech.innerch);
1714
0
    s->ext.ech.innerch = (unsigned char *)di_mem->data;
1715
0
    di_mem->data = NULL;
1716
0
    rv = 1;
1717
0
err:
1718
0
    WPACKET_cleanup(&di);
1719
0
    BUF_MEM_free(di_mem);
1720
0
    return rv;
1721
0
}
1722
1723
/*
1724
 * wrapper for hpke_dec just to save code repetition
1725
 * ee is the selected ECH_STORE entry
1726
 * the_ech is the value sent by the client
1727
 * aad_len is the length of the AAD to use
1728
 * aad is the AAD to use
1729
 * forhrr is 0 if not hrr, 1 if this is for 2nd CH
1730
 * innerlen points to the size of the recovered plaintext
1731
 * return pointer to plaintext or NULL (if error)
1732
 *
1733
 * The plaintext returned is allocated here and must
1734
 * be freed by the caller later.
1735
 */
1736
static unsigned char *hpke_decrypt_encch(SSL_CONNECTION *s,
1737
    OSSL_ECHSTORE_ENTRY *ee,
1738
    OSSL_ECH_ENCCH *the_ech,
1739
    size_t aad_len, unsigned char *aad,
1740
    int forhrr, size_t *innerlen)
1741
0
{
1742
0
    size_t cipherlen = 0;
1743
0
    unsigned char *cipher = NULL;
1744
0
    size_t senderpublen = 0;
1745
0
    unsigned char *senderpub = NULL;
1746
0
    size_t clearlen = 0;
1747
0
    unsigned char *clear = NULL;
1748
0
    int hpke_mode = OSSL_HPKE_MODE_BASE;
1749
0
    OSSL_HPKE_SUITE hpke_suite = OSSL_HPKE_SUITE_DEFAULT;
1750
0
    unsigned char info[OSSL_ECH_MAX_INFO_LEN];
1751
0
    size_t info_len = OSSL_ECH_MAX_INFO_LEN;
1752
0
    int rv = 0;
1753
0
    OSSL_HPKE_CTX *hctx = NULL;
1754
0
    SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
1755
0
#ifdef OSSL_ECH_SUPERVERBOSE
1756
0
    size_t publen = 0;
1757
0
    unsigned char *pub = NULL;
1758
0
#endif
1759
1760
0
    if (ee == NULL || ee->nsuites == 0)
1761
0
        return NULL;
1762
0
    cipherlen = the_ech->payload_len;
1763
0
    cipher = the_ech->payload;
1764
0
    senderpublen = the_ech->enc_len;
1765
0
    senderpub = the_ech->enc;
1766
0
    hpke_suite.aead_id = the_ech->aead_id;
1767
0
    hpke_suite.kdf_id = the_ech->kdf_id;
1768
0
    clearlen = cipherlen; /* small overestimate */
1769
0
    clear = OPENSSL_malloc(clearlen);
1770
0
    if (clear == NULL)
1771
0
        return NULL;
1772
    /* The kem_id will be the same for all suites in the entry */
1773
0
    hpke_suite.kem_id = ee->suites[0].kem_id;
1774
0
#ifdef OSSL_ECH_SUPERVERBOSE
1775
0
    publen = ee->pub_len;
1776
0
    pub = ee->pub;
1777
0
    ossl_ech_pbuf("aad", aad, aad_len);
1778
0
    ossl_ech_pbuf("my local pub", pub, publen);
1779
0
    ossl_ech_pbuf("senderpub", senderpub, senderpublen);
1780
0
    ossl_ech_pbuf("cipher", cipher, cipherlen);
1781
0
#endif
1782
0
    if (ossl_ech_make_enc_info(ee->encoded, ee->encoded_len,
1783
0
            info, &info_len)
1784
0
        != 1) {
1785
0
        OPENSSL_free(clear);
1786
0
        return NULL;
1787
0
    }
1788
0
#ifdef OSSL_ECH_SUPERVERBOSE
1789
0
    ossl_ech_pbuf("info", info, info_len);
1790
0
#endif
1791
0
    OSSL_TRACE_BEGIN(TLS)
1792
0
    {
1793
0
        BIO_printf(trc_out,
1794
0
            "hpke_dec suite: kem: %04x, kdf: %04x, aead: %04x\n",
1795
0
            hpke_suite.kem_id, hpke_suite.kdf_id, hpke_suite.aead_id);
1796
0
    }
1797
0
    OSSL_TRACE_END(TLS);
1798
    /*
1799
     * We may generate externally visible OpenSSL errors
1800
     * if decryption fails (which is normal) but we'll
1801
     * ignore those as we might be dealing with a GREASEd
1802
     * ECH. To do that we need to now ignore some errors
1803
     * so we use ERR_set_mark() then later ERR_pop_to_mark().
1804
     */
1805
0
    ERR_set_mark();
1806
    /* Use OSSL_HPKE_* APIs */
1807
0
    hctx = OSSL_HPKE_CTX_new(hpke_mode, hpke_suite, OSSL_HPKE_ROLE_RECEIVER,
1808
0
        sctx->libctx, sctx->propq);
1809
0
    if (hctx == NULL)
1810
0
        goto clearerrs;
1811
0
    rv = OSSL_HPKE_decap(hctx, senderpub, senderpublen, ee->keyshare,
1812
0
        info, info_len);
1813
0
    if (rv != 1)
1814
0
        goto clearerrs;
1815
0
    if (forhrr == 1) {
1816
0
        rv = OSSL_HPKE_CTX_set_seq(hctx, 1);
1817
0
        if (rv != 1) {
1818
            /* don't clear this error - GREASE can't cause it */
1819
0
            ERR_clear_last_mark();
1820
0
            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
1821
0
            goto end;
1822
0
        }
1823
0
    }
1824
0
    rv = OSSL_HPKE_open(hctx, clear, &clearlen, aad, aad_len,
1825
0
        cipher, cipherlen);
1826
0
clearerrs:
1827
    /* close off our error handling */
1828
0
    ERR_pop_to_mark();
1829
0
end:
1830
0
    OSSL_HPKE_CTX_free(hctx);
1831
0
    if (rv != 1) {
1832
0
        OSSL_TRACE(TLS, "HPKE decryption failed somehow\n");
1833
0
        OPENSSL_free(clear);
1834
0
        return NULL;
1835
0
    }
1836
0
#ifdef OSSL_ECH_SUPERVERBOSE
1837
0
    ossl_ech_pbuf("padded clear", clear, clearlen);
1838
0
#endif
1839
    /* we need to remove possible (actually, v. likely) padding */
1840
0
    *innerlen = clearlen;
1841
0
    if (ee->version == OSSL_ECH_RFC9849_VERSION) {
1842
        /* draft-13 pads after the encoded CH with zeros */
1843
0
        size_t extsoffset = 0;
1844
0
        size_t extslen = 0;
1845
0
        size_t ch_len = 0;
1846
0
        size_t startofsessid = 0;
1847
0
        size_t echoffset = 0; /* offset of start of ECH within CH */
1848
0
        uint16_t echtype = OSSL_ECH_type_unknown; /* type of ECH seen */
1849
0
        size_t outersnioffset = 0; /* offset to SNI in outer */
1850
0
        int innerflag = -1;
1851
0
        PACKET innerchpkt;
1852
1853
0
        if (PACKET_buf_init(&innerchpkt, clear, clearlen) != 1) {
1854
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1855
0
            goto paderr;
1856
0
        }
1857
        /* reset the offsets, as we move from outer to inner CH */
1858
0
        s->ext.ech.ch_offsets_done = 0;
1859
0
        rv = ossl_ech_get_ch_offsets(s, &innerchpkt, &startofsessid,
1860
0
            &extsoffset, &echoffset, &echtype,
1861
0
            &innerflag, &outersnioffset);
1862
0
        if (rv != 1) {
1863
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1864
0
            goto paderr;
1865
0
        }
1866
        /* odd form of check below just for emphasis */
1867
0
        if ((extsoffset + 1) > clearlen) {
1868
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1869
0
            goto paderr;
1870
0
        }
1871
0
        extslen = (unsigned char)(clear[extsoffset]) * 256
1872
0
            + (unsigned char)(clear[extsoffset + 1]);
1873
0
        ch_len = extsoffset + 2 + extslen;
1874
        /* the check below protects us from bogus data */
1875
0
        if (ch_len > clearlen) {
1876
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1877
0
            goto paderr;
1878
0
        }
1879
        /*
1880
         * The RFC calls for that padding to be all zeros. I'm not so
1881
         * keen on that being a good idea to enforce, so we'll make it
1882
         * easy to not do so (but check by default)
1883
         */
1884
0
#define CHECKZEROS
1885
0
#ifdef CHECKZEROS
1886
0
        {
1887
0
            size_t zind = 0;
1888
1889
0
            if (*innerlen < ch_len)
1890
0
                goto paderr;
1891
0
            for (zind = ch_len; zind != *innerlen; zind++) {
1892
0
                if (clear[zind] != 0x00)
1893
0
                    goto paderr;
1894
0
            }
1895
0
        }
1896
0
#endif
1897
0
        *innerlen = ch_len;
1898
0
#ifdef OSSL_ECH_SUPERVERBOSE
1899
0
        ossl_ech_pbuf("unpadded clear", clear, *innerlen);
1900
0
#endif
1901
0
        return clear;
1902
0
    }
1903
0
paderr:
1904
0
    OPENSSL_free(clear);
1905
0
    return NULL;
1906
0
}
1907
1908
/*
1909
 * If an ECH is present, attempt decryption
1910
 * outerpkt is the packet with the outer CH
1911
 * newpkt is the packet with the decrypted inner CH
1912
 * return 1 for success, other otherwise
1913
 *
1914
 * If decryption succeeds, the caller can swap the inner and outer
1915
 * CHs so that all further processing will only take into account
1916
 * the inner CH.
1917
 *
1918
 * The fact that decryption worked is signalled to the caller
1919
 * via s->ext.ech.success
1920
 *
1921
 * This function is called early, (hence the name:-), before
1922
 * the outer CH decoding has really started, so we need to be
1923
 * careful peeking into the packet
1924
 *
1925
 * The plan:
1926
 * 1. check if there's an ECH
1927
 * 2. trial-decrypt or check if config matches one loaded
1928
 * 3. if decrypt fails tee-up GREASE
1929
 * 4. if decrypt worked, decode and de-compress cleartext to
1930
 *    make up real inner CH for later processing
1931
 */
1932
int ossl_ech_early_decrypt(SSL_CONNECTION *s, PACKET *outerpkt, PACKET *newpkt)
1933
0
{
1934
0
    int num = 0, cfgind = -1, foundcfg = 0, forhrr = 0, innerflag = -1;
1935
0
    OSSL_ECH_ENCCH *extval = NULL;
1936
0
    PACKET echpkt;
1937
0
    const unsigned char *startofech = NULL, *opd = NULL;
1938
0
    size_t echlen = 0, clearlen = 0, aad_len = 0;
1939
0
    unsigned char *clear = NULL, *aad = NULL;
1940
    /* offsets of things within CH */
1941
0
    size_t startofsessid = 0, startofexts = 0, echoffset = 0, opl = 0;
1942
0
    size_t outersnioffset = 0, startofciphertext = 0, lenofciphertext = 0;
1943
0
    uint16_t echtype = OSSL_ECH_type_unknown; /* type of ECH seen */
1944
0
    char *osni_str = NULL;
1945
0
    OSSL_ECHSTORE *es = NULL;
1946
0
    OSSL_ECHSTORE_ENTRY *ee = NULL;
1947
1948
0
    if (s == NULL)
1949
0
        return 0;
1950
0
    if (outerpkt == NULL || newpkt == NULL) {
1951
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1952
0
        return 0;
1953
0
    }
1954
    /* find offsets - on success, outputs are safe to use */
1955
0
    if (ossl_ech_get_ch_offsets(s, outerpkt, &startofsessid, &startofexts,
1956
0
            &echoffset, &echtype, &innerflag,
1957
0
            &outersnioffset)
1958
0
        != 1) {
1959
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1960
0
        return 0;
1961
0
    }
1962
0
    if (echoffset == 0 || echtype != TLSEXT_TYPE_ech)
1963
0
        return 1; /* ECH not present or wrong version */
1964
0
    if (innerflag == 1) {
1965
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1966
0
        return 0;
1967
0
    }
1968
0
    s->ext.ech.attempted = 1; /* Remember that we got an ECH */
1969
0
    s->ext.ech.attempted_type = echtype;
1970
0
    if (s->hello_retry_request == SSL_HRR_PENDING)
1971
0
        forhrr = 1; /* set forhrr if that's correct */
1972
0
    opl = PACKET_remaining(outerpkt);
1973
0
    opd = PACKET_data(outerpkt);
1974
0
    s->tmp_session_id_len = opd[startofsessid]; /* grab the session id */
1975
0
    if (s->tmp_session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH
1976
0
        || startofsessid + 1 + s->tmp_session_id_len > opl) {
1977
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1978
0
        goto err;
1979
0
    }
1980
0
    memcpy(s->tmp_session_id, &opd[startofsessid + 1], s->tmp_session_id_len);
1981
0
    if (outersnioffset > 0) { /* Grab the outer SNI for tracing */
1982
0
        if (ech_get_outer_sni(s, &osni_str, opd, opl, outersnioffset) != 1
1983
0
            || osni_str == NULL) {
1984
0
            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1985
0
            goto err;
1986
0
        }
1987
0
        OSSL_TRACE1(TLS, "EARLY: outer SNI of %s\n", osni_str);
1988
0
    } else {
1989
0
        OSSL_TRACE(TLS, "EARLY: no sign of an outer SNI\n");
1990
0
    }
1991
0
    if (echoffset > opl - 4) {
1992
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1993
0
        goto err;
1994
0
    }
1995
0
    startofech = &opd[echoffset + 4];
1996
0
    echlen = opd[echoffset + 2] * 256 + opd[echoffset + 3];
1997
0
    if (echlen > opl - echoffset - 4) {
1998
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
1999
0
        goto err;
2000
0
    }
2001
0
    if (PACKET_buf_init(&echpkt, startofech, echlen) != 1) {
2002
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
2003
0
        goto err;
2004
0
    }
2005
0
    if (ech_decode_inbound_ech(s, &echpkt, &extval, &startofciphertext) != 1)
2006
0
        goto err; /* SSLfatal already called if needed */
2007
    /*
2008
     * startofciphertext is within the ECH value and after the length of the
2009
     * ciphertext, so we need to bump it by the offset of ECH within the CH
2010
     * plus the ECH type (2 octets) and length (also 2 octets) and that
2011
     * ciphertext length (another 2 octets) for a total of 6 octets
2012
     */
2013
0
    startofciphertext += echoffset + 6;
2014
0
    lenofciphertext = extval->payload_len;
2015
0
    aad_len = opl;
2016
0
    if (aad_len < startofciphertext + lenofciphertext) {
2017
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
2018
0
        goto err;
2019
0
    }
2020
0
    aad = OPENSSL_memdup(opd, aad_len);
2021
0
    if (aad == NULL) {
2022
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
2023
0
        goto err;
2024
0
    }
2025
0
    memset(aad + startofciphertext, 0, lenofciphertext);
2026
0
#ifdef OSSL_ECH_SUPERVERBOSE
2027
0
    ossl_ech_pbuf("EARLY aad", aad, aad_len);
2028
0
#endif
2029
0
    s->ext.ech.grease = OSSL_ECH_GREASE_UNKNOWN;
2030
0
    if (s->ext.ech.es == NULL) {
2031
0
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
2032
0
        goto err;
2033
0
    }
2034
0
    es = s->ext.ech.es;
2035
0
    num = (es == NULL || es->entries == NULL ? 0
2036
0
                                             : sk_OSSL_ECHSTORE_ENTRY_num(es->entries));
2037
0
    for (cfgind = 0; cfgind != num; cfgind++) {
2038
0
        ee = sk_OSSL_ECHSTORE_ENTRY_value(es->entries, cfgind);
2039
0
        OSSL_TRACE_BEGIN(TLS)
2040
0
        {
2041
0
            BIO_printf(trc_out,
2042
0
                "EARLY: rx'd config id (%x) ==? %d-th configured (%x)\n",
2043
0
                extval->config_id, cfgind, ee->config_id);
2044
0
        }
2045
0
        OSSL_TRACE_END(TLS);
2046
0
        if (extval->config_id == ee->config_id) {
2047
0
            foundcfg = 1;
2048
0
            break;
2049
0
        }
2050
0
    }
2051
0
    if (foundcfg == 1) {
2052
0
        clear = hpke_decrypt_encch(s, ee, extval, aad_len, aad,
2053
0
            forhrr, &clearlen);
2054
0
        if (clear == NULL)
2055
0
            s->ext.ech.grease = OSSL_ECH_IS_GREASE;
2056
0
    }
2057
    /* if still needed, trial decryptions */
2058
0
    if (clear == NULL && (s->options & SSL_OP_ECH_TRIALDECRYPT)) {
2059
0
        foundcfg = 0; /* reset as we're trying again */
2060
0
        for (cfgind = 0; cfgind != num; cfgind++) {
2061
0
            ee = sk_OSSL_ECHSTORE_ENTRY_value(es->entries, cfgind);
2062
0
            clear = hpke_decrypt_encch(s, ee, extval,
2063
0
                aad_len, aad, forhrr, &clearlen);
2064
0
            if (clear != NULL) {
2065
0
                foundcfg = 1;
2066
0
                s->ext.ech.grease = OSSL_ECH_NOT_GREASE;
2067
0
                break;
2068
0
            }
2069
0
        }
2070
0
    }
2071
0
    OPENSSL_free(aad);
2072
0
    aad = NULL;
2073
0
    s->ext.ech.done = 1; /* decrypting worked or not, but we're done now */
2074
0
    s->ext.ech.grease = OSSL_ECH_IS_GREASE; /* if decrypt fails tee-up GREASE */
2075
0
    s->ext.ech.success = 0;
2076
0
    if (clear != NULL) {
2077
0
        s->ext.ech.grease = OSSL_ECH_NOT_GREASE;
2078
0
        s->ext.ech.success = 1;
2079
0
    }
2080
0
    OSSL_TRACE_BEGIN(TLS)
2081
0
    {
2082
0
        BIO_printf(trc_out, "EARLY: success: %d, assume_grease: %d, "
2083
0
                            "foundcfg: %d, cfgind: %d, clearlen: %zd, clear %p\n",
2084
0
            s->ext.ech.success, s->ext.ech.grease, foundcfg,
2085
0
            cfgind, clearlen, (void *)clear);
2086
0
    }
2087
0
    OSSL_TRACE_END(TLS);
2088
0
#ifdef OSSL_ECH_SUPERVERBOSE
2089
0
    if (foundcfg == 1 && clear != NULL) { /* Bit more logging */
2090
0
        ossl_ech_pbuf("local config_id", &ee->config_id, 1);
2091
0
        ossl_ech_pbuf("remote config_id", &extval->config_id, 1);
2092
0
        ossl_ech_pbuf("clear", clear, clearlen);
2093
0
    }
2094
0
#endif
2095
0
    ossl_ech_encch_free(extval);
2096
0
    OPENSSL_free(extval);
2097
0
    extval = NULL;
2098
0
    if (s->ext.ech.grease == OSSL_ECH_IS_GREASE) {
2099
0
        OPENSSL_free(clear);
2100
0
        return 1;
2101
0
    }
2102
    /* 4. if decrypt worked, de-compress cleartext to make up real inner CH */
2103
0
    if (ech_decode_inner(s, opd, opl, clear, clearlen) != 1) {
2104
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
2105
0
        goto err;
2106
0
    }
2107
0
    OPENSSL_free(clear);
2108
0
    clear = NULL;
2109
0
#ifdef OSSL_ECH_SUPERVERBOSE
2110
0
    ossl_ech_pbuf("Inner CH (decoded)", s->ext.ech.innerch,
2111
0
        s->ext.ech.innerch_len);
2112
0
#endif
2113
0
    if (PACKET_buf_init(newpkt, s->ext.ech.innerch,
2114
0
            s->ext.ech.innerch_len)
2115
0
        != 1) {
2116
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
2117
0
        goto err;
2118
0
    }
2119
    /* tls_process_client_hello doesn't want the message header, so skip it */
2120
0
    if (!PACKET_forward(newpkt, SSL3_HM_HEADER_LENGTH)) {
2121
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
2122
0
        goto err;
2123
0
    }
2124
0
    if (ossl_ech_intbuf_add(s, s->ext.ech.innerch,
2125
0
            s->ext.ech.innerch_len, 0)
2126
0
        != 1) {
2127
0
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
2128
0
        goto err;
2129
0
    }
2130
0
    return 1;
2131
0
err:
2132
0
    OPENSSL_free(aad);
2133
0
    if (extval != NULL) {
2134
0
        ossl_ech_encch_free(extval);
2135
0
        OPENSSL_free(extval);
2136
0
    }
2137
0
    OPENSSL_free(clear);
2138
0
    return 0;
2139
0
}
2140
2141
int ossl_ech_intbuf_add(SSL_CONNECTION *s, const unsigned char *buf,
2142
    size_t blen, int hash_existing)
2143
0
{
2144
0
    EVP_MD_CTX *ctx = NULL;
2145
0
    EVP_MD *md = NULL;
2146
0
    unsigned int rv = 0, hashlen = 0;
2147
0
    unsigned char hashval[EVP_MAX_MD_SIZE], *t1;
2148
0
    size_t tlen;
2149
0
    WPACKET tpkt = { 0 };
2150
0
    BUF_MEM *tpkt_mem = NULL;
2151
2152
0
    if (s == NULL || buf == NULL || blen == 0)
2153
0
        goto err;
2154
0
    if (hash_existing == 1) {
2155
        /* hash existing buffer, needed during HRR */
2156
0
        if (s->ext.ech.transbuf == NULL
2157
0
            || (md = (EVP_MD *)ssl_handshake_md(s)) == NULL
2158
0
            || (ctx = EVP_MD_CTX_new()) == NULL
2159
0
            || EVP_DigestInit_ex(ctx, md, NULL) <= 0
2160
0
            || EVP_DigestUpdate(ctx, s->ext.ech.transbuf,
2161
0
                   s->ext.ech.transbuf_len)
2162
0
                <= 0
2163
0
            || EVP_DigestFinal_ex(ctx, hashval, &hashlen) <= 0
2164
0
            || (tpkt_mem = BUF_MEM_new()) == NULL
2165
0
            || !WPACKET_init(&tpkt, tpkt_mem)
2166
0
            || !WPACKET_put_bytes_u8(&tpkt, SSL3_MT_MESSAGE_HASH)
2167
0
            || !WPACKET_put_bytes_u24(&tpkt, hashlen)
2168
0
            || !WPACKET_memcpy(&tpkt, hashval, hashlen)
2169
0
            || !WPACKET_get_length(&tpkt, &tlen)
2170
0
            || (t1 = OPENSSL_realloc(s->ext.ech.transbuf, tlen + blen)) == NULL)
2171
0
            goto err;
2172
0
        s->ext.ech.transbuf = t1;
2173
0
        memcpy(s->ext.ech.transbuf, tpkt_mem->data, tlen);
2174
0
        memcpy(s->ext.ech.transbuf + tlen, buf, blen);
2175
0
        s->ext.ech.transbuf_len = tlen + blen;
2176
0
    } else {
2177
        /* just add new octets */
2178
0
        if ((t1 = OPENSSL_realloc(s->ext.ech.transbuf,
2179
0
                 s->ext.ech.transbuf_len + blen))
2180
0
            == NULL)
2181
0
            goto err;
2182
0
        s->ext.ech.transbuf = t1;
2183
0
        memcpy(s->ext.ech.transbuf + s->ext.ech.transbuf_len, buf, blen);
2184
0
        s->ext.ech.transbuf_len += blen;
2185
0
    }
2186
0
    rv = 1;
2187
0
err:
2188
0
    BUF_MEM_free(tpkt_mem);
2189
0
    WPACKET_cleanup(&tpkt);
2190
0
    EVP_MD_CTX_free(ctx);
2191
0
    return rv;
2192
0
}
2193
2194
int ossl_ech_intbuf_fetch(SSL_CONNECTION *s, unsigned char **buf, size_t *blen)
2195
0
{
2196
0
    if (s == NULL || buf == NULL || blen == NULL || s->ext.ech.transbuf == NULL)
2197
0
        return 0;
2198
0
    *buf = s->ext.ech.transbuf;
2199
0
    *blen = s->ext.ech.transbuf_len;
2200
0
    return 1;
2201
0
}
2202
2203
int ossl_ech_stash_keyshares(SSL_CONNECTION *s)
2204
0
{
2205
0
    size_t i;
2206
2207
0
    ech_free_stashed_key_shares(&s->ext.ech);
2208
0
    for (i = 0; i != s->s3.tmp.num_ks_pkey; i++) {
2209
0
        s->ext.ech.ks_pkey[i] = s->s3.tmp.ks_pkey[i];
2210
0
        if (EVP_PKEY_up_ref(s->ext.ech.ks_pkey[i]) != 1)
2211
0
            return 0;
2212
0
        s->ext.ech.ks_group_id[i] = s->s3.tmp.ks_group_id[i];
2213
0
    }
2214
0
    s->ext.ech.num_ks_pkey = s->s3.tmp.num_ks_pkey;
2215
0
    return 1;
2216
0
}
2217
2218
int ossl_ech_unstash_keyshares(SSL_CONNECTION *s)
2219
0
{
2220
0
    size_t i;
2221
2222
0
    for (i = 0; i != s->s3.tmp.num_ks_pkey; i++) {
2223
0
        EVP_PKEY_free(s->s3.tmp.ks_pkey[i]);
2224
0
        s->s3.tmp.ks_pkey[i] = NULL;
2225
0
    }
2226
0
    for (i = 0; i != s->ext.ech.num_ks_pkey; i++) {
2227
0
        s->s3.tmp.ks_pkey[i] = s->ext.ech.ks_pkey[i];
2228
0
        if (EVP_PKEY_up_ref(s->s3.tmp.ks_pkey[i]) != 1)
2229
0
            return 0;
2230
0
        s->s3.tmp.ks_group_id[i] = s->ext.ech.ks_group_id[i];
2231
0
    }
2232
0
    s->s3.tmp.num_ks_pkey = s->ext.ech.num_ks_pkey;
2233
0
    ech_free_stashed_key_shares(&s->ext.ech);
2234
0
    return 1;
2235
0
}
2236
#endif