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