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