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