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