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