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