lsquic_handshake.c revision 83287402
1/* Copyright (c) 2017 LiteSpeed Technologies Inc.  See LICENSE. */
2
3#include <assert.h>
4#include <errno.h>
5#include <time.h>
6#include <string.h>
7#include <sys/queue.h>
8#include <sys/socket.h>
9
10#include <openssl/ssl.h>
11#include <openssl/crypto.h>
12#include <openssl/stack.h>
13#include <openssl/x509.h>
14#include <openssl/rand.h>
15#include <openssl/nid.h>
16#include <zlib.h>
17
18#include "lsquic.h"
19#include "lsquic_types.h"
20#include "lsquic_crypto.h"
21#include "lsquic_str.h"
22#include "lsquic_handshake.h"
23#include "lsquic_parse.h"
24#include "lsquic_crt_compress.h"
25#include "lsquic_util.h"
26#include "lsquic_version.h"
27#include "lsquic_mm.h"
28#include "lsquic_engine_public.h"
29#include "lsquic_hash.h"
30#include "lsquic_buf.h"
31#include "lsquic_qtags.h"
32
33#include "fiu-local.h"
34
35#include "lsquic_ev_log.h"
36
37#define MIN_CHLO_SIZE 1024
38
39#define LSQUIC_LOGGER_MODULE LSQLM_HANDSHAKE
40#include "lsquic_logger.h"
41
42enum handshake_state
43{
44    HSK_CHLO_REJ = 0,
45    HSK_SHLO,
46    HSK_COMPLETED,
47    N_HSK_STATES
48};
49
50#if LSQUIC_KEEP_ENC_SESS_HISTORY
51typedef unsigned char eshist_idx_t;
52
53enum enc_sess_history_event
54{
55    ESHE_EMPTY              =  '\0',
56    ESHE_SET_SNI            =  'I',
57    ESHE_SET_SNO            =  'O',
58    ESHE_SET_STK            =  'K',
59    ESHE_SET_SCID           =  'D',
60    ESHE_SET_PROF           =  'P',
61};
62#endif
63
64
65typedef struct hs_ctx_st
66{
67    enum {
68        HSET_TCID     =   (1 << 0),     /* tcid is set */
69        HSET_SMHL     =   (1 << 1),     /* smhl is set */
70        HSET_SCID     =   (1 << 2),
71    }           set;
72    enum {
73        HOPT_NSTP     =   (1 << 0),     /* NSTP option present in COPT */
74        HOPT_SREJ     =   (1 << 1),     /* SREJ option present in COPT */
75    }           opts;
76    uint32_t    pdmd;
77    uint32_t    aead;
78    uint32_t    kexs;
79
80    uint32_t    mids;
81    uint32_t    scls;
82    uint32_t    cfcw;
83    uint32_t    sfcw;
84    uint32_t    srbf;
85    uint32_t    icsl;
86
87    uint32_t    irtt;
88    uint64_t    rcid;
89    uint32_t    tcid;
90    uint32_t    smhl;
91    uint64_t    ctim;  /* any usage? */
92    uint64_t    sttl;
93    unsigned char scid[SCID_LENGTH];
94    //unsigned char chlo_hash[32]; //SHA256 HASH of CHLO
95    unsigned char nonc[DNONC_LENGTH]; /* 4 tm, 8 orbit ---> REJ, 20 rand */
96    unsigned char  pubs[32];
97
98    uint32_t    rrej;
99    struct lsquic_str ccs;
100    struct lsquic_str sni;   /* 0 rtt */
101    struct lsquic_str ccrt;
102    struct lsquic_str stk;
103    struct lsquic_str sno;
104    struct lsquic_str prof;
105
106    struct lsquic_str csct;
107    struct lsquic_str crt; /* compressed certs buffer */
108} hs_ctx_t;
109
110
111struct lsquic_enc_session
112{
113    enum handshake_state hsk_state;
114
115    uint8_t have_key; /* 0, no 1, I, 2, D, 3, F */
116    uint8_t peer_have_final_key;
117    uint8_t server_start_use_final_key;
118
119    lsquic_cid_t cid;
120    unsigned char priv_key[32];
121    EVP_AEAD_CTX *enc_ctx_i;
122    EVP_AEAD_CTX *dec_ctx_i;
123
124    /* Have to save the initial key for diversification need */
125    unsigned char enc_key_i[aes128_key_len];
126    unsigned char dec_key_i[aes128_key_len];
127    unsigned char enc_key_nonce_i[aes128_iv_len];
128    unsigned char dec_key_nonce_i[aes128_iv_len];
129
130    EVP_AEAD_CTX *enc_ctx_f;
131    EVP_AEAD_CTX *dec_ctx_f;
132    unsigned char enc_key_nonce_f[aes128_iv_len];
133    unsigned char dec_key_nonce_f[aes128_iv_len];
134
135    hs_ctx_t hs_ctx;
136    lsquic_session_cache_info_t *info;
137    SSL_CTX *  ssl_ctx;
138    const struct lsquic_engine_public *enpub;
139    struct lsquic_str * cert_ptr; /* pointer to the leaf cert of the server, not real copy */
140    struct lsquic_str   chlo; /* real copy of CHLO message */
141    struct lsquic_str   sstk;
142    struct lsquic_str   ssno;
143
144#if LSQUIC_KEEP_ENC_SESS_HISTORY
145    eshist_idx_t        es_hist_idx;
146    unsigned char       es_hist_buf[1 << ESHIST_BITS];
147#endif
148};
149
150
151/***
152 * client side, it will store the domain/certs as cache cert
153 */
154static struct lsquic_hash *s_cached_client_certs;
155
156/**
157 * client side will save the session_info for next time 0rtt
158 */
159static struct lsquic_hash *s_cached_client_session_infos;
160
161/* save to hash table */
162static lsquic_session_cache_info_t *retrieve_session_info_entry(const char *key);
163static void remove_expire_session_info_entry();
164static void remove_session_info_entry(struct lsquic_str *key);
165
166static void free_info (lsquic_session_cache_info_t *);
167
168static void c_free_cert_hash_item (cert_hash_item_t *item);
169static void c_free_cert_hash_item(cert_hash_item_t *item);
170
171
172static int get_tag_val_u32 (unsigned char *v, int len, uint32_t *val);
173static int init_hs_hash_tables(int flags);
174static uint32_t get_tag_value_i32(unsigned char *, int);
175static uint64_t get_tag_value_i64(unsigned char *, int);
176
177static int determine_keys(lsquic_enc_session_t *enc_session);
178
179
180#if LSQUIC_KEEP_ENC_SESS_HISTORY
181static void
182eshist_append (lsquic_enc_session_t *enc_session,
183                                        enum enc_sess_history_event eh_event)
184{
185    enc_session->es_hist_buf[
186                    ESHIST_MASK & enc_session->es_hist_idx++ ] = eh_event;
187}
188
189
190#   define ESHIST_APPEND(sess, event) eshist_append(sess, event)
191#else
192#   define ESHIST_APPEND(sess, event) do { } while (0)
193#endif
194
195static int
196lsquic_handshake_init(int flags)
197{
198    crypto_init();
199    return init_hs_hash_tables(flags);
200}
201
202
203static void
204cleanup_hs_hash_tables (void)
205{
206    struct lsquic_hash_elem *el;
207
208    if (s_cached_client_session_infos)
209    {
210        for (el = lsquic_hash_first(s_cached_client_session_infos); el;
211                        el = lsquic_hash_next(s_cached_client_session_infos))
212        {
213            lsquic_session_cache_info_t *entry = lsquic_hashelem_getdata(el);
214            free_info(entry);
215        }
216        lsquic_hash_destroy(s_cached_client_session_infos);
217        s_cached_client_session_infos = NULL;
218    }
219
220    if (s_cached_client_certs)
221    {
222        for (el = lsquic_hash_first(s_cached_client_certs); el;
223                                el = lsquic_hash_next(s_cached_client_certs))
224        {
225            cert_hash_item_t *item = lsquic_hashelem_getdata(el);
226            c_free_cert_hash_item(item);
227        }
228        lsquic_hash_destroy(s_cached_client_certs);
229        s_cached_client_certs = NULL;
230    }
231
232}
233
234
235static void
236lsquic_handshake_cleanup (void)
237{
238    cleanup_hs_hash_tables();
239    lsquic_crt_cleanup();
240}
241
242
243/* return -1 for fail, 0 OK*/
244static int init_hs_hash_tables(int flags)
245{
246    if (flags & LSQUIC_GLOBAL_CLIENT)
247    {
248        s_cached_client_session_infos = lsquic_hash_create();
249        if (!s_cached_client_session_infos)
250            return -1;
251
252        s_cached_client_certs = lsquic_hash_create();
253        if (!s_cached_client_certs)
254            return -1;
255    }
256
257    return 0;
258}
259
260
261/* client */
262cert_hash_item_t *
263c_find_certs (const lsquic_str_t *domain)
264{
265    struct lsquic_hash_elem *el;
266
267    if (!s_cached_client_certs)
268        return NULL;
269
270    el = lsquic_hash_find(s_cached_client_certs, lsquic_str_cstr(domain),
271                                                    lsquic_str_len(domain));
272    if (el == NULL)
273        return NULL;
274
275    return lsquic_hashelem_getdata(el);
276}
277
278
279/* client */
280/* certs is an array of lsquic_str_t * */
281static cert_hash_item_t *
282make_cert_hash_item (lsquic_str_t *domain, lsquic_str_t **certs, int count)
283{
284    int i;
285    uint64_t hash;
286    cert_hash_item_t *item = (cert_hash_item_t *)malloc(sizeof(cert_hash_item_t));
287    item->crts = (lsquic_str_t *)malloc(count * sizeof(lsquic_str_t));
288    item->domain = lsquic_str_new(NULL, 0);
289    item->hashs = lsquic_str_new(NULL, 0);
290    lsquic_str_copy(item->domain, domain);
291    item->count = count;
292    for(i=0; i<count; ++i)
293    {
294        lsquic_str_copy(&item->crts[i], certs[i]);
295        hash = fnv1a_64((const uint8_t *)lsquic_str_cstr(certs[i]), lsquic_str_len(certs[i]));
296        lsquic_str_append(item->hashs, (char *)&hash, 8);
297    }
298    return item;
299}
300
301
302/* client */
303void
304c_free_cert_hash_item (cert_hash_item_t *item)
305{
306    int i;
307    if (item)
308    {
309        lsquic_str_delete(item->hashs);
310        lsquic_str_delete(item->domain);
311        for(i=0; i<item->count; ++i)
312            lsquic_str_d(&item->crts[i]);
313        free(item->crts);
314        free(item);
315    }
316}
317
318
319/* client */
320static int
321c_insert_certs (cert_hash_item_t *item)
322{
323    if (lsquic_hash_insert(s_cached_client_certs,
324            lsquic_str_cstr(item->domain),
325                lsquic_str_len(item->domain), item) == NULL)
326        return -1;
327    else
328        return 0;
329}
330
331
332static int save_session_info_entry(lsquic_str_t *key, lsquic_session_cache_info_t *entry)
333{
334    lsquic_str_setto(&entry->sni_key, lsquic_str_cstr(key), lsquic_str_len(key));
335    if (lsquic_hash_insert(s_cached_client_session_infos,
336            lsquic_str_cstr(&entry->sni_key),
337                lsquic_str_len(&entry->sni_key), entry) == NULL)
338    {
339        lsquic_str_d(&entry->sni_key);
340        return -1;
341    }
342    else
343        return 0;
344}
345
346
347/* If entry updated and need to remove cached entry */
348static void
349remove_session_info_entry (lsquic_str_t *key)
350{
351    lsquic_session_cache_info_t *entry;
352    struct lsquic_hash_elem *el;
353    el = lsquic_hash_find(s_cached_client_session_infos,
354                                lsquic_str_cstr(key), lsquic_str_len(key));
355    if (el)
356    {
357        entry = lsquic_hashelem_getdata(el);
358        lsquic_str_d(&entry->sni_key);
359        lsquic_hash_erase(s_cached_client_session_infos, el);
360    }
361}
362
363
364/* client */
365static lsquic_session_cache_info_t *
366retrieve_session_info_entry (const char *key)
367{
368    lsquic_session_cache_info_t *entry;
369    struct lsquic_hash_elem *el;
370
371    if (!s_cached_client_session_infos)
372        return NULL;
373
374    if (!key)
375        return NULL;
376
377    el = lsquic_hash_find(s_cached_client_session_infos, key, strlen(key));
378    if (el == NULL)
379        return NULL;
380
381    entry = lsquic_hashelem_getdata(el);
382    LSQ_DEBUG("[QUIC]retrieve_session_info_entry find cached session info %p.\n", entry);
383    return entry;
384}
385
386
387/* call it in timer() */
388#if __GNUC__
389__attribute__((unused))
390#endif
391static void
392remove_expire_session_info_entry (void)
393{
394    time_t tm = time(NULL);
395    struct lsquic_hash_elem *el;
396
397    for (el = lsquic_hash_first(s_cached_client_session_infos); el;
398                        el = lsquic_hash_next(s_cached_client_session_infos))
399    {
400        lsquic_session_cache_info_t *entry = lsquic_hashelem_getdata(el);
401        if ((uint64_t)tm > entry->expy)
402        {
403            free_info(entry);
404            lsquic_hash_erase(s_cached_client_session_infos, el);
405        }
406    }
407}
408
409
410static lsquic_enc_session_t *
411lsquic_enc_session_create_client (const char *domain, lsquic_cid_t cid,
412                                    const struct lsquic_engine_public *enpub)
413{
414    lsquic_session_cache_info_t *info;
415    lsquic_enc_session_t *enc_session;
416
417    if (!domain)
418    {
419        errno = EINVAL;
420        return NULL;
421    }
422
423    enc_session = calloc(1, sizeof(*enc_session));
424    if (!enc_session)
425        return NULL;
426
427    info = retrieve_session_info_entry(domain);
428    if (info)
429        memcpy(enc_session->hs_ctx.pubs, info->spubs, 32);
430    else
431    {
432        info = calloc(1, sizeof(*info));
433        if (!info)
434        {
435            free(enc_session);
436            return NULL;
437        }
438    }
439
440    enc_session->enpub = enpub;
441    enc_session->cid   = cid;
442    enc_session->info  = info;
443    /* FIXME: allocation may fail */
444    lsquic_str_append(&enc_session->hs_ctx.sni, domain, strlen(domain));
445    return enc_session;
446}
447
448
449static void
450lsquic_enc_session_destroy (lsquic_enc_session_t *enc_session)
451{
452    if (!enc_session)
453        return ;
454
455    hs_ctx_t *hs_ctx = &enc_session->hs_ctx;
456    lsquic_str_d(&hs_ctx->sni);
457    lsquic_str_d(&hs_ctx->ccs);
458    lsquic_str_d(&hs_ctx->ccrt);
459    lsquic_str_d(&hs_ctx->stk);
460    lsquic_str_d(&hs_ctx->sno);
461    lsquic_str_d(&hs_ctx->prof);
462    lsquic_str_d(&hs_ctx->csct);
463    lsquic_str_d(&hs_ctx->crt);
464    lsquic_str_d(&enc_session->chlo);
465    lsquic_str_d(&enc_session->sstk);
466    lsquic_str_d(&enc_session->ssno);
467    if (enc_session->dec_ctx_i)
468    {
469        EVP_AEAD_CTX_cleanup(enc_session->dec_ctx_i);
470        free(enc_session->dec_ctx_i);
471    }
472    if (enc_session->enc_ctx_i)
473    {
474        EVP_AEAD_CTX_cleanup(enc_session->enc_ctx_i);
475        free(enc_session->enc_ctx_i);
476    }
477    if (enc_session->dec_ctx_f)
478    {
479        EVP_AEAD_CTX_cleanup(enc_session->dec_ctx_f);
480        free(enc_session->dec_ctx_f);
481    }
482    if (enc_session->enc_ctx_f)
483    {
484        EVP_AEAD_CTX_cleanup(enc_session->enc_ctx_f);
485        free(enc_session->enc_ctx_f);
486    }
487    free(enc_session);
488
489}
490
491
492static void
493free_info (lsquic_session_cache_info_t *info)
494{
495    lsquic_str_d(&info->sstk);
496    lsquic_str_d(&info->scfg);
497    lsquic_str_d(&info->sni_key);
498    free(info);
499}
500
501
502static int get_hs_state(lsquic_enc_session_t *enc_session)
503{
504    return enc_session->hsk_state;
505}
506
507
508/* make sure have more room for encrypt */
509static int
510lsquic_enc_session_is_hsk_done (lsquic_enc_session_t *enc_session)
511{
512    return (get_hs_state(enc_session) == HSK_COMPLETED);
513}
514
515
516static void
517process_copt (lsquic_enc_session_t *enc_session, const uint32_t *const opts,
518                unsigned n_opts)
519{
520    unsigned i;
521    for (i = 0; i < n_opts; ++i)
522        switch (opts[i])
523        {
524        case QTAG_NSTP:
525            enc_session->hs_ctx.opts |= HOPT_NSTP;
526            break;
527        case QTAG_SREJ:
528            enc_session->hs_ctx.opts |= HOPT_SREJ;
529            break;
530        }
531}
532
533
534static int parse_hs_data (lsquic_enc_session_t *enc_session, uint32_t tag,
535                          unsigned char *val, int len, uint32_t head_tag)
536{
537    hs_ctx_t * hs_ctx = &enc_session->hs_ctx;
538
539    switch(tag)
540    {
541    case QTAG_PDMD:
542        hs_ctx->pdmd = get_tag_value_i32(val, len);
543        break;
544
545    case QTAG_MIDS:
546        if (0 != get_tag_val_u32(val, len, &hs_ctx->mids))
547            return -1;
548        break;
549
550    case QTAG_SCLS:
551        hs_ctx->scls = get_tag_value_i32(val, len);
552        break;
553
554    case QTAG_CFCW:
555        if (0 != get_tag_val_u32(val, len, &hs_ctx->cfcw))
556            return -1;
557        break;
558
559    case QTAG_SFCW:
560        if (0 != get_tag_val_u32(val, len, &hs_ctx->sfcw))
561            return -1;
562        break;
563
564    case QTAG_SRBF:
565        hs_ctx->srbf = get_tag_value_i32(val, len);
566        break;
567
568    case QTAG_ICSL:
569        hs_ctx->icsl = get_tag_value_i32(val, len);
570        break;
571
572    case QTAG_IRTT:
573        hs_ctx->irtt = get_tag_value_i32(val, len);
574        break;
575
576    case QTAG_COPT:
577        if (0 == len % sizeof(uint32_t))
578            process_copt(enc_session, (uint32_t *) val, len / sizeof(uint32_t));
579        /* else ignore, following the reference implementation */
580        break;
581
582    case QTAG_CTIM:
583        hs_ctx->ctim = get_tag_value_i64(val, len);
584        break;
585
586    case QTAG_SNI:
587        lsquic_str_setto(&hs_ctx->sni, val, len);
588        ESHIST_APPEND(enc_session, ESHE_SET_SNI);
589        break;
590
591    case QTAG_CCS:
592        lsquic_str_setto(&hs_ctx->ccs, val, len);
593        break;
594
595    case QTAG_CCRT:
596        lsquic_str_setto(&hs_ctx->ccrt, val, len);
597        break;
598
599    case QTAG_CRT:
600        lsquic_str_setto(&hs_ctx->crt, val, len);
601        break;
602
603    case QTAG_PUBS:
604        /* FIXME:Server side may send a list of pubs,
605         * we support only ONE kenx now.
606         * REJ is 35 bytes, SHLO is 32 bytes
607         * Only save other peer's pubs to hs_ctx
608         */
609        if( len < 32)
610            break;
611        memcpy(hs_ctx->pubs, val + (len - 32), 32);
612        if (head_tag == QTAG_SCFG)
613        {
614            memcpy(enc_session->info->spubs, hs_ctx->pubs, 32);
615        }
616        break;
617
618    case QTAG_RCID:
619        hs_ctx->rcid = get_tag_value_i64(val, len);
620        break;
621
622
623    case QTAG_SMHL:
624        if (0 != get_tag_val_u32(val, len, &hs_ctx->smhl))
625            return -1;
626        hs_ctx->set |= HSET_SMHL;
627        break;
628
629    case QTAG_TCID:
630        if (0 != get_tag_val_u32(val, len, &hs_ctx->tcid))
631            return -1;
632        hs_ctx->set |= HSET_TCID;
633        break;
634
635    case QTAG_EXPY:
636        enc_session->info->expy = get_tag_value_i64(val, len);
637        break;
638
639    case QTAG_ORBT:
640        enc_session->info->orbt = get_tag_value_i64(val, len);
641        break;
642
643    case QTAG_SNO:
644            lsquic_str_setto(&enc_session->ssno, val, len);
645        ESHIST_APPEND(enc_session, ESHE_SET_SNO);
646        break;
647
648    case QTAG_STK:
649            if (lsquic_str_len(&enc_session->info->sstk) > 0)
650                remove_session_info_entry(&enc_session->info->sstk);
651            lsquic_str_setto(&enc_session->info->sstk, val, len);
652        ESHIST_APPEND(enc_session, ESHE_SET_STK);
653        break;
654
655    case QTAG_SCID:
656        if (len != SCID_LENGTH)
657            return -1;
658            memcpy(enc_session->info->sscid, val, len);
659        ESHIST_APPEND(enc_session, ESHE_SET_SCID);
660        break;
661
662    case QTAG_AEAD:
663            enc_session->info->aead = get_tag_value_i32(val, len);
664        break;
665
666    case QTAG_KEXS:
667            enc_session->info->kexs = get_tag_value_i32(val, len);
668        break;
669
670    case QTAG_NONC:
671        if (len != sizeof(hs_ctx->nonc))
672            return -1;
673        memcpy(hs_ctx->nonc, val, len);
674        break;
675
676    case QTAG_SCFG:
677            lsquic_str_setto(&enc_session->info->scfg, val, len);
678            enc_session->info->scfg_flag = 1;
679        break;
680
681    case QTAG_PROF:
682        lsquic_str_setto(&hs_ctx->prof, val, len);
683        ESHIST_APPEND(enc_session, ESHE_SET_PROF);
684        break;
685
686    case QTAG_STTL:
687        hs_ctx->sttl = get_tag_value_i64(val, len);
688        break;
689
690    default:
691        LSQ_DEBUG("Ignored tag '%.*s'", 4, (char *)&tag);
692        break;
693    }
694
695    return 0;
696}
697
698
699/* only for the hs stream-frame data, NOT with the packet header or frame header*/
700static enum handshake_error parse_hs (lsquic_enc_session_t *enc_session,
701                                      const unsigned char *buf, int buf_len,
702                                      uint32_t *head_tag)
703{
704    uint16_t i;
705    const unsigned char *p = buf;
706    const unsigned char *pend = buf + buf_len;
707
708    unsigned char *data;
709    uint32_t len = 0, offset = 0;
710    uint16_t num;
711    uint32_t tag;
712    if (buf_len < 6)
713        return DATA_FORMAT_ERROR;
714
715    memcpy(&tag, p, 4);
716    p += 4;
717
718    {
719        if (tag != QTAG_SREJ && tag != QTAG_REJ && tag != QTAG_SHLO &&
720                                                        tag != QTAG_SCFG)
721            return DATA_FORMAT_ERROR;
722    }
723
724    *head_tag = tag;
725
726    memcpy((char *)&num, p, 2);
727    p += 2 + 2;  /* the 2 bytes padding 0x0000 need to be bypassed */
728
729    if (num < 1)
730        return DATA_FORMAT_ERROR;
731
732    data = (uint8_t *)(buf + 4 * 2 * (1 + num));
733    if ((const char *)data > (const char *)pend)
734    {
735        LSQ_DEBUG("parse_hs tag '%.*s' error: data not enough", 4, (char *)head_tag);
736        return DATA_NOT_ENOUGH;
737    }
738
739    /* check last offset */
740    memcpy((char *)&len, data - 4, 4);
741    if ((const char *)data + len > (const char *)pend)
742    {
743        LSQ_DEBUG("parse_hs tag '%.*s' error: data not enough!!!", 4, (char *)head_tag);
744        return DATA_NOT_ENOUGH;
745    }
746
747    for (i=0; i<num; ++i)
748    {
749        memcpy((char *)&tag, p, 4);
750        p += 4;
751        memcpy((char *)&len, p, 4);
752        len -= offset;
753        p += 4;
754
755        if ((const char *)data + offset + len > (const char *)pend)
756            return DATA_FORMAT_ERROR;
757
758        if (0 != parse_hs_data(enc_session, tag, data + offset, len,
759                                                                *head_tag))
760            return DATA_FORMAT_ERROR;
761        offset += len;
762    }
763
764    LSQ_DEBUG("parse_hs tag '%.*s' no error.", 4, (char *)head_tag);
765    return DATA_NO_ERROR;
766}
767
768
769static uint32_t get_tag_value_i32(unsigned char *val, int len)
770{
771    uint32_t v;
772    if (len < 4)
773        return 0;
774    memcpy(&v, val, 4);
775    return v;
776}
777
778
779static uint64_t get_tag_value_i64(unsigned char *val, int len)
780{
781    uint64_t v;
782    if (len < 8)
783        return 0;
784    memcpy(&v, val, 8);
785    return v;
786}
787
788
789static int
790get_tag_val_u32 (unsigned char *v, int len, uint32_t *val)
791{
792    if (len != 4)
793        return -1;
794    memcpy(val, v, 4);
795    return 0;
796}
797
798
799static void
800generate_cid_buf (void *buf, size_t bufsz)
801{
802    RAND_bytes(buf, bufsz);
803}
804
805
806static lsquic_cid_t
807lsquic_generate_cid (void)
808{
809    lsquic_cid_t cid;
810    generate_cid_buf(&cid, sizeof(cid));
811    return cid;
812}
813
814
815/*  From "QUIC Crypto" for easy reference:
816 *
817 *  A handshake message consists of:
818 *    - The tag of the message.
819 *    - A uint16 containing the number of tag-value pairs.
820 *    - Two bytes of padding which should be zero when sent but ignored when
821 *          received.
822 *    - A series of uint32 tags and uint32 end offsets, one for each
823 *          tag-value pair. The tags must be strictly monotonically
824 *          increasing, and the end-offsets must be monotonic non-decreasing.
825 *          The end offset gives the offset, from the start of the value
826 *          data, to a byte one beyond the end of the data for that tag.
827 *          (Thus the end offset of the last tag contains the length of the
828 *          value data).
829 *    - The value data, concatenated without padding.
830 */
831
832struct table_entry { uint32_t tag, off; };
833
834struct message_writer
835{
836    unsigned char       *mw_p;
837    struct table_entry   mw_first_dummy_entry;
838    struct table_entry  *mw_entry,
839                        *mw_prev_entry,
840                        *mw_end;
841};
842
843/* MW_ family of macros is used to write entries to handshake message
844 * (MW stands for "message writer").
845 */
846#define MW_BEGIN(mw, msg_tag, n_entries, data_ptr) do {             \
847    uint32_t t_ = msg_tag;                                          \
848    uint16_t n_ = n_entries;                                        \
849    memcpy(data_ptr, &t_, 4);                                       \
850    memcpy(data_ptr + 4, &n_, 2);                                   \
851    memset(data_ptr + 4 + 2, 0, 2);                                 \
852    (mw)->mw_entry = (void *) (data_ptr + 8);                       \
853    (mw)->mw_p = data_ptr + 8 +                                     \
854                    n_entries * sizeof((mw)->mw_entry[0]);          \
855    (mw)->mw_first_dummy_entry.tag = 0;                             \
856    (mw)->mw_first_dummy_entry.off = 0;                             \
857    (mw)->mw_prev_entry = &(mw)->mw_first_dummy_entry;              \
858    (mw)->mw_end = (void *) (mw)->mw_p;                             \
859} while (0)
860
861#ifndef NDEBUG
862#   define MW_END(mw) do {                                          \
863        assert((mw)->mw_entry == (mw)->mw_end);                     \
864    } while (0)
865#else
866#   define MW_END(mw)
867#endif
868
869#define MW_P(mw) ((mw)->mw_p)
870
871#define MW_ADVANCE_P(mw, n) do {                                    \
872    MW_P(mw) += (n);                                                \
873} while (0)
874
875#define MW_WRITE_TABLE_ENTRY(mw, tag_, sz) do {                     \
876    assert((mw)->mw_prev_entry->tag < (tag_));                      \
877    assert((mw)->mw_entry < (mw)->mw_end);                          \
878    (mw)->mw_entry->tag = (tag_);                                   \
879    (mw)->mw_entry->off = (mw)->mw_prev_entry->off + (sz);          \
880    (mw)->mw_prev_entry = (mw)->mw_entry;                           \
881    ++(mw)->mw_entry;                                               \
882} while (0)
883
884#define MW_WRITE_BUFFER(mw, tag, buf, sz) do {                      \
885    MW_WRITE_TABLE_ENTRY(mw, tag, sz);                              \
886    memcpy(MW_P(mw), buf, sz);                                      \
887    MW_ADVANCE_P(mw, sz);                                           \
888} while (0)
889
890#define MW_WRITE_LS_STR(mw, tag, s) \
891    MW_WRITE_BUFFER(mw, tag, lsquic_str_buf(s), lsquic_str_len(s))
892
893#define MW_WRITE_UINT32(mw, tag, val) do {                          \
894    uint32_t v_ = (val);                                            \
895    MW_WRITE_BUFFER(mw, tag, &v_, sizeof(v_));                      \
896} while (0)
897
898#define MW_WRITE_UINT64(mw, tag, val) do {                          \
899    uint64_t v_ = (val);                                            \
900    MW_WRITE_BUFFER(mw, tag, &v_, sizeof(v_));                      \
901} while (0)
902
903
904/* MSG_LEN_ family of macros calculates buffer size required for a
905 * handshake message.
906 */
907#define MSG_LEN_INIT(len) do {                                      \
908    len = 4 /* Tag */ + 2 /* # tags */ + 2 /* Two zero bytes */;    \
909} while (0)
910
911#define MSG_LEN_ADD(len, payload_sz) do {                           \
912    len += 4 + 4 + (payload_sz);                                    \
913} while (0)
914
915#define MSG_LEN_VAL(len) (+(len))
916
917
918static int
919lsquic_enc_session_gen_chlo (lsquic_enc_session_t *enc_session,
920                        enum lsquic_version version, uint8_t *buf, size_t *len)
921{
922    int ret, include_pad;
923    const lsquic_str_t *const ccs = get_common_certs_hash();
924    const struct lsquic_engine_settings *const settings =
925                                        &enc_session->enpub->enp_settings;
926    cert_hash_item_t *const cached_certs_item =
927                                    c_find_certs(&enc_session->hs_ctx.sni);
928    unsigned char pub_key[32];
929    size_t ua_len;
930    uint32_t opts[1];  /* Only NSTP is supported for now */
931    unsigned n_opts, msg_len, n_tags, pad_size;
932    struct message_writer mw;
933
934    /* Before we do anything else, sanity check: */
935    if (*len < MIN_CHLO_SIZE)
936        return -1;
937
938    n_opts = 0;
939    if (settings->es_support_nstp)
940        opts[ n_opts++ ] = QTAG_NSTP;
941
942    /* Count tags and calculate required buffer size: */
943    MSG_LEN_INIT(msg_len);                  n_tags = 0;
944    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* PDMD */
945    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* AEAD */
946    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* VER  */
947    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* MIDS */
948    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* SCLS */
949    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* CFCW */
950    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* SFCW */
951    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* ICSL */
952    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* SMHL */
953    MSG_LEN_ADD(msg_len, 8);                ++n_tags;           /* CTIM */
954    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* KEXS */
955    MSG_LEN_ADD(msg_len, 0);                ++n_tags;           /* CSCT */
956    if (n_opts > 0)
957    {
958        MSG_LEN_ADD(msg_len, sizeof(opts[0]) * n_opts);
959                                            ++n_tags;           /* COPT */
960    }
961    if (settings->es_ua)
962    {
963        ua_len = strlen(settings->es_ua);
964        if (ua_len > 0)
965        {
966            MSG_LEN_ADD(msg_len, ua_len);   ++n_tags;           /* UAID */
967        }
968    }
969    else
970        ua_len = 0;
971    MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->hs_ctx.sni));
972                                            ++n_tags;           /* SNI  */
973    MSG_LEN_ADD(msg_len, lsquic_str_len(ccs));  ++n_tags;           /* CCS  */
974    if (cached_certs_item)
975    {
976        enc_session->cert_ptr = &cached_certs_item->crts[0];
977        MSG_LEN_ADD(msg_len, lsquic_str_len(cached_certs_item->hashs));
978                                            ++n_tags;           /* CCRT */
979        MSG_LEN_ADD(msg_len, 8);            ++n_tags;           /* XLCT */
980    }
981    MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->ssno));
982                                            ++n_tags;           /* SNO  */
983    MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->info->sstk));
984                                            ++n_tags;           /* STK  */
985    if (lsquic_str_len(&enc_session->info->scfg) > 0)
986    {
987        MSG_LEN_ADD(msg_len, sizeof(enc_session->info->sscid));
988                                            ++n_tags;           /* SCID */
989        if (enc_session->cert_ptr)
990        {
991            MSG_LEN_ADD(msg_len, sizeof(pub_key));
992                                            ++n_tags;           /* PUBS */
993            MSG_LEN_ADD(msg_len, sizeof(enc_session->hs_ctx.nonc));
994                                            ++n_tags;           /* NONC */
995            rand_bytes(enc_session->priv_key, 32);
996            c255_get_pub_key(enc_session->priv_key, pub_key);
997            gen_nonce_c(enc_session->hs_ctx.nonc, enc_session->info->orbt);
998        }
999    }
1000    include_pad = MSG_LEN_VAL(msg_len) < MIN_CHLO_SIZE;
1001    if (include_pad)
1002    {
1003        if (MSG_LEN_VAL(msg_len) + sizeof(struct table_entry) < MIN_CHLO_SIZE)
1004            pad_size = MIN_CHLO_SIZE - MSG_LEN_VAL(msg_len) -
1005                                                sizeof(struct table_entry);
1006        else
1007            pad_size = 0;
1008        MSG_LEN_ADD(msg_len, pad_size);     ++n_tags;           /* PAD  */
1009    }
1010
1011    /* Check that we have enough room in the output buffer: */
1012    if (MSG_LEN_VAL(msg_len) > *len)
1013        return -1;
1014
1015    /* Calculate any remaining values: */
1016    enc_session->hs_ctx.ctim = time(NULL);
1017
1018    /* XXX: should we use MSPC instead of MIDS in newer versions of gQUIC? */
1019
1020    /* Write CHLO: */
1021    MW_BEGIN(&mw, QTAG_CHLO, n_tags, buf);
1022    if (include_pad)
1023    {
1024        memset(MW_P(&mw), '-', pad_size);
1025        MW_WRITE_TABLE_ENTRY(&mw, QTAG_PAD, pad_size);
1026        MW_ADVANCE_P(&mw, pad_size);
1027    }
1028    MW_WRITE_LS_STR(&mw, QTAG_SNI, &enc_session->hs_ctx.sni);
1029    MW_WRITE_LS_STR(&mw, QTAG_STK, &enc_session->info->sstk);
1030    MW_WRITE_LS_STR(&mw, QTAG_SNO, &enc_session->ssno);
1031    MW_WRITE_UINT32(&mw, QTAG_VER, lsquic_ver2tag(version));
1032    MW_WRITE_LS_STR(&mw, QTAG_CCS, ccs);
1033    if (lsquic_str_len(&enc_session->info->scfg) > 0 && enc_session->cert_ptr)
1034        MW_WRITE_BUFFER(&mw, QTAG_NONC, enc_session->hs_ctx.nonc,
1035                                        sizeof(enc_session->hs_ctx.nonc));
1036    MW_WRITE_UINT32(&mw, QTAG_AEAD, settings->es_aead);
1037    if (ua_len)
1038        MW_WRITE_BUFFER(&mw, QTAG_UAID, settings->es_ua, ua_len);
1039    if (lsquic_str_len(&enc_session->info->scfg) > 0)
1040        MW_WRITE_BUFFER(&mw, QTAG_SCID, enc_session->info->sscid,
1041                                        sizeof(enc_session->info->sscid));
1042    MW_WRITE_UINT32(&mw, QTAG_PDMD, settings->es_pdmd);
1043    MW_WRITE_UINT32(&mw, QTAG_SMHL, 1);
1044    MW_WRITE_UINT32(&mw, QTAG_ICSL, settings->es_idle_conn_to / 1000000);
1045    MW_WRITE_UINT64(&mw, QTAG_CTIM, enc_session->hs_ctx.ctim);
1046    if (lsquic_str_len(&enc_session->info->scfg) > 0 && enc_session->cert_ptr)
1047        MW_WRITE_BUFFER(&mw, QTAG_PUBS, pub_key, sizeof(pub_key));
1048    MW_WRITE_UINT32(&mw, QTAG_MIDS, settings->es_max_streams_in);
1049    MW_WRITE_UINT32(&mw, QTAG_SCLS, settings->es_silent_close);
1050    MW_WRITE_UINT32(&mw, QTAG_KEXS, settings->es_kexs);
1051    if (cached_certs_item)
1052        MW_WRITE_BUFFER(&mw, QTAG_XLCT, lsquic_str_buf(cached_certs_item->hashs), 8);
1053    /* CSCT is empty on purpose (retained from original code) */
1054    MW_WRITE_TABLE_ENTRY(&mw, QTAG_CSCT, 0);
1055    if (n_opts > 0)
1056        MW_WRITE_BUFFER(&mw, QTAG_COPT, opts, n_opts * sizeof(opts[0]));
1057    if (cached_certs_item)
1058        MW_WRITE_LS_STR(&mw, QTAG_CCRT, cached_certs_item->hashs);
1059    MW_WRITE_UINT32(&mw, QTAG_CFCW, settings->es_cfcw);
1060    MW_WRITE_UINT32(&mw, QTAG_SFCW, settings->es_sfcw);
1061    MW_END(&mw);
1062    assert(buf + *len >= MW_P(&mw));
1063
1064    *len = MW_P(&mw) - buf;
1065
1066    lsquic_str_setto(&enc_session->chlo, buf, *len);
1067
1068    if (lsquic_str_len(&enc_session->info->scfg) > 0 && enc_session->cert_ptr)
1069    {
1070        enc_session->have_key = 0;
1071        assert(lsquic_str_len(enc_session->cert_ptr) > 0);
1072        ret = determine_keys(enc_session
1073                                            );
1074        enc_session->have_key = 1;
1075    }
1076    else
1077        ret = 0;
1078
1079    LSQ_DEBUG("lsquic_enc_session_gen_chlo called, return %d, buf_len %zd.", ret, *len);
1080    return ret;
1081}
1082
1083
1084static int handle_chlo_reply_verify_prof(lsquic_enc_session_t *enc_session,
1085                                         lsquic_str_t **out_certs,
1086                                         size_t *out_certs_count,
1087                                         lsquic_str_t *cached_certs,
1088                                         int cached_certs_count)
1089{
1090    const unsigned char *const in =
1091                (const unsigned char *) lsquic_str_buf(&enc_session->hs_ctx.crt);
1092    const unsigned char *const in_end =
1093                                    in + lsquic_str_len(&enc_session->hs_ctx.crt);
1094    EVP_PKEY *pub_key;
1095    int ret;
1096    X509 *cert;
1097    ret = decompress_certs(in, in_end,cached_certs, cached_certs_count,
1098                           out_certs, out_certs_count);
1099    if (ret)
1100        return ret;
1101
1102    cert = bio_to_crt((const char *)lsquic_str_cstr(out_certs[0]),
1103                      lsquic_str_len(out_certs[0]), 0);
1104    pub_key = X509_get_pubkey(cert);
1105    ret = verify_prof((const uint8_t *)lsquic_str_cstr(&enc_session->chlo),
1106                      (size_t)lsquic_str_len(&enc_session->chlo),
1107                      &enc_session->info->scfg,
1108                      pub_key,
1109                      (const uint8_t *)lsquic_str_cstr(&enc_session->hs_ctx.prof),
1110                      lsquic_str_len(&enc_session->hs_ctx.prof));
1111    EVP_PKEY_free(pub_key);
1112    X509_free(cert);
1113    return ret;
1114}
1115
1116
1117void setup_aead_ctx(EVP_AEAD_CTX **ctx, unsigned char key[], int key_len,
1118                    unsigned char *key_copy)
1119{
1120    const EVP_AEAD *aead_ = EVP_aead_aes_128_gcm();
1121    const int auth_tag_size = 12;
1122    if (*ctx)
1123    {
1124        EVP_AEAD_CTX_cleanup(*ctx);
1125    }
1126    else
1127        *ctx = (EVP_AEAD_CTX *)malloc(sizeof(EVP_AEAD_CTX));
1128
1129    EVP_AEAD_CTX_init(*ctx, aead_, key, key_len, auth_tag_size, NULL);
1130    if (key_copy)
1131        memcpy(key_copy, key, key_len);
1132}
1133
1134
1135static int
1136determine_diversification_key (lsquic_enc_session_t *enc_session,
1137                  uint8_t *diversification_nonce
1138                  )
1139{
1140    EVP_AEAD_CTX **ctx_s_key;
1141    unsigned char *key_i, *iv;
1142    uint8_t ikm[aes128_key_len + aes128_iv_len];
1143
1144        ctx_s_key = &enc_session->dec_ctx_i;
1145        key_i = enc_session->dec_key_i;
1146        iv = enc_session->dec_key_nonce_i;
1147    memcpy(ikm, key_i, aes128_key_len);
1148    memcpy(ikm + aes128_key_len, iv, aes128_iv_len);
1149    export_key_material(ikm, aes128_key_len + aes128_iv_len,
1150                        diversification_nonce, DNONC_LENGTH,
1151                        (const unsigned char *) "QUIC key diversification", 24,
1152                        0, NULL, aes128_key_len, key_i, 0, NULL,
1153                        aes128_iv_len, iv, NULL);
1154
1155    setup_aead_ctx(ctx_s_key, key_i, aes128_key_len, NULL);
1156    LSQ_DEBUG("determine_diversification_keys diversification_key: %s\n",
1157              get_bin_str(key_i, aes128_key_len, 512));
1158    LSQ_DEBUG("determine_diversification_keys diversification_key nonce: %s\n",
1159              get_bin_str(iv, aes128_iv_len, 512));
1160    return 0;
1161}
1162
1163
1164/* After CHLO msg generatered, call it to determine_keys */
1165static int determine_keys(lsquic_enc_session_t *enc_session)
1166{
1167    lsquic_str_t *chlo = &enc_session->chlo;
1168    uint8_t shared_key_c[32];
1169    struct lsquic_buf *nonce_c = lsquic_buf_create(100);
1170    struct lsquic_buf *hkdf_input = lsquic_buf_create(0);
1171
1172    unsigned char c_key[aes128_key_len];
1173    unsigned char s_key[aes128_key_len];
1174    unsigned char *c_key_bin = NULL;
1175    unsigned char *s_key_bin = NULL;
1176
1177    unsigned char *c_iv;
1178    unsigned char *s_iv;
1179    unsigned char sub_key[32];
1180    EVP_AEAD_CTX **ctx_c_key, **ctx_s_key;
1181    char key_flag;
1182
1183    lsquic_buf_clear(nonce_c);
1184    lsquic_buf_clear(hkdf_input);
1185    if (enc_session->have_key == 0)
1186    {
1187        lsquic_buf_append(hkdf_input, "QUIC key expansion\0", 18 + 1); // Add a 0x00 */
1188        key_flag = 'I';
1189    }
1190    else
1191    {
1192        lsquic_buf_append(hkdf_input, "QUIC forward secure key expansion\0", 33 + 1); // Add a 0x00 */
1193        key_flag = 'F';
1194    }
1195
1196    c255_gen_share_key(enc_session->priv_key,
1197                       enc_session->hs_ctx.pubs,
1198                       (unsigned char *)shared_key_c);
1199    {
1200        if (enc_session->have_key == 0)
1201        {
1202            ctx_c_key = &enc_session->enc_ctx_i;
1203            ctx_s_key = &enc_session->dec_ctx_i;
1204            c_iv = (unsigned char *) enc_session->enc_key_nonce_i;
1205            s_iv = (unsigned char *) enc_session->dec_key_nonce_i;
1206            c_key_bin = enc_session->enc_key_i;
1207            s_key_bin = enc_session->dec_key_i;
1208        }
1209        else
1210        {
1211            ctx_c_key = &enc_session->enc_ctx_f;
1212            ctx_s_key = &enc_session->dec_ctx_f;
1213            c_iv = (unsigned char *) enc_session->enc_key_nonce_f;
1214            s_iv = (unsigned char *) enc_session->dec_key_nonce_f;
1215        }
1216    }
1217
1218    LSQ_DEBUG("export_key_material c255_gen_share_key %s",
1219              get_bin_str(shared_key_c, 32, 512));
1220
1221    lsquic_buf_append(hkdf_input, (char *)&enc_session->cid, sizeof(enc_session->cid));
1222    lsquic_buf_append(hkdf_input, lsquic_str_cstr(chlo), lsquic_str_len(chlo)); /* CHLO msg */
1223    {
1224        lsquic_buf_append(hkdf_input, lsquic_str_cstr(&enc_session->info->scfg),
1225                       lsquic_str_len(&enc_session->info->scfg)); /* scfg msg */
1226    }
1227    lsquic_buf_append(hkdf_input, lsquic_str_cstr(enc_session->cert_ptr),
1228                   lsquic_str_len(enc_session->cert_ptr));
1229    LSQ_DEBUG("export_key_material hkdf_input %s",
1230              get_bin_str(lsquic_buf_begin(hkdf_input),
1231                          (size_t)lsquic_buf_size(hkdf_input), 512));
1232
1233    /* then need to use the salts and the shared_key_* to get the real aead key */
1234    lsquic_buf_append(nonce_c, (const char *) enc_session->hs_ctx.nonc, 32);
1235    lsquic_buf_append(nonce_c, lsquic_str_cstr(&enc_session->ssno),
1236                   lsquic_str_len(&enc_session->ssno));
1237    LSQ_DEBUG("export_key_material nonce %s",
1238              get_bin_str(lsquic_buf_begin(nonce_c),
1239                          (size_t)lsquic_buf_size(nonce_c), 512));
1240
1241    export_key_material(shared_key_c, 32,
1242                        (unsigned char *)lsquic_buf_begin(nonce_c), lsquic_buf_size(nonce_c),
1243                        (unsigned char *)lsquic_buf_begin(hkdf_input),
1244                        lsquic_buf_size(hkdf_input),
1245                        aes128_key_len, c_key,
1246                        aes128_key_len, s_key,
1247                        aes128_iv_len, c_iv,
1248                        aes128_iv_len, s_iv,
1249                        sub_key);
1250
1251    setup_aead_ctx(ctx_c_key, c_key, aes128_key_len, c_key_bin);
1252    setup_aead_ctx(ctx_s_key, s_key, aes128_key_len, s_key_bin);
1253
1254
1255    lsquic_buf_destroy(nonce_c);
1256    lsquic_buf_destroy(hkdf_input);
1257
1258    LSQ_DEBUG("***export_key_material '%c' c_key: %s", key_flag,
1259              get_bin_str(c_key, aes128_key_len, 512));
1260    LSQ_DEBUG("***export_key_material '%c' s_key: %s", key_flag,
1261              get_bin_str(s_key, aes128_key_len, 512));
1262    LSQ_DEBUG("***export_key_material '%c' c_iv: %s", key_flag,
1263              get_bin_str(c_iv, aes128_iv_len, 512));
1264    LSQ_DEBUG("***export_key_material '%c' s_iv: %s", key_flag,
1265              get_bin_str(s_iv, aes128_iv_len, 512));
1266    LSQ_DEBUG("***export_key_material '%c' subkey: %s", key_flag,
1267              get_bin_str(sub_key, 32, 512));
1268
1269    return 0;
1270}
1271
1272
1273/* 0 Match */
1274static int cached_certs_match(cert_hash_item_t *cached_certs_item, lsquic_str_t **certs,
1275                                         int certs_count)
1276{
1277    int i;
1278    if (!cached_certs_item || cached_certs_item->count != certs_count)
1279        return -1;
1280
1281    for (i=0; i<certs_count; ++i)
1282    {
1283        if (lsquic_str_bcmp(certs[i], &cached_certs_item->crts[i]) != 0)
1284            return -1;
1285    }
1286
1287    return 0;
1288}
1289
1290
1291static const char *
1292he2str (enum handshake_error he)
1293{
1294    switch (he)
1295    {
1296    case DATA_NOT_ENOUGH:   return "DATA_NOT_ENOUGH";
1297    case HS_ERROR:          return "HS_ERROR";
1298    case HS_SHLO:           return "HS_SHLO";
1299    case HS_1RTT:           return "HS_1RTT";
1300    case HS_2RTT:           return "HS_2RTT";
1301    default:
1302        assert(0);          return "<unknown enum value>";
1303    }
1304}
1305
1306
1307/* NOT packet, just the frames-data */
1308/* return rtt number:
1309 *      0 OK
1310 *      DATA_NOT_ENOUGH(-2) for not enough data,
1311 *      DATA_FORMAT_ERROR(-1) all other errors
1312 */
1313static int
1314lsquic_enc_session_handle_chlo_reply (lsquic_enc_session_t *enc_session,
1315                                                const uint8_t *data, int len)
1316{
1317    uint32_t head_tag;
1318    int ret;
1319    lsquic_session_cache_info_t *info = enc_session->info;
1320    hs_ctx_t * hs_ctx = &enc_session->hs_ctx;
1321    cert_hash_item_t *cached_certs_item = c_find_certs(&hs_ctx->sni);
1322
1323    /* FIXME get the number first */
1324    lsquic_str_t **out_certs = NULL;
1325    size_t out_certs_count = 0, i;
1326
1327    ret = parse_hs(enc_session, data, len, &head_tag);
1328    if (ret)
1329        goto end;
1330
1331    if (head_tag != QTAG_SREJ &&
1332        head_tag != QTAG_REJ &&
1333        head_tag != QTAG_SHLO)
1334    {
1335        ret = 1;
1336        goto end;
1337    }
1338
1339    if (head_tag == QTAG_SREJ || head_tag == QTAG_REJ)
1340        enc_session->hsk_state = HSK_CHLO_REJ;
1341    else if(head_tag == QTAG_SHLO)
1342    {
1343        enc_session->hsk_state = HSK_COMPLETED;
1344    }
1345
1346    if (info->scfg_flag == 1)
1347    {
1348        ret = parse_hs(enc_session, (uint8_t *)lsquic_str_cstr(&info->scfg),
1349                       lsquic_str_len(&info->scfg), &head_tag);
1350
1351        /* After handled, set the length to 0 to avoid do it again*/
1352        enc_session->info->scfg_flag = 2;
1353        if (ret)
1354            goto end;
1355
1356        if (lsquic_str_len(&enc_session->hs_ctx.crt) > 0)
1357        {
1358            out_certs_count = get_certs_count(&enc_session->hs_ctx.crt);
1359            if (out_certs_count > 0)
1360            {
1361                out_certs = (lsquic_str_t **)malloc(out_certs_count * sizeof(lsquic_str_t *));
1362                if (!out_certs)
1363                {
1364                    ret = -1;
1365                    goto end;
1366                }
1367
1368                for (i=0; i<out_certs_count; ++i)
1369                    out_certs[i] = lsquic_str_new(NULL, 0);
1370
1371                ret = handle_chlo_reply_verify_prof(enc_session, out_certs,
1372                                            &out_certs_count,
1373                                            (cached_certs_item ? cached_certs_item->crts : NULL),
1374                                            (cached_certs_item ? cached_certs_item->count : 0));
1375                if (ret == 0)
1376                {
1377                    if (out_certs_count > 0)
1378                    {
1379                        if (cached_certs_item &&
1380                            cached_certs_match(cached_certs_item, out_certs, out_certs_count) == 0)
1381                            ;
1382                        else
1383                        {
1384                            if (cached_certs_item)
1385                                c_free_cert_hash_item(cached_certs_item);
1386
1387                            cached_certs_item = make_cert_hash_item(&hs_ctx->sni,
1388                                                                    out_certs, out_certs_count);
1389                            c_insert_certs(cached_certs_item);
1390                        }
1391                        enc_session->cert_ptr = &cached_certs_item->crts[0];
1392                    }
1393                }
1394
1395                for (i=0; i<out_certs_count; ++i)
1396                    lsquic_str_delete(out_certs[i]);
1397                free(out_certs);
1398
1399                if (ret)
1400                    goto end;
1401            }
1402        }
1403    }
1404
1405    if (enc_session->hsk_state == HSK_COMPLETED)
1406    {
1407        if (!lsquic_str_buf(&info->sni_key))
1408            save_session_info_entry(&enc_session->hs_ctx.sni, info);
1409        ret = determine_keys(enc_session
1410                                           ); /* FIXME: check ret */
1411        enc_session->have_key = 3;
1412    }
1413
1414  end:
1415    LSQ_DEBUG("lsquic_enc_session_handle_chlo_reply called, buf in %d, return %d.", len, ret);
1416    EV_LOG_CONN_EVENT(enc_session->cid, "%s returning %s", __func__,
1417                                                                he2str(ret));
1418    return ret;
1419}
1420
1421
1422static uint64_t combine_path_id_pack_num(uint8_t path_id, uint64_t pack_num)
1423{
1424    uint64_t v = ((uint64_t)path_id << 56) | pack_num;
1425    return v;
1426}
1427
1428
1429#   define IS_SERVER(session) 0
1430
1431static int
1432verify_packet_hash (const lsquic_enc_session_t *enc_session,
1433    enum lsquic_version version, const unsigned char *buf, size_t *header_len,
1434    size_t data_len, unsigned char *buf_out, size_t max_out_len,
1435    size_t *out_len)
1436{
1437    uint8_t md[HS_PKT_HASH_LENGTH];
1438    uint128 hash;
1439    int ret;
1440
1441    if (data_len < HS_PKT_HASH_LENGTH)
1442        return -1;
1443
1444    if (version >= LSQVER_037)
1445    {
1446            hash = fnv1a_128_3(buf, *header_len,
1447                        buf + *header_len + HS_PKT_HASH_LENGTH,
1448                        data_len - HS_PKT_HASH_LENGTH,
1449                        (unsigned char *) "Server", 6);
1450    }
1451    else
1452    {
1453        hash = fnv1a_128_2(buf, *header_len,
1454                        buf + *header_len + HS_PKT_HASH_LENGTH,
1455                        data_len - HS_PKT_HASH_LENGTH);
1456    }
1457
1458    serialize_fnv128_short(hash, md);
1459    ret = memcmp(md, buf + *header_len, HS_PKT_HASH_LENGTH);
1460    if(ret == 0)
1461    {
1462        *header_len += HS_PKT_HASH_LENGTH;
1463        *out_len = data_len - HS_PKT_HASH_LENGTH;
1464        if (max_out_len < *header_len + *out_len)
1465            return -1;
1466
1467        memcpy(buf_out, buf, *header_len + *out_len);
1468        return 0;
1469    }
1470    else
1471        return -1;
1472}
1473
1474
1475static int
1476decrypt_packet (lsquic_enc_session_t *enc_session, uint8_t path_id,
1477                uint64_t pack_num, unsigned char *buf, size_t *header_len,
1478                size_t data_len, unsigned char *buf_out, size_t max_out_len,
1479                size_t *out_len)
1480{
1481    int ret;
1482    /* Comment: 12 = sizeof(dec_key_iv] 4 + sizeof(pack_num) 8 */
1483    uint8_t nonce[12];
1484    uint64_t path_id_packet_number;
1485    EVP_AEAD_CTX *key = NULL;
1486    int try_times = 0;
1487
1488    path_id_packet_number = combine_path_id_pack_num(path_id, pack_num);
1489    memcpy(buf_out, buf, *header_len);
1490    while(try_times < 2)
1491    {
1492        if (enc_session->have_key == 3 && try_times == 0)
1493        {
1494            key = enc_session->dec_ctx_f;
1495            memcpy(nonce, enc_session->dec_key_nonce_f, 4);
1496            LSQ_DEBUG("decrypt_packet using 'F' key...");
1497        }
1498        else
1499        {
1500            key = enc_session->dec_ctx_i;
1501            memcpy(nonce, enc_session->dec_key_nonce_i, 4);
1502            LSQ_DEBUG("decrypt_packet using 'I' key...");
1503        }
1504        memcpy(nonce + 4, &path_id_packet_number,
1505               sizeof(path_id_packet_number));
1506
1507        *out_len = data_len;
1508        ret = aes_aead_dec(key,
1509                           buf, *header_len,
1510                           nonce, 12,
1511                           buf + *header_len, data_len,
1512                           buf_out + *header_len, out_len);
1513
1514        if (ret != 0)
1515            ++try_times;
1516        else
1517        {
1518            if (enc_session->peer_have_final_key == 0 &&
1519                enc_session->have_key == 3 &&
1520                try_times == 0)
1521            {
1522                LSQ_DEBUG("!!!decrypt_packet find peer have final key.");
1523                enc_session->peer_have_final_key = 1;
1524                EV_LOG_CONN_EVENT(enc_session->cid, "settled on private key "
1525                    "'%c' after %d tries (packet number %"PRIu64")",
1526                    key == enc_session->dec_ctx_f ? 'F' : 'I',
1527                    try_times, pack_num);
1528            }
1529            break;
1530        }
1531    }
1532
1533//     if (ret)
1534//     {
1535//        *out_len = data_len;
1536//        memcpy(buf_out, buf, *header_len);
1537//        key = "\x45\xCA\x99\x4A\x40\xBC\xE3\x3B\x32\x16\x59\x51\x98\x36\xD4\x21";
1538//        ret = aes_aead_dec(key,
1539//                           buf, 0,
1540//                           lsquic_str_cstr(enc_session->sstk), 12,
1541//                           buf + *header_len, data_len,
1542//                           buf_out + *header_len, out_len);
1543//     }
1544
1545    LSQ_DEBUG("***decrypt_packet %s.", (ret == 0 ? "succeed" : "failed"));
1546    return ret;
1547}
1548
1549
1550static int
1551lsquic_enc_session_have_key_gt_one (const lsquic_enc_session_t *enc_session)
1552{
1553    return enc_session && enc_session->have_key > 1;
1554}
1555
1556
1557/* The size of `buf' is *header_len plus data_len.  The two parts of the
1558 * buffer correspond to the header and the payload of incoming QUIC packet.
1559 */
1560/* 0 for OK, otherwise nonezero */
1561static int
1562lsquic_enc_session_decrypt (lsquic_enc_session_t *enc_session,
1563               enum lsquic_version version,
1564               uint8_t path_id, uint64_t pack_num,
1565               unsigned char *buf, size_t *header_len, size_t data_len,
1566               unsigned char *diversification_nonce,
1567               unsigned char *buf_out, size_t max_out_len, size_t *out_len)
1568{
1569    /* Client: got SHLO which should have diversification_nonce */
1570    if (diversification_nonce && enc_session && enc_session->have_key == 1)
1571    {
1572        determine_diversification_key(enc_session, diversification_nonce);
1573        enc_session->have_key = 2;
1574    }
1575
1576    if (lsquic_enc_session_have_key_gt_one(enc_session))
1577        return decrypt_packet(enc_session, path_id, pack_num, buf,
1578                        header_len, data_len, buf_out, max_out_len, out_len);
1579    else
1580        return verify_packet_hash(enc_session, version, buf, header_len,
1581                                    data_len, buf_out, max_out_len, out_len);
1582}
1583
1584
1585static int
1586lsquic_enc_session_encrypt (lsquic_enc_session_t *enc_session,
1587               enum lsquic_version version,
1588               uint8_t path_id, uint64_t pack_num,
1589               const unsigned char *header, size_t header_len,
1590               const unsigned char *data, size_t data_len,
1591               unsigned char *buf_out, size_t max_out_len, size_t *out_len,
1592               int is_hello)
1593{
1594    uint8_t md[HS_PKT_HASH_LENGTH];
1595    uint128 hash;
1596    int ret;
1597    int is_chlo = (is_hello && ((IS_SERVER(enc_session)) == 0));
1598    int is_shlo = (is_hello && (IS_SERVER(enc_session)));
1599
1600    /* Comment: 12 = sizeof(dec_key_iv] 4 + sizeof(pack_num) 8 */
1601    uint8_t nonce[12];
1602    uint64_t path_id_packet_number;
1603    EVP_AEAD_CTX *key;
1604
1605    if (enc_session)
1606        LSQ_DEBUG("%s: hsk_state: %d", __func__, enc_session->hsk_state);
1607    else
1608        LSQ_DEBUG("%s: enc_session is not set", __func__);
1609
1610    if (!enc_session || enc_session->have_key == 0 || is_chlo)
1611    {
1612        *out_len = header_len + data_len + HS_PKT_HASH_LENGTH;
1613        if (max_out_len < *out_len)
1614            return -1;
1615
1616        if (version >= LSQVER_037)
1617        {
1618                hash = fnv1a_128_3(header, header_len, data, data_len,
1619                                            (unsigned char *) "Client", 6);
1620        }
1621        else
1622        {
1623            hash = fnv1a_128_2(header, header_len, data, data_len);
1624        }
1625
1626        serialize_fnv128_short(hash, md);
1627        memcpy(buf_out, header, header_len);
1628        memcpy(buf_out + header_len, md, HS_PKT_HASH_LENGTH);
1629        memcpy(buf_out + header_len + HS_PKT_HASH_LENGTH, data, data_len);
1630        return 0;
1631    }
1632    else
1633    {
1634        if (enc_session->have_key != 3 || is_shlo ||
1635            ((IS_SERVER(enc_session)) &&
1636             enc_session->server_start_use_final_key == 0))
1637        {
1638            LSQ_DEBUG("lsquic_enc_session_encrypt using 'I' key...");
1639            key = enc_session->enc_ctx_i;
1640            memcpy(nonce, enc_session->enc_key_nonce_i, 4);
1641            if (is_shlo && enc_session->have_key == 3)
1642            {
1643                enc_session->server_start_use_final_key = 1;
1644            }
1645        }
1646        else
1647        {
1648            LSQ_DEBUG("lsquic_enc_session_encrypt using 'F' key...");
1649            key = enc_session->enc_ctx_f;
1650            memcpy(nonce, enc_session->enc_key_nonce_f, 4);
1651        }
1652        path_id_packet_number = combine_path_id_pack_num(path_id, pack_num);
1653        memcpy(nonce + 4, &path_id_packet_number,
1654               sizeof(path_id_packet_number));
1655
1656        memcpy(buf_out, header, header_len);
1657        *out_len = max_out_len - header_len;
1658
1659        ret = aes_aead_enc(key, header, header_len, nonce, 12, data,
1660                           data_len, buf_out + header_len, out_len);
1661        *out_len += header_len;
1662        return ret;
1663    }
1664}
1665
1666
1667static int
1668lsquic_enc_session_get_peer_option (const lsquic_enc_session_t *enc_session,
1669                                                                uint32_t tag)
1670{
1671    switch (tag)
1672    {
1673    case QTAG_NSTP:
1674        return !!(enc_session->hs_ctx.opts & HOPT_NSTP);
1675    case QTAG_SREJ:
1676        return !!(enc_session->hs_ctx.opts & HOPT_SREJ);
1677    default:
1678        assert(0);
1679        return 0;
1680    }
1681}
1682
1683
1684/* Query a several parameters sent by the peer that are required by
1685 * connection.
1686 */
1687static int
1688lsquic_enc_session_get_peer_setting (const lsquic_enc_session_t *enc_session,
1689                                        uint32_t tag, uint32_t *val)
1690{
1691    switch (tag)
1692    {
1693    case QTAG_TCID:
1694        if (enc_session->hs_ctx.set & HSET_TCID)
1695        {
1696            *val = enc_session->hs_ctx.tcid;
1697            return 0;
1698        }
1699        else
1700            return -1;
1701    case QTAG_SMHL:
1702        if (enc_session->hs_ctx.set & HSET_SMHL)
1703        {
1704            *val = enc_session->hs_ctx.smhl;
1705            return 0;
1706        }
1707        else
1708            return -1;
1709    }
1710
1711    /* XXX For the following values, there is no record which were present
1712     *     in CHLO or SHLO and which were not.  Assume that zero means that
1713     *     they weren't present.
1714     */
1715        switch (tag)
1716        {
1717        case QTAG_CFCW:
1718            if (enc_session->hs_ctx.cfcw)
1719            {
1720                *val = enc_session->hs_ctx.cfcw;
1721                return 0;
1722            }
1723            else
1724                return -1;
1725        case QTAG_SFCW:
1726            if (enc_session->hs_ctx.sfcw)
1727            {
1728                *val = enc_session->hs_ctx.sfcw;
1729                return 0;
1730            }
1731            else
1732                return -1;
1733        case QTAG_MIDS:
1734            if (enc_session->hs_ctx.mids)
1735            {
1736                *val = enc_session->hs_ctx.mids;
1737                return 0;
1738            }
1739            else
1740                return -1;
1741        default:
1742            return -1;
1743        }
1744}
1745
1746
1747#if LSQUIC_KEEP_ENC_SESS_HISTORY
1748static void
1749lsquic_get_enc_hist (const lsquic_enc_session_t *enc_session,
1750                                        char buf[(1 << ESHIST_BITS) + 1])
1751{
1752    const unsigned hist_idx = ESHIST_MASK & enc_session->es_hist_idx;
1753    if (enc_session->es_hist_buf[hist_idx] == ESHE_EMPTY)
1754        memcpy(buf, enc_session->es_hist_buf, hist_idx + 1);
1755    else
1756    {
1757        memcpy(buf, enc_session->es_hist_buf + hist_idx, sizeof(enc_session->es_hist_buf) - hist_idx);
1758        memcpy(buf + hist_idx, enc_session->es_hist_buf, hist_idx);
1759        buf[(1 << ESHIST_BITS)] = '\0';
1760    }
1761}
1762
1763
1764#endif
1765
1766
1767
1768#ifdef NDEBUG
1769const
1770#endif
1771struct enc_session_funcs lsquic_enc_session_gquic_1 =
1772{
1773    .esf_global_init    = lsquic_handshake_init,
1774    .esf_global_cleanup = lsquic_handshake_cleanup,
1775#if LSQUIC_KEEP_ENC_SESS_HISTORY
1776    .esf_get_hist       = lsquic_get_enc_hist,
1777#endif
1778    .esf_destroy = lsquic_enc_session_destroy,
1779    .esf_is_hsk_done = lsquic_enc_session_is_hsk_done,
1780    .esf_encrypt = lsquic_enc_session_encrypt,
1781    .esf_decrypt = lsquic_enc_session_decrypt,
1782    .esf_get_peer_setting = lsquic_enc_session_get_peer_setting,
1783    .esf_get_peer_option = lsquic_enc_session_get_peer_option,
1784    .esf_create_client = lsquic_enc_session_create_client,
1785    .esf_generate_cid = lsquic_generate_cid,
1786    .esf_gen_chlo = lsquic_enc_session_gen_chlo,
1787    .esf_handle_chlo_reply = lsquic_enc_session_handle_chlo_reply,
1788};
1789