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