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