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