lsquic_handshake.c revision 06b2a236
1/* Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc.  See LICENSE. */
2#define _GNU_SOURCE         /* for memmem */
3
4#include <assert.h>
5#include <errno.h>
6#include <limits.h>
7#include <time.h>
8#include <string.h>
9#include <sys/queue.h>
10#ifndef WIN32
11#include <netinet/in.h>
12#include <netdb.h>
13#include <sys/socket.h>
14#else
15#include <malloc.h>
16#endif
17
18#include <openssl/ssl.h>
19#include <openssl/crypto.h>
20#include <openssl/stack.h>
21#include <openssl/x509.h>
22#include <openssl/rand.h>
23#include <openssl/nid.h>
24#include <openssl/bn.h>
25#include <openssl/hkdf.h>
26#include <zlib.h>
27
28#include "lsquic.h"
29#include "lsquic_types.h"
30#include "lsquic_crypto.h"
31#include "lsquic_str.h"
32#include "lsquic_enc_sess.h"
33#include "lsquic_parse.h"
34#include "lsquic_crt_compress.h"
35#include "lsquic_util.h"
36#include "lsquic_version.h"
37#include "lsquic_mm.h"
38#include "lsquic_engine_public.h"
39#include "lsquic_hash.h"
40#include "lsquic_qtags.h"
41#include "lsquic_byteswap.h"
42#include "lsquic_sizes.h"
43#include "lsquic_tokgen.h"
44#include "lsquic_conn.h"
45#include "lsquic_packet_common.h"
46#include "lsquic_packet_out.h"
47#include "lsquic_packet_in.h"
48#include "lsquic_handshake.h"
49#include "lsquic_hkdf.h"
50#include "lsquic_packet_ietf.h"
51
52#if __GNUC__
53#   define UNLIKELY(cond) __builtin_expect(cond, 0)
54#else
55#   define UNLIKELY(cond) cond
56#endif
57
58#include "fiu-local.h"
59
60#include "lsquic_ev_log.h"
61
62#define MIN_CHLO_SIZE 1024
63
64#define MAX_SCFG_LENGTH 512
65#define MAX_SPUBS_LENGTH 32
66
67#define LSQUIC_LOGGER_MODULE LSQLM_HANDSHAKE
68#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(                         \
69    enc_session && enc_session->es_conn     ? enc_session->es_conn :    \
70    lconn && lconn != &dummy_lsquic_conn    ? lconn :                   \
71                                              &dummy_lsquic_conn)
72#include "lsquic_logger.h"
73
74/* enc_session may be NULL when encrypt and decrypt packet functions are
75 * called.  This is a workaround.
76 */
77static struct conn_cid_elem dummy_cce;
78static const struct lsquic_conn dummy_lsquic_conn = { .cn_cces = &dummy_cce, };
79static const struct lsquic_conn *const lconn = &dummy_lsquic_conn;
80
81static int s_ccrt_idx;
82
83static const int s_log_seal_and_open;
84static char s_str[0x1000];
85
86static const unsigned char salt_Q050[] = {
87    0x50, 0x45, 0x74, 0xEF, 0xD0, 0x66, 0xFE, 0x2F, 0x9D, 0x94,
88    0x5C, 0xFC, 0xDB, 0xD3, 0xA7, 0xF0, 0xD3, 0xB5, 0x6B, 0x45,
89};
90
91enum handshake_state
92{
93    HSK_CHLO_REJ = 0,
94    HSK_SHLO,
95    HSK_COMPLETED,
96    N_HSK_STATES
97};
98
99#if LSQUIC_KEEP_ENC_SESS_HISTORY
100typedef unsigned char eshist_idx_t;
101
102enum enc_sess_history_event
103{
104    ESHE_EMPTY              =  '\0',
105    ESHE_SET_SNI            =  'I',
106    ESHE_SET_SNO            =  'O',
107    ESHE_SET_STK            =  'K',
108    ESHE_SET_SCID           =  'D',
109    ESHE_SET_PROF           =  'P',
110    ESHE_SET_SRST           =  'S',
111    ESHE_VSTK_OK            =  'V',
112    ESHE_VSTK_FAILED        =  'W',
113    ESHE_SNI_FAIL           =  'J',
114    ESHE_HAS_SSTK           =  'H',
115    ESHE_UNKNOWN_CONFIG     =  'a',
116    ESHE_MISSING_SCID       =  'b',
117    ESHE_EMPTY_CCRT         =  'c',
118    ESHE_MISSING_SNO        =  'd',
119    ESHE_SNO_MISMATCH       =  'e',
120    ESHE_SNO_OK             =  'f',
121    ESHE_MULTI2_2BITS       =  'i',
122    ESHE_SNI_DELAYED        =  'Y',
123};
124#endif
125
126
127typedef struct hs_ctx_st
128{
129    enum {
130        HSET_TCID     =   (1 << 0),     /* tcid is set */
131        HSET_SMHL     =   (1 << 1),     /* smhl is set */
132        HSET_SCID     =   (1 << 2),
133        HSET_IRTT     =   (1 << 3),
134        HSET_SRST     =   (1 << 4),
135    }           set;
136    enum {
137        HOPT_NSTP     =   (1 << 0),     /* NSTP option present in COPT */
138        HOPT_SREJ     =   (1 << 1),     /* SREJ option present in COPT */
139    }           opts;
140    uint32_t    pdmd;
141    uint32_t    aead;
142    uint32_t    kexs;
143
144    uint32_t    mids;
145    uint32_t    scls;
146    uint32_t    cfcw;
147    uint32_t    sfcw;
148    uint32_t    smids;
149    uint32_t    scfcw;
150    uint32_t    ssfcw;
151    uint32_t    icsl;
152
153    uint32_t    irtt;
154    uint64_t    rcid;
155    uint32_t    tcid;
156    uint32_t    smhl;
157    uint64_t    sttl;
158    unsigned char scid[SCID_LENGTH];
159    //unsigned char chlo_hash[32]; //SHA256 HASH of CHLO
160    unsigned char nonc[DNONC_LENGTH]; /* 4 tm, 8 orbit ---> REJ, 20 rand */
161    unsigned char  pubs[32];
162    unsigned char srst[SRST_LENGTH];
163
164    uint32_t    rrej;
165    struct lsquic_str ccs;
166    struct lsquic_str uaid;
167    struct lsquic_str sni;   /* 0 rtt */
168    struct lsquic_str ccrt;
169    struct lsquic_str stk;
170    struct lsquic_str sno;
171    struct lsquic_str prof;
172
173    struct lsquic_str csct;
174    struct compressed_cert *ccert;
175    struct lsquic_str scfg_pubs; /* Need to copy PUBS, as KEXS comes after it */
176} hs_ctx_t;
177
178
179/* client side need to store 0rtt info per STK */
180typedef struct lsquic_session_cache_info_st
181{
182    unsigned char   sscid[SCID_LENGTH];
183    unsigned char   spubs[32];  /* server pub key for next time 0rtt */
184    uint32_t    ver;  /* one VERSION */
185    uint32_t    aead;
186    uint32_t    kexs;
187    uint32_t    pdmd;
188    uint64_t    orbt;
189    uint64_t    expy;
190    int         scfg_flag; /* 0, no-init, 1, no parse, 2, parsed */
191    struct lsquic_str    sstk;
192    struct lsquic_str    scfg;
193    struct lsquic_str    sni_key;   /* This is only used as key */
194    struct lsquic_hash_elem hash_el;
195
196} lsquic_session_cache_info_t;
197
198
199/* client */
200typedef struct c_cert_item_st
201{
202    struct lsquic_str*  crts;
203    struct lsquic_str*  hashs;
204    int                 count;
205} c_cert_item_t;
206
207
208struct lsquic_sess_resume_storage
209{
210    uint32_t    quic_version_tag;
211    uint32_t    serializer_version;
212    uint32_t    ver;
213    uint32_t    aead;
214    uint32_t    kexs;
215    uint32_t    pdmd;
216    uint64_t    orbt;
217    uint64_t    expy;
218    uint64_t    sstk_len;
219    uint64_t    scfg_len;
220    uint64_t    scfg_flag;
221    uint8_t     sstk[STK_LENGTH];
222    uint8_t     scfg[MAX_SCFG_LENGTH];
223    uint8_t     sscid[SCID_LENGTH];
224    uint8_t     spubs[MAX_SPUBS_LENGTH];
225    uint32_t    cert_count;
226};
227
228
229
230
231/* gQUIC crypto has three crypto levels. */
232enum gel { GEL_CLEAR, GEL_EARLY, GEL_FORW, N_GELS /* Angels! */ };
233
234#define MAX(a, b) ((a) > (b) ? (a) : (b))
235#define IQUIC_IV_LEN 12
236#define IQUIC_HP_LEN 16
237#define MAX_IV_LEN MAX(aes128_iv_len, IQUIC_IV_LEN)
238
239struct lsquic_enc_session
240{
241    struct lsquic_conn  *es_conn;
242    enum handshake_state hsk_state;
243    enum {
244        ES_SERVER =     1 << 0,
245        ES_RECV_REJ =   1 << 1,
246        ES_RECV_SREJ =  1 << 2,
247        ES_FREE_CERT_PTR = 1 << 3,
248        ES_LOG_SECRETS   = 1 << 4,
249        ES_GQUIC2        = 1 << 5,
250    }                    es_flags;
251
252    uint8_t have_key; /* 0, no 1, I, 2, D, 3, F */
253    uint8_t peer_have_final_key;
254    uint8_t server_start_use_final_key;
255
256    lsquic_cid_t cid;
257    unsigned char priv_key[32];
258
259    /* Have to save the initial key for diversification need */
260    unsigned char enc_key_i[aes128_key_len];
261    unsigned char dec_key_i[aes128_key_len];
262
263#define enc_ctx_i es_aead_ctxs[GEL_EARLY][0]
264#define dec_ctx_i es_aead_ctxs[GEL_EARLY][1]
265#define enc_ctx_f es_aead_ctxs[GEL_FORW][0]
266#define dec_ctx_f es_aead_ctxs[GEL_FORW][1]
267    EVP_AEAD_CTX    *es_aead_ctxs[N_GELS][2];
268
269#define enc_key_nonce_i es_ivs[GEL_EARLY][0]
270#define dec_key_nonce_i es_ivs[GEL_EARLY][1]
271#define enc_key_nonce_f es_ivs[GEL_FORW][0]
272#define dec_key_nonce_f es_ivs[GEL_FORW][1]
273    unsigned char    es_ivs[N_GELS][2][MAX_IV_LEN];
274
275    unsigned char    es_hps[N_GELS][2][IQUIC_HP_LEN];
276
277    hs_ctx_t hs_ctx;
278    lsquic_session_cache_info_t *info;
279    c_cert_item_t *cert_item;
280    lsquic_server_config_t *server_config;
281    SSL_CTX *  ssl_ctx;
282    struct lsquic_engine_public *enpub;
283    struct lsquic_str * cert_ptr; /* pointer to the leaf cert of the server, not real copy */
284    struct lsquic_str   chlo; /* real copy of CHLO message */
285    struct lsquic_str   sstk;
286    struct lsquic_str   ssno;
287
288#if LSQUIC_KEEP_ENC_SESS_HISTORY
289    eshist_idx_t        es_hist_idx;
290    unsigned char       es_hist_buf[1 << ESHIST_BITS];
291#endif
292    /* The remaining fields in the struct are used for Q050+ crypto */
293    lsquic_packno_t             es_max_packno;
294};
295
296
297
298/* server side */
299typedef struct compress_cert_hash_item_st
300{
301    struct lsquic_str*   domain; /*with port, such as "xyz.com:8088" as the key */
302    struct lsquic_str*   crts_compress_buf;
303    struct lsquic_hash_elem hash_el;
304
305} compress_cert_hash_item_t;
306
307/* server side, only one cert */
308typedef struct cert_item_st
309{
310    struct lsquic_str*      crt;
311    struct lsquic_hash_elem hash_el;
312    unsigned char           key[0];
313} cert_item_t;
314
315/* server */
316static cert_item_t* find_cert(struct lsquic_engine_public *, const unsigned char *, size_t);
317static void s_free_cert_hash_item(cert_item_t *item);
318static cert_item_t* insert_cert(struct lsquic_engine_public *,
319        const unsigned char *key, size_t key_sz, const struct lsquic_str *crt);
320
321#ifdef NDEBUG
322static
323enum hsk_failure_reason
324lsquic_verify_stk (enc_session_t *,
325               const struct sockaddr *ip_addr, uint64_t tm, lsquic_str_t *stk);
326
327static
328#endif
329void lsquic_gen_stk(lsquic_server_config_t *, const struct sockaddr *, uint64_t tm,
330             unsigned char stk_out[STK_LENGTH]);
331
332/* client */
333static c_cert_item_t *make_c_cert_item(struct lsquic_str **certs, int count);
334static void free_c_cert_item(c_cert_item_t *item);
335
336static int get_tag_val_u32 (unsigned char *v, int len, uint32_t *val);
337static uint32_t get_tag_value_i32(unsigned char *, int);
338static uint64_t get_tag_value_i64(unsigned char *, int);
339
340static void determine_keys(struct lsquic_enc_session *enc_session);
341
342static void put_compressed_cert (struct compressed_cert *);
343
344
345#if LSQUIC_KEEP_ENC_SESS_HISTORY
346static void
347eshist_append (struct lsquic_enc_session *enc_session,
348                                        enum enc_sess_history_event eh_event)
349{
350    enc_session->es_hist_buf[
351                    ESHIST_MASK & enc_session->es_hist_idx++ ] = eh_event;
352}
353
354
355#   define ESHIST_APPEND(sess, event) eshist_append(sess, event)
356#else
357#   define ESHIST_APPEND(sess, event) do { } while (0)
358#endif
359
360
361static void
362free_compressed_cert (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
363                            int index, long argl, void *argp)
364{
365    put_compressed_cert(ptr);
366}
367
368
369static int
370lsquic_handshake_init(int flags)
371{
372    lsquic_crypto_init();
373    if (flags & LSQUIC_GLOBAL_SERVER)
374    {
375        s_ccrt_idx = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
376                                                        free_compressed_cert);
377        if (s_ccrt_idx < 0)
378            return -1;
379    }
380    return lsquic_crt_init();
381}
382
383
384void
385lsquic_cleanup_gquic_crypto (struct lsquic_engine_public *enpub)
386{
387    struct lsquic_hash_elem *el;
388    if (enpub->enp_compressed_server_certs)
389    {
390        for (el = lsquic_hash_first(enpub->enp_compressed_server_certs); el;
391                        el = lsquic_hash_next(enpub->enp_compressed_server_certs))
392        {
393            compress_cert_hash_item_t *item = lsquic_hashelem_getdata(el);
394            lsquic_str_delete(item->domain);
395            lsquic_str_delete(item->crts_compress_buf);
396            free(item);
397        }
398        lsquic_hash_destroy(enpub->enp_compressed_server_certs);
399        enpub->enp_compressed_server_certs = NULL;
400    }
401
402    if (enpub->enp_server_certs)
403    {
404        for (el = lsquic_hash_first(enpub->enp_server_certs); el;
405                                    el = lsquic_hash_next(enpub->enp_server_certs))
406        {
407            s_free_cert_hash_item( lsquic_hashelem_getdata(el) );
408        }
409        lsquic_hash_destroy(enpub->enp_server_certs);
410        enpub->enp_server_certs = NULL;
411    }
412
413    free(enpub->enp_server_config);
414}
415
416
417static void
418lsquic_handshake_cleanup (void)
419{
420    lsquic_crt_cleanup();
421}
422
423
424int
425lsquic_init_gquic_crypto (struct lsquic_engine_public *enpub)
426{
427    enpub->enp_server_config = calloc(1, sizeof(*enpub->enp_server_config));
428    if (!enpub->enp_server_config)
429        return -1;
430
431    enpub->enp_compressed_server_certs = lsquic_hash_create();
432    if (!enpub->enp_compressed_server_certs)
433        return -1;
434
435    enpub->enp_server_certs = lsquic_hash_create();
436    if (!enpub->enp_server_certs)
437    {
438        lsquic_hash_destroy(enpub->enp_compressed_server_certs);
439        enpub->enp_compressed_server_certs = NULL;
440        return -1;
441    }
442
443    return 0;
444}
445
446
447/* server */
448static cert_item_t *
449find_cert (struct lsquic_engine_public *enpub, const unsigned char *key,
450                                                                size_t key_sz)
451{
452    struct lsquic_hash_elem *el;
453
454    if (!enpub->enp_server_certs)
455        return NULL;
456
457    el = lsquic_hash_find(enpub->enp_server_certs, key, key_sz);
458    if (el == NULL)
459        return NULL;
460
461    return lsquic_hashelem_getdata(el);
462}
463
464
465/* client */
466static c_cert_item_t *
467make_c_cert_item (lsquic_str_t **certs, int count)
468{
469    int i;
470    uint64_t hash;
471    c_cert_item_t *item = calloc(1, sizeof(*item));
472    item->crts = (lsquic_str_t *)malloc(count * sizeof(lsquic_str_t));
473    item->hashs = lsquic_str_new(NULL, 0);
474    item->count = count;
475    for (i = 0; i < count; ++i)
476    {
477        lsquic_str_copy(&item->crts[i], certs[i]);
478        hash = lsquic_fnv1a_64((const uint8_t *)lsquic_str_cstr(certs[i]),
479                        lsquic_str_len(certs[i]));
480        lsquic_str_append(item->hashs, (char *)&hash, 8);
481    }
482    return item;
483}
484
485
486/* client */
487static void
488free_c_cert_item (c_cert_item_t *item)
489{
490    int i;
491    if (item)
492    {
493        lsquic_str_delete(item->hashs);
494        for(i=0; i<item->count; ++i)
495            lsquic_str_d(&item->crts[i]);
496        free(item->crts);
497        free(item);
498    }
499}
500
501
502/* server */
503static void
504s_free_cert_hash_item (cert_item_t *item)
505{
506    if (item)
507    {
508        lsquic_str_delete(item->crt);
509        free(item);
510    }
511}
512
513
514/* server */
515static cert_item_t *
516insert_cert (struct lsquic_engine_public *enpub, const unsigned char *key,
517                                    size_t key_sz, const lsquic_str_t *crt)
518{
519    struct lsquic_hash_elem *el;
520    lsquic_str_t *crt_copy;
521    cert_item_t *item;
522
523    crt_copy = lsquic_str_new(lsquic_str_cstr(crt), lsquic_str_len(crt));
524    if (!crt_copy)
525        return NULL;
526
527    item = calloc(1, sizeof(*item) + key_sz);
528    if (!item)
529    {
530        lsquic_str_delete(crt_copy);
531        return NULL;
532    }
533
534    item->crt = crt_copy;
535    memcpy(item->key, key, key_sz);
536    el = lsquic_hash_insert(enpub->enp_server_certs, item->key, key_sz,
537                                                        item, &item->hash_el);
538    if (el)
539        return lsquic_hashelem_getdata(el);
540    else
541    {
542        s_free_cert_hash_item(item);
543        return NULL;
544    }
545}
546
547
548enum rtt_deserialize_return_type
549{
550    RTT_DESERIALIZE_OK              = 0,
551    RTT_DESERIALIZE_BAD_QUIC_VER    = 1,
552    RTT_DESERIALIZE_BAD_SERIAL_VER  = 2,
553    RTT_DESERIALIZE_BAD_CERT_SIZE   = 3,
554};
555
556#define RTT_SERIALIZER_VERSION  (1 << 0)
557
558static void
559lsquic_enc_session_serialize_sess_resume(struct lsquic_sess_resume_storage *storage,
560                                        enum lsquic_version version,
561                                        const lsquic_session_cache_info_t *info,
562                                                const c_cert_item_t *cert_item)
563{
564    uint32_t i;
565    uint32_t *cert_len;
566    uint8_t *cert_data;
567    /*
568     * assign versions
569     */
570    storage->quic_version_tag = lsquic_ver2tag(version);
571    storage->serializer_version = RTT_SERIALIZER_VERSION;
572    /*
573     * server config
574     */
575    storage->ver = info->ver;
576    storage->aead = info->aead;
577    storage->kexs = info->kexs;
578    storage->pdmd = info->pdmd;
579    storage->orbt = info->orbt;
580    storage->expy = info->expy;
581    storage->sstk_len = lsquic_str_len(&info->sstk);
582    storage->scfg_len = lsquic_str_len(&info->scfg);
583    storage->scfg_flag = info->scfg_flag;
584    memcpy(storage->sstk, lsquic_str_buf(&info->sstk), storage->sstk_len);
585    memcpy(storage->scfg, lsquic_str_buf(&info->scfg), storage->scfg_len);
586    memcpy(storage->sscid, &info->sscid, SCID_LENGTH);
587    memcpy(storage->spubs, &info->spubs, MAX_SPUBS_LENGTH);
588    /*
589     * certificate chain
590     */
591    storage->cert_count = (uint32_t)cert_item->count;
592    cert_len = (uint32_t *)(storage + 1);
593    cert_data = (uint8_t *)(cert_len + 1);
594    for (i = 0; i < storage->cert_count; i++)
595    {
596        *cert_len = lsquic_str_len(&cert_item->crts[i]);
597        memcpy(cert_data, lsquic_str_buf(&cert_item->crts[i]), *cert_len);
598        cert_len = (uint32_t *)(cert_data + *cert_len);
599        cert_data = (uint8_t *)(cert_len + 1);
600    }
601}
602
603
604#define CHECK_SPACE(need, start, end) \
605    do { if ((intptr_t) (need) > ((intptr_t) (end) - (intptr_t) (start))) \
606        { return RTT_DESERIALIZE_BAD_CERT_SIZE; } \
607    } while (0) \
608
609static enum rtt_deserialize_return_type
610lsquic_enc_session_deserialize_sess_resume(
611                                const struct lsquic_sess_resume_storage *storage,
612                                                        size_t storage_size,
613                                const struct lsquic_engine_settings *settings,
614                                            lsquic_session_cache_info_t *info,
615                                                    c_cert_item_t *cert_item)
616{
617    enum lsquic_version ver;
618    uint32_t i, len;
619    uint64_t hash;
620    uint32_t *cert_len;
621    uint8_t *cert_data;
622    void *storage_end = (uint8_t *)storage + storage_size;
623    /*
624     * check versions
625     */
626    ver = lsquic_tag2ver(storage->quic_version_tag);
627    if ((int)ver == -1 || !((1 << ver) & settings->es_versions))
628        return RTT_DESERIALIZE_BAD_QUIC_VER;
629    if (storage->serializer_version != RTT_SERIALIZER_VERSION)
630        return RTT_DESERIALIZE_BAD_SERIAL_VER;
631    /*
632     * server config
633     */
634    info->ver = storage->ver;
635    info->aead = storage->aead;
636    info->kexs = storage->kexs;
637    info->pdmd = storage->pdmd;
638    info->orbt = storage->orbt;
639    info->expy = storage->expy;
640    info->scfg_flag = storage->scfg_flag;
641    lsquic_str_setto(&info->sstk, storage->sstk, storage->sstk_len);
642    lsquic_str_setto(&info->scfg, storage->scfg, storage->scfg_len);
643    memcpy(&info->sscid, storage->sscid, SCID_LENGTH);
644    memcpy(&info->spubs, storage->spubs, MAX_SPUBS_LENGTH);
645    /*
646     * certificate chain
647     */
648    cert_item->count = storage->cert_count;
649    cert_item->crts = malloc(cert_item->count * sizeof(lsquic_str_t));
650    cert_item->hashs = lsquic_str_new(NULL, 0);
651    cert_len = (uint32_t *)(storage + 1);
652    for (i = 0; i < storage->cert_count; i++)
653    {
654        CHECK_SPACE(sizeof(uint32_t), cert_len, storage_end);
655        cert_data = (uint8_t *)(cert_len + 1);
656        memcpy(&len, cert_len, sizeof(len));
657        CHECK_SPACE(len, cert_data, storage_end);
658        lsquic_str_prealloc(&cert_item->crts[i], len);
659        lsquic_str_setlen(&cert_item->crts[i], len);
660        memcpy(lsquic_str_buf(&cert_item->crts[i]), cert_data, len);
661        hash = lsquic_fnv1a_64((const uint8_t *)cert_data, len);
662        lsquic_str_append(cert_item->hashs, (char *)&hash, 8);
663        cert_len = (uint32_t *)(cert_data + len);
664    }
665    return RTT_DESERIALIZE_OK;
666}
667
668
669#define KEY_LABEL "quic key"
670#define KEY_LABEL_SZ (sizeof(KEY_LABEL) - 1)
671#define IV_LABEL "quic iv"
672#define IV_LABEL_SZ (sizeof(IV_LABEL) - 1)
673#define PN_LABEL "quic hp"
674#define PN_LABEL_SZ (sizeof(PN_LABEL) - 1)
675
676
677static int
678gquic2_init_crypto_ctx (struct lsquic_enc_session *enc_session,
679                unsigned idx, const unsigned char *secret, size_t secret_sz)
680{
681    const EVP_MD *const md = EVP_sha256();
682    const EVP_AEAD *const aead = EVP_aead_aes_128_gcm();
683    unsigned char key[aes128_key_len];
684    char hexbuf[sizeof(key) * 2 + 1];
685
686    lsquic_qhkdf_expand(md, secret, secret_sz, KEY_LABEL, KEY_LABEL_SZ,
687        key, sizeof(key));
688    if (enc_session->es_flags & ES_LOG_SECRETS)
689        LSQ_DEBUG("handshake key idx %u: %s", idx,
690                                    HEXSTR(key, sizeof(key), hexbuf));
691    lsquic_qhkdf_expand(md, secret, secret_sz, IV_LABEL, IV_LABEL_SZ,
692        enc_session->es_ivs[GEL_CLEAR][idx], IQUIC_IV_LEN);
693    lsquic_qhkdf_expand(md, secret, secret_sz, PN_LABEL, PN_LABEL_SZ,
694        enc_session->es_hps[GEL_CLEAR][idx], IQUIC_HP_LEN);
695    assert(!enc_session->es_aead_ctxs[GEL_CLEAR][idx]);
696    enc_session->es_aead_ctxs[GEL_CLEAR][idx]
697                = malloc(sizeof(*enc_session->es_aead_ctxs[GEL_CLEAR][idx]));
698    if (!enc_session->es_aead_ctxs[GEL_CLEAR][idx])
699        return -1;
700    if (!EVP_AEAD_CTX_init(enc_session->es_aead_ctxs[GEL_CLEAR][idx], aead,
701                                    key, sizeof(key), IQUIC_TAG_LEN, NULL))
702    {
703        free(enc_session->es_aead_ctxs[GEL_CLEAR][idx]);
704        enc_session->es_aead_ctxs[GEL_CLEAR][idx] = NULL;
705        return -1;
706    }
707    return 0;
708}
709
710
711static void
712log_crypto_ctx (const struct lsquic_enc_session *enc_session,
713                                    enum enc_level enc_level, int idx)
714{
715    char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
716
717    LSQ_DEBUG("%s keys for level %s", lsquic_enclev2str[enc_level],
718        idx == 0 ? "encrypt" : "decrypt");
719    LSQ_DEBUG("iv: %s",
720        HEXSTR(enc_session->es_ivs[enc_level][idx], IQUIC_IV_LEN, hexbuf));
721    LSQ_DEBUG("hp: %s",
722        HEXSTR(enc_session->es_hps[enc_level][idx], IQUIC_HP_LEN, hexbuf));
723}
724
725
726static int
727gquic2_setup_handshake_keys (struct lsquic_enc_session *enc_session)
728{
729    const unsigned char *const cid_buf = enc_session->es_conn->cn_cid.idbuf;
730    const size_t cid_buf_sz = enc_session->es_conn->cn_cid.len;
731    size_t hsk_secret_sz;
732    int i, idx;
733    const EVP_MD *const md = EVP_sha256();
734    const char *const labels[] = { CLIENT_LABEL, SERVER_LABEL, };
735    const size_t label_sizes[] = { CLIENT_LABEL_SZ, SERVER_LABEL_SZ, };
736    const unsigned dirs[2] = {
737        (enc_session->es_flags & ES_SERVER),
738        !(enc_session->es_flags & ES_SERVER),
739    };
740    unsigned char hsk_secret[EVP_MAX_MD_SIZE];
741    unsigned char secret[SHA256_DIGEST_LENGTH];
742
743    if (!HKDF_extract(hsk_secret, &hsk_secret_sz, md, cid_buf, cid_buf_sz,
744                                                salt_Q050, sizeof(salt_Q050)))
745    {
746        LSQ_WARN("HKDF extract failed");
747        return -1;
748    }
749
750    for (i = 0; i < 2; ++i)
751    {
752        idx = dirs[i];
753        lsquic_qhkdf_expand(md, hsk_secret, hsk_secret_sz, labels[idx],
754                    label_sizes[idx], secret, sizeof(secret));
755        /*
756        LSQ_DEBUG("`%s' handshake secret: %s",
757            HEXSTR(secret, sizeof(secret), hexbuf));
758        */
759        if (0 != gquic2_init_crypto_ctx(enc_session, i,
760                                                    secret, sizeof(secret)))
761            goto err;
762        if (enc_session->es_flags & ES_LOG_SECRETS)
763            log_crypto_ctx(enc_session, ENC_LEV_CLEAR, i);
764    }
765
766    return 0;
767
768  err:
769    return -1;
770}
771
772
773static void
774maybe_log_secrets (struct lsquic_enc_session *enc_session)
775{
776    const char *log;
777    log = getenv("LSQUIC_LOG_SECRETS");
778    if (log)
779    {
780        if (atoi(log))
781            enc_session->es_flags |= ES_LOG_SECRETS;
782        LSQ_DEBUG("will %slog secrets",
783            enc_session->es_flags & ES_LOG_SECRETS ? "" : "not ");
784    }
785}
786
787
788static enc_session_t *
789lsquic_enc_session_create_client (struct lsquic_conn *lconn, const char *domain,
790                    lsquic_cid_t cid, struct lsquic_engine_public *enpub,
791                                    const unsigned char *sess_resume, size_t sess_resume_len)
792{
793    lsquic_session_cache_info_t *info;
794    struct lsquic_enc_session *enc_session;
795    c_cert_item_t *item;
796    const struct lsquic_sess_resume_storage *sess_resume_storage;
797
798    if (!domain)
799    {
800        errno = EINVAL;
801        return NULL;
802    }
803
804    enc_session = calloc(1, sizeof(*enc_session));
805    if (!enc_session)
806        return NULL;
807
808    /* have to allocate every time */
809    info = calloc(1, sizeof(*info));
810    if (!info)
811    {
812        free(enc_session);
813        return NULL;
814    }
815
816    if (sess_resume && sess_resume_len > sizeof(struct lsquic_sess_resume_storage))
817    {
818        item = calloc(1, sizeof(*item));
819        if (!item)
820        {
821            free(enc_session);
822            free(info);
823            return NULL;
824        }
825        sess_resume_storage = (const struct lsquic_sess_resume_storage *)sess_resume;
826        switch (lsquic_enc_session_deserialize_sess_resume(sess_resume_storage,
827                                                        sess_resume_len,
828                                                        &enpub->enp_settings,
829                                                        info, item))
830        {
831            case RTT_DESERIALIZE_BAD_QUIC_VER:
832                LSQ_ERROR("provided sess_resume has unsupported QUIC version");
833                free(item);
834                break;
835            case RTT_DESERIALIZE_BAD_SERIAL_VER:
836                LSQ_ERROR("provided sess_resume has bad serializer version");
837                free(item);
838                break;
839            case RTT_DESERIALIZE_BAD_CERT_SIZE:
840                LSQ_ERROR("provided sess_resume has bad cert size");
841                free(item);
842                break;
843            case RTT_DESERIALIZE_OK:
844                memcpy(enc_session->hs_ctx.pubs, info->spubs, 32);
845                enc_session->cert_item = item;
846                break;
847        }
848    }
849    enc_session->es_conn = lconn;
850    enc_session->enpub = enpub;
851    enc_session->cid   = cid;
852    enc_session->info  = info;
853    /* FIXME: allocation may fail */
854    lsquic_str_append(&enc_session->hs_ctx.sni, domain, strlen(domain));
855    maybe_log_secrets(enc_session);
856    if (lconn->cn_version >= LSQVER_050)
857    {
858        enc_session->es_flags |= ES_GQUIC2;
859        gquic2_setup_handshake_keys(enc_session);
860    }
861    return enc_session;
862}
863
864
865/* Server side: Session_cache_entry can be saved for 0rtt */
866static enc_session_t *
867lsquic_enc_session_create_server (struct lsquic_conn *lconn, lsquic_cid_t cid,
868                        struct lsquic_engine_public *enpub)
869{
870    fiu_return_on("handshake/new_enc_session", NULL);
871
872    struct lsquic_enc_session *enc_session;
873
874    enc_session = calloc(1, sizeof(*enc_session));
875    if (!enc_session)
876        return NULL;
877
878    enc_session->es_conn = lconn;
879    enc_session->enpub = enpub;
880    enc_session->cid = cid;
881    enc_session->es_flags |= ES_SERVER;
882    maybe_log_secrets(enc_session);
883    if (lconn->cn_version >= LSQVER_050)
884    {
885        enc_session->es_flags |= ES_GQUIC2;
886        gquic2_setup_handshake_keys(enc_session);
887    }
888    return enc_session;
889}
890
891
892static void
893lsquic_enc_session_reset_cid (enc_session_t *enc_session_p,
894                                        const lsquic_cid_t *new_cid)
895{
896    struct lsquic_enc_session *const enc_session = enc_session_p;
897
898    LSQ_INFOC("changing CID to %"CID_FMT, CID_BITS(new_cid));
899    enc_session->cid = *new_cid;
900}
901
902
903static void
904put_compressed_cert (struct compressed_cert *ccert)
905{
906    if (ccert)
907    {
908        assert(ccert->refcnt > 0);
909        --ccert->refcnt;
910        if (0 == ccert->refcnt)
911            free(ccert);
912    }
913}
914
915
916static struct compressed_cert *
917new_compressed_cert (const unsigned char *buf, size_t len)
918{
919    struct compressed_cert *ccert;
920
921    ccert = malloc(sizeof(*ccert) + len);
922    if (ccert)
923    {
924        ccert->refcnt = 1;
925        ccert->len = len;
926        memcpy(ccert->buf, buf, len);
927    }
928    return ccert;
929}
930
931
932static void
933lsquic_enc_session_destroy (enc_session_t *enc_session_p)
934{
935    struct lsquic_enc_session *const enc_session = enc_session_p;
936    enum gel gel;
937    unsigned i;
938
939    if (!enc_session)
940        return ;
941
942    hs_ctx_t *hs_ctx = &enc_session->hs_ctx;
943
944    lsquic_str_d(&hs_ctx->sni);
945    lsquic_str_d(&hs_ctx->ccs);
946    lsquic_str_d(&hs_ctx->ccrt);
947    lsquic_str_d(&hs_ctx->stk);
948    lsquic_str_d(&hs_ctx->sno);
949    lsquic_str_d(&hs_ctx->prof);
950    lsquic_str_d(&hs_ctx->csct);
951    put_compressed_cert(hs_ctx->ccert);
952    hs_ctx->ccert = NULL;
953    lsquic_str_d(&hs_ctx->uaid);
954    lsquic_str_d(&hs_ctx->scfg_pubs);
955    lsquic_str_d(&enc_session->chlo);
956    lsquic_str_d(&enc_session->sstk);
957    lsquic_str_d(&enc_session->ssno);
958    for (gel = 0; gel < N_GELS; ++gel)
959        for (i = 0; i < 2; ++i)
960            if (enc_session->es_aead_ctxs[gel][i])
961            {
962                EVP_AEAD_CTX_cleanup(enc_session->es_aead_ctxs[gel][i]);
963                free(enc_session->es_aead_ctxs[gel][i]);
964            }
965    memset(enc_session->es_aead_ctxs, 0, sizeof(enc_session->es_aead_ctxs));
966    if (enc_session->info)
967    {
968        lsquic_str_d(&enc_session->info->sstk);
969        lsquic_str_d(&enc_session->info->scfg);
970        lsquic_str_d(&enc_session->info->sni_key);
971        free(enc_session->info);
972    }
973    if (enc_session->cert_item)
974    {
975        free_c_cert_item(enc_session->cert_item);
976        enc_session->cert_item = NULL;
977    }
978    if ((enc_session->es_flags & ES_FREE_CERT_PTR) && enc_session->cert_ptr)
979        lsquic_str_delete(enc_session->cert_ptr);
980    free(enc_session);
981
982}
983
984
985static int get_hs_state(struct lsquic_enc_session *enc_session)
986{
987    return enc_session->hsk_state;
988}
989
990
991/* make sure have more room for encrypt */
992static int
993lsquic_enc_session_is_hsk_done (enc_session_t *enc_session_p)
994{
995    struct lsquic_enc_session *const enc_session = enc_session_p;
996    return (get_hs_state(enc_session) == HSK_COMPLETED);
997}
998
999
1000static void
1001process_copt (struct lsquic_enc_session *enc_session, const uint32_t *const opts,
1002                unsigned n_opts)
1003{
1004    unsigned i;
1005    for (i = 0; i < n_opts; ++i)
1006        switch (opts[i])
1007        {
1008        case QTAG_NSTP:
1009            enc_session->hs_ctx.opts |= HOPT_NSTP;
1010            break;
1011        case QTAG_SREJ:
1012            enc_session->hs_ctx.opts |= HOPT_SREJ;
1013            break;
1014        }
1015}
1016
1017
1018static int parse_hs_data (struct lsquic_enc_session *enc_session, uint32_t tag,
1019                          unsigned char *val, int len, uint32_t head_tag)
1020{
1021    hs_ctx_t * hs_ctx = &enc_session->hs_ctx;
1022    int is_client = (head_tag != QTAG_CHLO);
1023
1024    switch(tag)
1025    {
1026    case QTAG_PDMD:
1027        hs_ctx->pdmd = get_tag_value_i32(val, len);
1028        break;
1029
1030    case QTAG_MIDS:
1031        if (0 != get_tag_val_u32(val, len,
1032                    (is_client ? &hs_ctx->mids : &hs_ctx->smids)))
1033            return -1;
1034        break;
1035
1036    case QTAG_SCLS:
1037        hs_ctx->scls = get_tag_value_i32(val, len);
1038        break;
1039
1040    case QTAG_CFCW:
1041        if (0 != get_tag_val_u32(val, len, (is_client ? &hs_ctx->cfcw : &hs_ctx->scfcw)))
1042            return -1;
1043        break;
1044
1045    case QTAG_SFCW:
1046        if (0 != get_tag_val_u32(val, len, (is_client ? &hs_ctx->sfcw : &hs_ctx->ssfcw)))
1047            return -1;
1048        break;
1049
1050    case QTAG_ICSL:
1051        hs_ctx->icsl = get_tag_value_i32(val, len);
1052        break;
1053
1054    case QTAG_IRTT:
1055        if (0 != get_tag_val_u32(val, len, &hs_ctx->irtt))
1056            return -1;
1057        hs_ctx->set |= HSET_IRTT;
1058        break;
1059
1060    case QTAG_COPT:
1061        if (0 == len % sizeof(uint32_t))
1062            process_copt(enc_session, (uint32_t *) val, len / sizeof(uint32_t));
1063        /* else ignore, following the reference implementation */
1064        break;
1065
1066    case QTAG_SNI:
1067        lsquic_str_setto(&hs_ctx->sni, val, len);
1068        ESHIST_APPEND(enc_session, ESHE_SET_SNI);
1069        break;
1070
1071    case QTAG_CCS:
1072        lsquic_str_setto(&hs_ctx->ccs, val, len);
1073        break;
1074
1075    case QTAG_CCRT:
1076        lsquic_str_setto(&hs_ctx->ccrt, val, len);
1077        break;
1078
1079    case QTAG_CRT:
1080        put_compressed_cert(hs_ctx->ccert);
1081        hs_ctx->ccert = new_compressed_cert(val, len);
1082        break;
1083
1084    case QTAG_PUBS:
1085        if (head_tag == QTAG_SCFG)
1086            lsquic_str_setto(&hs_ctx->scfg_pubs, val, len);
1087        else if (len == 32)
1088            memcpy(hs_ctx->pubs, val, len);
1089        break;
1090
1091    case QTAG_RCID:
1092        hs_ctx->rcid = get_tag_value_i64(val, len);
1093        break;
1094
1095    case QTAG_UAID:
1096        lsquic_str_setto(&hs_ctx->uaid, val, len);
1097        break;
1098
1099    case QTAG_SMHL:
1100        if (0 != get_tag_val_u32(val, len, &hs_ctx->smhl))
1101            return -1;
1102        hs_ctx->set |= HSET_SMHL;
1103        break;
1104
1105    case QTAG_TCID:
1106        if (0 != get_tag_val_u32(val, len, &hs_ctx->tcid))
1107            return -1;
1108        hs_ctx->set |= HSET_TCID;
1109        break;
1110
1111    case QTAG_EXPY:
1112        enc_session->info->expy = get_tag_value_i64(val, len);
1113        break;
1114
1115    case QTAG_ORBT:
1116        enc_session->info->orbt = get_tag_value_i64(val, len);
1117        break;
1118
1119    case QTAG_SNO:
1120        if (is_client)
1121        {
1122            lsquic_str_setto(&enc_session->ssno, val, len);
1123        }
1124        else
1125        {
1126            /* Server side save a copy of SNO just for verify */
1127            lsquic_str_setto(&hs_ctx->sno, val, len);
1128        }
1129        ESHIST_APPEND(enc_session, ESHE_SET_SNO);
1130        break;
1131
1132    case QTAG_STK:
1133        if (is_client)
1134        {
1135            lsquic_str_setto(&enc_session->info->sstk, val, len);
1136        }
1137        else
1138        {
1139            /* Server need to save a copy to verify */
1140            lsquic_str_setto(&hs_ctx->stk, val, len);
1141        }
1142        ESHIST_APPEND(enc_session, ESHE_SET_STK);
1143        break;
1144
1145    case QTAG_SCID:
1146        if (len != SCID_LENGTH)
1147            return -1;
1148        if (is_client)
1149        {
1150            memcpy(enc_session->info->sscid, val, len);
1151        }
1152        else
1153        {
1154            memcpy(hs_ctx->scid, val, len);
1155            hs_ctx->set |= HSET_SCID;
1156        }
1157        ESHIST_APPEND(enc_session, ESHE_SET_SCID);
1158        break;
1159
1160    case QTAG_AEAD:
1161        if (is_client)
1162            enc_session->info->aead = get_tag_value_i32(val, len);
1163        else
1164            hs_ctx->aead = get_tag_value_i32(val, len);
1165        break;
1166
1167    case QTAG_KEXS:
1168        if (is_client)
1169        {
1170            if (head_tag == QTAG_SCFG && 0 == len % 4)
1171            {
1172                const unsigned char *p, *end;
1173                unsigned pub_idx, idx;
1174#ifdef WIN32
1175                pub_idx = 0;
1176#endif
1177
1178                for (p = val; p < val + len; p += 4)
1179                    if (0 == memcmp(p, "C255", 4))
1180                    {
1181                        memcpy(&enc_session->info->kexs, p, 4);
1182                        pub_idx = (p - val) / 4;
1183                        LSQ_DEBUG("Parsing SCFG: supported KEXS C255 at "
1184                                                        "index %u", pub_idx);
1185                        break;
1186                    }
1187                if (p >= val + len)
1188                {
1189                    LSQ_INFO("supported KEXS not found, trouble ahead");
1190                    break;
1191                }
1192                if (lsquic_str_len(&hs_ctx->scfg_pubs) > 0)
1193                {
1194                    p = (const unsigned char *)
1195                                        lsquic_str_cstr(&hs_ctx->scfg_pubs);
1196                    end = p + lsquic_str_len(&hs_ctx->scfg_pubs);
1197
1198                    for (idx = 0; p < end; ++idx)
1199                    {
1200                        uint32_t sz = 0;
1201                        if (p + 3 > end)
1202                            break;
1203                        sz |= *p++;
1204                        sz |= *p++ << 8;
1205                        sz |= *p++ << 16;
1206                        if (p + sz > end)
1207                            break;
1208                        if (idx == pub_idx)
1209                        {
1210                            if (sz == 32)
1211                            {
1212                                memcpy(hs_ctx->pubs, p, 32);
1213                                memcpy(enc_session->info->spubs, p, 32);
1214                            }
1215                            break;
1216                        }
1217                        p += sz;
1218                    }
1219                }
1220                else
1221                    LSQ_INFO("No PUBS from SCFG to parse");
1222            }
1223        }
1224        else
1225            hs_ctx->kexs = get_tag_value_i32(val, len);
1226        break;
1227
1228    case QTAG_NONC:
1229        if (len != sizeof(hs_ctx->nonc))
1230            return -1;
1231        memcpy(hs_ctx->nonc, val, len);
1232        break;
1233
1234    case QTAG_SCFG:
1235        if (is_client)
1236        {
1237            lsquic_str_setto(&enc_session->info->scfg, val, len);
1238            enc_session->info->scfg_flag = 1;
1239        }
1240        else
1241            LSQ_INFO("unexpected SCFG");
1242        break;
1243
1244    case QTAG_PROF:
1245        lsquic_str_setto(&hs_ctx->prof, val, len);
1246        ESHIST_APPEND(enc_session, ESHE_SET_PROF);
1247        break;
1248
1249    case QTAG_STTL:
1250        hs_ctx->sttl = get_tag_value_i64(val, len);
1251        break;
1252
1253    case QTAG_SRST:
1254        if (enc_session->es_flags & ES_SERVER)
1255            break;
1256        if (len != sizeof(hs_ctx->srst))
1257        {
1258            LSQ_INFO("Unexpected size of SRST: %u instead of %zu bytes",
1259                len, sizeof(hs_ctx->srst));
1260            return -1;
1261        }
1262        memcpy(hs_ctx->srst, val, len);
1263        hs_ctx->set |= HSET_SRST;
1264        ESHIST_APPEND(enc_session, ESHE_SET_SRST);
1265        break;
1266
1267    default:
1268        LSQ_DEBUG("Ignored tag '%.*s'", 4, (char *)&tag);
1269        break;
1270    }
1271
1272    return 0;
1273}
1274
1275
1276/* only for the hs stream-frame data, NOT with the packet header or frame header*/
1277static enum handshake_error parse_hs (struct lsquic_enc_session *enc_session,
1278                                      const unsigned char *buf, int buf_len,
1279                                      uint32_t *head_tag)
1280{
1281    uint16_t i;
1282    const unsigned char *p = buf;
1283    const unsigned char *pend = buf + buf_len;
1284
1285    unsigned char *data;
1286    uint32_t len = 0, offset = 0;
1287    uint16_t num;
1288    uint32_t tag;
1289    if (buf_len < 6)
1290        return DATA_FORMAT_ERROR;
1291
1292    memcpy(&tag, p, 4);
1293    p += 4;
1294
1295    if (enc_session->es_flags & ES_SERVER)
1296    {   /* Server only expects to receive CHLO messages from the client */
1297        if (tag != QTAG_CHLO)
1298            return DATA_FORMAT_ERROR;
1299    }
1300    else
1301    {
1302        if (tag != QTAG_SREJ && tag != QTAG_REJ && tag != QTAG_SHLO &&
1303                                                        tag != QTAG_SCFG)
1304            return DATA_FORMAT_ERROR;
1305    }
1306
1307    *head_tag = tag;
1308
1309    memcpy((char *)&num, p, 2);
1310    p += 2 + 2;  /* the 2 bytes padding 0x0000 need to be bypassed */
1311
1312    if (num < 1)
1313        return DATA_FORMAT_ERROR;
1314
1315    data = (uint8_t *)(buf + 4 * 2 * (1 + num));
1316    if ((const char *)data > (const char *)pend)
1317    {
1318        LSQ_DEBUG("parse_hs tag '%.*s' error: data not enough", 4, (char *)head_tag);
1319        return DATA_NOT_ENOUGH;
1320    }
1321
1322    /* check last offset */
1323    memcpy((char *)&len, data - 4, 4);
1324    if ((const char *)data + len > (const char *)pend)
1325    {
1326        LSQ_DEBUG("parse_hs tag '%.*s' error: data not enough!!!", 4, (char *)head_tag);
1327        return DATA_NOT_ENOUGH;
1328    }
1329
1330    for (i=0; i<num; ++i)
1331    {
1332        memcpy((char *)&tag, p, 4);
1333        p += 4;
1334        memcpy((char *)&len, p, 4);
1335        len -= offset;
1336        p += 4;
1337
1338        if ((const char *)data + offset + len > (const char *)pend)
1339            return DATA_FORMAT_ERROR;
1340
1341        if (0 != parse_hs_data(enc_session, tag, data + offset, len,
1342                                                                *head_tag))
1343            return DATA_FORMAT_ERROR;
1344        offset += len;
1345    }
1346
1347    LSQ_DEBUG("parse_hs tag '%.*s' no error.", 4, (char *)head_tag);
1348    return DATA_NO_ERROR;
1349}
1350
1351
1352static uint32_t get_tag_value_i32(unsigned char *val, int len)
1353{
1354    uint32_t v;
1355    if (len < 4)
1356        return 0;
1357    memcpy(&v, val, 4);
1358    return v;
1359}
1360
1361
1362static uint64_t get_tag_value_i64(unsigned char *val, int len)
1363{
1364    uint64_t v;
1365    if (len < 8)
1366        return 0;
1367    memcpy(&v, val, 8);
1368    return v;
1369}
1370
1371
1372static int
1373get_tag_val_u32 (unsigned char *v, int len, uint32_t *val)
1374{
1375    if (len != 4)
1376        return -1;
1377    memcpy(val, v, 4);
1378    return 0;
1379}
1380
1381
1382/*  From "QUIC Crypto" for easy reference:
1383 *
1384 *  A handshake message consists of:
1385 *    - The tag of the message.
1386 *    - A uint16 containing the number of tag-value pairs.
1387 *    - Two bytes of padding which should be zero when sent but ignored when
1388 *          received.
1389 *    - A series of uint32 tags and uint32 end offsets, one for each
1390 *          tag-value pair. The tags must be strictly monotonically
1391 *          increasing, and the end-offsets must be monotonic non-decreasing.
1392 *          The end offset gives the offset, from the start of the value
1393 *          data, to a byte one beyond the end of the data for that tag.
1394 *          (Thus the end offset of the last tag contains the length of the
1395 *          value data).
1396 *    - The value data, concatenated without padding.
1397 */
1398
1399struct table_entry { uint32_t tag, off; };
1400
1401struct message_writer
1402{
1403    unsigned char       *mw_p;
1404    struct table_entry   mw_first_dummy_entry;
1405    struct table_entry  *mw_entry,
1406                        *mw_prev_entry,
1407                        *mw_end;
1408};
1409
1410/* MW_ family of macros is used to write entries to handshake message
1411 * (MW stands for "message writer").
1412 */
1413#define MW_BEGIN(mw, msg_tag, n_entries, data_ptr) do {             \
1414    uint32_t t_ = msg_tag;                                          \
1415    uint16_t n_ = n_entries;                                        \
1416    memcpy(data_ptr, &t_, 4);                                       \
1417    memcpy(data_ptr + 4, &n_, 2);                                   \
1418    memset(data_ptr + 4 + 2, 0, 2);                                 \
1419    (mw)->mw_entry = (void *) (data_ptr + 8);                       \
1420    (mw)->mw_p = data_ptr + 8 +                                     \
1421                    (n_entries) * sizeof((mw)->mw_entry[0]);        \
1422    (mw)->mw_first_dummy_entry.tag = 0;                             \
1423    (mw)->mw_first_dummy_entry.off = 0;                             \
1424    (mw)->mw_prev_entry = &(mw)->mw_first_dummy_entry;              \
1425    (mw)->mw_end = (void *) (mw)->mw_p;                             \
1426} while (0)
1427
1428#ifndef NDEBUG
1429#   define MW_END(mw) do {                                          \
1430        assert((mw)->mw_entry == (mw)->mw_end);                     \
1431    } while (0)
1432#else
1433#   define MW_END(mw)
1434#endif
1435
1436#define MW_P(mw) ((mw)->mw_p)
1437
1438#define MW_ADVANCE_P(mw, n) do {                                    \
1439    MW_P(mw) += (n);                                                \
1440} while (0)
1441
1442#define MW_WRITE_TABLE_ENTRY(mw, tag_, sz) do {                     \
1443    assert((mw)->mw_prev_entry->tag < (tag_));                      \
1444    assert((mw)->mw_entry < (mw)->mw_end);                          \
1445    (mw)->mw_entry->tag = (tag_);                                   \
1446    (mw)->mw_entry->off = (mw)->mw_prev_entry->off + (sz);          \
1447    (mw)->mw_prev_entry = (mw)->mw_entry;                           \
1448    ++(mw)->mw_entry;                                               \
1449} while (0)
1450
1451#define MW_WRITE_BUFFER(mw, tag, buf, sz) do {                      \
1452    MW_WRITE_TABLE_ENTRY(mw, tag, sz);                              \
1453    memcpy(MW_P(mw), buf, sz);                                      \
1454    MW_ADVANCE_P(mw, sz);                                           \
1455} while (0)
1456
1457#define MW_WRITE_LS_STR(mw, tag, s) \
1458    MW_WRITE_BUFFER(mw, tag, lsquic_str_buf(s), lsquic_str_len(s))
1459
1460#define MW_WRITE_UINT32(mw, tag, val) do {                          \
1461    uint32_t v_ = (val);                                            \
1462    MW_WRITE_BUFFER(mw, tag, &v_, sizeof(v_));                      \
1463} while (0)
1464
1465#define MW_WRITE_UINT64(mw, tag, val) do {                          \
1466    uint64_t v_ = (val);                                            \
1467    MW_WRITE_BUFFER(mw, tag, &v_, sizeof(v_));                      \
1468} while (0)
1469
1470
1471/* MSG_LEN_ family of macros calculates buffer size required for a
1472 * handshake message.
1473 */
1474#define MSG_LEN_INIT(len) do {                                      \
1475    len = 4 /* Tag */ + 2 /* # tags */ + 2 /* Two zero bytes */;    \
1476} while (0)
1477
1478#define MSG_LEN_ADD(len, payload_sz) do {                           \
1479    len += 4 + 4 + (payload_sz);                                    \
1480} while (0)
1481
1482#define MSG_LEN_VAL(len) (+(len))
1483
1484
1485static int
1486lsquic_enc_session_gen_chlo (enc_session_t *enc_session_p,
1487                        enum lsquic_version version, uint8_t *buf, size_t *len)
1488{
1489    struct lsquic_enc_session *const enc_session = enc_session_p;
1490    int include_pad;
1491    const lsquic_str_t *const ccs = lsquic_get_common_certs_hash();
1492    const struct lsquic_engine_settings *const settings =
1493                                        &enc_session->enpub->enp_settings;
1494    c_cert_item_t *const cert_item = enc_session->cert_item;
1495    unsigned char pub_key[32];
1496    size_t ua_len;
1497    uint32_t opts[1];  /* Only NSTP is supported for now */
1498    unsigned n_opts, msg_len, n_tags, pad_size;
1499    struct message_writer mw;
1500
1501    /* Before we do anything else, sanity check: */
1502    if (*len < MIN_CHLO_SIZE)
1503        return -1;
1504
1505    n_opts = 0;
1506    /* CHLO is not regenerated during version negotiation.  Hence we always
1507     * include this option to cover the case when Q044 or Q046 gets negotiated
1508     * down.
1509     */
1510    if (settings->es_support_nstp)
1511        opts[ n_opts++ ] = QTAG_NSTP;
1512
1513    /* Count tags and calculate required buffer size: */
1514    MSG_LEN_INIT(msg_len);                  n_tags = 0;
1515    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* PDMD */
1516    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* AEAD */
1517    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* VER  */
1518    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* MIDS */
1519    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* SCLS */
1520    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* CFCW */
1521    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* SFCW */
1522    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* ICSL */
1523    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* SMHL */
1524    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* KEXS */
1525    MSG_LEN_ADD(msg_len, 0);                ++n_tags;           /* CSCT */
1526    if (n_opts > 0)
1527    {
1528        MSG_LEN_ADD(msg_len, sizeof(opts[0]) * n_opts);
1529                                            ++n_tags;           /* COPT */
1530    }
1531    if (settings->es_ua)
1532    {
1533        ua_len = strlen(settings->es_ua);
1534        if (ua_len > 0)
1535        {
1536            MSG_LEN_ADD(msg_len, ua_len);   ++n_tags;           /* UAID */
1537        }
1538    }
1539    else
1540        ua_len = 0;
1541    if (settings->es_support_tcid0)
1542    {
1543        MSG_LEN_ADD(msg_len, 4);            ++n_tags;           /* TCID */
1544    }
1545    MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->hs_ctx.sni));
1546                                            ++n_tags;           /* SNI  */
1547    MSG_LEN_ADD(msg_len, lsquic_str_len(ccs));  ++n_tags;           /* CCS  */
1548    if (cert_item)
1549    {
1550        enc_session->cert_ptr = &cert_item->crts[0];
1551        MSG_LEN_ADD(msg_len, lsquic_str_len(cert_item->hashs));
1552                                            ++n_tags;           /* CCRT */
1553        MSG_LEN_ADD(msg_len, 8);            ++n_tags;           /* XLCT */
1554    }
1555    MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->ssno));
1556                                            ++n_tags;           /* SNO  */
1557    MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->info->sstk));
1558                                            ++n_tags;           /* STK  */
1559    if (lsquic_str_len(&enc_session->info->scfg) > 0)
1560    {
1561        MSG_LEN_ADD(msg_len, sizeof(enc_session->info->sscid));
1562                                            ++n_tags;           /* SCID */
1563        if (enc_session->cert_ptr)
1564        {
1565            MSG_LEN_ADD(msg_len, sizeof(pub_key));
1566                                            ++n_tags;           /* PUBS */
1567            MSG_LEN_ADD(msg_len, sizeof(enc_session->hs_ctx.nonc));
1568                                            ++n_tags;           /* NONC */
1569            RAND_bytes(enc_session->priv_key, 32);
1570            lsquic_c255_get_pub_key(enc_session->priv_key, pub_key);
1571            lsquic_gen_nonce_c(enc_session->hs_ctx.nonc, enc_session->info->orbt);
1572        }
1573    }
1574    include_pad = MSG_LEN_VAL(msg_len) < MIN_CHLO_SIZE;
1575    if (include_pad)
1576    {
1577        if (MSG_LEN_VAL(msg_len) + sizeof(struct table_entry) < MIN_CHLO_SIZE)
1578            pad_size = MIN_CHLO_SIZE - MSG_LEN_VAL(msg_len) -
1579                                                sizeof(struct table_entry);
1580        else
1581            pad_size = 0;
1582        MSG_LEN_ADD(msg_len, pad_size);     ++n_tags;           /* PAD  */
1583    }
1584#ifdef WIN32
1585    else
1586        pad_size = 0;
1587#endif
1588
1589    /* Check that we have enough room in the output buffer: */
1590    if (MSG_LEN_VAL(msg_len) > *len)
1591        return -1;
1592
1593    /* Write CHLO: */
1594    MW_BEGIN(&mw, QTAG_CHLO, n_tags, buf);
1595    if (include_pad)
1596    {
1597        memset(MW_P(&mw), '-', pad_size);
1598        MW_WRITE_TABLE_ENTRY(&mw, QTAG_PAD, pad_size);
1599        MW_ADVANCE_P(&mw, pad_size);
1600    }
1601    MW_WRITE_LS_STR(&mw, QTAG_SNI, &enc_session->hs_ctx.sni);
1602    MW_WRITE_LS_STR(&mw, QTAG_STK, &enc_session->info->sstk);
1603    MW_WRITE_LS_STR(&mw, QTAG_SNO, &enc_session->ssno);
1604    MW_WRITE_UINT32(&mw, QTAG_VER, lsquic_ver2tag(version));
1605    MW_WRITE_LS_STR(&mw, QTAG_CCS, ccs);
1606    if (lsquic_str_len(&enc_session->info->scfg) > 0 && enc_session->cert_ptr)
1607        MW_WRITE_BUFFER(&mw, QTAG_NONC, enc_session->hs_ctx.nonc,
1608                                        sizeof(enc_session->hs_ctx.nonc));
1609    MW_WRITE_UINT32(&mw, QTAG_AEAD, settings->es_aead);
1610    if (ua_len)
1611        MW_WRITE_BUFFER(&mw, QTAG_UAID, settings->es_ua, ua_len);
1612    if (lsquic_str_len(&enc_session->info->scfg) > 0)
1613        MW_WRITE_BUFFER(&mw, QTAG_SCID, enc_session->info->sscid,
1614                                        sizeof(enc_session->info->sscid));
1615    if (settings->es_support_tcid0)
1616        MW_WRITE_UINT32(&mw, QTAG_TCID, 0);
1617    MW_WRITE_UINT32(&mw, QTAG_PDMD, settings->es_pdmd);
1618    MW_WRITE_UINT32(&mw, QTAG_SMHL, 1);
1619    MW_WRITE_UINT32(&mw, QTAG_ICSL, settings->es_idle_conn_to / 1000000);
1620    if (lsquic_str_len(&enc_session->info->scfg) > 0 && enc_session->cert_ptr)
1621        MW_WRITE_BUFFER(&mw, QTAG_PUBS, pub_key, sizeof(pub_key));
1622    MW_WRITE_UINT32(&mw, QTAG_MIDS, settings->es_max_streams_in);
1623    MW_WRITE_UINT32(&mw, QTAG_SCLS, settings->es_silent_close);
1624    MW_WRITE_UINT32(&mw, QTAG_KEXS, settings->es_kexs);
1625    if (cert_item)
1626        MW_WRITE_BUFFER(&mw, QTAG_XLCT, lsquic_str_buf(cert_item->hashs), 8);
1627    /* CSCT is empty on purpose (retained from original code) */
1628    MW_WRITE_TABLE_ENTRY(&mw, QTAG_CSCT, 0);
1629    if (n_opts > 0)
1630        MW_WRITE_BUFFER(&mw, QTAG_COPT, opts, n_opts * sizeof(opts[0]));
1631    if (cert_item)
1632        MW_WRITE_LS_STR(&mw, QTAG_CCRT, cert_item->hashs);
1633    MW_WRITE_UINT32(&mw, QTAG_CFCW, settings->es_cfcw);
1634    MW_WRITE_UINT32(&mw, QTAG_SFCW, settings->es_sfcw);
1635    MW_END(&mw);
1636    assert(buf + *len >= MW_P(&mw));
1637
1638    *len = MW_P(&mw) - buf;
1639
1640    lsquic_str_setto(&enc_session->chlo, buf, *len);
1641
1642    if (lsquic_str_len(&enc_session->info->scfg) > 0 && enc_session->cert_ptr)
1643    {
1644        enc_session->have_key = 0;
1645        assert(lsquic_str_len(enc_session->cert_ptr) > 0);
1646        determine_keys(enc_session);
1647        enc_session->have_key = 1;
1648    }
1649
1650    LSQ_DEBUG("lsquic_enc_session_gen_chlo called, return 0, buf_len %zd.", *len);
1651    return 0;
1652}
1653
1654
1655static enum handshake_error
1656determine_rtts (struct lsquic_enc_session *enc_session,
1657                                    const struct sockaddr *ip_addr, time_t t)
1658{
1659    hs_ctx_t *const hs_ctx = &enc_session->hs_ctx;
1660    enum hsk_failure_reason hfr;
1661
1662    if (!(hs_ctx->set & HSET_SCID))
1663    {
1664        hs_ctx->rrej = HFR_CONFIG_INCHOATE_HELLO;
1665        ESHIST_APPEND(enc_session, ESHE_MISSING_SCID);
1666        goto fail_1rtt;
1667    }
1668
1669    hfr = lsquic_verify_stk(enc_session, ip_addr, t, &hs_ctx->stk);
1670    if (hfr != HFR_HANDSHAKE_OK)
1671    {
1672        hs_ctx->rrej = hfr;
1673        ESHIST_APPEND(enc_session, ESHE_VSTK_FAILED);
1674        goto fail_1rtt;
1675    }
1676    else
1677        ESHIST_APPEND(enc_session, ESHE_VSTK_OK);
1678
1679    if (memcmp(enc_session->server_config->lsc_scfg->info.sscid, hs_ctx->scid, 16) != 0)
1680    {
1681        hs_ctx->rrej = HFR_CONFIG_UNKNOWN_CONFIG;
1682        ESHIST_APPEND(enc_session, ESHE_UNKNOWN_CONFIG);
1683        goto fail_1rtt;
1684    }
1685
1686    if (!(lsquic_str_len(&hs_ctx->ccrt) > 0))
1687    {
1688        /* We provide incorrect RREJ here because there is not one that fits
1689         * this case.  We can tell them apart: one comes in SREJ, the other
1690         * in REJ.
1691         */
1692        hs_ctx->rrej = HFR_CONFIG_INCHOATE_HELLO;
1693        ESHIST_APPEND(enc_session, ESHE_EMPTY_CCRT);
1694        goto fail_1rtt;
1695    }
1696
1697    if (lsquic_str_len(&enc_session->ssno) > 0)
1698    {
1699        if (lsquic_str_len(&hs_ctx->sno) == 0)
1700        {
1701            hs_ctx->rrej = HFR_SERVER_NONCE_REQUIRED;
1702            ESHIST_APPEND(enc_session, ESHE_MISSING_SNO);
1703            goto fail_1rtt;
1704        }
1705        else if (lsquic_str_bcmp(&enc_session->ssno, &hs_ctx->sno) != 0)
1706        {
1707            hs_ctx->rrej = HFR_SERVER_NONCE_INVALID;
1708            ESHIST_APPEND(enc_session, ESHE_SNO_MISMATCH);
1709            goto fail_1rtt;
1710        }
1711        else
1712            ESHIST_APPEND(enc_session, ESHE_SNO_OK);
1713    }
1714
1715    enc_session->hsk_state = HSK_SHLO;
1716    memcpy(enc_session->priv_key, enc_session->server_config->lsc_scfg->info.priv_key, 32);
1717    return HS_SHLO;
1718
1719  fail_1rtt:
1720    enc_session->hsk_state = HSK_CHLO_REJ;
1721    return HS_1RTT;
1722}
1723
1724
1725static int
1726config_has_correct_size (const struct lsquic_enc_session *enc_session,
1727                                            const void *data, unsigned shm_len)
1728{
1729    /* EVP_AEAD_CTX from boringssl after-18d9f28f0df9f95570. */
1730    struct new_evp_aead_ctx_st {
1731        void *ptr1;     /* aead */
1732        void *ptr2;     /* aead_state */
1733        uint8_t tag_len;
1734    };
1735
1736    /* This is how SHM would like in 5.2.1 builds 7 and 8: */
1737    struct old_scfg_info
1738    {
1739        unsigned char   sscid[SCID_LENGTH];
1740        unsigned char   priv_key[32];
1741        unsigned char   skt_key[16];
1742        uint32_t        aead;
1743        uint32_t        kexs;
1744        uint32_t        pdmd;
1745        uint64_t        orbt;
1746        uint64_t        expy;
1747        struct new_evp_aead_ctx_st ctx;
1748        short           scfg_len;
1749    };
1750
1751    const SCFG_t               *const modern_config = data;
1752    const struct old_scfg_info *const old_info      = data;
1753    size_t expected_size;
1754
1755    expected_size = modern_config->info.scfg_len + sizeof(*modern_config);
1756    if (expected_size == shm_len)
1757        return 1;
1758
1759    if (old_info->scfg_len + sizeof(*old_info) == shm_len)
1760    {
1761        LSQ_WARN("Generating new server config");
1762        return 0;
1763    }
1764
1765    LSQ_ERROR("Server config has size %u -- expected %zd", shm_len,
1766                                                            expected_size);
1767    return 0;
1768}
1769
1770
1771static lsquic_server_config_t *
1772get_valid_scfg (const struct lsquic_enc_session *enc_session,
1773                                    const struct lsquic_engine_public *enpub)
1774{
1775#define SERVER_SCFG_KEY         "SERVER_SCFG"
1776#define SERVER_SCFG_KEY_SIZE    (sizeof(SERVER_SCFG_KEY) - 1)
1777    const struct lsquic_engine_settings *const settings = &enpub->enp_settings;
1778    const struct lsquic_shared_hash_if *const shi = enpub->enp_shi;
1779    void *const shi_ctx = enpub->enp_shi_ctx;
1780    uint8_t spubs[35] = {0x20, 0, 0, };/* need to init first 3 bytes */
1781    time_t t = time(NULL);
1782    unsigned int real_len;
1783    SCFG_info_t *temp_scfg;
1784    SCFG_t *tmp_scfg_copy = NULL;
1785    void *scfg_ptr;
1786    int ret;
1787    unsigned msg_len, server_config_sz;
1788    struct message_writer mw;
1789
1790    if (enc_session->enpub->enp_server_config->lsc_scfg && (enc_session->enpub->enp_server_config->lsc_scfg->info.expy > (uint64_t)t))
1791        return enc_session->enpub->enp_server_config;
1792
1793    ret = shi->shi_lookup(shi_ctx, SERVER_SCFG_KEY, SERVER_SCFG_KEY_SIZE,
1794                          &scfg_ptr, &real_len);
1795    if (ret == 1)
1796    {
1797        if (config_has_correct_size(enc_session, scfg_ptr, real_len) &&
1798                (enc_session->enpub->enp_server_config->lsc_scfg = scfg_ptr,
1799                            enc_session->enpub->enp_server_config->lsc_scfg->info.expy > (uint64_t)t))
1800        {
1801            /* Why need to init here, because this memory may be read from SHM,
1802             * the struct is ready but AEAD_CTX is not ready.
1803             **/
1804            EVP_AEAD_CTX_init(&enc_session->enpub->enp_server_config->lsc_stk_ctx, EVP_aead_aes_128_gcm(),
1805                              enc_session->enpub->enp_server_config->lsc_scfg->info.skt_key, 16, 12, NULL);
1806            return enc_session->enpub->enp_server_config;
1807        }
1808        else
1809        {
1810            shi->shi_delete(shi_ctx, SERVER_SCFG_KEY, SERVER_SCFG_KEY_SIZE);
1811        }
1812    }
1813
1814    MSG_LEN_INIT(msg_len);
1815    MSG_LEN_ADD(msg_len, sizeof(temp_scfg->sscid));
1816    MSG_LEN_ADD(msg_len, sizeof(spubs));
1817    MSG_LEN_ADD(msg_len, enpub->enp_ver_tags_len);
1818    MSG_LEN_ADD(msg_len, sizeof(temp_scfg->aead));
1819    MSG_LEN_ADD(msg_len, sizeof(temp_scfg->kexs));
1820    MSG_LEN_ADD(msg_len, sizeof(temp_scfg->pdmd));
1821    MSG_LEN_ADD(msg_len, sizeof(temp_scfg->orbt));
1822    MSG_LEN_ADD(msg_len, sizeof(temp_scfg->expy));
1823
1824    server_config_sz = sizeof(*enc_session->enpub->enp_server_config->lsc_scfg) + MSG_LEN_VAL(msg_len);
1825    enc_session->enpub->enp_server_config->lsc_scfg = malloc(server_config_sz);
1826    if (!enc_session->enpub->enp_server_config->lsc_scfg)
1827        return NULL;
1828
1829    temp_scfg = &enc_session->enpub->enp_server_config->lsc_scfg->info;
1830    RAND_bytes(temp_scfg->skt_key, sizeof(temp_scfg->skt_key));
1831    RAND_bytes(temp_scfg->sscid, sizeof(temp_scfg->sscid));
1832    RAND_bytes(temp_scfg->priv_key, sizeof(temp_scfg->priv_key));
1833    lsquic_c255_get_pub_key(temp_scfg->priv_key, spubs + 3);
1834    temp_scfg->aead = settings->es_aead;
1835    temp_scfg->kexs = settings->es_kexs;
1836    temp_scfg->pdmd = settings->es_pdmd;
1837    temp_scfg->orbt = 0;
1838    temp_scfg->expy = t + settings->es_sttl;
1839
1840    MW_BEGIN(&mw, QTAG_SCFG, 8, enc_session->enpub->enp_server_config->lsc_scfg->scfg);
1841    MW_WRITE_BUFFER(&mw, QTAG_VER, enpub->enp_ver_tags_buf,
1842                                                enpub->enp_ver_tags_len);
1843    MW_WRITE_UINT32(&mw, QTAG_AEAD, temp_scfg->aead);
1844    MW_WRITE_BUFFER(&mw, QTAG_SCID, temp_scfg->sscid, sizeof(temp_scfg->sscid));
1845    MW_WRITE_UINT32(&mw, QTAG_PDMD, temp_scfg->pdmd);
1846    MW_WRITE_BUFFER(&mw, QTAG_PUBS, spubs, sizeof(spubs));
1847    MW_WRITE_UINT32(&mw, QTAG_KEXS, temp_scfg->kexs);
1848    MW_WRITE_UINT64(&mw, QTAG_ORBT, temp_scfg->orbt);
1849    MW_WRITE_UINT64(&mw, QTAG_EXPY, temp_scfg->expy);
1850    MW_END(&mw);
1851    assert(MW_P(&mw) == enc_session->enpub->enp_server_config->lsc_scfg->scfg + MSG_LEN_VAL(msg_len));
1852
1853    temp_scfg->scfg_len = MSG_LEN_VAL(msg_len);
1854
1855    LSQ_DEBUG("%s called, return len %d.", __func__, temp_scfg->scfg_len);
1856
1857//     /* TODO: will shi_delete call free to release the buffer? */
1858//     shi->shi_delete(shi_ctx, SERVER_SCFG_KEY, SERVER_SCFG_KEY_SIZE);
1859    void *scfg_key = strdup(SERVER_SCFG_KEY);
1860    shi->shi_insert(shi_ctx, scfg_key, SERVER_SCFG_KEY_SIZE,
1861            enc_session->enpub->enp_server_config->lsc_scfg, server_config_sz, t + settings->es_sttl);
1862
1863    ret = shi->shi_lookup(shi_ctx, scfg_key, SERVER_SCFG_KEY_SIZE,
1864                          &scfg_ptr, &real_len);
1865    if (ret == 1)
1866    {
1867        tmp_scfg_copy = scfg_ptr;
1868        if (tmp_scfg_copy != enc_session->enpub->enp_server_config->lsc_scfg)
1869        {
1870            free(enc_session->enpub->enp_server_config->lsc_scfg);
1871            enc_session->enpub->enp_server_config->lsc_scfg = tmp_scfg_copy;
1872        }
1873    }
1874    else
1875    {
1876        /* Since internal error occured, but I have to use a SCFG, log it*/
1877        LSQ_DEBUG("get_valid_scfg got an shi internal error.\n");
1878    }
1879
1880    ret = EVP_AEAD_CTX_init(&enc_session->enpub->enp_server_config->lsc_stk_ctx, EVP_aead_aes_128_gcm(),
1881                              enc_session->enpub->enp_server_config->lsc_scfg->info.skt_key,
1882                              sizeof(enc_session->enpub->enp_server_config->lsc_scfg->info.skt_key), 12, NULL);
1883
1884    LSQ_DEBUG("get_valid_scfg::EVP_AEAD_CTX_init return %d.", ret);
1885    return enc_session->enpub->enp_server_config;
1886}
1887
1888
1889static int
1890generate_crt (struct lsquic_enc_session *enc_session)
1891{
1892    int i, n, len, crt_num, rv = -1;
1893    lsquic_str_t **crts;
1894    unsigned char *out;
1895    X509* crt;
1896    STACK_OF(X509)      *pXchain;
1897    SSL_CTX *const ctx = enc_session->ssl_ctx;
1898    hs_ctx_t *const hs_ctx = &enc_session->hs_ctx;
1899    struct compressed_cert *ccert;
1900
1901    SSL_CTX_get0_chain_certs(ctx, &pXchain);
1902    n = sk_X509_num(pXchain);
1903    crt_num = n + 1;
1904
1905    crts = calloc(crt_num, sizeof(crts[0]));
1906    if (!crts)
1907        return -1;
1908
1909    crts[0] = lsquic_str_new(lsquic_str_cstr(enc_session->cert_ptr),
1910                                    lsquic_str_len(enc_session->cert_ptr));
1911    if (!crts[0])
1912        goto cleanup;
1913
1914    for (i = 1; i < crt_num; i++)
1915    {
1916        crt = sk_X509_value(pXchain, i - 1);
1917        out = NULL;
1918        len = i2d_X509(crt, &out);
1919        if (len < 0)
1920            goto cleanup;
1921        crts[i] = lsquic_str_new((const char *) out, len);
1922        OPENSSL_free(out);
1923    }
1924
1925    ccert = lsquic_compress_certs(crts, crt_num, &hs_ctx->ccs, &hs_ctx->ccrt);
1926    if (!ccert)
1927        goto cleanup;
1928
1929    if (SSL_CTX_set_ex_data(ctx, s_ccrt_idx, ccert))
1930        ++ccert->refcnt;
1931    else
1932    {
1933        free(ccert);
1934        ccert = NULL;
1935        goto cleanup;
1936    }
1937
1938    ++ccert->refcnt;
1939    hs_ctx->ccert = ccert;
1940
1941    /* We got here, set rv to 0: success */
1942    rv = 0;
1943
1944  cleanup:
1945    for (i = 0; i < crt_num; ++i)
1946        if (crts[i])
1947            lsquic_str_delete(crts[i]);
1948    free(crts);
1949    return rv;
1950}
1951
1952
1953/* rtt == 1 case */
1954static int
1955gen_rej1_data (struct lsquic_enc_session *enc_session, uint8_t *data,
1956                    size_t max_len, const struct sockaddr *ip, time_t t)
1957{
1958#ifndef WIN32
1959#   define ERR(e_) do { return (e_); } while (0)
1960#else
1961#   define ERR(e_) do { len = (e_); goto end; } while (0)
1962#endif
1963    int len;
1964    EVP_PKEY * rsa_priv_key;
1965    SSL_CTX *ctx = enc_session->ssl_ctx;
1966    const struct lsquic_engine_settings *const settings =
1967                                        &enc_session->enpub->enp_settings;
1968    hs_ctx_t *const hs_ctx = &enc_session->hs_ctx;
1969    int scfg_len = enc_session->server_config->lsc_scfg->info.scfg_len;
1970    uint8_t *scfg_data = enc_session->server_config->lsc_scfg->scfg;
1971    size_t msg_len;
1972    struct message_writer mw;
1973
1974    rsa_priv_key = SSL_CTX_get0_privatekey(ctx);
1975    if (!rsa_priv_key)
1976        return -1;
1977
1978    size_t prof_len = (size_t) EVP_PKEY_size(rsa_priv_key);
1979#ifndef WIN32
1980    char prof_buf[prof_len];
1981#else
1982    char *prof_buf = _malloca(prof_len);
1983    if (!prof_buf)
1984        return -1;
1985#endif
1986
1987    if (hs_ctx->ccert)
1988    {
1989        put_compressed_cert(hs_ctx->ccert);
1990        hs_ctx->ccert = NULL;
1991    }
1992
1993    hs_ctx->ccert = SSL_CTX_get_ex_data(ctx, s_ccrt_idx);
1994    if (hs_ctx->ccert)
1995    {
1996        ++hs_ctx->ccert->refcnt;
1997        LSQ_DEBUG("use cached compressed cert");
1998    }
1999    else if (0 == generate_crt(enc_session))
2000        LSQ_DEBUG("generated compressed cert");
2001    else
2002    {
2003        LSQ_INFO("cannot could not generate compressed cert for");
2004        ERR(-1);
2005    }
2006
2007    LSQ_DEBUG("gQUIC rej1 data");
2008    LSQ_DEBUG("gQUIC NOT enabled");
2009    const int s = lsquic_gen_prof((const uint8_t *)lsquic_str_cstr(&enc_session->chlo),
2010         (size_t)lsquic_str_len(&enc_session->chlo),
2011         scfg_data, scfg_len,
2012         rsa_priv_key, (uint8_t *)prof_buf, &prof_len);
2013    if (s != 0)
2014    {
2015        LSQ_INFO("could not generate server proof, code %d", s);
2016        ERR(-1);
2017    }
2018
2019    lsquic_str_setto(&hs_ctx->prof, prof_buf, prof_len);
2020
2021    if (!hs_ctx->rrej)
2022    {
2023        LSQ_WARN("REJ: RREJ is not set, use default");
2024        hs_ctx->rrej = HFR_CLIENT_NONCE_UNKNOWN;
2025    }
2026
2027    MSG_LEN_INIT(msg_len);
2028    MSG_LEN_ADD(msg_len, sizeof(hs_ctx->rrej));
2029    MSG_LEN_ADD(msg_len, scfg_len);
2030    MSG_LEN_ADD(msg_len, STK_LENGTH);
2031    MSG_LEN_ADD(msg_len, SNO_LENGTH);
2032    MSG_LEN_ADD(msg_len, sizeof(settings->es_sttl));
2033    MSG_LEN_ADD(msg_len, lsquic_str_len(&hs_ctx->prof));
2034    if (hs_ctx->ccert)
2035        MSG_LEN_ADD(msg_len, hs_ctx->ccert->len);
2036
2037    if (MSG_LEN_VAL(msg_len) > max_len)
2038        ERR(-1);
2039
2040    memcpy(enc_session->priv_key, enc_session->server_config->lsc_scfg->info.priv_key, 32);
2041
2042    if (lsquic_str_len(&enc_session->sstk) != STK_LENGTH)
2043    {
2044        lsquic_str_d(&enc_session->sstk);
2045        lsquic_str_prealloc(&enc_session->sstk, STK_LENGTH);
2046        lsquic_str_setlen(&enc_session->sstk, STK_LENGTH);
2047    }
2048    lsquic_gen_stk(enc_session->server_config, ip, t,
2049                        (unsigned char *) lsquic_str_buf(&enc_session->sstk));
2050
2051    if (lsquic_str_len(&enc_session->ssno) != SNO_LENGTH)
2052    {
2053        lsquic_str_d(&enc_session->ssno);
2054        lsquic_str_prealloc(&enc_session->ssno, SNO_LENGTH);
2055        lsquic_str_setlen(&enc_session->ssno, SNO_LENGTH);
2056    }
2057    RAND_bytes((uint8_t *) lsquic_str_buf(&enc_session->ssno), SNO_LENGTH);
2058
2059    MW_BEGIN(&mw, QTAG_REJ, 7, data);
2060    MW_WRITE_LS_STR(&mw, QTAG_STK, &enc_session->sstk);
2061    MW_WRITE_LS_STR(&mw, QTAG_SNO, &enc_session->ssno);
2062    MW_WRITE_LS_STR(&mw, QTAG_PROF, &hs_ctx->prof);
2063    MW_WRITE_BUFFER(&mw, QTAG_SCFG, scfg_data, scfg_len);
2064    MW_WRITE_BUFFER(&mw, QTAG_RREJ, &hs_ctx->rrej, sizeof(hs_ctx->rrej));
2065    MW_WRITE_BUFFER(&mw, QTAG_STTL, &settings->es_sttl,
2066                                                sizeof(settings->es_sttl));
2067    if (hs_ctx->ccert)
2068        MW_WRITE_BUFFER(&mw, QTAG_CRT, hs_ctx->ccert->buf, hs_ctx->ccert->len);
2069    MW_END(&mw);
2070
2071    assert(data + max_len >= MW_P(&mw));
2072    len = MW_P(&mw) - data;
2073    LSQ_DEBUG("gen_rej1_data called, return len %d.", len);
2074#ifdef WIN32
2075  end:
2076    _freea(prof_buf);
2077#endif
2078    return len;
2079#undef ERR
2080}
2081
2082
2083/* rtt == 0 case */
2084static int
2085gen_shlo_data (uint8_t *buf, size_t buf_len, struct lsquic_enc_session *enc_session,
2086                  enum lsquic_version version, const struct sockaddr *ip,
2087                  time_t t, uint8_t *nonce)
2088{
2089    char pub_key[32];
2090    const struct lsquic_engine_settings *const settings =
2091                                        &enc_session->enpub->enp_settings;
2092    struct message_writer mw;
2093    int len;
2094    const int include_reset_token = version >= LSQVER_046;
2095    size_t msg_len;
2096
2097    MSG_LEN_INIT(msg_len);
2098    MSG_LEN_ADD(msg_len, enc_session->enpub->enp_ver_tags_len);
2099    MSG_LEN_ADD(msg_len, sizeof(pub_key));
2100    MSG_LEN_ADD(msg_len, 4);    /* MIDS */
2101    MSG_LEN_ADD(msg_len, 4);    /* CFCW */
2102    MSG_LEN_ADD(msg_len, 4);    /* SFCW */
2103    MSG_LEN_ADD(msg_len, 4);    /* ICSL */
2104    MSG_LEN_ADD(msg_len, 4);    /* SMHL */
2105    MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->sstk));
2106    MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->ssno));
2107    if (include_reset_token)
2108        MSG_LEN_ADD(msg_len, SRST_LENGTH);
2109
2110    if (MSG_LEN_VAL(msg_len) > buf_len)
2111        return -1;
2112
2113    RAND_bytes(nonce, 32);
2114    RAND_bytes(enc_session->priv_key, 32);
2115    lsquic_c255_get_pub_key(enc_session->priv_key, (unsigned char *)pub_key);
2116    if (lsquic_str_len(&enc_session->sstk) != STK_LENGTH)
2117    {
2118        lsquic_str_d(&enc_session->sstk);
2119        lsquic_str_prealloc(&enc_session->sstk, STK_LENGTH);
2120        lsquic_str_setlen(&enc_session->sstk, STK_LENGTH);
2121    }
2122    lsquic_gen_stk(enc_session->server_config, ip, t,
2123                        (unsigned char *) lsquic_str_buf(&enc_session->sstk));
2124    if (lsquic_str_len(&enc_session->ssno) != SNO_LENGTH)
2125    {
2126        lsquic_str_d(&enc_session->ssno);
2127        lsquic_str_prealloc(&enc_session->ssno, SNO_LENGTH);
2128        lsquic_str_setlen(&enc_session->ssno, SNO_LENGTH);
2129    }
2130    RAND_bytes((uint8_t *) lsquic_str_buf(&enc_session->ssno), SNO_LENGTH);
2131
2132    MW_BEGIN(&mw, QTAG_SHLO, 9 + include_reset_token, buf);
2133    MW_WRITE_LS_STR(&mw, QTAG_STK, &enc_session->sstk);
2134    MW_WRITE_LS_STR(&mw, QTAG_SNO, &enc_session->ssno);
2135    MW_WRITE_BUFFER(&mw, QTAG_VER, enc_session->enpub->enp_ver_tags_buf,
2136                                    enc_session->enpub->enp_ver_tags_len);
2137    MW_WRITE_UINT32(&mw, QTAG_SMHL, 1);
2138    MW_WRITE_UINT32(&mw, QTAG_ICSL, settings->es_idle_conn_to / 1000000);
2139    MW_WRITE_BUFFER(&mw, QTAG_PUBS, pub_key, sizeof(pub_key));
2140    MW_WRITE_UINT32(&mw, QTAG_MIDS, settings->es_max_streams_in);
2141    if (include_reset_token)
2142    {
2143        MW_WRITE_TABLE_ENTRY(&mw, QTAG_SRST, SRST_LENGTH);
2144        lsquic_tg_generate_sreset(enc_session->enpub->enp_tokgen,
2145                                                &enc_session->cid, MW_P(&mw));
2146        MW_ADVANCE_P(&mw, SRST_LENGTH);
2147    }
2148    MW_WRITE_UINT32(&mw, QTAG_CFCW, settings->es_cfcw);
2149    MW_WRITE_UINT32(&mw, QTAG_SFCW, settings->es_sfcw);
2150    MW_END(&mw);
2151
2152    assert(buf + buf_len >= MW_P(&mw));
2153    len = MW_P(&mw) - buf;
2154    LSQ_DEBUG("gen_shlo_data called, return len %d.", len);
2155    return len;
2156}
2157
2158
2159/* Generate key based on issuer and serial number.  The key has the following
2160 * structure:
2161 *
2162 *      size_t          length of issuer.  This field is required to prevent
2163 *                        the chance (however remote) that concatenation of
2164 *                        the next two fields is ambiguous.
2165 *      uint8_t[]       DER-encoded issuer
2166 *      uint8_t[]       Serial number represented as sequence of bytes output
2167 *                        by BN_bn2bin
2168 *
2169 * Return size of the key or zero on error.
2170 */
2171static size_t
2172gen_iasn_key (X509 *cert, unsigned char *const out, size_t const sz)
2173{
2174    const unsigned char *name_bytes;
2175    size_t name_sz;
2176    X509_NAME *name;
2177    ASN1_INTEGER *sernum;
2178    BIGNUM *bn;
2179    unsigned bn_sz;
2180
2181    name = X509_get_issuer_name(cert);
2182    if (!name)
2183        return 0;
2184    if (!X509_NAME_get0_der(name, &name_bytes, &name_sz))
2185        return 0;
2186    sernum = X509_get_serialNumber(cert);
2187    if (!sernum)
2188        return 0;
2189    bn = ASN1_INTEGER_to_BN(sernum, NULL);
2190    if (!bn)
2191        return 0;
2192    bn_sz = BN_num_bytes(bn);
2193    if (sizeof(size_t) + name_sz + bn_sz > sz)
2194    {
2195        BN_free(bn);
2196        return 0;
2197    }
2198
2199    memcpy(out, &name_sz, sizeof(name_sz));
2200    memcpy(out + sizeof(name_sz), name_bytes, name_sz);
2201    BN_bn2bin(bn, out + sizeof(name_sz) +  name_sz);
2202    BN_free(bn);
2203
2204    return sizeof(name_sz) + name_sz + bn_sz;
2205}
2206
2207
2208static enum {
2209    GET_SNI_OK,
2210    GET_SNI_ERR,
2211}
2212
2213
2214get_sni_SSL_CTX(struct lsquic_enc_session *enc_session, lsquic_lookup_cert_f cb,
2215                    void *cb_ctx, const struct sockaddr *local)
2216{
2217    X509 *crt = NULL;
2218    unsigned char *out;
2219    int len;
2220    lsquic_str_t crtstr;
2221    cert_item_t *item;
2222    struct ssl_ctx_st *ssl_ctx;
2223    size_t key_sz;
2224    unsigned char key[0x400];
2225
2226    if (!enc_session->ssl_ctx)
2227    {
2228        if (!cb)
2229            return GET_SNI_ERR;
2230        ssl_ctx = cb(cb_ctx, local, lsquic_str_cstr(&enc_session->hs_ctx.sni));
2231        if (ssl_ctx == NULL)
2232            return GET_SNI_ERR;
2233        enc_session->ssl_ctx = ssl_ctx;
2234    }
2235
2236    if (enc_session->cert_ptr == NULL)
2237    {
2238        crt = SSL_CTX_get0_certificate(enc_session->ssl_ctx);
2239        if (!crt)
2240            return GET_SNI_ERR;
2241        key_sz = gen_iasn_key(crt, key, sizeof(key));
2242        if (key_sz)
2243        {
2244            item = find_cert(enc_session->enpub, key, key_sz);
2245            if (item)
2246                LSQ_DEBUG("found cert in cache");
2247            else
2248            {
2249                out = NULL;
2250                len = i2d_X509(crt, &out);
2251                if (len < 0)
2252                    return GET_SNI_ERR;
2253                lsquic_str_set(&crtstr, (char *) out, len);
2254                item = insert_cert(enc_session->enpub, key, key_sz, &crtstr);
2255                if (item)
2256                {
2257                    OPENSSL_free(out);
2258                    LSQ_DEBUG("inserted cert into cache");
2259                }
2260                else
2261                {
2262                    LSQ_DEBUG("cert insertion failed, keep own copy");
2263                    goto copy;
2264                }
2265            }
2266            enc_session->cert_ptr = item->crt;
2267        }
2268        else
2269        {
2270            LSQ_INFO("cannot generate cert cache key, make copy");
2271            out = NULL;
2272            len = i2d_X509(crt, &out);
2273            if (len < 0)
2274                return GET_SNI_ERR;
2275  copy:     enc_session->cert_ptr = lsquic_str_new((char *) out, len);
2276            OPENSSL_free(out);
2277            if (!enc_session->cert_ptr)
2278                return GET_SNI_ERR;
2279            enc_session->es_flags |= ES_FREE_CERT_PTR;
2280        }
2281    }
2282    return GET_SNI_OK;
2283}
2284
2285
2286/***
2287 * Comments: data and len are the frame(s) parsed data, no packet header.
2288 * return rtt number:
2289 *      1 for rej1 and 0 for shlo
2290 *      DATA_NOT_ENOUGH(-2) for not enough data,
2291 *      DATA_FORMAT_ERROR(-1) all other errors
2292 *      HS_DELAYED handshake delayed
2293 */
2294static enum handshake_error
2295handle_chlo_frames_data(const uint8_t *data, int len,
2296                                        struct lsquic_enc_session *enc_session,
2297                                        lsquic_lookup_cert_f cb, void *cb_ctx,
2298                                        const struct sockaddr *local,
2299                                        const struct lsquic_shared_hash_if *shi,
2300                                        void *shi_ctx, const struct sockaddr *ip, time_t t)
2301{
2302    /* start to parse it */
2303//     struct lsquic_enc_session *enc_session = retrive_enc_session(cid);
2304    uint32_t head_tag;
2305    enum handshake_error rtt;
2306    int ret;
2307
2308    LSQ_DEBUG("handle_chlo_frames_data called.");
2309
2310    ret = parse_hs(enc_session, data, len, &head_tag);
2311    if (ret)
2312    {
2313        LSQ_DEBUG("handle_chlo_frames_data parse_hs error,s o quit.");
2314        return ret;
2315    }
2316
2317    if (head_tag != QTAG_CHLO)
2318    {
2319        LSQ_DEBUG("handle_chlo_frames_data got data format error 1.");
2320        return DATA_FORMAT_ERROR;
2321    }
2322
2323
2324    rtt = determine_rtts(enc_session, ip, t);
2325    ESHIST_APPEND(enc_session, ESHE_MULTI2_2BITS + rtt);
2326    lsquic_str_setto(&enc_session->chlo, (const char *)data, len);
2327    switch (get_sni_SSL_CTX(enc_session, cb, cb_ctx, local))
2328    {
2329    case GET_SNI_ERR:
2330        ESHIST_APPEND(enc_session, ESHE_SNI_FAIL);
2331        LSQ_DEBUG("handle_chlo_frames_data got data format error 2.");
2332        return DATA_FORMAT_ERROR;
2333    default:
2334        break;
2335    }
2336
2337
2338    LSQ_DEBUG("handle_chlo_frames_data return %d.", rtt);
2339    return rtt;
2340}
2341
2342
2343static int handle_chlo_reply_verify_prof(struct lsquic_enc_session *enc_session,
2344                                         lsquic_str_t **out_certs,
2345                                         size_t *out_certs_count,
2346                                         lsquic_str_t *cached_certs,
2347                                         int cached_certs_count)
2348{
2349    const unsigned char *dummy = (unsigned char *) "";
2350    const unsigned char *const in = enc_session->hs_ctx.ccert
2351                                    ? enc_session->hs_ctx.ccert->buf : dummy;
2352    const unsigned char *const in_end = enc_session->hs_ctx.ccert
2353                                    ? in + enc_session->hs_ctx.ccert->len : 0;
2354    EVP_PKEY *pub_key;
2355    int ret;
2356    size_t i;
2357    X509 *cert, *server_cert;
2358    STACK_OF(X509) *chain = NULL;
2359    ret = lsquic_decompress_certs(in, in_end,cached_certs, cached_certs_count,
2360                           out_certs, out_certs_count);
2361    if (ret)
2362        return ret;
2363
2364    server_cert = lsquic_bio_to_crt((const char *)lsquic_str_cstr(out_certs[0]),
2365                      lsquic_str_len(out_certs[0]), 0);
2366    pub_key = X509_get_pubkey(server_cert);
2367    ret = lsquic_verify_prof((const uint8_t *)lsquic_str_cstr(&enc_session->chlo),
2368                      (size_t)lsquic_str_len(&enc_session->chlo),
2369                      &enc_session->info->scfg,
2370                      pub_key,
2371                      (const uint8_t *)lsquic_str_cstr(&enc_session->hs_ctx.prof),
2372                      lsquic_str_len(&enc_session->hs_ctx.prof));
2373    EVP_PKEY_free(pub_key);
2374    if (ret != 0)
2375    {
2376        LSQ_DEBUG("cannot verify server proof");
2377        goto cleanup;
2378    }
2379
2380    if (enc_session->enpub->enp_verify_cert)
2381    {
2382        chain = sk_X509_new_null();
2383        sk_X509_push(chain, server_cert);
2384        for (i = 1; i < *out_certs_count; ++i)
2385        {
2386            cert = lsquic_bio_to_crt((const char *)lsquic_str_cstr(out_certs[i]),
2387                                    lsquic_str_len(out_certs[i]), 0);
2388            if (cert)
2389                sk_X509_push(chain, cert);
2390            else
2391            {
2392                LSQ_WARN("cannot push certificate to stack");
2393                ret = -1;
2394                goto cleanup;
2395            }
2396        }
2397        ret = enc_session->enpub->enp_verify_cert(
2398                                enc_session->enpub->enp_verify_ctx, chain);
2399        LSQ_INFO("server certificate verification %ssuccessful",
2400                                                    ret == 0 ? "" : "not ");
2401    }
2402    EV_LOG_CHECK_CERTS(&enc_session->cid, (const lsquic_str_t **)out_certs, *out_certs_count);
2403
2404  cleanup:
2405    if (chain)
2406        sk_X509_free(chain);
2407    X509_free(server_cert);
2408    return ret;
2409}
2410
2411
2412static void
2413setup_aead_ctx (const struct lsquic_enc_session *enc_session,
2414                EVP_AEAD_CTX **ctx, unsigned char key[], int key_len,
2415                unsigned char *key_copy)
2416{
2417    const EVP_AEAD *aead_ = EVP_aead_aes_128_gcm();
2418    const int auth_tag_size = enc_session->es_flags & ES_GQUIC2
2419                                    ? IQUIC_TAG_LEN : GQUIC_PACKET_HASH_SZ;
2420    if (*ctx)
2421    {
2422        EVP_AEAD_CTX_cleanup(*ctx);
2423    }
2424    else
2425        *ctx = (EVP_AEAD_CTX *)malloc(sizeof(EVP_AEAD_CTX));
2426
2427    EVP_AEAD_CTX_init(*ctx, aead_, key, key_len, auth_tag_size, NULL);
2428    if (key_copy)
2429        memcpy(key_copy, key, key_len);
2430}
2431
2432
2433static int
2434determine_diversification_key (enc_session_t *enc_session_p,
2435                                          uint8_t *diversification_nonce)
2436{
2437    struct lsquic_enc_session *const enc_session = enc_session_p;
2438    const int is_client = !(enc_session->es_flags & ES_SERVER);
2439    EVP_AEAD_CTX **ctx_s_key;
2440    unsigned char *key_i, *iv;
2441    const size_t iv_len = enc_session->es_flags & ES_GQUIC2
2442                                            ? IQUIC_IV_LEN : aes128_iv_len;
2443    uint8_t ikm[aes128_key_len + MAX_IV_LEN];
2444    char str_buf[DNONC_LENGTH * 2 + 1];
2445
2446    if (is_client)
2447    {
2448        ctx_s_key = &enc_session->dec_ctx_i;
2449        key_i = enc_session->dec_key_i;
2450        iv = enc_session->dec_key_nonce_i;
2451    }
2452    else
2453    {
2454        ctx_s_key = &enc_session->enc_ctx_i;
2455        key_i = enc_session->enc_key_i;
2456        iv = enc_session->enc_key_nonce_i;
2457    }
2458    memcpy(ikm, key_i, aes128_key_len);
2459    memcpy(ikm + aes128_key_len, iv, iv_len);
2460    lsquic_export_key_material(ikm, aes128_key_len + iv_len,
2461                        diversification_nonce, DNONC_LENGTH,
2462                        (const unsigned char *) "QUIC key diversification", 24,
2463                        0, NULL, aes128_key_len, key_i, 0, NULL,
2464                        iv_len, iv, NULL, NULL, NULL);
2465
2466    setup_aead_ctx(enc_session, ctx_s_key, key_i, aes128_key_len, NULL);
2467    if (enc_session->es_flags & ES_LOG_SECRETS)
2468    {
2469        LSQ_DEBUG("determine_diversification_keys nonce: %s",
2470            HEXSTR(diversification_nonce, DNONC_LENGTH, str_buf));
2471        LSQ_DEBUG("determine_diversification_keys diversification key: %s",
2472            HEXSTR(key_i, aes128_key_len, str_buf));
2473        LSQ_DEBUG("determine_diversification_keys diversification iv: %s",
2474            HEXSTR(iv, iv_len, str_buf));
2475    }
2476    return 0;
2477}
2478
2479
2480/* After CHLO msg generatered, call it to determine_keys */
2481static void
2482determine_keys (struct lsquic_enc_session *enc_session)
2483{
2484    lsquic_str_t *chlo = &enc_session->chlo;
2485    const int is_client = !(enc_session->es_flags & ES_SERVER);
2486    uint8_t shared_key_c[32];
2487    const size_t iv_len = enc_session->es_flags & ES_GQUIC2
2488                                            ? IQUIC_IV_LEN : aes128_iv_len;
2489    unsigned char *nonce_c;
2490    unsigned char *hkdf_input, *hkdf_input_p;
2491
2492    unsigned char c_key[aes128_key_len];
2493    unsigned char s_key[aes128_key_len];
2494    unsigned char *c_key_bin = NULL;
2495    unsigned char *s_key_bin = NULL;
2496
2497    unsigned char *c_iv;
2498    unsigned char *s_iv;
2499    uint8_t *c_hp, *s_hp;
2500    size_t nonce_len, hkdf_input_len;
2501    unsigned char sub_key[32];
2502    EVP_AEAD_CTX **ctx_c_key, **ctx_s_key;
2503    char key_flag;
2504    char str_buf[512];
2505
2506    hkdf_input_len = (enc_session->have_key == 0 ? 18 + 1 : 33 + 1)
2507        + enc_session->cid.len
2508        + lsquic_str_len(chlo)
2509        + (is_client
2510                ? lsquic_str_len(&enc_session->info->scfg)
2511                : (size_t) enc_session->server_config->lsc_scfg->info.scfg_len)
2512        + lsquic_str_len(enc_session->cert_ptr);
2513    hkdf_input = malloc(hkdf_input_len);
2514    if (UNLIKELY(!hkdf_input))
2515    {
2516        LSQ_WARN("cannot allocate memory for hkdf_input");
2517        return;
2518    }
2519    hkdf_input_p = hkdf_input;
2520
2521    if (enc_session->have_key == 0)
2522    {
2523        memcpy(hkdf_input_p, "QUIC key expansion\0", 18 + 1); /* Add a 0x00 */
2524        hkdf_input_p += 18 + 1;
2525        key_flag = 'I';
2526    }
2527    else
2528    {
2529        memcpy(hkdf_input_p, "QUIC forward secure key expansion\0", 33 + 1); /* Add a 0x00 */
2530        hkdf_input_p += 33 + 1;
2531        key_flag = 'F';
2532    }
2533
2534    lsquic_c255_gen_share_key(enc_session->priv_key,
2535                       enc_session->hs_ctx.pubs,
2536                       (unsigned char *)shared_key_c);
2537    if (is_client)
2538    {
2539        if (enc_session->have_key == 0)
2540        {
2541            ctx_c_key = &enc_session->enc_ctx_i;
2542            ctx_s_key = &enc_session->dec_ctx_i;
2543            c_iv = (unsigned char *) enc_session->enc_key_nonce_i;
2544            s_iv = (unsigned char *) enc_session->dec_key_nonce_i;
2545            c_key_bin = enc_session->enc_key_i;
2546            s_key_bin = enc_session->dec_key_i;
2547            c_hp = enc_session->es_flags & ES_GQUIC2
2548                                ? enc_session->es_hps[GEL_EARLY][0] : NULL;
2549            s_hp = enc_session->es_flags & ES_GQUIC2
2550                                ? enc_session->es_hps[GEL_EARLY][1] : NULL;
2551        }
2552        else
2553        {
2554            ctx_c_key = &enc_session->enc_ctx_f;
2555            ctx_s_key = &enc_session->dec_ctx_f;
2556            c_iv = (unsigned char *) enc_session->enc_key_nonce_f;
2557            s_iv = (unsigned char *) enc_session->dec_key_nonce_f;
2558            c_hp = enc_session->es_flags & ES_GQUIC2
2559                                ? enc_session->es_hps[GEL_FORW][0] : NULL;
2560            s_hp = enc_session->es_flags & ES_GQUIC2
2561                                ? enc_session->es_hps[GEL_FORW][1] : NULL;
2562        }
2563    }
2564    else
2565    {
2566        if (enc_session->have_key == 0)
2567        {
2568            ctx_c_key = &enc_session->dec_ctx_i;
2569            ctx_s_key = &enc_session->enc_ctx_i;
2570            c_iv = (unsigned char *) enc_session->dec_key_nonce_i;
2571            s_iv = (unsigned char *) enc_session->enc_key_nonce_i;
2572            c_key_bin = enc_session->dec_key_i;
2573            s_key_bin = enc_session->enc_key_i;
2574            c_hp = enc_session->es_flags & ES_GQUIC2
2575                                ? enc_session->es_hps[GEL_EARLY][1] : NULL;
2576            s_hp = enc_session->es_flags & ES_GQUIC2
2577                                ? enc_session->es_hps[GEL_EARLY][0] : NULL;
2578        }
2579        else
2580        {
2581            ctx_c_key = &enc_session->dec_ctx_f;
2582            ctx_s_key = &enc_session->enc_ctx_f;
2583            c_iv = (unsigned char *) enc_session->dec_key_nonce_f;
2584            s_iv = (unsigned char *) enc_session->enc_key_nonce_f;
2585            c_hp = enc_session->es_flags & ES_GQUIC2
2586                                ? enc_session->es_hps[GEL_FORW][1] : NULL;
2587            s_hp = enc_session->es_flags & ES_GQUIC2
2588                                ? enc_session->es_hps[GEL_FORW][0] : NULL;
2589        }
2590    }
2591
2592    LSQ_DEBUG("export_key_material lsquic_c255_gen_share_key %s",
2593              lsquic_get_bin_str(shared_key_c, 32, 512));
2594
2595    memcpy(hkdf_input_p, enc_session->cid.idbuf, enc_session->cid.len);
2596    hkdf_input_p += enc_session->cid.len;
2597    memcpy(hkdf_input_p, lsquic_str_cstr(chlo), lsquic_str_len(chlo)); /* CHLO msg */
2598    hkdf_input_p += lsquic_str_len(chlo);
2599    if (is_client)
2600    {
2601        memcpy(hkdf_input_p, lsquic_str_cstr(&enc_session->info->scfg),
2602                       lsquic_str_len(&enc_session->info->scfg)); /* scfg msg */
2603        hkdf_input_p += lsquic_str_len(&enc_session->info->scfg);
2604    }
2605    else
2606    {
2607        memcpy(hkdf_input_p,
2608                (const char *) enc_session->server_config->lsc_scfg->scfg,
2609                       enc_session->server_config->lsc_scfg->info.scfg_len);
2610        hkdf_input_p += enc_session->server_config->lsc_scfg->info.scfg_len;
2611    }
2612    memcpy(hkdf_input_p, lsquic_str_cstr(enc_session->cert_ptr),
2613                   lsquic_str_len(enc_session->cert_ptr));
2614    assert(hkdf_input + hkdf_input_len
2615                == hkdf_input_p + lsquic_str_len(enc_session->cert_ptr));
2616    LSQ_DEBUG("export_key_material hkdf_input %s",
2617              HEXSTR(hkdf_input, hkdf_input_len, str_buf));
2618
2619    /* then need to use the salts and the shared_key_* to get the real aead key */
2620    nonce_len = sizeof(enc_session->hs_ctx.nonc)
2621                                            + lsquic_str_len(&enc_session->ssno);
2622    nonce_c = malloc(nonce_len);
2623    if (UNLIKELY(!nonce_c))
2624    {
2625        LSQ_WARN("cannot allocate memory for nonce_c");
2626        free(hkdf_input);
2627        return;
2628    }
2629    memcpy(nonce_c, enc_session->hs_ctx.nonc, sizeof(enc_session->hs_ctx.nonc));
2630    memcpy(nonce_c + sizeof(enc_session->hs_ctx.nonc),
2631        lsquic_str_cstr(&enc_session->ssno),
2632        lsquic_str_len(&enc_session->ssno));
2633
2634    LSQ_DEBUG("export_key_material nonce %s",
2635                  HEXSTR(nonce_c, nonce_len, str_buf));
2636
2637    lsquic_export_key_material(shared_key_c, 32,
2638                        nonce_c, nonce_len,
2639                        hkdf_input, hkdf_input_len,
2640                        aes128_key_len, c_key,
2641                        aes128_key_len, s_key,
2642                        iv_len, c_iv,
2643                        iv_len, s_iv,
2644                        sub_key,
2645                        c_hp, s_hp
2646                        );
2647
2648    setup_aead_ctx(enc_session, ctx_c_key, c_key, aes128_key_len, c_key_bin);
2649    setup_aead_ctx(enc_session, ctx_s_key, s_key, aes128_key_len, s_key_bin);
2650
2651    free(nonce_c);
2652    free(hkdf_input);
2653
2654    if (enc_session->es_flags & ES_LOG_SECRETS)
2655    {
2656        LSQ_DEBUG("***export_key_material '%c' c_key: %s", key_flag,
2657                  HEXSTR(c_key, aes128_key_len, str_buf));
2658        LSQ_DEBUG("***export_key_material '%c' s_key: %s", key_flag,
2659                  HEXSTR(s_key, aes128_key_len, str_buf));
2660        LSQ_DEBUG("***export_key_material '%c' c_iv: %s", key_flag,
2661                  HEXSTR(c_iv, iv_len, str_buf));
2662        LSQ_DEBUG("***export_key_material '%c' s_iv: %s", key_flag,
2663                  HEXSTR(s_iv, iv_len, str_buf));
2664        LSQ_DEBUG("***export_key_material '%c' subkey: %s", key_flag,
2665                  HEXSTR(sub_key, 32, str_buf));
2666        if (c_hp)
2667            LSQ_DEBUG("***export_key_material '%c' c_hp: %s", key_flag,
2668                  HEXSTR(c_hp, IQUIC_HP_LEN, str_buf));
2669        if (s_hp)
2670            LSQ_DEBUG("***export_key_material '%c' s_hp: %s", key_flag,
2671                  HEXSTR(s_hp, IQUIC_HP_LEN, str_buf));
2672    }
2673}
2674
2675
2676/* 0 Match */
2677static int cached_certs_match(c_cert_item_t *item,
2678                                        lsquic_str_t **certs, int count)
2679{
2680    int i;
2681    if (!item || item->count != count)
2682        return -1;
2683
2684    for (i=0; i<count; ++i)
2685    {
2686        if (lsquic_str_bcmp(certs[i], &item->crts[i]) != 0)
2687            return -1;
2688    }
2689
2690    return 0;
2691}
2692
2693
2694static const char *
2695he2str (enum handshake_error he)
2696{
2697    switch (he)
2698    {
2699    case DATA_NOT_ENOUGH:   return "DATA_NOT_ENOUGH";
2700    case HS_ERROR:          return "HS_ERROR";
2701    case HS_SHLO:           return "HS_SHLO";
2702    case HS_1RTT:           return "HS_1RTT";
2703    case HS_SREJ:           return "HS_SREJ";
2704    default:
2705        assert(0);          return "<unknown enum value>";
2706    }
2707}
2708
2709
2710/* NOT packet, just the frames-data */
2711/* return rtt number:
2712 *      0 OK
2713 *      DATA_NOT_ENOUGH(-2) for not enough data,
2714 *      DATA_FORMAT_ERROR(-1) all other errors
2715 */
2716static int
2717lsquic_enc_session_handle_chlo_reply (enc_session_t *enc_session_p,
2718                                                const uint8_t *data, int len)
2719{
2720    struct lsquic_enc_session *const enc_session = enc_session_p;
2721    uint32_t head_tag;
2722    int ret, got_srej;
2723    lsquic_session_cache_info_t *info = enc_session->info;
2724    c_cert_item_t *cert_item = enc_session->cert_item;
2725
2726    /* FIXME get the number first */
2727    lsquic_str_t **out_certs = NULL;
2728    size_t out_certs_count = 0, i;
2729
2730    ret = parse_hs(enc_session, data, len, &head_tag);
2731    if (ret)
2732        goto end;
2733
2734    got_srej = head_tag == QTAG_SREJ;
2735    switch (head_tag)
2736    {
2737    case QTAG_SREJ:
2738        if (enc_session->es_flags & ES_RECV_SREJ)
2739        {
2740            LSQ_DEBUG("received second SREJ: handshake failed");
2741            ret = -1;
2742            goto end;
2743        }
2744        enc_session->es_flags |= ES_RECV_SREJ;
2745        /* fall-through */
2746    case QTAG_REJ:
2747        enc_session->hsk_state = HSK_CHLO_REJ;
2748        enc_session->es_flags |= ES_RECV_REJ;
2749        break;
2750    case QTAG_SHLO:
2751        enc_session->hsk_state = HSK_COMPLETED;
2752        EV_LOG_HSK_COMPLETED(&enc_session->cid);
2753        if (!(enc_session->es_flags & ES_RECV_REJ))
2754            EV_LOG_SESSION_RESUMPTION(&enc_session->cid);
2755        break;
2756    default:
2757        ret = 1;    /* XXX Why 1? */
2758        goto end;
2759    }
2760
2761    if (info->scfg_flag == 1)
2762    {
2763        ret = parse_hs(enc_session, (uint8_t *)lsquic_str_cstr(&info->scfg),
2764                       lsquic_str_len(&info->scfg), &head_tag);
2765
2766        /* After handled, set the length to 0 to avoid do it again*/
2767        enc_session->info->scfg_flag = 2;
2768        if (ret)
2769            goto end;
2770
2771        if (got_srej)
2772        {
2773            if (lsquic_str_len(&enc_session->info->sstk))
2774                ret = HS_SREJ;
2775            else
2776            {
2777                LSQ_DEBUG("expected STK in SREJ message from the server");
2778                ret = -1;
2779            }
2780            goto end;
2781        }
2782
2783        if (enc_session->hs_ctx.ccert)
2784        {
2785            out_certs_count = lsquic_get_certs_count(enc_session->hs_ctx.ccert);
2786            if (out_certs_count > 0)
2787            {
2788                out_certs = malloc(out_certs_count * sizeof(lsquic_str_t *));
2789                if (!out_certs)
2790                {
2791                    ret = -1;
2792                    goto end;
2793                }
2794
2795                for (i=0; i<out_certs_count; ++i)
2796                    out_certs[i] = lsquic_str_new(NULL, 0);
2797
2798                ret = handle_chlo_reply_verify_prof(enc_session, out_certs,
2799                                            &out_certs_count,
2800                                            (cert_item ? cert_item->crts : NULL),
2801                                            (cert_item ? cert_item->count : 0));
2802                if (ret == 0)
2803                {
2804                    if (out_certs_count > 0)
2805                    {
2806                        if (cached_certs_match(cert_item, out_certs,
2807                                                        out_certs_count) != 0)
2808                        {
2809                            cert_item = make_c_cert_item(out_certs,
2810                                                            out_certs_count);
2811                            enc_session->cert_item = cert_item;
2812                            enc_session->cert_ptr = &cert_item->crts[0];
2813                        }
2814                    }
2815                }
2816                for (i=0; i<out_certs_count; ++i)
2817                    lsquic_str_delete(out_certs[i]);
2818                free(out_certs);
2819
2820                if (ret)
2821                    goto end;
2822            }
2823        }
2824    }
2825
2826    if (enc_session->hsk_state == HSK_COMPLETED)
2827    {
2828        determine_keys(enc_session);
2829        enc_session->have_key = 3;
2830    }
2831
2832  end:
2833    LSQ_DEBUG("lsquic_enc_session_handle_chlo_reply called, buf in %d, return %d.", len, ret);
2834    EV_LOG_CONN_EVENT(&enc_session->cid, "%s returning %s", __func__,
2835                                                                he2str(ret));
2836    return ret;
2837}
2838
2839
2840/** stk = 16 bytes IP ( V4 is 4 bytes, will add 12 byes 0 )
2841 *      + 8 bytes time
2842 *      + 36 bytes random bytes (24 bytes can be reserved for other using)
2843 *  then stk first 48 byte will be encrypted with AES128-GCM
2844 *  when encrypting, the salt is the last 12 bytes
2845 */
2846#ifdef NDEBUG
2847static
2848#endif
2849void
2850lsquic_gen_stk (lsquic_server_config_t *server_config, const struct sockaddr *ip_addr,
2851         uint64_t tm, unsigned char stk_out[STK_LENGTH])
2852{
2853    unsigned char stk[STK_LENGTH + 16];
2854    size_t out_len = STK_LENGTH + 16;
2855
2856    memset(stk, 0 , 24);
2857    if (AF_INET == ip_addr->sa_family)
2858        memcpy(stk, &((struct sockaddr_in *)ip_addr)->sin_addr.s_addr, 4);
2859    else
2860        memcpy(stk, &((struct sockaddr_in6 *)ip_addr)->sin6_addr, 16);
2861    memcpy(stk + 16, &tm, 8);
2862    RAND_bytes(stk + 24, STK_LENGTH - 24 - 12);
2863    RAND_bytes(stk_out + STK_LENGTH - 12, 12);
2864    lsquic_aes_aead_enc(&server_config->lsc_stk_ctx, NULL, 0, stk_out + STK_LENGTH - 12, 12, stk,
2865                 STK_LENGTH - 12 - 12, stk_out, &out_len);
2866}
2867
2868
2869/* server using */
2870#ifdef NDEBUG
2871static
2872#endif
2873enum hsk_failure_reason
2874lsquic_verify_stk0 (const struct lsquic_enc_session *enc_session,
2875             lsquic_server_config_t *server_config,
2876             const struct sockaddr *ip_addr, uint64_t tm, lsquic_str_t *stk,
2877             unsigned secs_since_stk_generated)
2878{
2879    uint64_t tm0, exp;
2880    unsigned char *const stks = (unsigned char *) lsquic_str_buf(stk);
2881    unsigned char stk_out[STK_LENGTH];
2882    size_t out_len = STK_LENGTH;
2883
2884    if (lsquic_str_len(stk) < STK_LENGTH)
2885        return HFR_SRC_ADDR_TOKEN_INVALID;
2886
2887    int ret = lsquic_aes_aead_dec(&server_config->lsc_stk_ctx, NULL, 0,
2888                           stks + STK_LENGTH - 12, 12, stks,
2889                           STK_LENGTH - 12, stk_out, &out_len);
2890    if (ret != 0)
2891    {
2892        LSQ_DEBUG("***lsquic_verify_stk decrypted failed.");
2893        return HFR_SRC_ADDR_TOKEN_DECRYPTION;
2894    }
2895
2896    if (AF_INET == ip_addr->sa_family)
2897    {
2898        if (memcmp(stk_out, &((struct sockaddr_in *)ip_addr)->sin_addr.s_addr, 4) != 0)
2899        {
2900            LSQ_DEBUG("***lsquic_verify_stk for ipv4 failed.");
2901            return HFR_SRC_ADDR_TOKEN_DIFFERENT_IP_ADDRESS;
2902        }
2903    }
2904    else
2905    {
2906        if (memcmp(stk_out, &((struct sockaddr_in6 *)ip_addr)->sin6_addr, 16) != 0)
2907        {
2908            LSQ_DEBUG("***lsquic_verify_stk for ipv6 failed.");
2909            return HFR_SRC_ADDR_TOKEN_DIFFERENT_IP_ADDRESS;
2910        }
2911    }
2912
2913    memcpy((void *)&tm0, stk_out + 16, 8);
2914    if (tm < tm0)
2915    {
2916        LSQ_DEBUG("***lsquic_verify_stk timestamp is in the future.");
2917        return HFR_SRC_ADDR_TOKEN_CLOCK_SKEW;
2918    }
2919
2920    if (secs_since_stk_generated)
2921        exp = tm0 + secs_since_stk_generated;
2922    else
2923        exp = server_config->lsc_scfg->info.expy;
2924
2925    if (tm > server_config->lsc_scfg->info.expy /* XXX this check does not seem needed */ ||
2926                                                        tm0 > exp)
2927    {
2928        LSQ_DEBUG("***lsquic_verify_stk stk expired");
2929        return HFR_SRC_ADDR_TOKEN_EXPIRED;
2930    }
2931
2932    LSQ_DEBUG("***lsquic_verify_stk pass.");
2933    return HFR_HANDSHAKE_OK;
2934}
2935
2936
2937/* 0, verified, other fail */
2938#ifdef NDEBUG
2939static
2940#endif
2941enum hsk_failure_reason
2942lsquic_verify_stk (enc_session_t *enc_session_p,
2943               const struct sockaddr *ip_addr, uint64_t tm, lsquic_str_t *stk)
2944{
2945    struct lsquic_enc_session *const enc_session = enc_session_p;
2946    if (lsquic_str_len(&enc_session->sstk) > 0)
2947    {
2948        ESHIST_APPEND(enc_session, ESHE_HAS_SSTK);
2949        if (0 == lsquic_str_bcmp(&enc_session->sstk, &enc_session->hs_ctx.stk))
2950            return HFR_HANDSHAKE_OK;
2951        else
2952            return HFR_SRC_ADDR_TOKEN_INVALID;
2953    }
2954    else
2955        return lsquic_verify_stk0(enc_session, enc_session->server_config,
2956                                                        ip_addr, tm, stk, 0);
2957}
2958
2959
2960static uint64_t combine_path_id_pack_num(uint8_t path_id, uint64_t pack_num)
2961{
2962    uint64_t v = ((uint64_t)path_id << 56) | pack_num;
2963    return v;
2964}
2965
2966
2967#   define IS_SERVER(session) ((session)->es_flags & ES_SERVER)
2968
2969static int
2970verify_packet_hash (const struct lsquic_enc_session *enc_session,
2971    enum lsquic_version version, const unsigned char *buf, size_t *header_len,
2972    size_t data_len, unsigned char *buf_out, size_t max_out_len,
2973    size_t *out_len)
2974{
2975    uint8_t md[HS_PKT_HASH_LENGTH];
2976    uint128 hash;
2977    int ret;
2978
2979    if (data_len < HS_PKT_HASH_LENGTH)
2980        return -1;
2981
2982    if (!enc_session || (IS_SERVER(enc_session)))
2983        hash = lsquic_fnv1a_128_3(buf, *header_len,
2984                    buf + *header_len + HS_PKT_HASH_LENGTH,
2985                    data_len - HS_PKT_HASH_LENGTH,
2986                    (unsigned char *) "Client", 6);
2987    else
2988        hash = lsquic_fnv1a_128_3(buf, *header_len,
2989                    buf + *header_len + HS_PKT_HASH_LENGTH,
2990                    data_len - HS_PKT_HASH_LENGTH,
2991                    (unsigned char *) "Server", 6);
2992
2993    lsquic_serialize_fnv128_short(hash, md);
2994    ret = memcmp(md, buf + *header_len, HS_PKT_HASH_LENGTH);
2995    if(ret == 0)
2996    {
2997        *header_len += HS_PKT_HASH_LENGTH;
2998        *out_len = data_len - HS_PKT_HASH_LENGTH;
2999        if (max_out_len < *header_len + *out_len)
3000            return -1;
3001
3002        memcpy(buf_out, buf, *header_len + *out_len);
3003        return 0;
3004    }
3005    else
3006        return -1;
3007}
3008
3009
3010static enum enc_level
3011decrypt_packet (struct lsquic_enc_session *enc_session, uint8_t path_id,
3012                uint64_t pack_num, unsigned char *buf, size_t *header_len,
3013                size_t data_len, unsigned char *buf_out, size_t max_out_len,
3014                size_t *out_len)
3015{
3016    int ret;
3017    /* Comment: 12 = sizeof(dec_key_iv] 4 + sizeof(pack_num) 8 */
3018    uint8_t nonce[12];
3019    uint64_t path_id_packet_number;
3020    EVP_AEAD_CTX *key = NULL;
3021    int try_times = 0;
3022    enum enc_level enc_level;
3023
3024    path_id_packet_number = combine_path_id_pack_num(path_id, pack_num);
3025    memcpy(buf_out, buf, *header_len);
3026    do
3027    {
3028        if (enc_session->have_key == 3 && try_times == 0)
3029        {
3030            key = enc_session->dec_ctx_f;
3031            memcpy(nonce, enc_session->dec_key_nonce_f, 4);
3032            LSQ_DEBUG("decrypt_packet using 'F' key...");
3033            enc_level = ENC_LEV_FORW;
3034        }
3035        else
3036        {
3037            key = enc_session->dec_ctx_i;
3038            memcpy(nonce, enc_session->dec_key_nonce_i, 4);
3039            LSQ_DEBUG("decrypt_packet using 'I' key...");
3040            enc_level = ENC_LEV_INIT;
3041        }
3042        memcpy(nonce + 4, &path_id_packet_number,
3043               sizeof(path_id_packet_number));
3044
3045        *out_len = data_len;
3046        ret = lsquic_aes_aead_dec(key,
3047                           buf, *header_len,
3048                           nonce, 12,
3049                           buf + *header_len, data_len,
3050                           buf_out + *header_len, out_len);
3051
3052        if (ret != 0)
3053            ++try_times;
3054        else
3055        {
3056            if (enc_session->peer_have_final_key == 0 &&
3057                enc_session->have_key == 3 &&
3058                try_times == 0)
3059            {
3060                LSQ_DEBUG("!!!decrypt_packet find peer have final key.");
3061                enc_session->peer_have_final_key = 1;
3062                EV_LOG_CONN_EVENT(&enc_session->cid, "settled on private key "
3063                    "'%c' after %d tries (packet number %"PRIu64")",
3064                    key == enc_session->dec_ctx_f ? 'F' : 'I',
3065                    try_times, pack_num);
3066            }
3067            break;
3068        }
3069    }
3070    while (try_times < 2);
3071
3072    LSQ_DEBUG("***decrypt_packet %s.", (ret == 0 ? "succeed" : "failed"));
3073    return ret == 0 ? enc_level : (enum enc_level) -1;
3074}
3075
3076
3077static int
3078lsquic_enc_session_have_key_gt_one (enc_session_t *enc_session_p)
3079{
3080    struct lsquic_enc_session *const enc_session = enc_session_p;
3081    return enc_session && enc_session->have_key > 1;
3082}
3083
3084
3085/* The size of `buf' is *header_len plus data_len.  The two parts of the
3086 * buffer correspond to the header and the payload of incoming QUIC packet.
3087 */
3088static enum enc_level
3089lsquic_enc_session_decrypt (struct lsquic_enc_session *enc_session,
3090               enum lsquic_version version,
3091               uint8_t path_id, uint64_t pack_num,
3092               unsigned char *buf, size_t *header_len, size_t data_len,
3093               unsigned char *diversification_nonce,
3094               unsigned char *buf_out, size_t max_out_len, size_t *out_len)
3095{
3096    /* Client: got SHLO which should have diversification_nonce */
3097    if (diversification_nonce && enc_session && enc_session->have_key == 1)
3098    {
3099        determine_diversification_key(enc_session, diversification_nonce);
3100        enc_session->have_key = 2;
3101    }
3102
3103    if (lsquic_enc_session_have_key_gt_one(enc_session))
3104        return decrypt_packet(enc_session, path_id, pack_num, buf,
3105                        header_len, data_len, buf_out, max_out_len, out_len);
3106    else if (0 == verify_packet_hash(enc_session, version, buf, header_len,
3107                                     data_len, buf_out, max_out_len, out_len))
3108        return ENC_LEV_CLEAR;
3109    else
3110        return -1;
3111}
3112
3113
3114static enum dec_packin
3115gquic_decrypt_packet (enc_session_t *enc_session_p,
3116                            struct lsquic_engine_public *enpub,
3117                            const struct lsquic_conn *lconn,
3118                            struct lsquic_packet_in *packet_in)
3119{
3120    struct lsquic_enc_session *const enc_session = enc_session_p;
3121    size_t header_len, data_len;
3122    enum enc_level enc_level;
3123    size_t out_len = 0;
3124    unsigned char *copy = lsquic_mm_get_packet_in_buf(&enpub->enp_mm, 1370);
3125    if (!copy)
3126    {
3127        LSQ_WARN("cannot allocate memory to copy incoming packet data");
3128        return DECPI_NOMEM;
3129    }
3130
3131    assert(packet_in->pi_data);
3132    header_len = packet_in->pi_header_sz;
3133    data_len   = packet_in->pi_data_sz - packet_in->pi_header_sz;
3134    enc_level = lsquic_enc_session_decrypt(enc_session,
3135                        lconn->cn_version, 0,
3136                        packet_in->pi_packno, packet_in->pi_data,
3137                        &header_len, data_len,
3138                        lsquic_packet_in_nonce(packet_in),
3139                        copy, 1370, &out_len);
3140    if ((enum enc_level) -1 == enc_level)
3141    {
3142        lsquic_mm_put_packet_in_buf(&enpub->enp_mm, copy, 1370);
3143        EV_LOG_CONN_EVENT(&lconn->cn_cid, "could not decrypt packet %"PRIu64,
3144                                                        packet_in->pi_packno);
3145        return DECPI_BADCRYPT;
3146    }
3147
3148    assert(header_len + out_len <= 1370);
3149    if (packet_in->pi_flags & PI_OWN_DATA)
3150        lsquic_mm_put_packet_in_buf(&enpub->enp_mm, packet_in->pi_data, 1370);
3151    packet_in->pi_data = copy;
3152    packet_in->pi_flags |= PI_OWN_DATA | PI_DECRYPTED
3153                        | (enc_level << PIBIT_ENC_LEV_SHIFT);
3154    packet_in->pi_header_sz = header_len;
3155    packet_in->pi_data_sz   = out_len + header_len;
3156    EV_LOG_CONN_EVENT(&lconn->cn_cid, "decrypted packet %"PRIu64,
3157                                                    packet_in->pi_packno);
3158    return DECPI_OK;
3159}
3160
3161
3162static enum enc_level
3163gquic_encrypt_buf (struct lsquic_enc_session *enc_session,
3164               enum lsquic_version version,
3165               uint8_t path_id, uint64_t pack_num,
3166               const unsigned char *header, size_t header_len,
3167               const unsigned char *data, size_t data_len,
3168               unsigned char *buf_out, size_t max_out_len, size_t *out_len,
3169               int is_hello)
3170{
3171    uint8_t md[HS_PKT_HASH_LENGTH];
3172    uint128 hash;
3173    int ret;
3174    enum enc_level enc_level;
3175    int is_chlo = (is_hello && ((IS_SERVER(enc_session)) == 0));
3176    int is_shlo = (is_hello && (IS_SERVER(enc_session)));
3177
3178    /* Comment: 12 = sizeof(dec_key_iv] 4 + sizeof(pack_num) 8 */
3179    uint8_t nonce[12];
3180    uint64_t path_id_packet_number;
3181    EVP_AEAD_CTX *key;
3182
3183    if (enc_session)
3184        LSQ_DEBUG("%s: hsk_state: %d", __func__, enc_session->hsk_state);
3185    else
3186        LSQ_DEBUG("%s: enc_session is not set", __func__);
3187
3188    if (!enc_session || enc_session->have_key == 0 || is_chlo)
3189    {
3190        *out_len = header_len + data_len + HS_PKT_HASH_LENGTH;
3191        if (max_out_len < *out_len)
3192            return -1;
3193
3194        if (!enc_session || (IS_SERVER(enc_session)))
3195            hash = lsquic_fnv1a_128_3(header, header_len, data, data_len,
3196                                        (unsigned char *) "Server", 6);
3197        else
3198            hash = lsquic_fnv1a_128_3(header, header_len, data, data_len,
3199                                        (unsigned char *) "Client", 6);
3200
3201        lsquic_serialize_fnv128_short(hash, md);
3202        memcpy(buf_out, header, header_len);
3203        memcpy(buf_out + header_len, md, HS_PKT_HASH_LENGTH);
3204        memcpy(buf_out + header_len + HS_PKT_HASH_LENGTH, data, data_len);
3205        return ENC_LEV_CLEAR;
3206    }
3207    else
3208    {
3209        if (enc_session->have_key != 3 || is_shlo ||
3210            ((IS_SERVER(enc_session)) &&
3211             enc_session->server_start_use_final_key == 0))
3212        {
3213            LSQ_DEBUG("lsquic_enc_session_encrypt using 'I' key...");
3214            key = enc_session->enc_ctx_i;
3215            memcpy(nonce, enc_session->enc_key_nonce_i, 4);
3216            if (is_shlo && enc_session->have_key == 3)
3217            {
3218                enc_session->server_start_use_final_key = 1;
3219            }
3220            enc_level = ENC_LEV_INIT;
3221        }
3222        else
3223        {
3224            LSQ_DEBUG("lsquic_enc_session_encrypt using 'F' key...");
3225            key = enc_session->enc_ctx_f;
3226            memcpy(nonce, enc_session->enc_key_nonce_f, 4);
3227            enc_level = ENC_LEV_FORW;
3228        }
3229        path_id_packet_number = combine_path_id_pack_num(path_id, pack_num);
3230        memcpy(nonce + 4, &path_id_packet_number,
3231               sizeof(path_id_packet_number));
3232
3233        memcpy(buf_out, header, header_len);
3234        *out_len = max_out_len - header_len;
3235
3236        ret = lsquic_aes_aead_enc(key, header, header_len, nonce, 12, data,
3237                           data_len, buf_out + header_len, out_len);
3238        if (ret == 0)
3239        {
3240            *out_len += header_len;
3241            return enc_level;
3242        }
3243        else
3244            return -1;
3245    }
3246}
3247
3248
3249/* server */
3250/* out_len should have init value as the max length of out */
3251/* return -1 error, 0, SHLO, 1, RTT1, 2, RTT2, DELAYED */
3252static enum handshake_error
3253lsquic_enc_session_handle_chlo(enc_session_t *enc_session_p,
3254                                 enum lsquic_version version,
3255                                 const uint8_t *in, int in_len, time_t t,
3256                                 const struct sockaddr *peer,
3257                                 const struct sockaddr *local,
3258                                 uint8_t *out, size_t *out_len,
3259                                 uint8_t nonce[DNONC_LENGTH], int *nonce_set)
3260{
3261    struct lsquic_enc_session *const enc_session = enc_session_p;
3262    enum handshake_error rtt;
3263    int len;
3264    lsquic_server_config_t *server_config;
3265    const struct lsquic_engine_public *const enpub = enc_session->enpub;
3266    const struct lsquic_shared_hash_if *const shi = enpub->enp_shi;
3267    void *const shi_ctx = enpub->enp_shi_ctx;
3268
3269    server_config = get_valid_scfg(enc_session, enpub);
3270    if (!server_config)
3271        return HS_ERROR;
3272    assert(server_config->lsc_scfg);
3273
3274    enc_session->server_config = server_config;
3275
3276    *nonce_set = 0;
3277    rtt = handle_chlo_frames_data(in, in_len, enc_session,
3278                    enpub->enp_lookup_cert, enpub->enp_cert_lu_ctx,
3279                    local, shi, shi_ctx, peer, t);
3280    if (rtt == HS_1RTT)
3281    {
3282
3283        LSQ_DEBUG("lsquic_enc_session_handle_chlo call gen_rej1_data");
3284        len = gen_rej1_data(enc_session, out, *out_len, peer, t);
3285        if (len < 0)
3286        {
3287            rtt = HS_ERROR;
3288            goto end;
3289        }
3290        *out_len = len;
3291    }
3292    else if (rtt == HS_SHLO)
3293    {
3294        enc_session->have_key = 0;
3295        determine_keys(enc_session);
3296        enc_session->have_key = 1;
3297
3298        if (lsquic_str_len(&enc_session->hs_ctx.stk) > 0)
3299        {
3300            shi->shi_delete(shi_ctx, lsquic_str_cstr(&enc_session->hs_ctx.stk),
3301                            lsquic_str_len(&enc_session->hs_ctx.stk));
3302        }
3303
3304        LSQ_DEBUG("lsquic_enc_session_handle_chlo call gen_shlo_data");
3305        len = gen_shlo_data(out, *out_len, enc_session, version, peer,
3306                                                                    t, nonce);
3307        if (len < 0)
3308        {
3309            rtt = HS_ERROR;
3310            goto end;
3311        }
3312        *out_len = len;
3313        *nonce_set = 1;
3314
3315        determine_diversification_key(enc_session, nonce);
3316        enc_session->have_key = 2;
3317        determine_keys(enc_session);
3318        enc_session->have_key = 3;
3319
3320        enc_session->hsk_state = HSK_COMPLETED;
3321        LSQ_DEBUG("lsquic_enc_session_handle_chlo have_key 3 hsk_state HSK_COMPLETED.");
3322    }
3323
3324  end:
3325    EV_LOG_CONN_EVENT(&enc_session->cid, "%s returning %s", __func__,
3326                                                            he2str(rtt));
3327    return rtt;
3328}
3329
3330
3331static int
3332lsquic_enc_session_get_peer_option (enc_session_t *enc_session_p,
3333                                                                uint32_t tag)
3334{
3335    struct lsquic_enc_session *const enc_session = enc_session_p;
3336    switch (tag)
3337    {
3338    case QTAG_NSTP:
3339        return !!(enc_session->hs_ctx.opts & HOPT_NSTP);
3340    case QTAG_SREJ:
3341        return !!(enc_session->hs_ctx.opts & HOPT_SREJ);
3342    default:
3343        assert(0);
3344        return 0;
3345    }
3346}
3347
3348
3349/* Query a several parameters sent by the peer that are required by
3350 * connection.
3351 */
3352static int
3353lsquic_enc_session_get_peer_setting (enc_session_t *enc_session_p,
3354                                        uint32_t tag, uint32_t *val)
3355{
3356    struct lsquic_enc_session *const enc_session = enc_session_p;
3357    switch (tag)
3358    {
3359    case QTAG_TCID:
3360        if (enc_session->hs_ctx.set & HSET_TCID)
3361        {
3362            *val = enc_session->hs_ctx.tcid;
3363            return 0;
3364        }
3365        else
3366            return -1;
3367    case QTAG_SMHL:
3368        if (enc_session->hs_ctx.set & HSET_SMHL)
3369        {
3370            *val = enc_session->hs_ctx.smhl;
3371            return 0;
3372        }
3373        else
3374            return -1;
3375    case QTAG_IRTT:
3376        if (enc_session->hs_ctx.set & HSET_IRTT)
3377        {
3378            *val = enc_session->hs_ctx.irtt;
3379            return 0;
3380        }
3381        else
3382            return -1;
3383    }
3384
3385    /* XXX For the following values, there is no record which were present
3386     *     in CHLO or SHLO and which were not.  Assume that zero means that
3387     *     they weren't present.
3388     */
3389    if (IS_SERVER(enc_session))
3390        switch (tag)
3391        {
3392        case QTAG_CFCW:
3393            if (enc_session->hs_ctx.scfcw)
3394            {
3395                *val = enc_session->hs_ctx.scfcw;
3396                return 0;
3397            }
3398            else
3399                return -1;
3400        case QTAG_SFCW:
3401            if (enc_session->hs_ctx.ssfcw)
3402            {
3403                *val = enc_session->hs_ctx.ssfcw;
3404                return 0;
3405            }
3406            else
3407                return -1;
3408        case QTAG_MIDS:
3409            if (enc_session->hs_ctx.smids)
3410            {
3411                *val = enc_session->hs_ctx.smids;
3412                return 0;
3413            }
3414            else
3415                return -1;
3416        default:
3417            return -1;
3418        }
3419    else
3420        switch (tag)
3421        {
3422        case QTAG_CFCW:
3423            if (enc_session->hs_ctx.cfcw)
3424            {
3425                *val = enc_session->hs_ctx.cfcw;
3426                return 0;
3427            }
3428            else
3429                return -1;
3430        case QTAG_SFCW:
3431            if (enc_session->hs_ctx.sfcw)
3432            {
3433                *val = enc_session->hs_ctx.sfcw;
3434                return 0;
3435            }
3436            else
3437                return -1;
3438        case QTAG_MIDS:
3439            if (enc_session->hs_ctx.mids)
3440            {
3441                *val = enc_session->hs_ctx.mids;
3442                return 0;
3443            }
3444            else
3445                return -1;
3446        default:
3447            return -1;
3448        }
3449}
3450
3451
3452static const char *
3453lsquic_enc_session_cipher (enc_session_t *enc_session_p)
3454{
3455    return LN_aes_128_gcm; /* TODO: get this string from enc_session */
3456}
3457
3458
3459static int
3460lsquic_enc_session_keysize (enc_session_t *enc_session_p)
3461{
3462    return 128 /* bits */ / 8; /* TODO: get this info from enc_session */
3463}
3464
3465
3466static int
3467lsquic_enc_session_alg_keysize (enc_session_t *enc_session_p)
3468{
3469    return 16; /* TODO: get this info from enc_session */
3470}
3471
3472
3473#if LSQUIC_KEEP_ENC_SESS_HISTORY
3474static void
3475lsquic_get_enc_hist (enc_session_t *enc_session_p,
3476                                        char buf[(1 << ESHIST_BITS) + 1])
3477{
3478    struct lsquic_enc_session *const enc_session = enc_session_p;
3479    const unsigned hist_idx = ESHIST_MASK & enc_session->es_hist_idx;
3480    if (enc_session->es_hist_buf[hist_idx] == ESHE_EMPTY)
3481        memcpy(buf, enc_session->es_hist_buf, hist_idx + 1);
3482    else
3483    {
3484        memcpy(buf, enc_session->es_hist_buf + hist_idx, sizeof(enc_session->es_hist_buf) - hist_idx);
3485        memcpy(buf + hist_idx, enc_session->es_hist_buf, hist_idx);
3486        buf[(1 << ESHIST_BITS)] = '\0';
3487    }
3488}
3489
3490
3491#endif
3492
3493
3494static const char *
3495lsquic_enc_session_get_ua (enc_session_t *enc_session_p)
3496{
3497    struct lsquic_enc_session *const enc_session = enc_session_p;
3498    if (enc_session && lsquic_str_len(&enc_session->hs_ctx.uaid) > 0)
3499        return lsquic_str_buf(&enc_session->hs_ctx.uaid);
3500    else
3501        return NULL;
3502}
3503
3504
3505#ifndef NDEBUG
3506static uint8_t
3507lsquic_enc_session_have_key (enc_session_t *enc_session_p)
3508{
3509    struct lsquic_enc_session *const enc_session = enc_session_p;
3510    return enc_session->have_key;
3511}
3512
3513
3514static void
3515lsquic_enc_session_set_have_key (enc_session_t *enc_session_p, uint8_t val)
3516{
3517    struct lsquic_enc_session *const enc_session = enc_session_p;
3518    enc_session->have_key = val;
3519}
3520
3521
3522static const unsigned char *
3523lsquic_enc_session_get_enc_key_i (enc_session_t *enc_session_p)
3524{
3525    struct lsquic_enc_session *const enc_session = enc_session_p;
3526    return enc_session->enc_key_i;
3527}
3528
3529
3530static const unsigned char *
3531lsquic_enc_session_get_dec_key_i (enc_session_t *enc_session_p)
3532{
3533    struct lsquic_enc_session *const enc_session = enc_session_p;
3534    return enc_session->dec_key_i;
3535}
3536
3537
3538static const unsigned char *
3539lsquic_enc_session_get_enc_key_nonce_i (enc_session_t *enc_session_p)
3540{
3541    struct lsquic_enc_session *const enc_session = enc_session_p;
3542    return enc_session->enc_key_nonce_i;
3543}
3544
3545
3546static const unsigned char *
3547lsquic_enc_session_get_dec_key_nonce_i (enc_session_t *enc_session_p)
3548{
3549    struct lsquic_enc_session *const enc_session = enc_session_p;
3550    return enc_session->dec_key_nonce_i;
3551}
3552
3553
3554static const unsigned char *
3555lsquic_enc_session_get_enc_key_nonce_f (enc_session_t *enc_session_p)
3556{
3557    struct lsquic_enc_session *const enc_session = enc_session_p;
3558    return enc_session->enc_key_nonce_f;
3559}
3560
3561
3562static const unsigned char *
3563lsquic_enc_session_get_dec_key_nonce_f (enc_session_t *enc_session_p)
3564{
3565    struct lsquic_enc_session *const enc_session = enc_session_p;
3566    return enc_session->dec_key_nonce_f;
3567}
3568
3569
3570#endif  /* not defined NDEBUG */
3571
3572
3573static size_t
3574lsquic_enc_session_mem_used (enc_session_t *enc_session_p)
3575{
3576    struct lsquic_enc_session *const enc_session = enc_session_p;
3577    size_t size;
3578
3579    size = sizeof(*enc_session);
3580
3581    size += lsquic_str_len(&enc_session->chlo);
3582    size += lsquic_str_len(&enc_session->sstk);
3583    size += lsquic_str_len(&enc_session->ssno);
3584
3585    size += lsquic_str_len(&enc_session->hs_ctx.ccs);
3586    size += lsquic_str_len(&enc_session->hs_ctx.uaid);
3587    size += lsquic_str_len(&enc_session->hs_ctx.sni);
3588    size += lsquic_str_len(&enc_session->hs_ctx.ccrt);
3589    size += lsquic_str_len(&enc_session->hs_ctx.stk);
3590    size += lsquic_str_len(&enc_session->hs_ctx.sno);
3591    size += lsquic_str_len(&enc_session->hs_ctx.prof);
3592    size += lsquic_str_len(&enc_session->hs_ctx.csct);
3593    if (enc_session->hs_ctx.ccert)
3594        size += enc_session->hs_ctx.ccert->len
3595             + sizeof(*enc_session->hs_ctx.ccert);
3596
3597    if (enc_session->info)
3598    {
3599        size += sizeof(*enc_session->info);
3600        size += lsquic_str_len(&enc_session->info->sstk);
3601        size += lsquic_str_len(&enc_session->info->scfg);
3602        size += lsquic_str_len(&enc_session->info->sni_key);
3603    }
3604
3605    /* TODO: calculate memory taken up by SSL stuff */
3606
3607    return size;
3608}
3609
3610
3611static int
3612lsquic_enc_session_verify_reset_token (enc_session_t *enc_session_p,
3613                                        const unsigned char *buf, size_t bufsz)
3614{
3615    struct lsquic_enc_session *const enc_session = enc_session_p;
3616    if (bufsz == SRST_LENGTH
3617            && 0 == (enc_session->es_flags & ES_SERVER)
3618            && (enc_session->hs_ctx.set & HSET_SRST)
3619            && 0 == memcmp(buf, enc_session->hs_ctx.srst, SRST_LENGTH))
3620        return 0;
3621    else
3622        return -1;
3623}
3624
3625
3626static int
3627lsquic_enc_session_did_sess_resume_succeed (enc_session_t *enc_session_p)
3628{
3629    struct lsquic_enc_session *const enc_session = enc_session_p;
3630    return !(enc_session->es_flags & ES_RECV_REJ);
3631}
3632
3633
3634static int
3635lsquic_enc_session_is_sess_resume_enabled (enc_session_t *enc_session_p)
3636{
3637    struct lsquic_enc_session *const enc_session = enc_session_p;
3638    return enc_session->info && enc_session->cert_item;
3639}
3640
3641
3642static ssize_t
3643gquic_really_encrypt_packet (struct lsquic_enc_session *enc_session,
3644    const struct lsquic_conn *lconn, struct lsquic_packet_out *packet_out,
3645    unsigned char *buf, size_t bufsz)
3646{
3647    int header_sz, is_hello_packet;
3648    enum enc_level enc_level;
3649    size_t packet_sz;
3650    unsigned char header_buf[GQUIC_MAX_PUBHDR_SZ];
3651
3652    header_sz = lconn->cn_pf->pf_gen_reg_pkt_header(lconn, packet_out,
3653                                header_buf, sizeof(header_buf), NULL, NULL);
3654    if (header_sz < 0)
3655        return -1;
3656
3657    is_hello_packet = !!(packet_out->po_flags & PO_HELLO);
3658    enc_level = gquic_encrypt_buf(enc_session, lconn->cn_version, 0,
3659                packet_out->po_packno, header_buf, header_sz,
3660                packet_out->po_data, packet_out->po_data_sz,
3661                buf, bufsz, &packet_sz, is_hello_packet);
3662    if ((int) enc_level >= 0)
3663    {
3664        LSQ_DEBUG("encrypted packet %"PRIu64"; plaintext is %zu bytes, "
3665            "ciphertext is %zd bytes",
3666            packet_out->po_packno,
3667            lconn->cn_pf->pf_packout_size(lconn, packet_out) +
3668                                                packet_out->po_data_sz,
3669            packet_sz);
3670        lsquic_packet_out_set_enc_level(packet_out, enc_level);
3671        return packet_sz;
3672    }
3673    else
3674        return -1;
3675}
3676
3677
3678static STACK_OF(X509) *
3679lsquic_enc_session_get_server_cert_chain (enc_session_t *enc_session_p)
3680{
3681    struct lsquic_enc_session *const enc_session = enc_session_p;
3682    const struct c_cert_item_st *item;
3683    STACK_OF(X509) *chain;
3684    X509 *cert;
3685    int i;
3686
3687    if (enc_session->es_flags & ES_SERVER)
3688        return NULL;
3689    item = enc_session->cert_item;
3690    if (!item)
3691    {
3692        LSQ_WARN("could not find certificates for `%.*s'",
3693                            (int) lsquic_str_len(&enc_session->hs_ctx.sni),
3694                            lsquic_str_cstr(&enc_session->hs_ctx.sni));
3695        return NULL;
3696    }
3697
3698    chain = sk_X509_new_null();
3699    for (i = 0; i < item->count; ++i)
3700    {
3701        cert = lsquic_bio_to_crt(lsquic_str_cstr(&item->crts[i]),
3702                                lsquic_str_len(&item->crts[i]), 0);
3703        if (cert)
3704            sk_X509_push(chain, cert);
3705        else
3706        {
3707            sk_X509_free(chain);
3708            return NULL;
3709        }
3710    }
3711
3712    return chain;
3713}
3714
3715
3716static void
3717maybe_dispatch_sess_resume (enc_session_t *enc_session_p,
3718                void (*cb)(struct lsquic_conn *, const unsigned char *, size_t))
3719{
3720    struct lsquic_enc_session *const enc_session = enc_session_p;
3721    struct lsquic_conn *const lconn = enc_session->es_conn;
3722    void *buf;
3723    size_t sz;
3724    int i;
3725
3726    if (!(enc_session->info && enc_session->cert_item && cb))
3727    {
3728        LSQ_DEBUG("no session resumption information or callback is not set");
3729        return;
3730    }
3731
3732    for (sz = 0, i = 0; i < enc_session->cert_item->count; ++i)
3733    {
3734        sz += sizeof(uint32_t);
3735        sz += lsquic_str_len(&enc_session->cert_item->crts[i]);
3736    }
3737    sz += sizeof(struct lsquic_sess_resume_storage);
3738
3739    buf = malloc(sz);
3740    if (!buf)
3741    {
3742        LSQ_WARN("malloc failed: cannot allocate %zu bytes for session "
3743                                                            "resumption", sz);
3744        return;
3745    }
3746
3747    lsquic_enc_session_serialize_sess_resume(
3748        (struct lsquic_sess_resume_storage *) buf, lconn->cn_version,
3749        enc_session->info, enc_session->cert_item);
3750
3751    cb(lconn, buf, sz);
3752    free(buf);
3753}
3754
3755
3756static enum enc_packout
3757gquic_encrypt_packet (enc_session_t *enc_session_p,
3758        const struct lsquic_engine_public *enpub,
3759        struct lsquic_conn *lconn, struct lsquic_packet_out *packet_out)
3760{
3761    struct lsquic_enc_session *const enc_session = enc_session_p;
3762    ssize_t enc_sz;
3763    size_t bufsz;
3764    unsigned char *buf;
3765    int ipv6;
3766
3767    assert(!enc_session || lconn == enc_session->es_conn);
3768
3769    bufsz = lconn->cn_pf->pf_packout_size(lconn, packet_out);
3770    if (bufsz > USHRT_MAX)
3771        return ENCPA_BADCRYPT;  /* To cause connection to close */
3772    ipv6 = NP_IS_IPv6(packet_out->po_path);
3773    buf = enpub->enp_pmi->pmi_allocate(enpub->enp_pmi_ctx,
3774                        packet_out->po_path->np_peer_ctx, lconn->cn_conn_ctx,
3775                        bufsz, ipv6);
3776    if (!buf)
3777    {
3778        LSQ_DEBUG("could not allocate memory for outgoing packet of size %zd",
3779                                                                        bufsz);
3780        return ENCPA_NOMEM;
3781    }
3782
3783    enc_sz = gquic_really_encrypt_packet(enc_session,
3784                                            lconn, packet_out, buf, bufsz);
3785    if (enc_sz < 0)
3786    {
3787        enpub->enp_pmi->pmi_return(enpub->enp_pmi_ctx,
3788                                packet_out->po_path->np_peer_ctx, buf, ipv6);
3789        return ENCPA_BADCRYPT;
3790    }
3791
3792    packet_out->po_enc_data    = buf;
3793    packet_out->po_enc_data_sz = enc_sz;
3794    packet_out->po_sent_sz     = enc_sz;
3795    packet_out->po_flags &= ~PO_IPv6;
3796    packet_out->po_flags |= PO_ENCRYPTED|PO_SENT_SZ|(ipv6 << POIPv6_SHIFT);
3797    packet_out->po_dcid_len = GQUIC_CID_LEN;
3798
3799    return ENCPA_OK;
3800}
3801
3802
3803static void
3804gquic_esf_set_conn (enc_session_t *enc_session_p, struct lsquic_conn *lconn)
3805{
3806    struct lsquic_enc_session *const enc_session = enc_session_p;
3807    enc_session->es_conn = lconn;
3808    LSQ_DEBUG("updated conn reference");
3809}
3810
3811
3812#ifdef NDEBUG
3813const
3814#endif
3815struct enc_session_funcs_common lsquic_enc_session_common_gquic_1 =
3816{
3817    .esf_global_init    = lsquic_handshake_init,
3818    .esf_global_cleanup = lsquic_handshake_cleanup,
3819    .esf_cipher = lsquic_enc_session_cipher,
3820    .esf_keysize = lsquic_enc_session_keysize,
3821    .esf_alg_keysize = lsquic_enc_session_alg_keysize,
3822    .esf_encrypt_packet = gquic_encrypt_packet,
3823    .esf_decrypt_packet = gquic_decrypt_packet,
3824    .esf_tag_len = GQUIC_PACKET_HASH_SZ,
3825    .esf_get_server_cert_chain = lsquic_enc_session_get_server_cert_chain,
3826    .esf_verify_reset_token = lsquic_enc_session_verify_reset_token,
3827    .esf_did_sess_resume_succeed = lsquic_enc_session_did_sess_resume_succeed,
3828    .esf_is_sess_resume_enabled = lsquic_enc_session_is_sess_resume_enabled,
3829    .esf_set_conn        = gquic_esf_set_conn,
3830};
3831
3832
3833static void
3834gquic2_gen_hp_mask (struct lsquic_enc_session *enc_session,
3835        const unsigned char hp[IQUIC_HP_LEN],
3836        const unsigned char *sample, unsigned char mask[EVP_MAX_BLOCK_LENGTH])
3837{
3838    const EVP_CIPHER *const cipher = EVP_aes_128_ecb();
3839    EVP_CIPHER_CTX hp_ctx;
3840    int out_len;
3841
3842    EVP_CIPHER_CTX_init(&hp_ctx);
3843    if (EVP_EncryptInit_ex(&hp_ctx, cipher, NULL, hp, 0)
3844        && EVP_EncryptUpdate(&hp_ctx, mask, &out_len, sample, 16))
3845    {
3846        assert(out_len >= 5);
3847    }
3848    else
3849    {
3850        LSQ_WARN("cannot generate hp mask, error code: %"PRIu32,
3851                                                            ERR_get_error());
3852        enc_session->es_conn->cn_if->ci_internal_error(enc_session->es_conn,
3853            "cannot generate hp mask, error code: %"PRIu32, ERR_get_error());
3854    }
3855
3856    (void) EVP_CIPHER_CTX_cleanup(&hp_ctx);
3857
3858    if (0)
3859    {
3860        char hp_str[IQUIC_HP_LEN * 2 + 1], sample_str[16 * 2 + 1];
3861        LSQ_DEBUG("generated hp mask using hp %s and sample %s",
3862            HEXSTR(hp, IQUIC_HP_LEN, hp_str),
3863            HEXSTR(sample, 16, sample_str));
3864    }
3865}
3866
3867
3868static void
3869gquic2_apply_hp (struct lsquic_enc_session *enc_session,
3870        enum gel gel, unsigned char *dst, unsigned packno_off,
3871        unsigned sample_off, unsigned packno_len)
3872{
3873    unsigned char mask[EVP_MAX_BLOCK_LENGTH];
3874    char mask_str[5 * 2 + 1];
3875
3876    gquic2_gen_hp_mask(enc_session, enc_session->es_hps[gel][0],
3877                                                dst + sample_off, mask);
3878    LSQ_DEBUG("apply header protection using mask %s",
3879                                                HEXSTR(mask, 5, mask_str));
3880    dst[0] ^= (0xF | (((dst[0] & 0x80) == 0) << 4)) & mask[0];
3881    switch (packno_len)
3882    {
3883    case 4:
3884        dst[packno_off + 3] ^= mask[4];
3885        /* fall-through */
3886    case 3:
3887        dst[packno_off + 2] ^= mask[3];
3888        /* fall-through */
3889    case 2:
3890        dst[packno_off + 1] ^= mask[2];
3891        /* fall-through */
3892    default:
3893        dst[packno_off + 0] ^= mask[1];
3894    }
3895}
3896
3897
3898static const enum gel hety2gel[] =
3899{
3900    [HETY_NOT_SET]   = GEL_FORW,
3901    [HETY_VERNEG]    = 0,
3902    [HETY_INITIAL]   = GEL_CLEAR,
3903    [HETY_RETRY]     = 0,
3904    [HETY_HANDSHAKE] = GEL_CLEAR,
3905    [HETY_0RTT]      = GEL_EARLY,
3906};
3907
3908
3909static const char *const gel2str[] =
3910{
3911    [GEL_CLEAR] = "clear",
3912    [GEL_EARLY] = "early",
3913    [GEL_FORW]  = "forw-secure",
3914};
3915
3916
3917static const enum enc_level gel2el[] =
3918{
3919    [GEL_CLEAR] = ENC_LEV_CLEAR,
3920    [GEL_EARLY] = ENC_LEV_EARLY,
3921    [GEL_FORW]  = ENC_LEV_FORW,
3922};
3923
3924
3925static enum enc_packout
3926gquic2_esf_encrypt_packet (enc_session_t *enc_session_p,
3927    const struct lsquic_engine_public *enpub, struct lsquic_conn *lconn_UNUSED,
3928    struct lsquic_packet_out *packet_out)
3929{
3930    struct lsquic_enc_session *const enc_session = enc_session_p;
3931    struct lsquic_conn *const lconn = enc_session->es_conn;
3932    EVP_AEAD_CTX *aead_ctx;
3933    unsigned char *dst;
3934    enum gel gel;
3935    unsigned char nonce_buf[ IQUIC_IV_LEN + 8 ];
3936    unsigned char *nonce, *begin_xor;
3937    lsquic_packno_t packno;
3938    size_t out_sz, dst_sz;
3939    int header_sz;
3940    int ipv6;
3941    unsigned packno_off, packno_len, sample_off, divers_nonce_len;
3942    char errbuf[ERR_ERROR_STRING_BUF_LEN];
3943
3944    gel = hety2gel[ packet_out->po_header_type ];
3945    aead_ctx = enc_session->es_aead_ctxs[gel][0];
3946    if (UNLIKELY(!aead_ctx))
3947    {
3948        LSQ_WARN("encrypt crypto context at level %s not initialized",
3949                                                            gel2str[gel]);
3950        return ENCPA_BADCRYPT;
3951    }
3952
3953    if (packet_out->po_data_sz < 3)
3954    {
3955        /* [draft-ietf-quic-tls-20] Section 5.4.2 */
3956        enum packno_bits bits = lsquic_packet_out_packno_bits(packet_out);
3957        /* XXX same packet rules as in IETF QUIC? */
3958        unsigned len = iquic_packno_bits2len(bits);
3959        if (packet_out->po_data_sz + len < 4)
3960        {
3961            len = 4 - packet_out->po_data_sz - len;
3962            memset(packet_out->po_data + packet_out->po_data_sz, 0, len);
3963            packet_out->po_data_sz += len;
3964            packet_out->po_frame_types |= QUIC_FTBIT_PADDING;
3965            LSQ_DEBUG("padded packet %"PRIu64" with %u bytes of PADDING",
3966                packet_out->po_packno, len);
3967        }
3968    }
3969
3970    dst_sz = lconn->cn_pf->pf_packout_size(lconn, packet_out);
3971    ipv6 = NP_IS_IPv6(packet_out->po_path);
3972    dst = enpub->enp_pmi->pmi_allocate(enpub->enp_pmi_ctx,
3973                        packet_out->po_path->np_peer_ctx, lconn->cn_conn_ctx,
3974                        dst_sz, ipv6);
3975    if (!dst)
3976    {
3977        LSQ_DEBUG("could not allocate memory for outgoing packet of size %zd",
3978                                                                        dst_sz);
3979        return ENCPA_NOMEM;
3980    }
3981
3982    /* Align nonce so we can perform XOR safely in one shot: */
3983    begin_xor = nonce_buf + sizeof(nonce_buf) - 8;
3984    begin_xor = (unsigned char *) ((uintptr_t) begin_xor & ~0x7);
3985    nonce = begin_xor - IQUIC_IV_LEN + 8;
3986    memcpy(nonce, enc_session->es_ivs[gel][0], IQUIC_IV_LEN);
3987    packno = packet_out->po_packno;
3988#if __BYTE_ORDER == __LITTLE_ENDIAN
3989    packno = bswap_64(packno);
3990#endif
3991    *((uint64_t *) begin_xor) ^= packno;
3992
3993    header_sz = lconn->cn_pf->pf_gen_reg_pkt_header(lconn, packet_out, dst,
3994                                            dst_sz, &packno_off, &packno_len);
3995    if (header_sz < 0)
3996        goto err;
3997
3998    if (s_log_seal_and_open)
3999    {
4000        LSQ_DEBUG("seal: iv (%u bytes): %s", IQUIC_IV_LEN,
4001            HEXSTR(nonce, IQUIC_IV_LEN, s_str));
4002        LSQ_DEBUG("seal: ad (%u bytes): %s", header_sz,
4003            HEXSTR(dst, header_sz, s_str));
4004        LSQ_DEBUG("seal: in (%hu bytes): %s", packet_out->po_data_sz,
4005            HEXSTR(packet_out->po_data, packet_out->po_data_sz, s_str));
4006    }
4007
4008    if (!EVP_AEAD_CTX_seal(aead_ctx, dst + header_sz, &out_sz,
4009                dst_sz - header_sz, nonce, IQUIC_IV_LEN,
4010                packet_out->po_data, packet_out->po_data_sz, dst, header_sz))
4011    {
4012        LSQ_WARN("cannot seal packet #%"PRIu64": %s", packet_out->po_packno,
4013            ERR_error_string(ERR_get_error(), errbuf));
4014        goto err;
4015    }
4016    assert(out_sz == dst_sz - header_sz);
4017
4018    if (!packet_out->po_nonce)
4019        divers_nonce_len = 0;
4020    else
4021    {
4022        assert(enc_session->es_flags & ES_SERVER);
4023        assert(gel == GEL_EARLY);
4024        divers_nonce_len = DNONC_LENGTH;
4025    }
4026    sample_off = packno_off + divers_nonce_len + 4;
4027    assert(sample_off + IQUIC_TAG_LEN <= dst_sz);
4028    gquic2_apply_hp(enc_session, gel, dst, packno_off, sample_off, packno_len);
4029
4030    packet_out->po_enc_data    = dst;
4031    packet_out->po_enc_data_sz = dst_sz;
4032    packet_out->po_sent_sz     = dst_sz;
4033    packet_out->po_flags &= ~PO_IPv6;
4034    packet_out->po_flags |= PO_ENCRYPTED|PO_SENT_SZ|(ipv6 << POIPv6_SHIFT);
4035    lsquic_packet_out_set_enc_level(packet_out, gel2el[gel]);
4036    return ENCPA_OK;
4037
4038  err:
4039    enpub->enp_pmi->pmi_return(enpub->enp_pmi_ctx,
4040                                packet_out->po_path->np_peer_ctx, dst, ipv6);
4041    return ENCPA_BADCRYPT;
4042}
4043
4044
4045/* XXX this is an exact copy, can reuse */
4046static lsquic_packno_t
4047decode_packno (lsquic_packno_t max_packno, lsquic_packno_t packno,
4048                                                                unsigned shift)
4049{
4050    lsquic_packno_t candidates[3], epoch_delta;
4051    int64_t diffs[3];
4052    unsigned min;;
4053
4054    epoch_delta = 1ULL << shift;
4055    candidates[1] = (max_packno & ~(epoch_delta - 1)) + packno;
4056    candidates[0] = candidates[1] - epoch_delta;
4057    candidates[2] = candidates[1] + epoch_delta;
4058
4059    diffs[0] = llabs((int64_t) candidates[0] - (int64_t) max_packno);
4060    diffs[1] = llabs((int64_t) candidates[1] - (int64_t) max_packno);
4061    diffs[2] = llabs((int64_t) candidates[2] - (int64_t) max_packno);
4062
4063    min = diffs[1] < diffs[0];
4064    if (diffs[2] < diffs[min])
4065        min = 2;
4066
4067    return candidates[min];
4068}
4069
4070
4071static lsquic_packno_t
4072gquic2_strip_hp (struct lsquic_enc_session *enc_session,
4073        enum gel gel, const unsigned char *iv, unsigned char *dst,
4074        unsigned packno_off, unsigned *packno_len)
4075{
4076    lsquic_packno_t packno;
4077    unsigned shift;
4078    unsigned char mask[EVP_MAX_BLOCK_LENGTH];
4079    char mask_str[5 * 2 + 1];
4080
4081    gquic2_gen_hp_mask(enc_session, enc_session->es_hps[gel][1], iv, mask);
4082    LSQ_DEBUG("strip header protection using mask %s",
4083                                                HEXSTR(mask, 5, mask_str));
4084    dst[0] ^= (0xF | (((dst[0] & 0x80) == 0) << 4)) & mask[0];
4085    packno = 0;
4086    shift = 0;
4087    *packno_len = 1 + (dst[0] & 3);
4088    switch (*packno_len)
4089    {
4090    case 4:
4091        dst[packno_off + 3] ^= mask[4];
4092        packno |= dst[packno_off + 3];
4093        shift += 8;
4094        /* fall-through */
4095    case 3:
4096        dst[packno_off + 2] ^= mask[3];
4097        packno |= (unsigned) dst[packno_off + 2] << shift;
4098        shift += 8;
4099        /* fall-through */
4100    case 2:
4101        dst[packno_off + 1] ^= mask[2];
4102        packno |= (unsigned) dst[packno_off + 1] << shift;
4103        shift += 8;
4104        /* fall-through */
4105    default:
4106        dst[packno_off + 0] ^= mask[1];
4107        packno |= (unsigned) dst[packno_off + 0] << shift;
4108        shift += 8;
4109    }
4110    return decode_packno(enc_session->es_max_packno, packno, shift);
4111}
4112
4113
4114static enum dec_packin
4115gquic2_esf_decrypt_packet (enc_session_t *enc_session_p,
4116        struct lsquic_engine_public *enpub, const struct lsquic_conn *lconn,
4117        struct lsquic_packet_in *packet_in)
4118{
4119    struct lsquic_enc_session *const enc_session = enc_session_p;
4120    unsigned char *dst;
4121    unsigned char nonce_buf[ IQUIC_IV_LEN + 8 ];
4122    unsigned char *nonce, *begin_xor;
4123    unsigned sample_off, packno_len, divers_nonce_len;
4124    enum gel gel;
4125    lsquic_packno_t packno;
4126    size_t out_sz;
4127    enum dec_packin dec_packin;
4128    const size_t dst_sz = packet_in->pi_data_sz;
4129    char errbuf[ERR_ERROR_STRING_BUF_LEN];
4130
4131    dst = lsquic_mm_get_packet_in_buf(&enpub->enp_mm, dst_sz);
4132    if (!dst)
4133    {
4134        LSQ_WARN("cannot allocate memory to copy incoming packet data");
4135        dec_packin = DECPI_NOMEM;
4136        goto err;
4137    }
4138
4139    if (!(HETY_0RTT == packet_in->pi_header_type
4140                                && !(enc_session->es_flags & ES_SERVER)))
4141        divers_nonce_len = 0;
4142    else
4143        divers_nonce_len = DNONC_LENGTH;
4144
4145    gel = hety2gel[packet_in->pi_header_type];
4146    if (UNLIKELY(!enc_session->es_aead_ctxs[gel][1]))
4147    {
4148        LSQ_INFO("decrypt crypto context at level %s not initialized",
4149                                                            gel2str[gel]);
4150        dec_packin = DECPI_BADCRYPT;
4151        goto err;
4152    }
4153
4154    /* Decrypt packet number.  After this operation, packet_in is adjusted:
4155     * the packet number becomes part of the header.
4156     */
4157    sample_off = packet_in->pi_header_sz + divers_nonce_len + 4;
4158    if (sample_off + IQUIC_TAG_LEN > packet_in->pi_data_sz)
4159    {
4160        LSQ_INFO("packet data is too short: %hu bytes",
4161                                                packet_in->pi_data_sz);
4162        dec_packin = DECPI_TOO_SHORT;
4163        goto err;
4164    }
4165    memcpy(dst, packet_in->pi_data, sample_off);
4166    packet_in->pi_packno =
4167    packno = gquic2_strip_hp(enc_session, gel,
4168        packet_in->pi_data + sample_off,
4169        dst, packet_in->pi_header_sz, &packno_len);
4170
4171    packet_in->pi_header_sz += packno_len;
4172    if (UNLIKELY(divers_nonce_len))
4173    {
4174        if (enc_session->have_key == 1)
4175        {
4176            determine_diversification_key(enc_session,
4177                                                dst + packet_in->pi_header_sz);
4178            enc_session->have_key = 2;
4179        }
4180        packet_in->pi_header_sz += divers_nonce_len;
4181    }
4182
4183    /* Align nonce so we can perform XOR safely in one shot: */
4184    begin_xor = nonce_buf + sizeof(nonce_buf) - 8;
4185    begin_xor = (unsigned char *) ((uintptr_t) begin_xor & ~0x7);
4186    nonce = begin_xor - IQUIC_IV_LEN + 8;
4187    memcpy(nonce, enc_session->es_ivs[gel][1], IQUIC_IV_LEN);
4188#if __BYTE_ORDER == __LITTLE_ENDIAN
4189    packno = bswap_64(packno);
4190#endif
4191    *((uint64_t *) begin_xor) ^= packno;
4192
4193    if (s_log_seal_and_open)
4194    {
4195        LSQ_DEBUG("open: iv (%u bytes): %s", IQUIC_IV_LEN,
4196            HEXSTR(nonce, IQUIC_IV_LEN, s_str));
4197        LSQ_DEBUG("open: ad (%u bytes): %s", packet_in->pi_header_sz,
4198            HEXSTR(dst, packet_in->pi_header_sz, s_str));
4199        LSQ_DEBUG("open: in (%u bytes): %s",
4200            packet_in->pi_data_sz - packet_in->pi_header_sz,
4201            HEXSTR(packet_in->pi_data + packet_in->pi_header_sz,
4202                   packet_in->pi_data_sz - packet_in->pi_header_sz, s_str));
4203    }
4204
4205    if (!EVP_AEAD_CTX_open(enc_session->es_aead_ctxs[gel][1],
4206                dst + packet_in->pi_header_sz, &out_sz,
4207                dst_sz - packet_in->pi_header_sz, nonce, IQUIC_IV_LEN,
4208                packet_in->pi_data + packet_in->pi_header_sz,
4209                packet_in->pi_data_sz - packet_in->pi_header_sz,
4210                dst, packet_in->pi_header_sz))
4211    {
4212        LSQ_INFO("cannot open packet #%"PRIu64": %s", packet_in->pi_packno,
4213            ERR_error_string(ERR_get_error(), errbuf));
4214        dec_packin = DECPI_BADCRYPT;
4215        goto err;
4216    }
4217
4218    /* Bits 2 and 3 are not set and don't need to be checked in gQUIC */
4219
4220    packet_in->pi_data_sz = packet_in->pi_header_sz + out_sz;
4221    if (packet_in->pi_flags & PI_OWN_DATA)
4222        lsquic_mm_put_packet_in_buf(&enpub->enp_mm, packet_in->pi_data,
4223                                                        packet_in->pi_data_sz);
4224    packet_in->pi_data = dst;
4225    packet_in->pi_flags |= PI_OWN_DATA | PI_DECRYPTED
4226                        | (gel2el[gel] << PIBIT_ENC_LEV_SHIFT);
4227    EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "decrypted packet %"PRIu64,
4228                                                    packet_in->pi_packno);
4229    if (packet_in->pi_packno > enc_session->es_max_packno)
4230        enc_session->es_max_packno = packet_in->pi_packno;
4231    return DECPI_OK;
4232
4233  err:
4234    if (dst)
4235        lsquic_mm_put_packet_in_buf(&enpub->enp_mm, dst, dst_sz);
4236    EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "could not decrypt packet (type %s, "
4237        "number %"PRIu64")", lsquic_hety2str[packet_in->pi_header_type],
4238                                                    packet_in->pi_packno);
4239    return dec_packin;
4240}
4241
4242
4243#ifdef NDEBUG
4244const
4245#endif
4246/* Q050 and later */
4247struct enc_session_funcs_common lsquic_enc_session_common_gquic_2 =
4248{
4249    .esf_global_init            =  lsquic_handshake_init,
4250    .esf_global_cleanup         =  lsquic_handshake_cleanup,
4251    .esf_cipher                 =  lsquic_enc_session_cipher,
4252    .esf_keysize                =  lsquic_enc_session_keysize,
4253    .esf_alg_keysize            =  lsquic_enc_session_alg_keysize,
4254    .esf_get_server_cert_chain  =  lsquic_enc_session_get_server_cert_chain,
4255    .esf_verify_reset_token     =  lsquic_enc_session_verify_reset_token,
4256    .esf_did_sess_resume_succeed   =  lsquic_enc_session_did_sess_resume_succeed,
4257    .esf_is_sess_resume_enabled    =  lsquic_enc_session_is_sess_resume_enabled,
4258    .esf_set_conn               =  gquic_esf_set_conn,
4259    /* These are different from gquic_1: */
4260    .esf_encrypt_packet         =  gquic2_esf_encrypt_packet,
4261    .esf_decrypt_packet         =  gquic2_esf_decrypt_packet,
4262    .esf_tag_len                =  IQUIC_TAG_LEN,
4263};
4264
4265
4266#ifdef NDEBUG
4267const
4268#endif
4269struct enc_session_funcs_gquic lsquic_enc_session_gquic_gquic_1 =
4270{
4271#if LSQUIC_KEEP_ENC_SESS_HISTORY
4272    .esf_get_hist       = lsquic_get_enc_hist,
4273#endif
4274    .esf_destroy = lsquic_enc_session_destroy,
4275    .esf_is_hsk_done = lsquic_enc_session_is_hsk_done,
4276    .esf_get_peer_setting = lsquic_enc_session_get_peer_setting,
4277    .esf_get_peer_option = lsquic_enc_session_get_peer_option,
4278    .esf_create_server = lsquic_enc_session_create_server,
4279    .esf_handle_chlo = lsquic_enc_session_handle_chlo,
4280    .esf_get_ua = lsquic_enc_session_get_ua,
4281    .esf_have_key_gt_one = lsquic_enc_session_have_key_gt_one,
4282#ifndef NDEBUG
4283    .esf_determine_diversification_key = determine_diversification_key,
4284    .esf_have_key = lsquic_enc_session_have_key,
4285    .esf_set_have_key = lsquic_enc_session_set_have_key,
4286    .esf_get_enc_key_i = lsquic_enc_session_get_enc_key_i,
4287    .esf_get_dec_key_i = lsquic_enc_session_get_dec_key_i,
4288    .esf_get_enc_key_nonce_i = lsquic_enc_session_get_enc_key_nonce_i,
4289    .esf_get_dec_key_nonce_i = lsquic_enc_session_get_dec_key_nonce_i,
4290    .esf_get_enc_key_nonce_f = lsquic_enc_session_get_enc_key_nonce_f,
4291    .esf_get_dec_key_nonce_f = lsquic_enc_session_get_dec_key_nonce_f,
4292#endif /* !defined(NDEBUG) */
4293    .esf_create_client = lsquic_enc_session_create_client,
4294    .esf_gen_chlo = lsquic_enc_session_gen_chlo,
4295    .esf_handle_chlo_reply = lsquic_enc_session_handle_chlo_reply,
4296    .esf_mem_used = lsquic_enc_session_mem_used,
4297    .esf_maybe_dispatch_sess_resume = maybe_dispatch_sess_resume,
4298    .esf_reset_cid = lsquic_enc_session_reset_cid,
4299};
4300
4301
4302typedef char reset_token_lengths_match[
4303                                SRST_LENGTH == IQUIC_SRESET_TOKEN_SZ ? 1 : -1];
4304
4305
4306