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