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