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