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