lsquic_enc_sess_ietf.c revision 307ca7fe
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_enc_sess_ietf.c -- Crypto session for IETF QUIC
4 */
5
6#include <assert.h>
7#include <errno.h>
8#include <stddef.h>
9#include <stdlib.h>
10#include <string.h>
11#include <sys/queue.h>
12#if LSQUIC_PREFERRED_ADDR
13#include <arpa/inet.h>
14#endif
15
16#include <openssl/chacha.h>
17#include <openssl/hkdf.h>
18#include <openssl/rand.h>
19#include <openssl/ssl.h>
20
21#include "fiu-local.h"
22
23#include "lsquic_types.h"
24#include "lsquic_hkdf.h"
25#include "lsquic.h"
26#include "lsquic_int_types.h"
27#include "lsquic_sizes.h"
28#include "lsquic_hash.h"
29#include "lsquic_conn.h"
30#include "lsquic_enc_sess.h"
31#include "lsquic_parse.h"
32#include "lsquic_mm.h"
33#include "lsquic_engine_public.h"
34#include "lsquic_packet_common.h"
35#include "lsquic_packet_out.h"
36#include "lsquic_packet_ietf.h"
37#include "lsquic_packet_in.h"
38#include "lsquic_util.h"
39#include "lsquic_byteswap.h"
40#include "lsquic_ev_log.h"
41#include "lsquic_trans_params.h"
42#include "lsquic_version.h"
43#include "lsquic_ver_neg.h"
44#include "lsquic_frab_list.h"
45#include "lsquic_tokgen.h"
46#include "lsquic_ietf.h"
47#include "lsquic_alarmset.h"
48
49#if __GNUC__
50#   define UNLIKELY(cond) __builtin_expect(cond, 0)
51#else
52#   define UNLIKELY(cond) cond
53#endif
54
55#define MAX(a, b) ((a) > (b) ? (a) : (b))
56
57#define LSQUIC_LOGGER_MODULE LSQLM_HANDSHAKE
58#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(enc_sess->esi_conn)
59#include "lsquic_logger.h"
60
61#define KEY_LABEL "quic key"
62#define KEY_LABEL_SZ (sizeof(KEY_LABEL) - 1)
63#define IV_LABEL "quic iv"
64#define IV_LABEL_SZ (sizeof(IV_LABEL) - 1)
65#define PN_LABEL "quic hp"
66#define PN_LABEL_SZ (sizeof(PN_LABEL) - 1)
67
68#define N_HSK_PAIRS (N_ENC_LEVS - 1)
69
70static const struct alpn_map {
71    enum lsquic_version  version;
72    const unsigned char *alpn;
73} s_h3_alpns[] = {
74    {   LSQVER_ID27, (unsigned char *) "\x05h3-27",     },
75    {   LSQVER_ID28, (unsigned char *) "\x05h3-28",     },
76    {   LSQVER_VERNEG, (unsigned char *) "\x05h3-28",     },
77};
78
79struct enc_sess_iquic;
80struct crypto_ctx;
81struct crypto_ctx_pair;
82struct header_prot;
83
84static const int s_log_seal_and_open;
85static char s_str[0x1000];
86
87static const SSL_QUIC_METHOD cry_quic_method;
88
89static int s_idx = -1;
90
91static int
92setup_handshake_keys (struct enc_sess_iquic *, const lsquic_cid_t *);
93
94static void
95free_handshake_keys (struct enc_sess_iquic *);
96
97static struct stack_st_X509 *
98iquic_esf_get_server_cert_chain (enc_session_t *);
99
100static void
101maybe_drop_SSL (struct enc_sess_iquic *);
102
103static void
104no_sess_ticket (enum alarm_id alarm_id, void *ctx,
105                                  lsquic_time_t expiry, lsquic_time_t now);
106
107
108typedef void (*gen_hp_mask_f)(struct enc_sess_iquic *,
109    const struct header_prot *, unsigned rw,
110    const unsigned char *sample, unsigned char mask[16]);
111
112
113struct header_prot
114{
115    const EVP_CIPHER   *hp_cipher;
116    gen_hp_mask_f       hp_gen_mask;
117    enum enc_level      hp_enc_level;
118    enum {
119        HP_CAN_READ  = 1 << 0,
120        HP_CAN_WRITE = 1 << 1,
121    }                   hp_flags;
122    unsigned            hp_sz;
123    unsigned char       hp_buf[2][EVP_MAX_KEY_LENGTH];
124};
125
126#define header_prot_inited(hp_, rw_) ((hp_)->hp_flags & (1 << (rw_)))
127
128
129struct crypto_ctx
130{
131    enum {
132        YK_INITED = 1 << 0,
133    }                   yk_flags;
134    EVP_AEAD_CTX        yk_aead_ctx;
135    unsigned            yk_key_sz;
136    unsigned            yk_iv_sz;
137    unsigned char       yk_key_buf[EVP_MAX_KEY_LENGTH];
138    unsigned char       yk_iv_buf[EVP_MAX_IV_LENGTH];
139};
140
141
142struct crypto_ctx_pair
143{
144    lsquic_packno_t     ykp_thresh;
145    struct crypto_ctx   ykp_ctx[2]; /* client, server */
146};
147
148
149/* [draft-ietf-quic-tls-12] Section 5.3.6 */
150static int
151init_crypto_ctx (struct crypto_ctx *crypto_ctx, const EVP_MD *md,
152                 const EVP_AEAD *aead, const unsigned char *secret,
153                 size_t secret_sz, enum evp_aead_direction_t dir)
154{
155    crypto_ctx->yk_key_sz = EVP_AEAD_key_length(aead);
156    crypto_ctx->yk_iv_sz = EVP_AEAD_nonce_length(aead);
157
158    if (crypto_ctx->yk_key_sz > sizeof(crypto_ctx->yk_key_buf)
159        || crypto_ctx->yk_iv_sz > sizeof(crypto_ctx->yk_iv_buf))
160    {
161        return -1;
162    }
163
164    lsquic_qhkdf_expand(md, secret, secret_sz, KEY_LABEL, KEY_LABEL_SZ,
165        crypto_ctx->yk_key_buf, crypto_ctx->yk_key_sz);
166    lsquic_qhkdf_expand(md, secret, secret_sz, IV_LABEL, IV_LABEL_SZ,
167        crypto_ctx->yk_iv_buf, crypto_ctx->yk_iv_sz);
168    if (!EVP_AEAD_CTX_init_with_direction(&crypto_ctx->yk_aead_ctx, aead,
169            crypto_ctx->yk_key_buf, crypto_ctx->yk_key_sz, IQUIC_TAG_LEN, dir))
170        return -1;
171
172    crypto_ctx->yk_flags |= YK_INITED;
173
174    return 0;
175}
176
177
178static void
179derive_hp_secrets (struct header_prot *hp, const EVP_MD *md,
180    const EVP_AEAD *aead, size_t secret_sz,
181    const unsigned char *client_secret, const unsigned char *server_secret)
182{
183    hp->hp_sz = EVP_AEAD_key_length(aead);
184    hp->hp_flags = HP_CAN_READ | HP_CAN_WRITE;
185    lsquic_qhkdf_expand(md, client_secret, secret_sz, PN_LABEL, PN_LABEL_SZ,
186        hp->hp_buf[0], hp->hp_sz);
187    lsquic_qhkdf_expand(md, server_secret, secret_sz, PN_LABEL, PN_LABEL_SZ,
188        hp->hp_buf[1], hp->hp_sz);
189}
190
191
192static void
193cleanup_crypto_ctx (struct crypto_ctx *crypto_ctx)
194{
195    if (crypto_ctx->yk_flags & YK_INITED)
196    {
197        EVP_AEAD_CTX_cleanup(&crypto_ctx->yk_aead_ctx);
198        crypto_ctx->yk_flags &= ~YK_INITED;
199    }
200}
201
202
203struct enc_sess_iquic
204{
205    struct lsquic_engine_public
206                        *esi_enpub;
207    struct lsquic_conn  *esi_conn;
208    void               **esi_streams;
209    const struct crypto_stream_if *esi_cryst_if;
210    const struct ver_neg
211                        *esi_ver_neg;
212    SSL                 *esi_ssl;
213
214    /* These are used for forward encryption key phase 0 and 1 */
215    struct header_prot   esi_hp;
216    struct crypto_ctx_pair
217                         esi_pairs[2];
218    /* These are used during handshake.  There are three of them.
219     * esi_hsk_pairs and esi_hsk_hps are allocated and freed
220     * together.
221     */
222    struct crypto_ctx_pair *
223                         esi_hsk_pairs;
224    struct header_prot  *esi_hsk_hps;
225    lsquic_packno_t      esi_max_packno[N_PNS];
226    lsquic_cid_t         esi_odcid;
227    lsquic_cid_t         esi_rscid; /* Retry SCID */
228    lsquic_cid_t         esi_iscid; /* Initial SCID */
229    unsigned             esi_key_phase;
230    enum {
231        ESI_INITIALIZED  = 1 << 0,
232        ESI_LOG_SECRETS  = 1 << 1,
233        ESI_HANDSHAKE_OK = 1 << 2,
234        ESI_ODCID        = 1 << 3,
235        ESI_ON_WRITE     = 1 << 4,
236        ESI_SERVER       = 1 << 5,
237        ESI_USE_SSL_TICKET = 1 << 6,
238        ESI_HAVE_PEER_TP = 1 << 7,
239        ESI_ALPN_CHECKED = 1 << 8,
240        ESI_CACHED_INFO  = 1 << 9,
241        ESI_HSK_CONFIRMED= 1 << 10,
242        ESI_WANT_TICKET  = 1 << 11,
243        ESI_RECV_QL_BITS = 1 << 12,
244        ESI_SEND_QL_BITS = 1 << 13,
245        ESI_RSCID        = 1 << 14,
246        ESI_ISCID        = 1 << 15,
247        ESI_RETRY        = 1 << 16, /* Connection was retried */
248    }                    esi_flags;
249    enum enc_level       esi_last_w;
250    unsigned             esi_trasec_sz;
251    char                *esi_hostname;
252    void                *esi_keylog_handle;
253#ifndef NDEBUG
254    char                *esi_sni_bypass;
255#endif
256    const unsigned char *esi_alpn;
257    unsigned char       *esi_zero_rtt_buf;
258    size_t               esi_zero_rtt_sz;
259    /* Need MD and AEAD for key rotation */
260    const EVP_MD        *esi_md;
261    const EVP_AEAD      *esi_aead;
262    struct {
263        const char *cipher_name;
264        int         alg_bits;
265    }                    esi_cached_info;
266    /* Secrets are kept for key rotation */
267    unsigned char        esi_traffic_secrets[2][EVP_MAX_KEY_LENGTH];
268    /* We never use the first two levels, so it seems we could reduce the
269     * memory requirement here at the cost of adding some code.
270     */
271    struct frab_list     esi_frals[N_ENC_LEVS];
272    struct transport_params
273                         esi_peer_tp;
274    struct lsquic_alarmset
275                        *esi_alset;
276    unsigned             esi_max_streams_uni;
277};
278
279
280static void
281gen_hp_mask_aes (struct enc_sess_iquic *enc_sess,
282        const struct header_prot *hp, unsigned rw,
283        const unsigned char *sample, unsigned char mask[EVP_MAX_BLOCK_LENGTH])
284{
285    EVP_CIPHER_CTX hp_ctx;
286    int out_len;
287
288    EVP_CIPHER_CTX_init(&hp_ctx);
289    if (EVP_EncryptInit_ex(&hp_ctx, hp->hp_cipher, NULL, hp->hp_buf[rw], 0)
290        && EVP_EncryptUpdate(&hp_ctx, mask, &out_len, sample, 16))
291    {
292        assert(out_len >= 5);
293    }
294    else
295    {
296        LSQ_WARN("cannot generate hp mask, error code: %"PRIu32,
297                                                            ERR_get_error());
298        enc_sess->esi_conn->cn_if->ci_internal_error(enc_sess->esi_conn,
299            "cannot generate hp mask, error code: %"PRIu32, ERR_get_error());
300    }
301
302    (void) EVP_CIPHER_CTX_cleanup(&hp_ctx);
303}
304
305
306static void
307gen_hp_mask_chacha20 (struct enc_sess_iquic *enc_sess,
308        const struct header_prot *hp, unsigned rw,
309        const unsigned char *sample, unsigned char mask[EVP_MAX_BLOCK_LENGTH])
310{
311    const uint8_t *nonce;
312    uint32_t counter;
313
314#if __BYTE_ORDER == __LITTLE_ENDIAN
315    memcpy(&counter, sample, sizeof(counter));
316#else
317#error TODO: support non-little-endian machines
318#endif
319    nonce = sample + sizeof(counter);
320    CRYPTO_chacha_20(mask, (unsigned char [5]) { 0, 0, 0, 0, 0, }, 5,
321                                        hp->hp_buf[rw], nonce, counter);
322}
323
324
325static void
326apply_hp (struct enc_sess_iquic *enc_sess,
327        const struct header_prot *hp,
328        unsigned char *dst, unsigned packno_off, unsigned packno_len)
329{
330    unsigned char mask[EVP_MAX_BLOCK_LENGTH];
331    char mask_str[5 * 2 + 1];
332
333    hp->hp_gen_mask(enc_sess, hp, 1, dst + packno_off + 4, mask);
334    LSQ_DEBUG("apply header protection using mask %s",
335                                                HEXSTR(mask, 5, mask_str));
336    if (enc_sess->esi_flags & ESI_SEND_QL_BITS)
337        dst[0] ^= (0x7 | ((dst[0] >> 7) << 3)) & mask[0];
338    else
339        dst[0] ^= (0xF | (((dst[0] & 0x80) == 0) << 4)) & mask[0];
340    switch (packno_len)
341    {
342    case 4:
343        dst[packno_off + 3] ^= mask[4];
344        /* fall-through */
345    case 3:
346        dst[packno_off + 2] ^= mask[3];
347        /* fall-through */
348    case 2:
349        dst[packno_off + 1] ^= mask[2];
350        /* fall-through */
351    default:
352        dst[packno_off + 0] ^= mask[1];
353    }
354}
355
356
357static lsquic_packno_t
358decode_packno (lsquic_packno_t max_packno, lsquic_packno_t packno,
359                                                                unsigned shift)
360{
361    lsquic_packno_t candidates[3], epoch_delta;
362    int64_t diffs[3];
363    unsigned min;;
364
365    epoch_delta = 1ULL << shift;
366    candidates[1] = (max_packno & ~(epoch_delta - 1)) + packno;
367    candidates[0] = candidates[1] - epoch_delta;
368    candidates[2] = candidates[1] + epoch_delta;
369
370    diffs[0] = llabs((int64_t) candidates[0] - (int64_t) max_packno);
371    diffs[1] = llabs((int64_t) candidates[1] - (int64_t) max_packno);
372    diffs[2] = llabs((int64_t) candidates[2] - (int64_t) max_packno);
373
374    min = diffs[1] < diffs[0];
375    if (diffs[2] < diffs[min])
376        min = 2;
377
378    return candidates[min];
379}
380
381
382static lsquic_packno_t
383strip_hp (struct enc_sess_iquic *enc_sess,
384        const struct header_prot *hp,
385        const unsigned char *iv, unsigned char *dst, unsigned packno_off,
386        unsigned *packno_len)
387{
388    enum packnum_space pns;
389    lsquic_packno_t packno;
390    unsigned shift;
391    unsigned char mask[EVP_MAX_BLOCK_LENGTH];
392    char mask_str[5 * 2 + 1];
393
394    hp->hp_gen_mask(enc_sess, hp, 0, iv, mask);
395    LSQ_DEBUG("strip header protection using mask %s",
396                                                HEXSTR(mask, 5, mask_str));
397    if (enc_sess->esi_flags & ESI_RECV_QL_BITS)
398        dst[0] ^= (0x7 | ((dst[0] >> 7) << 3)) & mask[0];
399    else
400        dst[0] ^= (0xF | (((dst[0] & 0x80) == 0) << 4)) & mask[0];
401    packno = 0;
402    shift = 0;
403    *packno_len = 1 + (dst[0] & 3);
404    switch (*packno_len)
405    {
406    case 4:
407        dst[packno_off + 3] ^= mask[4];
408        packno |= dst[packno_off + 3];
409        shift += 8;
410        /* fall-through */
411    case 3:
412        dst[packno_off + 2] ^= mask[3];
413        packno |= (unsigned) dst[packno_off + 2] << shift;
414        shift += 8;
415        /* fall-through */
416    case 2:
417        dst[packno_off + 1] ^= mask[2];
418        packno |= (unsigned) dst[packno_off + 1] << shift;
419        shift += 8;
420        /* fall-through */
421    default:
422        dst[packno_off + 0] ^= mask[1];
423        packno |= (unsigned) dst[packno_off + 0] << shift;
424        shift += 8;
425    }
426    pns = lsquic_enclev2pns[hp->hp_enc_level];
427    return decode_packno(enc_sess->esi_max_packno[pns], packno, shift);
428}
429
430
431static int
432gen_trans_params (struct enc_sess_iquic *enc_sess, unsigned char *buf,
433                                                                size_t bufsz)
434{
435    const struct lsquic_engine_settings *const settings =
436                                    &enc_sess->esi_enpub->enp_settings;
437    struct transport_params params;
438    const enum lsquic_version version = enc_sess->esi_conn->cn_version;
439    int len;
440
441    memset(&params, 0, sizeof(params));
442    if (version > LSQVER_ID27)
443    {
444        params.tp_initial_source_cid = *CN_SCID(enc_sess->esi_conn);
445        params.tp_set |= 1 << TPI_INITIAL_SOURCE_CID;
446    }
447    if (enc_sess->esi_flags & ESI_SERVER)
448    {
449        const struct lsquic_conn *const lconn = enc_sess->esi_conn;
450
451        params.tp_set |= 1 << TPI_STATELESS_RESET_TOKEN;
452        lsquic_tg_generate_sreset(enc_sess->esi_enpub->enp_tokgen,
453            CN_SCID(lconn), params.tp_stateless_reset_token);
454
455        if (enc_sess->esi_flags & ESI_ODCID)
456        {
457            params.tp_original_dest_cid = enc_sess->esi_odcid;
458            params.tp_set |= 1 << TPI_ORIGINAL_DEST_CID;
459        }
460#if LSQUIC_PREFERRED_ADDR
461        char addr_buf[INET6_ADDRSTRLEN + 6 /* port */ + 1];
462        const char *s, *colon;
463        struct lsquic_conn *conn;
464        struct conn_cid_elem *cce;
465        unsigned seqno;
466        s = getenv("LSQUIC_PREFERRED_ADDR4");
467        if (s && strlen(s) < sizeof(addr_buf) && (colon = strchr(s, ':')))
468        {
469            strncpy(addr_buf, s, colon - s);
470            addr_buf[colon - s] = '\0';
471            inet_pton(AF_INET, addr_buf, params.tp_preferred_address.ipv4_addr);
472            params.tp_preferred_address.ipv4_port = atoi(colon + 1);
473            params.tp_set |= 1 << TPI_PREFERRED_ADDRESS;
474        }
475        s = getenv("LSQUIC_PREFERRED_ADDR6");
476        if (s && strlen(s) < sizeof(addr_buf) && (colon = strrchr(s, ':')))
477        {
478            strncpy(addr_buf, s, colon - s);
479            addr_buf[colon - s] = '\0';
480            inet_pton(AF_INET6, addr_buf,
481                                        params.tp_preferred_address.ipv6_addr);
482            params.tp_preferred_address.ipv6_port = atoi(colon + 1);
483            params.tp_set |= 1 << TPI_PREFERRED_ADDRESS;
484        }
485        conn = enc_sess->esi_conn;
486        if ((params.tp_set & (1 << TPI_PREFERRED_ADDRESS))
487                            && (1 << conn->cn_n_cces) - 1 != conn->cn_cces_mask)
488        {
489            seqno = 0;
490            for (cce = lconn->cn_cces; cce < END_OF_CCES(lconn); ++cce)
491            {
492                if (lconn->cn_cces_mask & (1 << (cce - lconn->cn_cces)))
493                {
494                    if ((cce->cce_flags & CCE_SEQNO) && cce->cce_seqno > seqno)
495                        seqno = cce->cce_seqno;
496                }
497                else
498                    break;
499            }
500            if (cce == END_OF_CCES(lconn))
501            {
502                goto cant_use_prefaddr;
503            }
504            cce->cce_seqno = seqno + 1;
505            cce->cce_flags = CCE_SEQNO;
506            lsquic_generate_cid(&cce->cce_cid,
507                            enc_sess->esi_enpub->enp_settings.es_scid_len);
508            /* Don't add to hash: migration must not start until *after*
509             * handshake is complete.
510             */
511            conn->cn_cces_mask |= 1 << (cce - conn->cn_cces);
512            params.tp_preferred_address.cid = cce->cce_cid;
513            lsquic_tg_generate_sreset(enc_sess->esi_enpub->enp_tokgen,
514                &params.tp_preferred_address.cid,
515                params.tp_preferred_address.srst);
516        }
517        else
518        {
519  cant_use_prefaddr:
520            params.tp_set &= ~(1 << TPI_PREFERRED_ADDRESS);
521        }
522#endif
523    }
524#if LSQUIC_TEST_QUANTUM_READINESS
525    else
526    {
527        const char *s = getenv("LSQUIC_TEST_QUANTUM_READINESS");
528        if (s && atoi(s))
529            params.tp_set |= 1 << TPI_QUANTUM_READINESS;
530    }
531#endif
532    params.tp_init_max_data = settings->es_init_max_data;
533    params.tp_init_max_stream_data_bidi_local
534                            = settings->es_init_max_stream_data_bidi_local;
535    params.tp_init_max_stream_data_bidi_remote
536                            = settings->es_init_max_stream_data_bidi_remote;
537    params.tp_init_max_stream_data_uni
538                            = settings->es_init_max_stream_data_uni;
539    params.tp_init_max_streams_uni
540                            = enc_sess->esi_max_streams_uni;
541    params.tp_init_max_streams_bidi
542                            = settings->es_init_max_streams_bidi;
543    params.tp_ack_delay_exponent
544                            = TP_DEF_ACK_DELAY_EXP;
545    params.tp_max_idle_timeout = settings->es_idle_timeout * 1000;
546    params.tp_max_ack_delay = TP_DEF_MAX_ACK_DELAY;
547    params.tp_active_connection_id_limit = MAX_IETF_CONN_DCIDS;
548    params.tp_set |= (1 << TPI_INIT_MAX_DATA)
549                  |  (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL)
550                  |  (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE)
551                  |  (1 << TPI_INIT_MAX_STREAM_DATA_UNI)
552                  |  (1 << TPI_INIT_MAX_STREAMS_UNI)
553                  |  (1 << TPI_INIT_MAX_STREAMS_BIDI)
554                  |  (1 << TPI_ACK_DELAY_EXPONENT)
555                  |  (1 << TPI_MAX_IDLE_TIMEOUT)
556                  |  (1 << TPI_MAX_ACK_DELAY)
557                  |  (1 << TPI_ACTIVE_CONNECTION_ID_LIMIT)
558                  ;
559    if (settings->es_max_udp_payload_size_rx)
560    {
561        params.tp_max_udp_payload_size = settings->es_max_udp_payload_size_rx;
562        params.tp_set |= 1 << TPI_MAX_UDP_PAYLOAD_SIZE;
563    }
564    if (!settings->es_allow_migration)
565        params.tp_set |= 1 << TPI_DISABLE_ACTIVE_MIGRATION;
566    if (settings->es_ql_bits)
567    {
568        params.tp_loss_bits = settings->es_ql_bits - 1;
569        params.tp_set |= 1 << TPI_LOSS_BITS;
570    }
571    if (settings->es_delayed_acks)
572    {
573        params.tp_numerics[TPI_MIN_ACK_DELAY] = 10000;    /* TODO: make into a constant? make configurable? */
574        params.tp_set |= 1 << TPI_MIN_ACK_DELAY;
575    }
576    if (settings->es_timestamps)
577        params.tp_set |= 1 << TPI_TIMESTAMPS;
578
579    len = (version == LSQVER_ID27 ? lsquic_tp_encode_27 : lsquic_tp_encode)(
580                        &params, enc_sess->esi_flags & ESI_SERVER, buf, bufsz);
581    if (len >= 0)
582    {
583        char str[MAX_TP_STR_SZ];
584        LSQ_DEBUG("generated transport parameters buffer of %d bytes", len);
585        LSQ_DEBUG("%s", ((version == LSQVER_ID27 ? lsquic_tp_to_str_27
586                        : lsquic_tp_to_str)(&params, str, sizeof(str)), str));
587    }
588    else
589        LSQ_WARN("cannot generate transport parameters: %d", errno);
590    return len;
591}
592
593
594/*
595 * Format:
596 *      uint32_t    lsquic_ver_tag_t
597 *      uint32_t    encoder version
598 *      uint32_t    ticket_size
599 *      uint8_t     ticket_buf[ ticket_size ]
600 *      uint32_t    trapa_size
601 *      uint8_t     trapa_buf[ trapa_size ]
602 */
603
604#define ZERO_RTT_VERSION 1
605
606#if __BYTE_ORDER == __LITTLE_ENDIAN
607#define READ_NUM(var_, ptr_) do {                               \
608    memcpy(&var_, ptr_, sizeof(var_));                          \
609    var_ = bswap_32(var_);                                      \
610    ptr_ += sizeof(var_);                                       \
611} while (0)
612#else
613#define READ_NUM(var_, ptr_) do {                               \
614    memcpy(&var_, ptr_, sizeof(var_));                          \
615    ptr_ += sizeof(var_);                                       \
616} while (0)
617#endif
618
619static SSL_SESSION *
620maybe_create_SSL_SESSION (struct enc_sess_iquic *enc_sess,
621                                                    const SSL_CTX *ssl_ctx)
622{
623    SSL_SESSION *ssl_session;
624    lsquic_ver_tag_t ver_tag;
625    enum lsquic_version quic_ver;
626    uint32_t rtt_ver, ticket_sz, trapa_sz;
627    const unsigned char *ticket_buf, *trapa_buf, *p;
628    const unsigned char *const end
629                    = enc_sess->esi_zero_rtt_buf + enc_sess->esi_zero_rtt_sz;
630
631    if (enc_sess->esi_zero_rtt_sz
632                    < sizeof(ver_tag) + sizeof(rtt_ver) + sizeof(ticket_sz))
633    {
634        LSQ_DEBUG("rtt buf too short");
635        return NULL;
636    }
637
638    p = enc_sess->esi_zero_rtt_buf;
639    memcpy(&ver_tag, p, sizeof(ver_tag));
640    p += sizeof(ver_tag);
641    quic_ver = lsquic_tag2ver(ver_tag);
642    if (quic_ver != enc_sess->esi_ver_neg->vn_ver)
643    {
644        LSQ_DEBUG("negotiated version %s does not match that in the zero-rtt "
645            "info buffer", lsquic_ver2str[enc_sess->esi_ver_neg->vn_ver]);
646        return NULL;
647    }
648
649    READ_NUM(rtt_ver, p);
650    if (rtt_ver != ZERO_RTT_VERSION)
651    {
652        LSQ_DEBUG("cannot use zero-rtt buffer: encoded using %"PRIu32", "
653                "while current version is %u", rtt_ver, ZERO_RTT_VERSION);
654        return NULL;
655    }
656
657    READ_NUM(ticket_sz, p);
658    if (p + ticket_sz > end)
659    {
660        LSQ_WARN("truncated ticket buffer");
661        return NULL;
662    }
663
664    ticket_buf = p;
665    p += ticket_sz;
666
667    if (p + sizeof(trapa_sz) > end)
668    {
669        LSQ_WARN("too short to read trapa size");
670        return NULL;
671    }
672
673    READ_NUM(trapa_sz, p);
674    if (p + trapa_sz > end)
675    {
676        LSQ_WARN("truncated trapa buffer");
677        return NULL;
678    }
679    trapa_buf = p;
680    p += trapa_sz;
681    assert(p == end);
682
683    (void) /* TODO */ trapa_buf;
684
685    ssl_session = SSL_SESSION_from_bytes(ticket_buf, ticket_sz, ssl_ctx);
686    if (!ssl_session)
687    {
688        LSQ_WARN("SSL_SESSION could not be parsed out");
689        return NULL;
690    }
691
692    LSQ_INFO("instantiated SSL_SESSION from serialized buffer");
693    return ssl_session;
694}
695
696
697static void
698init_frals (struct enc_sess_iquic *enc_sess)
699{
700    struct frab_list *fral;
701
702    for (fral = enc_sess->esi_frals; fral < enc_sess->esi_frals
703            + sizeof(enc_sess->esi_frals) / sizeof(enc_sess->esi_frals[0]);
704                ++fral)
705        lsquic_frab_list_init(fral, 0x100, NULL, NULL, NULL);
706}
707
708
709static enc_session_t *
710iquic_esfi_create_client (const char *hostname,
711            struct lsquic_engine_public *enpub, struct lsquic_conn *lconn,
712            const lsquic_cid_t *dcid, const struct ver_neg *ver_neg,
713            void *crypto_streams[4], const struct crypto_stream_if *cryst_if,
714            const unsigned char *zero_rtt, size_t zero_rtt_sz,
715            struct lsquic_alarmset *alset, unsigned max_streams_uni)
716{
717    struct enc_sess_iquic *enc_sess;
718
719    fiu_return_on("enc_sess_ietf/create_client", NULL);
720
721    enc_sess = calloc(1, sizeof(*enc_sess));
722    if (!enc_sess)
723        return NULL;
724
725    if (hostname)
726    {
727        enc_sess->esi_hostname = strdup(hostname);
728        if (!enc_sess->esi_hostname)
729        {
730            free(enc_sess);
731            return NULL;
732        }
733    }
734    else
735        enc_sess->esi_hostname = NULL;
736
737    enc_sess->esi_enpub = enpub;
738    enc_sess->esi_streams = crypto_streams;
739    enc_sess->esi_cryst_if = cryst_if;
740    enc_sess->esi_conn = lconn;
741    enc_sess->esi_ver_neg = ver_neg;
742
743    enc_sess->esi_odcid = *dcid;
744    enc_sess->esi_flags |= ESI_ODCID;
745
746    LSQ_DEBUGC("created client, DCID: %"CID_FMT, CID_BITS(dcid));
747    {
748        const char *log;
749        log = getenv("LSQUIC_LOG_SECRETS");
750        if (log)
751        {
752            if (atoi(log))
753                enc_sess->esi_flags |= ESI_LOG_SECRETS;
754            LSQ_DEBUG("will %slog secrets", atoi(log) ? "" : "not ");
755        }
756    }
757
758    init_frals(enc_sess);
759
760    if (0 != setup_handshake_keys(enc_sess, dcid))
761    {
762        free(enc_sess);
763        return NULL;
764    }
765
766    /* Have to wait until the call to init_client() -- this is when the
767     * result of version negotiation is known.
768     */
769    if (zero_rtt && zero_rtt_sz)
770    {
771        enc_sess->esi_zero_rtt_buf = malloc(zero_rtt_sz);
772        if (enc_sess->esi_zero_rtt_buf)
773        {
774            memcpy(enc_sess->esi_zero_rtt_buf, zero_rtt, zero_rtt_sz);
775            enc_sess->esi_zero_rtt_sz = zero_rtt_sz;
776        }
777        else
778            enc_sess->esi_zero_rtt_sz = 0;
779    }
780    else
781    {
782        enc_sess->esi_zero_rtt_buf = NULL;
783        enc_sess->esi_zero_rtt_sz = 0;
784    }
785
786    if (enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info)
787        enc_sess->esi_flags |= ESI_WANT_TICKET;
788    enc_sess->esi_alset = alset;
789    lsquic_alarmset_init_alarm(enc_sess->esi_alset, AL_SESS_TICKET,
790                                            no_sess_ticket, enc_sess);
791
792    enc_sess->esi_max_streams_uni = max_streams_uni;
793
794    return enc_sess;
795}
796
797
798static void
799iquic_esfi_set_streams (enc_session_t *enc_session_p,
800        void *(crypto_streams)[4], const struct crypto_stream_if *cryst_if)
801{
802    struct enc_sess_iquic *const enc_sess = enc_session_p;
803    enc_sess->esi_streams = crypto_streams;
804    enc_sess->esi_cryst_if = cryst_if;
805}
806
807
808static enc_session_t *
809iquic_esfi_create_server (struct lsquic_engine_public *enpub,
810                    struct lsquic_conn *lconn, const lsquic_cid_t *first_dcid,
811                    void *(crypto_streams)[4],
812                    const struct crypto_stream_if *cryst_if,
813                    const struct lsquic_cid *odcid,
814                    const struct lsquic_cid *iscid )
815{
816    struct enc_sess_iquic *enc_sess;
817
818    enc_sess = calloc(1, sizeof(*enc_sess));
819    if (!enc_sess)
820        return NULL;
821
822#ifndef NDEBUG
823    enc_sess->esi_sni_bypass = getenv("LSQUIC_SNI_BYPASS");
824#endif
825
826    enc_sess->esi_flags = ESI_SERVER;
827    enc_sess->esi_streams = crypto_streams;
828    enc_sess->esi_cryst_if = cryst_if;
829    enc_sess->esi_enpub = enpub;
830    enc_sess->esi_conn = lconn;
831
832    if (odcid)
833    {
834        enc_sess->esi_odcid = *odcid;
835        enc_sess->esi_flags |= ESI_ODCID;
836    }
837    enc_sess->esi_iscid = *iscid;
838    enc_sess->esi_flags |= ESI_ISCID;
839
840    init_frals(enc_sess);
841
842    {
843        const char *log;
844        log = getenv("LSQUIC_LOG_SECRETS");
845        if (log)
846        {
847            if (atoi(log))
848                enc_sess->esi_flags |= ESI_LOG_SECRETS;
849            LSQ_DEBUG("will %slog secrets", atoi(log) ? "" : "not ");
850        }
851    }
852
853    if (0 != setup_handshake_keys(enc_sess, first_dcid))
854    {
855        free(enc_sess);
856        return NULL;
857    }
858
859    enc_sess->esi_max_streams_uni
860        = enpub->enp_settings.es_init_max_streams_uni;
861
862    return enc_sess;
863}
864
865
866static const char *const rw2str[] = { "read", "write", };
867
868typedef char evp_aead_enum_has_expected_values[
869    (int) evp_aead_open  == 0 && (int) evp_aead_seal == 1 ? 1 : -1];
870#define rw2dir(rw_) ((enum evp_aead_direction_t) (rw_))
871
872
873static void
874log_crypto_ctx (const struct enc_sess_iquic *enc_sess,
875                const struct crypto_ctx *ctx, const char *name, int rw)
876{
877    char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
878    LSQ_DEBUG("%s %s key: %s", name, rw2str[rw],
879        HEXSTR(ctx->yk_key_buf, ctx->yk_key_sz, hexbuf));
880    LSQ_DEBUG("%s %s iv: %s", name, rw2str[rw],
881        HEXSTR(ctx->yk_iv_buf, ctx->yk_iv_sz, hexbuf));
882}
883
884
885static void
886log_crypto_pair (const struct enc_sess_iquic *enc_sess,
887                    const struct crypto_ctx_pair *pair, const char *name)
888{
889    log_crypto_ctx(enc_sess, &pair->ykp_ctx[0], name, 0);
890    log_crypto_ctx(enc_sess, &pair->ykp_ctx[1], name, 1);
891}
892
893
894static void
895log_hp (const struct enc_sess_iquic *enc_sess,
896                    const struct header_prot *hp, const char *name)
897{
898    char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
899    LSQ_DEBUG("read %s hp: %s", name,
900        HEXSTR(hp->hp_buf[0], hp->hp_sz, hexbuf));
901    LSQ_DEBUG("write %s hp: %s", name,
902        HEXSTR(hp->hp_buf[1], hp->hp_sz, hexbuf));
903}
904
905
906/* [draft-ietf-quic-tls-12] Section 5.3.2 */
907static int
908setup_handshake_keys (struct enc_sess_iquic *enc_sess, const lsquic_cid_t *cid)
909{
910    const EVP_MD *const md = EVP_sha256();
911    const EVP_AEAD *const aead = EVP_aead_aes_128_gcm();
912    struct crypto_ctx_pair *pair;
913    struct header_prot *hp;
914    size_t hsk_secret_sz;
915    unsigned cliser;
916    unsigned char hsk_secret[EVP_MAX_MD_SIZE];
917    unsigned char secret[2][SHA256_DIGEST_LENGTH];  /* client, server */
918    char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
919
920    if (!enc_sess->esi_hsk_pairs)
921    {
922        enc_sess->esi_hsk_pairs = calloc(N_HSK_PAIRS,
923                                            sizeof(enc_sess->esi_hsk_pairs[0]));
924        enc_sess->esi_hsk_hps = calloc(N_HSK_PAIRS,
925                                            sizeof(enc_sess->esi_hsk_hps[0]));
926        if (!(enc_sess->esi_hsk_pairs && enc_sess->esi_hsk_hps))
927        {
928            free(enc_sess->esi_hsk_pairs);
929            free(enc_sess->esi_hsk_hps);
930            return -1;
931        }
932    }
933    pair = &enc_sess->esi_hsk_pairs[ENC_LEV_CLEAR];
934    pair->ykp_thresh = IQUIC_INVALID_PACKNO;
935    hp = &enc_sess->esi_hsk_hps[ENC_LEV_CLEAR];
936
937    HKDF_extract(hsk_secret, &hsk_secret_sz, md, cid->idbuf, cid->len,
938                                                        HSK_SALT, HSK_SALT_SZ);
939    if (enc_sess->esi_flags & ESI_LOG_SECRETS)
940    {
941        LSQ_DEBUG("handshake salt: %s", HEXSTR(HSK_SALT, HSK_SALT_SZ, hexbuf));
942        LSQ_DEBUG("handshake secret: %s", HEXSTR(hsk_secret, hsk_secret_sz,
943                                                                    hexbuf));
944    }
945
946    lsquic_qhkdf_expand(md, hsk_secret, hsk_secret_sz, CLIENT_LABEL,
947                CLIENT_LABEL_SZ, secret[0], sizeof(secret[0]));
948    lsquic_qhkdf_expand(md, hsk_secret, hsk_secret_sz, SERVER_LABEL,
949                SERVER_LABEL_SZ, secret[1], sizeof(secret[1]));
950    if (enc_sess->esi_flags & ESI_LOG_SECRETS)
951    {
952        LSQ_DEBUG("client handshake secret: %s",
953            HEXSTR(secret[0], sizeof(secret[0]), hexbuf));
954        LSQ_DEBUG("server handshake secret: %s",
955            HEXSTR(secret[1], sizeof(secret[1]), hexbuf));
956    }
957
958    cliser = !!(enc_sess->esi_flags & ESI_SERVER);
959    if (0 != init_crypto_ctx(&pair->ykp_ctx[!cliser], md, aead, secret[0],
960                sizeof(secret[0]), rw2dir(!cliser)))
961        goto err;
962    if (0 != init_crypto_ctx(&pair->ykp_ctx[cliser], md, aead, secret[1],
963                sizeof(secret[1]), rw2dir(cliser)))
964        goto err;
965
966    /* [draft-ietf-quic-tls-12] Section 5.6.1: AEAD_AES_128_GCM implies
967     * 128-bit AES-CTR.
968     */
969    hp->hp_cipher = EVP_aes_128_ecb();
970    hp->hp_gen_mask = gen_hp_mask_aes;
971    hp->hp_enc_level = ENC_LEV_CLEAR;
972    derive_hp_secrets(hp, md, aead, sizeof(secret[0]), secret[!cliser], secret[cliser]);
973
974    if (enc_sess->esi_flags & ESI_LOG_SECRETS)
975    {
976        log_crypto_pair(enc_sess, pair, "handshake");
977        log_hp(enc_sess, hp, "handshake");
978    }
979
980    return 0;
981
982  err:
983    cleanup_crypto_ctx(&pair->ykp_ctx[0]);
984    cleanup_crypto_ctx(&pair->ykp_ctx[1]);
985    return -1;
986}
987
988
989static void
990free_handshake_keys (struct enc_sess_iquic *enc_sess)
991{
992    struct crypto_ctx_pair *pair;
993
994    if (enc_sess->esi_hsk_pairs)
995    {
996        assert(enc_sess->esi_hsk_hps);
997        for (pair = enc_sess->esi_hsk_pairs; pair <
998                enc_sess->esi_hsk_pairs + N_HSK_PAIRS; ++pair)
999        {
1000            cleanup_crypto_ctx(&pair->ykp_ctx[0]);
1001            cleanup_crypto_ctx(&pair->ykp_ctx[1]);
1002        }
1003        free(enc_sess->esi_hsk_pairs);
1004        enc_sess->esi_hsk_pairs = NULL;
1005        free(enc_sess->esi_hsk_hps);
1006        enc_sess->esi_hsk_hps = NULL;
1007    }
1008    else
1009        assert(!enc_sess->esi_hsk_hps);
1010}
1011
1012
1013static void
1014keylog_callback (const SSL *ssl, const char *line)
1015{
1016    struct enc_sess_iquic *enc_sess;
1017
1018    enc_sess = SSL_get_ex_data(ssl, s_idx);
1019    if (enc_sess->esi_keylog_handle)
1020        enc_sess->esi_enpub->enp_kli->kli_log_line(
1021                                        enc_sess->esi_keylog_handle, line);
1022}
1023
1024
1025static void
1026maybe_setup_key_logging (struct enc_sess_iquic *enc_sess)
1027{
1028    if (enc_sess->esi_enpub->enp_kli)
1029    {
1030        enc_sess->esi_keylog_handle = enc_sess->esi_enpub->enp_kli->kli_open(
1031                        enc_sess->esi_enpub->enp_kli_ctx, enc_sess->esi_conn);
1032        LSQ_DEBUG("SSL keys %s be logged",
1033                            enc_sess->esi_keylog_handle ? "will" : "will not");
1034    }
1035}
1036
1037
1038static enum ssl_verify_result_t
1039verify_server_cert_callback (SSL *ssl, uint8_t *out_alert)
1040{
1041    struct enc_sess_iquic *enc_sess;
1042    struct stack_st_X509 *chain;
1043    int s;
1044
1045    enc_sess = SSL_get_ex_data(ssl, s_idx);
1046    chain = SSL_get_peer_cert_chain(ssl);
1047    if (!chain)
1048    {
1049        LSQ_ERROR("cannot get peer chain");
1050        return ssl_verify_invalid;
1051    }
1052
1053    EV_LOG_CERT_CHAIN(LSQUIC_LOG_CONN_ID, chain);
1054    if (enc_sess->esi_enpub->enp_verify_cert)
1055    {
1056        s = enc_sess->esi_enpub->enp_verify_cert(
1057                                    enc_sess->esi_enpub->enp_verify_ctx, chain);
1058        return s == 0 ? ssl_verify_ok : ssl_verify_invalid;
1059    }
1060    else
1061        return ssl_verify_ok;
1062}
1063
1064
1065static int
1066iquic_lookup_cert (SSL *ssl, void *arg)
1067{
1068    struct enc_sess_iquic *const enc_sess = arg;
1069    const struct network_path *path;
1070    const char *server_name;
1071    SSL_CTX *ssl_ctx;
1072
1073    server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
1074#ifndef NDEBUG
1075    if (!server_name)
1076        server_name = enc_sess->esi_sni_bypass;
1077#endif
1078    if (!server_name)
1079    {
1080        LSQ_DEBUG("cert lookup: server name is not set");
1081        /* SNI is required in HTTP/3 */
1082        if (enc_sess->esi_enpub->enp_flags & ENPUB_HTTP)
1083            return 1;
1084    }
1085
1086    path = enc_sess->esi_conn->cn_if->ci_get_path(enc_sess->esi_conn, NULL);
1087    ssl_ctx = enc_sess->esi_enpub->enp_lookup_cert(
1088                enc_sess->esi_enpub->enp_cert_lu_ctx, NP_LOCAL_SA(path),
1089                server_name);
1090
1091
1092    if (ssl_ctx)
1093    {
1094        if (SSL_set_SSL_CTX(enc_sess->esi_ssl, ssl_ctx))
1095        {
1096            LSQ_DEBUG("looked up cert for %s", server_name
1097                                                ? server_name : "<no SNI>");
1098            if (enc_sess->esi_enpub->enp_kli)
1099                SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
1100            SSL_set_verify(enc_sess->esi_ssl,
1101                                    SSL_CTX_get_verify_mode(ssl_ctx), NULL);
1102            SSL_set_verify_depth(enc_sess->esi_ssl,
1103                                    SSL_CTX_get_verify_depth(ssl_ctx));
1104            SSL_clear_options(enc_sess->esi_ssl,
1105                                    SSL_get_options(enc_sess->esi_ssl));
1106            SSL_set_options(enc_sess->esi_ssl,
1107                            SSL_CTX_get_options(ssl_ctx) & ~SSL_OP_NO_TLSv1_3);
1108            return 1;
1109        }
1110        else
1111        {
1112            LSQ_WARN("cannot set SSL_CTX");
1113            return 0;
1114        }
1115    }
1116    else
1117    {
1118        LSQ_DEBUG("could not look up cert for %s", server_name
1119                                                ? server_name : "<no SNI>");
1120        return 0;
1121    }
1122}
1123
1124
1125static void
1126iquic_esf_set_conn (enc_session_t *enc_session_p, struct lsquic_conn *lconn)
1127{
1128    struct enc_sess_iquic *const enc_sess = enc_session_p;
1129    enc_sess->esi_conn = lconn;
1130    LSQ_DEBUG("updated conn reference");
1131}
1132
1133
1134static int
1135iquic_esfi_init_server (enc_session_t *enc_session_p)
1136{
1137    struct enc_sess_iquic *const enc_sess = enc_session_p;
1138    const struct alpn_map *am;
1139    int transpa_len;
1140    SSL_CTX *ssl_ctx = NULL;
1141    union {
1142        char errbuf[ERR_ERROR_STRING_BUF_LEN];
1143        unsigned char trans_params[sizeof(struct transport_params)];
1144    } u;
1145
1146    if (enc_sess->esi_enpub->enp_alpn)
1147        enc_sess->esi_alpn = enc_sess->esi_enpub->enp_alpn;
1148    else if (enc_sess->esi_enpub->enp_flags & ENPUB_HTTP)
1149    {
1150        for (am = s_h3_alpns; am < s_h3_alpns + sizeof(s_h3_alpns)
1151                                                / sizeof(s_h3_alpns[0]); ++am)
1152            if (am->version == enc_sess->esi_conn->cn_version)
1153                goto ok;
1154        LSQ_ERROR("version %s has no matching ALPN",
1155                                lsquic_ver2str[enc_sess->esi_conn->cn_version]);
1156        return -1;
1157  ok:   enc_sess->esi_alpn = am->alpn;
1158    }
1159
1160    ssl_ctx = enc_sess->esi_enpub->enp_get_ssl_ctx(
1161                    lsquic_conn_get_peer_ctx(enc_sess->esi_conn, NULL));
1162    if (!ssl_ctx)
1163    {
1164        LSQ_ERROR("fetching SSL context associated with peer context failed");
1165        return -1;
1166    }
1167
1168    enc_sess->esi_ssl = SSL_new(ssl_ctx);
1169    if (!enc_sess->esi_ssl)
1170    {
1171        LSQ_ERROR("cannot create SSL object: %s",
1172            ERR_error_string(ERR_get_error(), u.errbuf));
1173        return -1;
1174    }
1175    if (!(SSL_set_quic_method(enc_sess->esi_ssl, &cry_quic_method)))
1176    {
1177        LSQ_INFO("could not set stream method");
1178        return -1;
1179    }
1180    maybe_setup_key_logging(enc_sess);
1181
1182    transpa_len = gen_trans_params(enc_sess, u.trans_params,
1183                                                    sizeof(u.trans_params));
1184    if (transpa_len < 0)
1185        return -1;
1186
1187    if (1 != SSL_set_quic_transport_params(enc_sess->esi_ssl, u.trans_params,
1188                                                            transpa_len))
1189    {
1190        LSQ_ERROR("cannot set QUIC transport params: %s",
1191            ERR_error_string(ERR_get_error(), u.errbuf));
1192        return -1;
1193    }
1194
1195    SSL_clear_options(enc_sess->esi_ssl, SSL_OP_NO_TLSv1_3);
1196    SSL_set_cert_cb(enc_sess->esi_ssl, iquic_lookup_cert, enc_sess);
1197    SSL_set_ex_data(enc_sess->esi_ssl, s_idx, enc_sess);
1198    SSL_set_accept_state(enc_sess->esi_ssl);
1199    LSQ_DEBUG("initialized server enc session");
1200    enc_sess->esi_flags |= ESI_INITIALIZED;
1201    return 0;
1202}
1203
1204
1205#if __BYTE_ORDER == __LITTLE_ENDIAN
1206#define WRITE_NUM(var_, val_, ptr_) do {                        \
1207    var_ = (val_);                                              \
1208    var_ = bswap_32(var_);                                      \
1209    memcpy((ptr_), &var_, sizeof(var_));                        \
1210    ptr_ += sizeof(var_);                                       \
1211} while (0)
1212#else
1213#define WRITE_NUM(var_, val_, ptr_) do {                        \
1214    var_ = (val_);                                              \
1215    memcpy((ptr_), &var_, sizeof(var_));                        \
1216    ptr_ += sizeof(var_);                                       \
1217} while (0)
1218#endif
1219
1220static int
1221iquic_new_session_cb (SSL *ssl, SSL_SESSION *session)
1222{
1223    struct enc_sess_iquic *enc_sess;
1224    uint32_t num;
1225    unsigned char *p, *buf;
1226    uint8_t *ticket_buf;
1227    size_t ticket_sz;
1228    lsquic_ver_tag_t tag;
1229    const uint8_t *trapa_buf;
1230    size_t trapa_sz, buf_sz;
1231
1232    enc_sess = SSL_get_ex_data(ssl, s_idx);
1233    assert(enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info);
1234
1235    SSL_get_peer_quic_transport_params(enc_sess->esi_ssl, &trapa_buf,
1236                                                                &trapa_sz);
1237    if (!(trapa_buf + trapa_sz))
1238    {
1239        LSQ_WARN("no transport parameters: cannot generate zero-rtt info");
1240        return 0;
1241    }
1242    if (trapa_sz > UINT32_MAX)
1243    {
1244        LSQ_WARN("trapa size too large: %zu", trapa_sz);
1245        return 0;
1246    }
1247
1248    if (!SSL_SESSION_to_bytes(session, &ticket_buf, &ticket_sz))
1249    {
1250        LSQ_INFO("could not serialize new session");
1251        return 0;
1252    }
1253    if (ticket_sz > UINT32_MAX)
1254    {
1255        LSQ_WARN("ticket size too large: %zu", ticket_sz);
1256        OPENSSL_free(ticket_buf);
1257        return 0;
1258    }
1259
1260    buf_sz = sizeof(tag) + sizeof(uint32_t) + sizeof(uint32_t)
1261                                + ticket_sz + sizeof(uint32_t) + trapa_sz;
1262    buf = malloc(buf_sz);
1263    if (!buf)
1264    {
1265        OPENSSL_free(ticket_buf);
1266        LSQ_WARN("%s: malloc failed", __func__);
1267        return 0;
1268    }
1269
1270    p = buf;
1271    tag = lsquic_ver2tag(enc_sess->esi_conn->cn_version);
1272    memcpy(p, &tag, sizeof(tag));
1273    p += sizeof(tag);
1274
1275    WRITE_NUM(num, ZERO_RTT_VERSION, p);
1276    WRITE_NUM(num, ticket_sz, p);
1277    memcpy(p, ticket_buf, ticket_sz);
1278    p += ticket_sz;
1279    WRITE_NUM(num, trapa_sz, p);
1280    memcpy(p, trapa_buf, trapa_sz);
1281    p += trapa_sz;
1282
1283    assert(buf + buf_sz == p);
1284    OPENSSL_free(ticket_buf);
1285
1286    LSQ_DEBUG("generated %zu bytes of zero-rtt buffer", buf_sz);
1287
1288    enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info(enc_sess->esi_conn,
1289                                                                buf, buf_sz);
1290    free(buf);
1291    enc_sess->esi_flags &= ~ESI_WANT_TICKET;
1292    lsquic_alarmset_unset(enc_sess->esi_alset, AL_SESS_TICKET);
1293    return 0;
1294}
1295
1296
1297static int
1298init_client (struct enc_sess_iquic *const enc_sess)
1299{
1300    SSL_CTX *ssl_ctx;
1301    SSL_SESSION *ssl_session;
1302    const struct alpn_map *am;
1303    int transpa_len;
1304    char errbuf[ERR_ERROR_STRING_BUF_LEN];
1305#define hexbuf errbuf   /* This is a dual-purpose buffer */
1306    unsigned char trans_params[0x80
1307#if LSQUIC_TEST_QUANTUM_READINESS
1308        + 4 + QUANTUM_READY_SZ
1309#endif
1310    ];
1311
1312    if (enc_sess->esi_enpub->enp_alpn)
1313        enc_sess->esi_alpn = enc_sess->esi_enpub->enp_alpn;
1314    else if (enc_sess->esi_enpub->enp_flags & ENPUB_HTTP)
1315    {
1316        for (am = s_h3_alpns; am < s_h3_alpns + sizeof(s_h3_alpns)
1317                                                / sizeof(s_h3_alpns[0]); ++am)
1318            if (am->version == enc_sess->esi_ver_neg->vn_ver)
1319                goto ok;
1320        LSQ_ERROR("version %s has no matching ALPN",
1321                                lsquic_ver2str[enc_sess->esi_ver_neg->vn_ver]);
1322        return -1;
1323  ok:   enc_sess->esi_alpn = am->alpn;
1324    }
1325
1326    LSQ_DEBUG("Create new SSL_CTX");
1327    ssl_ctx = SSL_CTX_new(TLS_method());
1328    if (!ssl_ctx)
1329    {
1330        LSQ_ERROR("cannot create SSL context: %s",
1331            ERR_error_string(ERR_get_error(), errbuf));
1332        goto err;
1333    }
1334    SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
1335    SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
1336    SSL_CTX_set_default_verify_paths(ssl_ctx);
1337    SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_CLIENT);
1338    if (enc_sess->esi_enpub->enp_stream_if->on_zero_rtt_info)
1339        SSL_CTX_sess_set_new_cb(ssl_ctx, iquic_new_session_cb);
1340    if (enc_sess->esi_enpub->enp_kli)
1341        SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
1342    if (enc_sess->esi_enpub->enp_verify_cert
1343            || LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)
1344            || LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_QLOG))
1345        SSL_CTX_set_custom_verify(ssl_ctx, SSL_VERIFY_PEER,
1346            verify_server_cert_callback);
1347    SSL_CTX_set_early_data_enabled(ssl_ctx, 1);
1348
1349    transpa_len = gen_trans_params(enc_sess, trans_params,
1350                                                    sizeof(trans_params));
1351    if (transpa_len < 0)
1352    {
1353        goto err;
1354    }
1355
1356    enc_sess->esi_ssl = SSL_new(ssl_ctx);
1357    if (!enc_sess->esi_ssl)
1358    {
1359        LSQ_ERROR("cannot create SSL object: %s",
1360            ERR_error_string(ERR_get_error(), errbuf));
1361        goto err;
1362    }
1363    if (!(SSL_set_quic_method(enc_sess->esi_ssl, &cry_quic_method)))
1364    {
1365        LSQ_INFO("could not set stream method");
1366        goto err;
1367    }
1368    maybe_setup_key_logging(enc_sess);
1369    if (1 != SSL_set_quic_transport_params(enc_sess->esi_ssl, trans_params,
1370                                                            transpa_len))
1371    {
1372        LSQ_ERROR("cannot set QUIC transport params: %s",
1373            ERR_error_string(ERR_get_error(), errbuf));
1374        goto err;
1375    }
1376    if (enc_sess->esi_alpn &&
1377            0 != SSL_set_alpn_protos(enc_sess->esi_ssl, enc_sess->esi_alpn,
1378                                                    enc_sess->esi_alpn[0] + 1))
1379    {
1380        LSQ_ERROR("cannot set ALPN: %s",
1381            ERR_error_string(ERR_get_error(), errbuf));
1382        goto err;
1383    }
1384    if (1 != SSL_set_tlsext_host_name(enc_sess->esi_ssl,
1385                                                    enc_sess->esi_hostname))
1386    {
1387        LSQ_ERROR("cannot set hostname: %s",
1388            ERR_error_string(ERR_get_error(), errbuf));
1389        goto err;
1390    }
1391    free(enc_sess->esi_hostname);
1392    enc_sess->esi_hostname = NULL;
1393    if (enc_sess->esi_zero_rtt_buf)
1394    {
1395        ssl_session = maybe_create_SSL_SESSION(enc_sess, ssl_ctx);
1396        if (ssl_session)
1397        {
1398            if (SSL_set_session(enc_sess->esi_ssl, ssl_session))
1399                enc_sess->esi_flags |= ESI_USE_SSL_TICKET;
1400            else
1401                LSQ_WARN("cannot set session");
1402        }
1403    }
1404
1405    SSL_set_ex_data(enc_sess->esi_ssl, s_idx, enc_sess);
1406    SSL_set_connect_state(enc_sess->esi_ssl);
1407    SSL_CTX_free(ssl_ctx);
1408    LSQ_DEBUG("initialized client enc session");
1409    enc_sess->esi_flags |= ESI_INITIALIZED;
1410    return 0;
1411
1412  err:
1413    if (ssl_ctx)
1414        SSL_CTX_free(ssl_ctx);
1415    return -1;
1416#undef hexbuf
1417}
1418
1419
1420struct crypto_params
1421{
1422    const EVP_AEAD      *aead;
1423    const EVP_MD        *md;
1424    const EVP_CIPHER    *hp;
1425    gen_hp_mask_f        gen_hp_mask;
1426};
1427
1428
1429static int
1430get_crypto_params (const struct enc_sess_iquic *enc_sess,
1431                    const SSL_CIPHER *cipher, struct crypto_params *params)
1432{
1433    unsigned key_sz, iv_sz;
1434    uint32_t id;
1435
1436    id = SSL_CIPHER_get_id(cipher);
1437
1438    LSQ_DEBUG("Negotiated cipher ID is 0x%"PRIX32, id);
1439
1440    /* RFC 8446, Appendix B.4 */
1441    switch (id)
1442    {
1443    case 0x03000000 | 0x1301:       /* TLS_AES_128_GCM_SHA256 */
1444        params->md          = EVP_sha256();
1445        params->aead        = EVP_aead_aes_128_gcm();
1446        params->hp          = EVP_aes_128_ecb();
1447        params->gen_hp_mask = gen_hp_mask_aes;
1448        break;
1449    case 0x03000000 | 0x1302:       /* TLS_AES_256_GCM_SHA384 */
1450        params->md          = EVP_sha384();
1451        params->aead        = EVP_aead_aes_256_gcm();
1452        params->hp          = EVP_aes_256_ecb();
1453        params->gen_hp_mask = gen_hp_mask_aes;
1454        break;
1455    case 0x03000000 | 0x1303:       /* TLS_CHACHA20_POLY1305_SHA256 */
1456        params->md          = EVP_sha256();
1457        params->aead        = EVP_aead_chacha20_poly1305();
1458        params->hp          = NULL;
1459        params->gen_hp_mask = gen_hp_mask_chacha20;
1460        break;
1461    default:
1462        /* TLS_AES_128_CCM_SHA256 and TLS_AES_128_CCM_8_SHA256 are not
1463         * supported by BoringSSL (grep for \b0x130[45]\b).
1464         */
1465        LSQ_DEBUG("unsupported cipher 0x%"PRIX32, id);
1466        return -1;
1467    }
1468
1469    key_sz = EVP_AEAD_key_length(params->aead);
1470    if (key_sz > EVP_MAX_KEY_LENGTH)
1471    {
1472        LSQ_DEBUG("key size %u is too large", key_sz);
1473        return -1;
1474    }
1475
1476    iv_sz = EVP_AEAD_nonce_length(params->aead);
1477    if (iv_sz < 8)
1478        iv_sz = 8;  /* [draft-ietf-quic-tls-11], Section 5.3 */
1479    if (iv_sz > EVP_MAX_IV_LENGTH)
1480    {
1481        LSQ_DEBUG("iv size %u is too large", iv_sz);
1482        return -1;
1483    }
1484
1485    /* FIXME: figure out why this duplicate check is here and either fix it
1486     * or get rid of it.
1487     */
1488    if (key_sz > EVP_MAX_KEY_LENGTH)
1489    {
1490        LSQ_DEBUG("PN size %u is too large", key_sz);
1491        return -1;
1492    }
1493
1494    return 0;
1495}
1496
1497
1498static int
1499get_peer_transport_params (struct enc_sess_iquic *enc_sess)
1500{
1501    struct transport_params *const trans_params = &enc_sess->esi_peer_tp;
1502    const uint8_t *params_buf;
1503    size_t bufsz;
1504    char *params_str;
1505    const enum lsquic_version version = enc_sess->esi_conn->cn_version;
1506
1507    SSL_get_peer_quic_transport_params(enc_sess->esi_ssl, &params_buf, &bufsz);
1508    if (!params_buf)
1509    {
1510        LSQ_DEBUG("no peer transport parameters");
1511        return -1;
1512    }
1513
1514    LSQ_DEBUG("have peer transport parameters (%zu bytes)", bufsz);
1515    if (0 > (version == LSQVER_ID27 ? lsquic_tp_decode_27
1516                : lsquic_tp_decode)(params_buf, bufsz,
1517                            !(enc_sess->esi_flags & ESI_SERVER),
1518                                                trans_params))
1519    {
1520        if (LSQ_LOG_ENABLED(LSQ_LOG_DEBUG))
1521        {
1522            params_str = lsquic_mm_get_4k(&enc_sess->esi_enpub->enp_mm);
1523            if (params_str)
1524            {
1525                lsquic_hexdump(params_buf, bufsz, params_str, 0x1000);
1526                LSQ_DEBUG("could not parse peer transport parameters "
1527                    "(%zd bytes):\n%s", bufsz, params_str);
1528                lsquic_mm_put_4k(&enc_sess->esi_enpub->enp_mm, params_str);
1529            }
1530            else
1531                LSQ_DEBUG("could not parse peer transport parameters "
1532                    "(%zd bytes)", bufsz);
1533        }
1534        return -1;
1535    }
1536
1537    const lsquic_cid_t *const cids[LAST_TPI + 1] = {
1538        [TP_CID_IDX(TPI_ORIGINAL_DEST_CID)]  = enc_sess->esi_flags & ESI_ODCID ? &enc_sess->esi_odcid : NULL,
1539        [TP_CID_IDX(TPI_RETRY_SOURCE_CID)]   = enc_sess->esi_flags & ESI_RSCID ? &enc_sess->esi_rscid : NULL,
1540        [TP_CID_IDX(TPI_INITIAL_SOURCE_CID)] = enc_sess->esi_flags & ESI_ISCID ? &enc_sess->esi_iscid : NULL,
1541    };
1542
1543    unsigned must_have, must_not_have = 0;
1544    if (version > LSQVER_ID27)
1545    {
1546        must_have = 1 << TPI_INITIAL_SOURCE_CID;
1547        if (enc_sess->esi_flags & ESI_SERVER)
1548            must_not_have |= 1 << TPI_ORIGINAL_DEST_CID;
1549        else
1550            must_have |= 1 << TPI_ORIGINAL_DEST_CID;
1551        if ((enc_sess->esi_flags & (ESI_RETRY|ESI_SERVER)) == ESI_RETRY)
1552            must_have |= 1 << TPI_RETRY_SOURCE_CID;
1553        else
1554            must_not_have |= 1 << TPI_RETRY_SOURCE_CID;
1555    }
1556    else if ((enc_sess->esi_flags & (ESI_RETRY|ESI_SERVER)) == ESI_RETRY)
1557        must_have = 1 << TPI_ORIGINAL_DEST_CID;
1558    else
1559        must_have = 0;
1560
1561    enum transport_param_id tpi;
1562    for (tpi = FIRST_TP_CID; tpi <= LAST_TP_CID; ++tpi)
1563    {
1564        if (!(must_have & (1 << tpi)))
1565            continue;
1566        if (!(trans_params->tp_set & (1 << tpi)))
1567        {
1568            LSQ_DEBUG("server did not produce %s", lsquic_tpi2str[tpi]);
1569            return -1;
1570        }
1571        if (!cids[TP_CID_IDX(tpi)])
1572        {
1573            LSQ_WARN("do not have CID %s for checking",
1574                                                    lsquic_tpi2str[tpi]);
1575            return -1;
1576        }
1577        if (LSQUIC_CIDS_EQ(cids[TP_CID_IDX(tpi)],
1578                                &trans_params->tp_cids[TP_CID_IDX(tpi)]))
1579            LSQ_DEBUG("%s values match", lsquic_tpi2str[tpi]);
1580        else
1581        {
1582            if (LSQ_LOG_ENABLED(LSQ_LOG_DEBUG))
1583            {
1584                char cidbuf[2][MAX_CID_LEN * 2 + 1];
1585                LSQ_DEBUG("server provided %s %"CID_FMT" that does not "
1586                    "match ours %"CID_FMT, lsquic_tpi2str[tpi],
1587                    CID_BITS_B(&trans_params->tp_cids[TP_CID_IDX(tpi)],
1588                                                            cidbuf[0]),
1589                    CID_BITS_B(cids[TP_CID_IDX(tpi)], cidbuf[1]));
1590            }
1591            return -1;
1592        }
1593    }
1594
1595    for (tpi = FIRST_TP_CID; tpi <= LAST_TP_CID; ++tpi)
1596        if (must_not_have & (1 << tpi) & trans_params->tp_set)
1597        {
1598            LSQ_DEBUG("server transport parameters unexpectedly contain %s",
1599                                        lsquic_tpi2str[tpi]);
1600            return -1;
1601        }
1602
1603    if ((trans_params->tp_set & (1 << TPI_LOSS_BITS))
1604                            && enc_sess->esi_enpub->enp_settings.es_ql_bits)
1605    {
1606        const unsigned our_loss_bits
1607            = enc_sess->esi_enpub->enp_settings.es_ql_bits - 1;
1608        switch ((our_loss_bits << 1) | trans_params->tp_loss_bits)
1609        {
1610        case    (0             << 1) | 0:
1611            LSQ_DEBUG("both sides only tolerate QL bits: don't enable them");
1612            break;
1613        case    (0             << 1) | 1:
1614            LSQ_DEBUG("peer sends QL bits, we receive them");
1615            enc_sess->esi_flags |= ESI_RECV_QL_BITS;
1616            break;
1617        case    (1             << 1) | 0:
1618            LSQ_DEBUG("we send QL bits, peer receives them");
1619            enc_sess->esi_flags |= ESI_SEND_QL_BITS;
1620            break;
1621        default/*1             << 1) | 1*/:
1622            LSQ_DEBUG("enable sending and receiving QL bits");
1623            enc_sess->esi_flags |= ESI_RECV_QL_BITS;
1624            enc_sess->esi_flags |= ESI_SEND_QL_BITS;
1625            break;
1626        }
1627    }
1628    else
1629        LSQ_DEBUG("no QL bits");
1630
1631    return 0;
1632}
1633
1634
1635static int
1636maybe_get_peer_transport_params (struct enc_sess_iquic *enc_sess)
1637{
1638    int s;
1639
1640    if (enc_sess->esi_flags & ESI_HAVE_PEER_TP)
1641        return 0;
1642
1643    s = get_peer_transport_params(enc_sess);
1644    if (s == 0)
1645        enc_sess->esi_flags |= ESI_HAVE_PEER_TP;
1646
1647    return s;
1648}
1649
1650
1651static enum iquic_handshake_status
1652iquic_esfi_handshake (struct enc_sess_iquic *enc_sess)
1653{
1654    int s, err;
1655    enum lsquic_hsk_status hsk_status;
1656    char errbuf[ERR_ERROR_STRING_BUF_LEN];
1657
1658    s = SSL_do_handshake(enc_sess->esi_ssl);
1659    if (s <= 0)
1660    {
1661        err = SSL_get_error(enc_sess->esi_ssl, s);
1662        switch (err)
1663        {
1664        case SSL_ERROR_WANT_READ:
1665            LSQ_DEBUG("retry read");
1666            return IHS_WANT_READ;
1667        case SSL_ERROR_WANT_WRITE:
1668            LSQ_DEBUG("retry write");
1669            return IHS_WANT_WRITE;
1670        case SSL_ERROR_EARLY_DATA_REJECTED:
1671            LSQ_DEBUG("early data rejected");
1672            hsk_status = LSQ_HSK_0RTT_FAIL;
1673            goto err;
1674            /* fall through */
1675        default:
1676            LSQ_DEBUG("handshake: %s", ERR_error_string(err, errbuf));
1677            hsk_status = LSQ_HSK_FAIL;
1678            goto err;
1679        }
1680    }
1681
1682
1683    if (SSL_in_early_data(enc_sess->esi_ssl))
1684    {
1685        LSQ_DEBUG("in early data");
1686        if (enc_sess->esi_flags & ESI_SERVER)
1687            LSQ_DEBUG("TODO");
1688        else
1689            return IHS_WANT_READ;
1690    }
1691
1692    hsk_status = LSQ_HSK_OK;
1693    LSQ_DEBUG("handshake reported complete");
1694    EV_LOG_HSK_COMPLETED(LSQUIC_LOG_CONN_ID);
1695    /* The ESI_USE_SSL_TICKET flag indicates if the client attempted 0-RTT.
1696     * If the handshake is complete, and the client attempted 0-RTT, it
1697     * must have succeeded.
1698     */
1699    if (enc_sess->esi_flags & ESI_USE_SSL_TICKET)
1700    {
1701        hsk_status = LSQ_HSK_0RTT_OK;
1702        EV_LOG_ZERO_RTT(LSQUIC_LOG_CONN_ID);
1703    }
1704
1705    if (0 != maybe_get_peer_transport_params(enc_sess))
1706    {
1707        hsk_status = LSQ_HSK_FAIL;
1708        goto err;
1709    }
1710
1711    enc_sess->esi_flags |= ESI_HANDSHAKE_OK;
1712    enc_sess->esi_conn->cn_if->ci_hsk_done(enc_sess->esi_conn, hsk_status);
1713
1714    return IHS_STOP;    /* XXX: what else can come on the crypto stream? */
1715
1716  err:
1717    LSQ_DEBUG("handshake failed");
1718    enc_sess->esi_conn->cn_if->ci_hsk_done(enc_sess->esi_conn, hsk_status);
1719    return IHS_STOP;
1720}
1721
1722
1723static enum iquic_handshake_status
1724iquic_esfi_post_handshake (struct enc_sess_iquic *enc_sess)
1725{
1726    int s;
1727
1728    s = SSL_process_quic_post_handshake(enc_sess->esi_ssl);
1729    LSQ_DEBUG("SSL_process_quic_post_handshake() returned %d", s);
1730    if (s == 1)
1731        return IHS_WANT_READ;
1732    else
1733    {
1734        enc_sess->esi_conn->cn_if->ci_internal_error(enc_sess->esi_conn,
1735                                        "post-handshake error, code %d", s);
1736        return IHS_STOP;
1737    }
1738}
1739
1740
1741static struct transport_params *
1742iquic_esfi_get_peer_transport_params (enc_session_t *enc_session_p)
1743{
1744    struct enc_sess_iquic *const enc_sess = enc_session_p;
1745
1746    if (0 == maybe_get_peer_transport_params(enc_sess))
1747        return &enc_sess->esi_peer_tp;
1748    else
1749        return NULL;
1750}
1751
1752
1753static void
1754iquic_esfi_destroy (enc_session_t *enc_session_p)
1755{
1756    struct enc_sess_iquic *const enc_sess = enc_session_p;
1757    struct frab_list *fral;
1758    LSQ_DEBUG("iquic_esfi_destroy");
1759
1760    for (fral = enc_sess->esi_frals; fral < enc_sess->esi_frals
1761            + sizeof(enc_sess->esi_frals) / sizeof(enc_sess->esi_frals[0]);
1762                ++fral)
1763        lsquic_frab_list_cleanup(fral);
1764    if (enc_sess->esi_keylog_handle)
1765        enc_sess->esi_enpub->enp_kli->kli_close(enc_sess->esi_keylog_handle);
1766    if (enc_sess->esi_ssl)
1767        SSL_free(enc_sess->esi_ssl);
1768
1769    free_handshake_keys(enc_sess);
1770
1771    free(enc_sess->esi_zero_rtt_buf);
1772    free(enc_sess->esi_hostname);
1773    free(enc_sess);
1774}
1775
1776
1777/* See [draft-ietf-quic-tls-14], Section 4 */
1778static const enum enc_level hety2el[] =
1779{
1780    [HETY_NOT_SET]   = ENC_LEV_FORW,
1781    [HETY_VERNEG]    = 0,
1782    [HETY_INITIAL]   = ENC_LEV_CLEAR,
1783    [HETY_RETRY]     = 0,
1784    [HETY_HANDSHAKE] = ENC_LEV_INIT,
1785    [HETY_0RTT]      = ENC_LEV_EARLY,
1786};
1787
1788
1789static const enum enc_level pns2enc_level[] =
1790{
1791    [PNS_INIT]  = ENC_LEV_CLEAR,
1792    [PNS_HSK]   = ENC_LEV_INIT,
1793    [PNS_APP]   = ENC_LEV_FORW,
1794};
1795
1796
1797static enum enc_packout
1798iquic_esf_encrypt_packet (enc_session_t *enc_session_p,
1799    const struct lsquic_engine_public *enpub, struct lsquic_conn *lconn_UNUSED,
1800    struct lsquic_packet_out *packet_out)
1801{
1802    struct enc_sess_iquic *const enc_sess = enc_session_p;
1803    struct lsquic_conn *const lconn = enc_sess->esi_conn;
1804    unsigned char *dst;
1805    const struct crypto_ctx_pair *pair;
1806    const struct crypto_ctx *crypto_ctx;
1807    const struct header_prot *hp;
1808    enum enc_level enc_level;
1809    unsigned char nonce_buf[ sizeof(crypto_ctx->yk_iv_buf) + 8 ];
1810    unsigned char *nonce, *begin_xor;
1811    lsquic_packno_t packno;
1812    size_t out_sz, dst_sz;
1813    int header_sz;
1814    int ipv6;
1815    unsigned packno_off, packno_len;
1816    enum packnum_space pns;
1817    char errbuf[ERR_ERROR_STRING_BUF_LEN];
1818
1819    pns = lsquic_packet_out_pns(packet_out);
1820    /* TODO Obviously, will need more logic for 0-RTT */
1821    enc_level = pns2enc_level[ pns ];
1822
1823    if (enc_level == ENC_LEV_FORW)
1824    {
1825        pair = &enc_sess->esi_pairs[ enc_sess->esi_key_phase ];
1826        crypto_ctx = &pair->ykp_ctx[ 1 ];
1827        hp = &enc_sess->esi_hp;
1828    }
1829    else if (enc_sess->esi_hsk_pairs)
1830    {
1831        pair = &enc_sess->esi_hsk_pairs[ enc_level ];
1832        crypto_ctx = &pair->ykp_ctx[ 1 ];
1833        hp = &enc_sess->esi_hsk_hps[ enc_level ];
1834    }
1835    else
1836    {
1837        LSQ_WARN("no keys for encryption level %s",
1838                                            lsquic_enclev2str[enc_level]);
1839        return ENCPA_BADCRYPT;
1840    }
1841
1842    if (UNLIKELY(0 == (crypto_ctx->yk_flags & YK_INITED)))
1843    {
1844        LSQ_WARN("encrypt crypto context at level %s not initialized",
1845                                            lsquic_enclev2str[enc_level]);
1846        return ENCPA_BADCRYPT;
1847    }
1848
1849    if (packet_out->po_data_sz < 3)
1850    {
1851        /* [draft-ietf-quic-tls-20] Section 5.4.2 */
1852        enum packno_bits bits = lsquic_packet_out_packno_bits(packet_out);
1853        unsigned len = iquic_packno_bits2len(bits);
1854        if (packet_out->po_data_sz + len < 4)
1855        {
1856            len = 4 - packet_out->po_data_sz - len;
1857            memset(packet_out->po_data + packet_out->po_data_sz, 0, len);
1858            packet_out->po_data_sz += len;
1859            packet_out->po_frame_types |= QUIC_FTBIT_PADDING;
1860            LSQ_DEBUG("padded packet %"PRIu64" with %u bytes of PADDING",
1861                packet_out->po_packno, len);
1862        }
1863    }
1864
1865    dst_sz = lconn->cn_pf->pf_packout_size(lconn, packet_out);
1866    ipv6 = NP_IS_IPv6(packet_out->po_path);
1867    dst = enpub->enp_pmi->pmi_allocate(enpub->enp_pmi_ctx,
1868                                packet_out->po_path->np_peer_ctx, dst_sz, ipv6);
1869    if (!dst)
1870    {
1871        LSQ_DEBUG("could not allocate memory for outgoing packet of size %zd",
1872                                                                        dst_sz);
1873        return ENCPA_NOMEM;
1874    }
1875
1876    /* Align nonce so we can perform XOR safely in one shot: */
1877    begin_xor = nonce_buf + sizeof(nonce_buf) - 8;
1878    begin_xor = (unsigned char *) ((uintptr_t) begin_xor & ~0x7);
1879    nonce = begin_xor - crypto_ctx->yk_iv_sz + 8;
1880    memcpy(nonce, crypto_ctx->yk_iv_buf, crypto_ctx->yk_iv_sz);
1881    packno = packet_out->po_packno;
1882    if (s_log_seal_and_open)
1883        LSQ_DEBUG("seal: iv: %s; packno: 0x%"PRIX64,
1884            HEXSTR(crypto_ctx->yk_iv_buf, crypto_ctx->yk_iv_sz, s_str), packno);
1885#if __BYTE_ORDER == __LITTLE_ENDIAN
1886    packno = bswap_64(packno);
1887#endif
1888    *((uint64_t *) begin_xor) ^= packno;
1889
1890    header_sz = lconn->cn_pf->pf_gen_reg_pkt_header(lconn, packet_out, dst,
1891                                                                        dst_sz);
1892    if (header_sz < 0)
1893        goto err;
1894    if (enc_level == ENC_LEV_FORW)
1895        dst[0] |= enc_sess->esi_key_phase << 2;
1896
1897    if (s_log_seal_and_open)
1898    {
1899        LSQ_DEBUG("seal: nonce (%u bytes): %s", crypto_ctx->yk_iv_sz,
1900            HEXSTR(nonce, crypto_ctx->yk_iv_sz, s_str));
1901        LSQ_DEBUG("seal: ad (%u bytes): %s", header_sz,
1902            HEXSTR(dst, header_sz, s_str));
1903        LSQ_DEBUG("seal: in (%u bytes): %s", packet_out->po_data_sz,
1904            HEXSTR(packet_out->po_data, packet_out->po_data_sz, s_str));
1905    }
1906    if (!EVP_AEAD_CTX_seal(&crypto_ctx->yk_aead_ctx, dst + header_sz, &out_sz,
1907                dst_sz - header_sz, nonce, crypto_ctx->yk_iv_sz, packet_out->po_data,
1908                packet_out->po_data_sz, dst, header_sz))
1909    {
1910        LSQ_WARN("cannot seal packet #%"PRIu64": %s", packet_out->po_packno,
1911            ERR_error_string(ERR_get_error(), errbuf));
1912        goto err;
1913    }
1914    assert(out_sz == dst_sz - header_sz);
1915
1916    lconn->cn_pf->pf_packno_info(lconn, packet_out, &packno_off, &packno_len);
1917#ifndef NDEBUG
1918    const unsigned sample_off = packno_off + 4;
1919    assert(sample_off + IQUIC_TAG_LEN <= dst_sz);
1920#endif
1921    apply_hp(enc_sess, hp, dst, packno_off, packno_len);
1922
1923    packet_out->po_enc_data    = dst;
1924    packet_out->po_enc_data_sz = dst_sz;
1925    packet_out->po_sent_sz     = dst_sz;
1926    packet_out->po_flags &= ~PO_IPv6;
1927    packet_out->po_flags |= PO_ENCRYPTED|PO_SENT_SZ|(ipv6 << POIPv6_SHIFT);
1928    lsquic_packet_out_set_enc_level(packet_out, enc_level);
1929    lsquic_packet_out_set_kp(packet_out, enc_sess->esi_key_phase);
1930    return ENCPA_OK;
1931
1932  err:
1933    enpub->enp_pmi->pmi_return(enpub->enp_pmi_ctx,
1934                                packet_out->po_path->np_peer_ctx, dst, ipv6);
1935    return ENCPA_BADCRYPT;
1936}
1937
1938
1939static struct ku_label
1940{
1941    const char *str;
1942    uint8_t     len;
1943}
1944
1945
1946select_ku_label (const struct enc_sess_iquic *enc_sess)
1947{
1948    return (struct ku_label) { "quic ku", 7, };
1949}
1950
1951
1952static enum dec_packin
1953iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
1954        struct lsquic_engine_public *enpub, const struct lsquic_conn *lconn,
1955        struct lsquic_packet_in *packet_in)
1956{
1957    struct enc_sess_iquic *const enc_sess = enc_session_p;
1958    unsigned char *dst;
1959    struct crypto_ctx_pair *pair;
1960    const struct header_prot *hp;
1961    struct crypto_ctx *crypto_ctx = NULL;
1962    unsigned char nonce_buf[ sizeof(crypto_ctx->yk_iv_buf) + 8 ];
1963    unsigned char *nonce, *begin_xor;
1964    unsigned sample_off, packno_len, key_phase;
1965    enum enc_level enc_level;
1966    enum packnum_space pns;
1967    lsquic_packno_t packno;
1968    size_t out_sz;
1969    enum dec_packin dec_packin;
1970    int s;
1971    const size_t dst_sz = packet_in->pi_data_sz;
1972    unsigned char new_secret[EVP_MAX_KEY_LENGTH];
1973    struct crypto_ctx crypto_ctx_buf;
1974    char secret_str[EVP_MAX_KEY_LENGTH * 2 + 1];
1975    char errbuf[ERR_ERROR_STRING_BUF_LEN];
1976
1977    dst = lsquic_mm_get_packet_in_buf(&enpub->enp_mm, dst_sz);
1978    if (!dst)
1979    {
1980        LSQ_WARN("cannot allocate memory to copy incoming packet data");
1981        dec_packin = DECPI_NOMEM;
1982        goto err;
1983    }
1984
1985    enc_level = hety2el[packet_in->pi_header_type];
1986    if (enc_level == ENC_LEV_FORW)
1987        hp = &enc_sess->esi_hp;
1988    else if (enc_sess->esi_hsk_pairs)
1989        hp = &enc_sess->esi_hsk_hps[ enc_level ];
1990    else
1991        hp = NULL;
1992
1993    if (UNLIKELY(!(hp && header_prot_inited(hp, 0))))
1994    {
1995        LSQ_DEBUG("header protection for level %u not initialized yet",
1996                                                                enc_level);
1997        dec_packin = DECPI_NOT_YET;
1998        goto err;
1999    }
2000
2001    /* Decrypt packet number.  After this operation, packet_in is adjusted:
2002     * the packet number becomes part of the header.
2003     */
2004    sample_off = packet_in->pi_header_sz + 4;
2005    if (sample_off + IQUIC_TAG_LEN > packet_in->pi_data_sz)
2006    {
2007        LSQ_INFO("packet data is too short: %hu bytes",
2008                                                packet_in->pi_data_sz);
2009        dec_packin = DECPI_TOO_SHORT;
2010        goto err;
2011    }
2012    memcpy(dst, packet_in->pi_data, sample_off);
2013    packet_in->pi_packno =
2014    packno = strip_hp(enc_sess, hp,
2015        packet_in->pi_data + sample_off,
2016        dst, packet_in->pi_header_sz, &packno_len);
2017
2018    if (enc_level == ENC_LEV_FORW)
2019    {
2020        key_phase = (dst[0] & 0x04) > 0;
2021        pair = &enc_sess->esi_pairs[ key_phase ];
2022        if (key_phase == enc_sess->esi_key_phase)
2023        {
2024            crypto_ctx = &pair->ykp_ctx[ 0 ];
2025            /* Checked by header_prot_inited() above */
2026            assert(crypto_ctx->yk_flags & YK_INITED);
2027        }
2028        else if (!is_valid_packno(
2029                        enc_sess->esi_pairs[enc_sess->esi_key_phase].ykp_thresh)
2030                || packet_in->pi_packno
2031                    > enc_sess->esi_pairs[enc_sess->esi_key_phase].ykp_thresh)
2032        {
2033            const struct ku_label kl = select_ku_label(enc_sess);
2034            lsquic_qhkdf_expand(enc_sess->esi_md,
2035                enc_sess->esi_traffic_secrets[0], enc_sess->esi_trasec_sz,
2036                kl.str, kl.len, new_secret, enc_sess->esi_trasec_sz);
2037            if (enc_sess->esi_flags & ESI_LOG_SECRETS)
2038                LSQ_DEBUG("key phase changed to %u, will try decrypting using "
2039                    "new secret %s", key_phase, HEXSTR(new_secret,
2040                    enc_sess->esi_trasec_sz, secret_str));
2041            else
2042                LSQ_DEBUG("key phase changed to %u, will try decrypting using "
2043                    "new secret", key_phase);
2044            crypto_ctx = &crypto_ctx_buf;
2045            crypto_ctx->yk_flags = 0;
2046            s = init_crypto_ctx(crypto_ctx, enc_sess->esi_md,
2047                        enc_sess->esi_aead, new_secret, enc_sess->esi_trasec_sz,
2048                        evp_aead_open);
2049            if (s != 0)
2050            {
2051                LSQ_ERROR("could not init open crypto ctx (key phase)");
2052                dec_packin = DECPI_BADCRYPT;
2053                goto err;
2054            }
2055        }
2056        else
2057        {
2058            crypto_ctx = &pair->ykp_ctx[ 0 ];
2059            if (UNLIKELY(0 == (crypto_ctx->yk_flags & YK_INITED)))
2060            {
2061                LSQ_DEBUG("supposedly older context is not initialized (key "
2062                    "phase: %u)", key_phase);
2063                dec_packin = DECPI_BADCRYPT;
2064                goto err;
2065            }
2066        }
2067    }
2068    else
2069    {
2070        key_phase = 0;
2071        assert(enc_sess->esi_hsk_pairs);
2072        pair = &enc_sess->esi_hsk_pairs[ enc_level ];
2073        crypto_ctx = &pair->ykp_ctx[ 0 ];
2074        if (UNLIKELY(0 == (crypto_ctx->yk_flags & YK_INITED)))
2075        {
2076            LSQ_WARN("decrypt crypto context at level %s not initialized",
2077                                                    lsquic_enclev2str[enc_level]);
2078            dec_packin = DECPI_BADCRYPT;
2079            goto err;
2080        }
2081    }
2082
2083    if (s_log_seal_and_open)
2084        LSQ_DEBUG("open: iv: %s; packno: 0x%"PRIX64,
2085            HEXSTR(crypto_ctx->yk_iv_buf, crypto_ctx->yk_iv_sz, s_str), packno);
2086    /* Align nonce so we can perform XOR safely in one shot: */
2087    begin_xor = nonce_buf + sizeof(nonce_buf) - 8;
2088    begin_xor = (unsigned char *) ((uintptr_t) begin_xor & ~0x7);
2089    nonce = begin_xor - crypto_ctx->yk_iv_sz + 8;
2090    memcpy(nonce, crypto_ctx->yk_iv_buf, crypto_ctx->yk_iv_sz);
2091#if __BYTE_ORDER == __LITTLE_ENDIAN
2092    packno = bswap_64(packno);
2093#endif
2094    *((uint64_t *) begin_xor) ^= packno;
2095
2096    packet_in->pi_header_sz += packno_len;
2097
2098    if (s_log_seal_and_open)
2099    {
2100        LSQ_DEBUG("open: nonce (%u bytes): %s", crypto_ctx->yk_iv_sz,
2101            HEXSTR(nonce, crypto_ctx->yk_iv_sz, s_str));
2102        LSQ_DEBUG("open: ad (%u bytes): %s", packet_in->pi_header_sz,
2103            HEXSTR(dst, packet_in->pi_header_sz, s_str));
2104        LSQ_DEBUG("open: in (%u bytes): %s", packet_in->pi_data_sz
2105            - packet_in->pi_header_sz, HEXSTR(packet_in->pi_data
2106            + packet_in->pi_header_sz, packet_in->pi_data_sz
2107            - packet_in->pi_header_sz, s_str));
2108    }
2109    if (!EVP_AEAD_CTX_open(&crypto_ctx->yk_aead_ctx,
2110                dst + packet_in->pi_header_sz, &out_sz,
2111                dst_sz - packet_in->pi_header_sz, nonce, crypto_ctx->yk_iv_sz,
2112                packet_in->pi_data + packet_in->pi_header_sz,
2113                packet_in->pi_data_sz - packet_in->pi_header_sz,
2114                dst, packet_in->pi_header_sz))
2115    {
2116        LSQ_INFO("cannot open packet #%"PRIu64": %s", packet_in->pi_packno,
2117            ERR_error_string(ERR_get_error(), errbuf));
2118        dec_packin = DECPI_BADCRYPT;
2119        goto err;
2120    }
2121
2122    if (enc_sess->esi_flags & ESI_SEND_QL_BITS)
2123    {
2124        packet_in->pi_flags |= PI_LOG_QL_BITS;
2125        if (dst[0] & 0x10)
2126            packet_in->pi_flags |= PI_SQUARE_BIT;
2127        if (dst[0] & 0x08)
2128            packet_in->pi_flags |= PI_LOSS_BIT;
2129    }
2130    else if (dst[0] & (0x0C << (packet_in->pi_header_type == HETY_NOT_SET)))
2131    {
2132        LSQ_DEBUG("reserved bits are not set to zero");
2133        dec_packin = DECPI_VIOLATION;
2134        goto err;
2135    }
2136
2137    if (crypto_ctx == &crypto_ctx_buf)
2138    {
2139        LSQ_DEBUG("decryption in the new key phase %u successful, rotate "
2140            "keys", key_phase);
2141        const struct ku_label kl = select_ku_label(enc_sess);
2142        pair->ykp_thresh = packet_in->pi_packno;
2143        pair->ykp_ctx[ 0 ] = crypto_ctx_buf;
2144        memcpy(enc_sess->esi_traffic_secrets[ 0 ], new_secret,
2145                                                enc_sess->esi_trasec_sz);
2146        lsquic_qhkdf_expand(enc_sess->esi_md,
2147            enc_sess->esi_traffic_secrets[1], enc_sess->esi_trasec_sz,
2148            kl.str, kl.len, new_secret, enc_sess->esi_trasec_sz);
2149        memcpy(enc_sess->esi_traffic_secrets[1], new_secret,
2150                                                enc_sess->esi_trasec_sz);
2151        s = init_crypto_ctx(&pair->ykp_ctx[1], enc_sess->esi_md,
2152                    enc_sess->esi_aead, new_secret, enc_sess->esi_trasec_sz,
2153                    evp_aead_seal);
2154        if (s != 0)
2155        {
2156            LSQ_ERROR("could not init seal crypto ctx (key phase)");
2157            cleanup_crypto_ctx(&pair->ykp_ctx[1]);
2158            /* This is a severe error, abort connection */
2159            enc_sess->esi_conn->cn_if->ci_internal_error(enc_sess->esi_conn,
2160                "crypto ctx failure during key phase shift");
2161            dec_packin = DECPI_BADCRYPT;
2162            goto err;
2163        }
2164        if (enc_sess->esi_flags & ESI_LOG_SECRETS)
2165            log_crypto_pair(enc_sess, pair, "updated");
2166        enc_sess->esi_key_phase = key_phase;
2167    }
2168
2169    packet_in->pi_data_sz = packet_in->pi_header_sz + out_sz;
2170    if (packet_in->pi_flags & PI_OWN_DATA)
2171        lsquic_mm_put_packet_in_buf(&enpub->enp_mm, packet_in->pi_data,
2172                                                        packet_in->pi_data_sz);
2173    packet_in->pi_data = dst;
2174    packet_in->pi_flags |= PI_OWN_DATA | PI_DECRYPTED
2175                        | (enc_level << PIBIT_ENC_LEV_SHIFT);
2176    EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "decrypted packet %"PRIu64,
2177                                                    packet_in->pi_packno);
2178    pns = lsquic_enclev2pns[enc_level];
2179    if (packet_in->pi_packno > enc_sess->esi_max_packno[pns])
2180        enc_sess->esi_max_packno[pns] = packet_in->pi_packno;
2181    if (is_valid_packno(pair->ykp_thresh)
2182                                && packet_in->pi_packno > pair->ykp_thresh)
2183        pair->ykp_thresh = packet_in->pi_packno;
2184    return DECPI_OK;
2185
2186  err:
2187    if (crypto_ctx == &crypto_ctx_buf)
2188        cleanup_crypto_ctx(crypto_ctx);
2189    if (dst)
2190        lsquic_mm_put_packet_in_buf(&enpub->enp_mm, dst, dst_sz);
2191    EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "could not decrypt packet (type %s, "
2192        "number %"PRIu64")", lsquic_hety2str[packet_in->pi_header_type],
2193                                                    packet_in->pi_packno);
2194    return dec_packin;
2195}
2196
2197
2198static int
2199iquic_esf_global_init (int flags)
2200{
2201    s_idx = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
2202    if (s_idx >= 0)
2203    {
2204        LSQ_LOG1(LSQ_LOG_DEBUG, "SSL extra data index: %d", s_idx);
2205        return 0;
2206    }
2207    else
2208    {
2209        LSQ_LOG1(LSQ_LOG_ERROR, "%s: could not select index", __func__);
2210        return -1;
2211    }
2212}
2213
2214
2215static void
2216iquic_esf_global_cleanup (void)
2217{
2218}
2219
2220
2221static void *
2222copy_X509 (void *cert)
2223{
2224    X509_up_ref(cert);
2225    return cert;
2226}
2227
2228
2229static struct stack_st_X509 *
2230iquic_esf_get_server_cert_chain (enc_session_t *enc_session_p)
2231{
2232    struct enc_sess_iquic *const enc_sess = enc_session_p;
2233    STACK_OF(X509) *chain;
2234
2235    if (enc_sess->esi_ssl)
2236    {
2237        chain = SSL_get_peer_cert_chain(enc_sess->esi_ssl);
2238        return (struct stack_st_X509 *)
2239            sk_deep_copy((const _STACK *) chain, sk_X509_call_copy_func,
2240                copy_X509, sk_X509_call_free_func, (void(*)(void*))X509_free);
2241    }
2242    else
2243        return NULL;
2244}
2245
2246
2247static const char *
2248iquic_esf_cipher (enc_session_t *enc_session_p)
2249{
2250    struct enc_sess_iquic *const enc_sess = enc_session_p;
2251    const SSL_CIPHER *cipher;
2252
2253    if (enc_sess->esi_flags & ESI_CACHED_INFO)
2254        return enc_sess->esi_cached_info.cipher_name;
2255    else if (enc_sess->esi_ssl)
2256    {
2257        cipher = SSL_get_current_cipher(enc_sess->esi_ssl);
2258        return SSL_CIPHER_get_name(cipher);
2259    }
2260    else
2261    {
2262        LSQ_WARN("SSL session is not set");
2263        return "null";
2264    }
2265}
2266
2267
2268static int
2269iquic_esf_keysize (enc_session_t *enc_session_p)
2270{
2271    struct enc_sess_iquic *const enc_sess = enc_session_p;
2272    const SSL_CIPHER *cipher;
2273    uint32_t id;
2274
2275    if (enc_sess->esi_flags & ESI_CACHED_INFO)
2276        return enc_sess->esi_cached_info.alg_bits / 8;
2277    else if (enc_sess->esi_ssl)
2278    {
2279        cipher = SSL_get_current_cipher(enc_sess->esi_ssl);
2280        id = SSL_CIPHER_get_id(cipher);
2281
2282        /* RFC 8446, Appendix B.4 */
2283        switch (id)
2284        {
2285        case 0x03000000 | 0x1301:       /* TLS_AES_128_GCM_SHA256 */
2286            return 128 / 8;
2287        case 0x03000000 | 0x1302:       /* TLS_AES_256_GCM_SHA384 */
2288            return 256 / 8;
2289        case 0x03000000 | 0x1303:       /* TLS_CHACHA20_POLY1305_SHA256 */
2290            return 256 / 8;
2291        default:
2292            return -1;
2293        }
2294    }
2295    else
2296    {
2297        LSQ_WARN("SSL session is not set");
2298        return -1;
2299    }
2300}
2301
2302
2303static int
2304iquic_esf_alg_keysize (enc_session_t *enc_session_p)
2305{
2306    /* Modeled on SslConnection::getEnv() */
2307    return iquic_esf_keysize(enc_session_p);
2308}
2309
2310
2311static int
2312iquic_esf_zero_rtt_enabled (enc_session_t *enc_session_p)
2313{
2314    struct enc_sess_iquic *const enc_sess = enc_session_p;
2315    return enc_sess->esi_zero_rtt_buf != NULL;
2316}
2317
2318
2319static void
2320iquic_esfi_set_iscid (enc_session_t *enc_session_p,
2321                                    const struct lsquic_packet_in *packet_in)
2322{
2323    struct enc_sess_iquic *const enc_sess = enc_session_p;
2324
2325    if (!(enc_sess->esi_flags & ESI_ISCID))
2326    {
2327        lsquic_scid_from_packet_in(packet_in, &enc_sess->esi_iscid);
2328        enc_sess->esi_flags |= ESI_ISCID;
2329        LSQ_DEBUGC("set ISCID to %"CID_FMT, CID_BITS(&enc_sess->esi_iscid));
2330    }
2331}
2332
2333
2334static int
2335iquic_esfi_reset_dcid (enc_session_t *enc_session_p,
2336        const lsquic_cid_t *old_dcid, const lsquic_cid_t *new_dcid)
2337{
2338    struct enc_sess_iquic *const enc_sess = enc_session_p;
2339    struct crypto_ctx_pair *pair;
2340
2341    enc_sess->esi_odcid = *old_dcid;
2342    enc_sess->esi_rscid = *new_dcid;
2343    enc_sess->esi_flags |= ESI_ODCID|ESI_RSCID|ESI_RETRY;
2344
2345    /* Free previous handshake keys */
2346    assert(enc_sess->esi_hsk_pairs);
2347    pair = &enc_sess->esi_hsk_pairs[ENC_LEV_CLEAR];
2348    cleanup_crypto_ctx(&pair->ykp_ctx[0]);
2349    cleanup_crypto_ctx(&pair->ykp_ctx[1]);
2350
2351    if (0 == setup_handshake_keys(enc_sess, new_dcid))
2352    {
2353        LSQ_INFOC("reset DCID to %"CID_FMT, CID_BITS(new_dcid));
2354        return 0;
2355    }
2356    else
2357        return -1;
2358}
2359
2360
2361static void
2362iquic_esfi_handshake_confirmed (enc_session_t *sess)
2363{
2364    struct enc_sess_iquic *enc_sess = (struct enc_sess_iquic *) sess;
2365
2366    if (!(enc_sess->esi_flags & ESI_HSK_CONFIRMED))
2367    {
2368        LSQ_DEBUG("handshake has been confirmed");
2369        enc_sess->esi_flags |= ESI_HSK_CONFIRMED;
2370        maybe_drop_SSL(enc_sess);
2371    }
2372}
2373
2374
2375static int
2376iquic_esfi_in_init (enc_session_t *sess)
2377{
2378    struct enc_sess_iquic *enc_sess = (struct enc_sess_iquic *) sess;
2379    int in_init;
2380
2381    if (enc_sess->esi_ssl)
2382    {
2383        in_init = SSL_in_init(enc_sess->esi_ssl);
2384        LSQ_DEBUG("in_init: %d", in_init);
2385        return in_init;
2386    }
2387    else
2388    {
2389        LSQ_DEBUG("no SSL object, in_init: 0");
2390        return 0;
2391    }
2392}
2393
2394
2395static int
2396iquic_esfi_data_in (enc_session_t *sess, enum enc_level enc_level,
2397                                    const unsigned char *buf, size_t len)
2398{
2399    struct enc_sess_iquic *enc_sess = (struct enc_sess_iquic *) sess;
2400    int s;
2401    size_t str_sz;
2402    char str[MAX(1500 * 5, ERR_ERROR_STRING_BUF_LEN)];
2403
2404    if (!enc_sess->esi_ssl)
2405        return -1;
2406
2407    s = SSL_provide_quic_data(enc_sess->esi_ssl,
2408                (enum ssl_encryption_level_t) enc_level, buf, len);
2409    if (!s)
2410    {
2411        LSQ_WARN("SSL_provide_quic_data returned false: %s",
2412                                    ERR_error_string(ERR_get_error(), str));
2413        return -1;
2414    }
2415    LSQ_DEBUG("provided %zu bytes of %u-level data to SSL", len, enc_level);
2416    str_sz = lsquic_hexdump(buf, len, str, sizeof(str));
2417    LSQ_DEBUG("\n%.*s", (int) str_sz, str);
2418    s = SSL_do_handshake(enc_sess->esi_ssl);
2419    LSQ_DEBUG("do_handshake returns %d", s);
2420    return 0;
2421}
2422
2423
2424static void iquic_esfi_shake_stream (enc_session_t *sess,
2425                            struct lsquic_stream *stream, const char *what);
2426
2427
2428const struct enc_session_funcs_iquic lsquic_enc_session_iquic_ietf_v1 =
2429{
2430    .esfi_create_client  = iquic_esfi_create_client,
2431    .esfi_destroy        = iquic_esfi_destroy,
2432    .esfi_get_peer_transport_params
2433                         = iquic_esfi_get_peer_transport_params,
2434    .esfi_reset_dcid     = iquic_esfi_reset_dcid,
2435    .esfi_init_server    = iquic_esfi_init_server,
2436    .esfi_set_iscid      = iquic_esfi_set_iscid,
2437    .esfi_set_streams    = iquic_esfi_set_streams,
2438    .esfi_create_server  = iquic_esfi_create_server,
2439    .esfi_shake_stream   = iquic_esfi_shake_stream,
2440    .esfi_handshake_confirmed
2441                         = iquic_esfi_handshake_confirmed,
2442    .esfi_in_init        = iquic_esfi_in_init,
2443    .esfi_data_in        = iquic_esfi_data_in,
2444};
2445
2446
2447const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1 =
2448{
2449    .esf_encrypt_packet  = iquic_esf_encrypt_packet,
2450    .esf_decrypt_packet  = iquic_esf_decrypt_packet,
2451    .esf_global_cleanup  = iquic_esf_global_cleanup,
2452    .esf_global_init     = iquic_esf_global_init,
2453    .esf_tag_len         = IQUIC_TAG_LEN,
2454    .esf_get_server_cert_chain
2455                         = iquic_esf_get_server_cert_chain,
2456    .esf_cipher          = iquic_esf_cipher,
2457    .esf_keysize         = iquic_esf_keysize,
2458    .esf_alg_keysize     = iquic_esf_alg_keysize,
2459    .esf_is_zero_rtt_enabled = iquic_esf_zero_rtt_enabled,
2460    .esf_set_conn        = iquic_esf_set_conn,
2461};
2462
2463
2464static void
2465cache_info (struct enc_sess_iquic *enc_sess)
2466{
2467    const SSL_CIPHER *cipher;
2468
2469    cipher = SSL_get_current_cipher(enc_sess->esi_ssl);
2470    enc_sess->esi_cached_info.cipher_name = SSL_CIPHER_get_name(cipher);
2471    SSL_CIPHER_get_bits(cipher, &enc_sess->esi_cached_info.alg_bits);
2472    enc_sess->esi_flags |= ESI_CACHED_INFO;
2473}
2474
2475
2476static void
2477drop_SSL (struct enc_sess_iquic *enc_sess)
2478{
2479    LSQ_DEBUG("drop SSL object");
2480    if (enc_sess->esi_conn->cn_if->ci_drop_crypto_streams)
2481        enc_sess->esi_conn->cn_if->ci_drop_crypto_streams(
2482                                                    enc_sess->esi_conn);
2483    cache_info(enc_sess);
2484    SSL_free(enc_sess->esi_ssl);
2485    enc_sess->esi_ssl = NULL;
2486    free_handshake_keys(enc_sess);
2487}
2488
2489
2490static void
2491maybe_drop_SSL (struct enc_sess_iquic *enc_sess)
2492{
2493    /* We rely on the following BoringSSL property: it writes new session
2494     * tickets before marking handshake as complete.  In this case, the new
2495     * session tickets have either been successfully written to crypto stream,
2496     * in which case we can close it, or (unlikely) they are buffered in the
2497     * frab list.
2498     */
2499    if ((enc_sess->esi_flags & (ESI_HSK_CONFIRMED|ESI_HANDSHAKE_OK))
2500                            == (ESI_HSK_CONFIRMED|ESI_HANDSHAKE_OK)
2501        && enc_sess->esi_ssl
2502        && lsquic_frab_list_empty(&enc_sess->esi_frals[ENC_LEV_FORW]))
2503    {
2504        if ((enc_sess->esi_flags & (ESI_SERVER|ESI_WANT_TICKET))
2505                                                            != ESI_WANT_TICKET)
2506            drop_SSL(enc_sess);
2507        else if (enc_sess->esi_alset
2508                && !lsquic_alarmset_is_set(enc_sess->esi_alset, AL_SESS_TICKET))
2509        {
2510            LSQ_DEBUG("no session ticket: delay dropping SSL object");
2511            lsquic_alarmset_set(enc_sess->esi_alset, AL_SESS_TICKET,
2512                /* Wait up to two seconds for session tickets */
2513                                                lsquic_time_now() + 2000000);
2514        }
2515    }
2516}
2517
2518
2519static void
2520no_sess_ticket (enum alarm_id alarm_id, void *ctx,
2521                                  lsquic_time_t expiry, lsquic_time_t now)
2522{
2523    struct enc_sess_iquic *enc_sess = ctx;
2524
2525    LSQ_DEBUG("no session tickets forthcoming -- drop SSL");
2526    drop_SSL(enc_sess);
2527}
2528
2529
2530typedef char enums_have_the_same_value[
2531    (int) ssl_encryption_initial     == (int) ENC_LEV_CLEAR &&
2532    (int) ssl_encryption_early_data  == (int) ENC_LEV_EARLY &&
2533    (int) ssl_encryption_handshake   == (int) ENC_LEV_INIT  &&
2534    (int) ssl_encryption_application == (int) ENC_LEV_FORW      ? 1 : -1];
2535
2536static int
2537set_secret (SSL *ssl, enum ssl_encryption_level_t level,
2538    const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len, int rw)
2539{
2540    struct enc_sess_iquic *enc_sess;
2541    struct crypto_ctx_pair *pair;
2542    struct header_prot *hp;
2543    struct crypto_params crypa;
2544    int have_alpn;
2545    const unsigned char *alpn;
2546    unsigned alpn_len;
2547    const enum enc_level enc_level = (enum enc_level) level;
2548    char errbuf[ERR_ERROR_STRING_BUF_LEN];
2549#define hexbuf errbuf
2550
2551    enc_sess = SSL_get_ex_data(ssl, s_idx);
2552    if (!enc_sess)
2553        return 0;
2554
2555    if ((enc_sess->esi_flags & (ESI_ALPN_CHECKED|ESI_SERVER)) == ESI_SERVER
2556                                                        && enc_sess->esi_alpn)
2557    {
2558        enc_sess->esi_flags |= ESI_ALPN_CHECKED;
2559        SSL_get0_alpn_selected(enc_sess->esi_ssl, &alpn, &alpn_len);
2560        have_alpn = alpn && alpn_len == enc_sess->esi_alpn[0]
2561                            && 0 == memcmp(alpn, enc_sess->esi_alpn + 1, alpn_len);
2562        if (have_alpn)
2563            LSQ_DEBUG("Selected ALPN %.*s", (int) alpn_len, (char *) alpn);
2564        else
2565        {
2566            LSQ_INFO("No ALPN is selected: send fatal alert");
2567            SSL_send_fatal_alert(ssl, ALERT_NO_APPLICATION_PROTOCOL);
2568            return 0;
2569        }
2570    }
2571
2572    if (0 != get_crypto_params(enc_sess, cipher, &crypa))
2573        return 0;
2574
2575/*
2576    if (enc_sess->esi_flags & ESI_SERVER)
2577        secrets[0] = read_secret, secrets[1] = write_secret;
2578    else
2579        secrets[0] = write_secret, secrets[1] = read_secret;
2580        */
2581
2582    if (enc_level < ENC_LEV_FORW)
2583    {
2584        assert(enc_sess->esi_hsk_pairs);
2585        pair = &enc_sess->esi_hsk_pairs[enc_level];
2586        hp = &enc_sess->esi_hsk_hps[enc_level];
2587    }
2588    else
2589    {
2590        pair = &enc_sess->esi_pairs[0];
2591        hp = &enc_sess->esi_hp;
2592        enc_sess->esi_trasec_sz = secret_len;
2593        memcpy(enc_sess->esi_traffic_secrets[rw], secret, secret_len);
2594        enc_sess->esi_md = crypa.md;
2595        enc_sess->esi_aead = crypa.aead;
2596    }
2597    pair->ykp_thresh = IQUIC_INVALID_PACKNO;
2598
2599    if (enc_sess->esi_flags & ESI_LOG_SECRETS)
2600        LSQ_DEBUG("set %s secret for level %u: %s", rw2str[rw], enc_level,
2601                            HEXSTR(secret, secret_len, hexbuf));
2602    else
2603        LSQ_DEBUG("set %s for level %u", rw2str[rw], enc_level);
2604
2605    if (0 != init_crypto_ctx(&pair->ykp_ctx[rw], crypa.md,
2606                crypa.aead, secret, secret_len, rw2dir(rw)))
2607        goto err;
2608
2609    if (pair->ykp_ctx[!rw].yk_flags & YK_INITED)
2610    {
2611        /* Sanity check that the two sides end up with the same header
2612         * protection logic, as they should.
2613         */
2614        assert(hp->hp_cipher   == crypa.hp);
2615        assert(hp->hp_gen_mask == crypa.gen_hp_mask);
2616    }
2617    else
2618    {
2619        hp->hp_enc_level = enc_level;
2620        hp->hp_cipher    = crypa.hp;
2621        hp->hp_gen_mask  = crypa.gen_hp_mask;
2622        hp->hp_sz        = EVP_AEAD_key_length(crypa.aead);
2623    }
2624    lsquic_qhkdf_expand(crypa.md, secret, secret_len, PN_LABEL, PN_LABEL_SZ,
2625        hp->hp_buf[rw], hp->hp_sz);
2626    hp->hp_flags |= 1 << rw;
2627
2628    if (enc_sess->esi_flags & ESI_LOG_SECRETS)
2629    {
2630        log_crypto_ctx(enc_sess, &pair->ykp_ctx[rw], "new", rw);
2631        LSQ_DEBUG("%s hp: %s", rw2str[rw],
2632                                    HEXSTR(hp->hp_buf[rw], hp->hp_sz, hexbuf));
2633    }
2634
2635    return 1;
2636
2637  err:
2638    cleanup_crypto_ctx(&pair->ykp_ctx[0]);
2639    cleanup_crypto_ctx(&pair->ykp_ctx[1]);
2640    return 0;
2641#undef hexbuf
2642}
2643
2644
2645static int
2646cry_sm_set_read_secret (SSL *ssl, enum ssl_encryption_level_t level,
2647            const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len)
2648{
2649    return set_secret(ssl, level, cipher, secret, secret_len, 0);
2650}
2651
2652
2653static int
2654cry_sm_set_write_secret (SSL *ssl, enum ssl_encryption_level_t level,
2655            const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len)
2656{
2657    return set_secret(ssl, level, cipher, secret, secret_len, 1);
2658}
2659
2660
2661static int
2662cry_sm_write_message (SSL *ssl, enum ssl_encryption_level_t level,
2663                                            const uint8_t *data, size_t len)
2664{
2665    struct enc_sess_iquic *enc_sess;
2666    void *stream;
2667    ssize_t nw;
2668
2669    enc_sess = SSL_get_ex_data(ssl, s_idx);
2670    if (!enc_sess)
2671        return 0;
2672
2673    stream = enc_sess->esi_streams[level];
2674    if (!stream)
2675        return 0;
2676
2677    /* The frab list logic is only applicable on the client.  XXX This is
2678     * likely to change when support for key updates is added.
2679     */
2680    if (enc_sess->esi_flags & (ESI_ON_WRITE|ESI_SERVER))
2681        nw = enc_sess->esi_cryst_if->csi_write(stream, data, len);
2682    else
2683    {
2684        LSQ_DEBUG("not in on_write event: buffer in a frab list");
2685        if (0 == lsquic_frab_list_write(&enc_sess->esi_frals[level], data, len))
2686        {
2687            if (!lsquic_frab_list_empty(&enc_sess->esi_frals[level]))
2688                enc_sess->esi_cryst_if->csi_wantwrite(stream, 1);
2689            nw = len;
2690        }
2691        else
2692            nw = -1;
2693    }
2694
2695    if (nw >= 0 && (size_t) nw == len)
2696    {
2697        enc_sess->esi_last_w = (enum enc_level) level;
2698        LSQ_DEBUG("wrote %zu bytes to stream at encryption level %u",
2699            len, level);
2700        maybe_drop_SSL(enc_sess);
2701        return 1;
2702    }
2703    else
2704    {
2705        LSQ_INFO("could not write %zu bytes: returned %zd", len, nw);
2706        return 0;
2707    }
2708}
2709
2710
2711static int
2712cry_sm_flush_flight (SSL *ssl)
2713{
2714    struct enc_sess_iquic *enc_sess;
2715    void *stream;
2716    unsigned level;
2717    int s;
2718
2719    enc_sess = SSL_get_ex_data(ssl, s_idx);
2720    if (!enc_sess)
2721        return 0;
2722
2723    level = enc_sess->esi_last_w;
2724    stream = enc_sess->esi_streams[level];
2725    if (!stream)
2726        return 0;
2727
2728    if (lsquic_frab_list_empty(&enc_sess->esi_frals[level]))
2729    {
2730        s = enc_sess->esi_cryst_if->csi_flush(stream);
2731        return s == 0;
2732    }
2733    else
2734        /* Frab list will get flushed */    /* TODO: add support for
2735        recording flush points in frab list. */
2736        return 1;
2737}
2738
2739
2740static int
2741cry_sm_send_alert (SSL *ssl, enum ssl_encryption_level_t level, uint8_t alert)
2742{
2743    struct enc_sess_iquic *enc_sess;
2744
2745    enc_sess = SSL_get_ex_data(ssl, s_idx);
2746    if (!enc_sess)
2747        return 0;
2748
2749    LSQ_INFO("got alert %"PRIu8, alert);
2750    enc_sess->esi_conn->cn_if->ci_tls_alert(enc_sess->esi_conn, alert);
2751
2752    return 1;
2753}
2754
2755
2756static const SSL_QUIC_METHOD cry_quic_method =
2757{
2758    .set_read_secret        = cry_sm_set_read_secret,
2759    .set_write_secret       = cry_sm_set_write_secret,
2760    .add_handshake_data     = cry_sm_write_message,
2761    .flush_flight           = cry_sm_flush_flight,
2762    .send_alert             = cry_sm_send_alert,
2763};
2764
2765
2766static lsquic_stream_ctx_t *
2767chsk_ietf_on_new_stream (void *stream_if_ctx, struct lsquic_stream *stream)
2768{
2769    struct enc_sess_iquic *const enc_sess = stream_if_ctx;
2770    enum enc_level enc_level;
2771
2772    enc_level = enc_sess->esi_cryst_if->csi_enc_level(stream);
2773    if (enc_level != ENC_LEV_CLEAR)
2774    {
2775        LSQ_DEBUG("skip initialization of stream at level %u", enc_level);
2776        goto end;
2777    }
2778
2779    if (
2780        (enc_sess->esi_flags & ESI_SERVER) == 0 &&
2781        0 != init_client(enc_sess))
2782    {
2783        LSQ_WARN("enc session could not be initialized");
2784        return NULL;
2785    }
2786
2787    enc_sess->esi_cryst_if->csi_wantwrite(stream, 1);
2788
2789    LSQ_DEBUG("handshake stream created successfully");
2790
2791  end:
2792    return stream_if_ctx;
2793}
2794
2795
2796static lsquic_stream_ctx_t *
2797shsk_ietf_on_new_stream (void *stream_if_ctx, struct lsquic_stream *stream)
2798{
2799    struct enc_sess_iquic *const enc_sess = stream_if_ctx;
2800    enum enc_level enc_level;
2801
2802    enc_level = enc_sess->esi_cryst_if->csi_enc_level(stream);
2803    LSQ_DEBUG("on_new_stream called on level %u", enc_level);
2804
2805    enc_sess->esi_cryst_if->csi_wantread(stream, 1);
2806
2807    return stream_if_ctx;
2808}
2809
2810
2811static void
2812chsk_ietf_on_close (struct lsquic_stream *stream, lsquic_stream_ctx_t *ctx)
2813{
2814    struct enc_sess_iquic *const enc_sess = (struct enc_sess_iquic *) ctx;
2815    if (enc_sess && enc_sess->esi_cryst_if)
2816        LSQ_DEBUG("crypto stream level %u is closed",
2817                (unsigned) enc_sess->esi_cryst_if->csi_enc_level(stream));
2818}
2819
2820
2821static const char *const ihs2str[] = {
2822    [IHS_WANT_READ]  = "want read",
2823    [IHS_WANT_WRITE] = "want write",
2824    [IHS_STOP]       = "stop",
2825};
2826
2827
2828static void
2829iquic_esfi_shake_stream (enc_session_t *sess,
2830                            struct lsquic_stream *stream, const char *what)
2831{
2832    struct enc_sess_iquic *enc_sess = (struct enc_sess_iquic *)sess;
2833    enum iquic_handshake_status st;
2834    enum enc_level enc_level;
2835    int write;
2836    if (0 == (enc_sess->esi_flags & ESI_HANDSHAKE_OK))
2837        st = iquic_esfi_handshake(enc_sess);
2838    else
2839        st = iquic_esfi_post_handshake(enc_sess);
2840    enc_level = enc_sess->esi_cryst_if->csi_enc_level(stream);
2841    LSQ_DEBUG("enc level %s after %s: %s", lsquic_enclev2str[enc_level], what,
2842                                                                ihs2str[st]);
2843    switch (st)
2844    {
2845    case IHS_WANT_READ:
2846        write = !lsquic_frab_list_empty(&enc_sess->esi_frals[enc_level]);
2847        enc_sess->esi_cryst_if->csi_wantwrite(stream, write);
2848        enc_sess->esi_cryst_if->csi_wantread(stream, 1);
2849        break;
2850    case IHS_WANT_WRITE:
2851        enc_sess->esi_cryst_if->csi_wantwrite(stream, 1);
2852        enc_sess->esi_cryst_if->csi_wantread(stream, 0);
2853        break;
2854    default:
2855        assert(st == IHS_STOP);
2856        write = !lsquic_frab_list_empty(&enc_sess->esi_frals[enc_level]);
2857        enc_sess->esi_cryst_if->csi_wantwrite(stream, write);
2858        enc_sess->esi_cryst_if->csi_wantread(stream, 0);
2859        break;
2860    }
2861    LSQ_DEBUG("Exit shake_stream");
2862    maybe_drop_SSL(enc_sess);
2863}
2864
2865
2866struct readf_ctx
2867{
2868    struct enc_sess_iquic  *enc_sess;
2869    enum enc_level          enc_level;
2870    int                     err;
2871};
2872
2873
2874static size_t
2875readf_cb (void *ctx, const unsigned char *buf, size_t len, int fin)
2876{
2877    struct readf_ctx *const readf_ctx = (void *) ctx;
2878    struct enc_sess_iquic *const enc_sess = readf_ctx->enc_sess;
2879    int s;
2880    size_t str_sz;
2881    char str[MAX(1500 * 5, ERR_ERROR_STRING_BUF_LEN)];
2882
2883    s = SSL_provide_quic_data(enc_sess->esi_ssl,
2884                (enum ssl_encryption_level_t) readf_ctx->enc_level, buf, len);
2885    if (s)
2886    {
2887        LSQ_DEBUG("provided %zu bytes of %u-level data to SSL", len,
2888                                                        readf_ctx->enc_level);
2889        str_sz = lsquic_hexdump(buf, len, str, sizeof(str));
2890        LSQ_DEBUG("\n%.*s", (int) str_sz, str);
2891        return len;
2892    }
2893    else
2894    {
2895        LSQ_WARN("SSL_provide_quic_data returned false: %s",
2896                                    ERR_error_string(ERR_get_error(), str));
2897        readf_ctx->err++;
2898        return 0;
2899    }
2900}
2901
2902
2903static size_t
2904discard_cb (void *ctx, const unsigned char *buf, size_t len, int fin)
2905{
2906    return len;
2907}
2908
2909
2910static void
2911chsk_ietf_on_read (struct lsquic_stream *stream, lsquic_stream_ctx_t *ctx)
2912{
2913    struct enc_sess_iquic *const enc_sess = (void *) ctx;
2914    enum enc_level enc_level = enc_sess->esi_cryst_if->csi_enc_level(stream);
2915    struct readf_ctx readf_ctx = { enc_sess, enc_level, 0, };
2916    ssize_t nread;
2917
2918
2919    if (enc_sess->esi_ssl)
2920    {
2921        nread = enc_sess->esi_cryst_if->csi_readf(stream, readf_cb, &readf_ctx);
2922        if (!(nread < 0 || readf_ctx.err))
2923            iquic_esfi_shake_stream((enc_session_t *)enc_sess, stream,
2924                                                                    "on_read");
2925        else
2926            enc_sess->esi_conn->cn_if->ci_internal_error(enc_sess->esi_conn,
2927                "shaking stream failed: nread: %zd, err: %d, SSL err: %"PRIu32,
2928                nread, readf_ctx.err, ERR_get_error());
2929    }
2930    else
2931    {
2932        /* This branch is reached when we don't want TLS ticket and drop
2933         * the SSL object before we process TLS tickets that have been
2934         * already received and waiting in the incoming stream buffer.
2935         */
2936        nread = enc_sess->esi_cryst_if->csi_readf(stream, discard_cb, NULL);
2937        lsquic_stream_wantread(stream, 0);
2938        LSQ_DEBUG("no SSL object: discard %zd bytes of SSL data", nread);
2939    }
2940}
2941
2942
2943static void
2944maybe_write_from_fral (struct enc_sess_iquic *enc_sess,
2945                                                struct lsquic_stream *stream)
2946{
2947    enum enc_level enc_level = enc_sess->esi_cryst_if->csi_enc_level(stream);
2948    struct frab_list *const fral = &enc_sess->esi_frals[enc_level];
2949    struct lsquic_reader reader = {
2950        .lsqr_read  = lsquic_frab_list_read,
2951        .lsqr_size  = lsquic_frab_list_size,
2952        .lsqr_ctx   = fral,
2953    };
2954    ssize_t nw;
2955
2956    if (lsquic_frab_list_empty(fral))
2957        return;
2958
2959    nw = lsquic_stream_writef(stream, &reader);
2960    if (nw >= 0)
2961    {
2962        LSQ_DEBUG("wrote %zd bytes to stream from frab list", nw);
2963        (void) lsquic_stream_flush(stream);
2964        if (lsquic_frab_list_empty(fral))
2965            lsquic_stream_wantwrite(stream, 0);
2966    }
2967    else
2968    {
2969        enc_sess->esi_conn->cn_if->ci_internal_error(enc_sess->esi_conn,
2970                            "cannot write to stream: %s", strerror(errno));
2971        lsquic_stream_wantwrite(stream, 0);
2972    }
2973}
2974
2975
2976static void
2977chsk_ietf_on_write (struct lsquic_stream *stream, lsquic_stream_ctx_t *ctx)
2978{
2979    struct enc_sess_iquic *const enc_sess = (void *) ctx;
2980
2981    maybe_write_from_fral(enc_sess, stream);
2982
2983    enc_sess->esi_flags |= ESI_ON_WRITE;
2984    iquic_esfi_shake_stream(enc_sess, stream, "on_write");
2985    enc_sess->esi_flags &= ~ESI_ON_WRITE;
2986}
2987
2988
2989const struct lsquic_stream_if lsquic_cry_sm_if =
2990{
2991    .on_new_stream = chsk_ietf_on_new_stream,
2992    .on_read       = chsk_ietf_on_read,
2993    .on_write      = chsk_ietf_on_write,
2994    .on_close      = chsk_ietf_on_close,
2995};
2996
2997
2998const struct lsquic_stream_if lsquic_mini_cry_sm_if =
2999{
3000    .on_new_stream = shsk_ietf_on_new_stream,
3001    .on_read       = chsk_ietf_on_read,
3002    .on_write      = chsk_ietf_on_write,
3003    .on_close      = chsk_ietf_on_close,
3004};
3005
3006
3007