1 /* 2 * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <openssl/err.h> 11 #include "internal/common.h" 12 #include "internal/quic_wire_pkt.h" 13 14 int ossl_quic_hdr_protector_init(QUIC_HDR_PROTECTOR *hpr, 15 OSSL_LIB_CTX *libctx, 16 const char *propq, 17 uint32_t cipher_id, 18 const unsigned char *quic_hp_key, 19 size_t quic_hp_key_len) 20 { 21 const char *cipher_name = NULL; 22 23 switch (cipher_id) { 24 case QUIC_HDR_PROT_CIPHER_AES_128: 25 cipher_name = "AES-128-ECB"; 26 break; 27 case QUIC_HDR_PROT_CIPHER_AES_256: 28 cipher_name = "AES-256-ECB"; 29 break; 30 case QUIC_HDR_PROT_CIPHER_CHACHA: 31 cipher_name = "ChaCha20"; 32 break; 33 default: 34 ERR_raise(ERR_LIB_SSL, ERR_R_UNSUPPORTED); 35 return 0; 36 } 37 38 hpr->cipher_ctx = EVP_CIPHER_CTX_new(); 39 if (hpr->cipher_ctx == NULL) { 40 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 41 return 0; 42 } 43 44 hpr->cipher = EVP_CIPHER_fetch(libctx, cipher_name, propq); 45 if (hpr->cipher == NULL 46 || quic_hp_key_len != (size_t)EVP_CIPHER_get_key_length(hpr->cipher)) { 47 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 48 goto err; 49 } 50 51 if (!EVP_CipherInit_ex(hpr->cipher_ctx, hpr->cipher, NULL, 52 quic_hp_key, NULL, 1)) { 53 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 54 goto err; 55 } 56 57 hpr->libctx = libctx; 58 hpr->propq = propq; 59 hpr->cipher_id = cipher_id; 60 return 1; 61 62 err: 63 ossl_quic_hdr_protector_cleanup(hpr); 64 return 0; 65 } 66 67 void ossl_quic_hdr_protector_cleanup(QUIC_HDR_PROTECTOR *hpr) 68 { 69 EVP_CIPHER_CTX_free(hpr->cipher_ctx); 70 hpr->cipher_ctx = NULL; 71 72 EVP_CIPHER_free(hpr->cipher); 73 hpr->cipher = NULL; 74 } 75 76 static int hdr_generate_mask(QUIC_HDR_PROTECTOR *hpr, 77 const unsigned char *sample, size_t sample_len, 78 unsigned char *mask) 79 { 80 int l = 0; 81 unsigned char dst[16]; 82 static const unsigned char zeroes[5] = { 0 }; 83 size_t i; 84 85 if (hpr->cipher_id == QUIC_HDR_PROT_CIPHER_AES_128 86 || hpr->cipher_id == QUIC_HDR_PROT_CIPHER_AES_256) { 87 if (sample_len < 16) { 88 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); 89 return 0; 90 } 91 92 if (!EVP_CipherInit_ex(hpr->cipher_ctx, NULL, NULL, NULL, NULL, 1) 93 || !EVP_CipherUpdate(hpr->cipher_ctx, dst, &l, sample, 16)) { 94 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 95 return 0; 96 } 97 98 for (i = 0; i < 5; ++i) 99 mask[i] = dst[i]; 100 } else if (hpr->cipher_id == QUIC_HDR_PROT_CIPHER_CHACHA) { 101 if (sample_len < 16) { 102 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); 103 return 0; 104 } 105 106 if (!EVP_CipherInit_ex(hpr->cipher_ctx, NULL, NULL, NULL, sample, 1) 107 || !EVP_CipherUpdate(hpr->cipher_ctx, mask, &l, 108 zeroes, sizeof(zeroes))) { 109 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 110 return 0; 111 } 112 } else { 113 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); 114 assert(0); 115 return 0; 116 } 117 118 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 119 /* No matter what we did above we use the same mask in fuzzing mode */ 120 memset(mask, 0, 5); 121 #endif 122 123 return 1; 124 } 125 126 int ossl_quic_hdr_protector_decrypt(QUIC_HDR_PROTECTOR *hpr, 127 QUIC_PKT_HDR_PTRS *ptrs) 128 { 129 return ossl_quic_hdr_protector_decrypt_fields(hpr, 130 ptrs->raw_sample, 131 ptrs->raw_sample_len, 132 ptrs->raw_start, 133 ptrs->raw_pn); 134 } 135 136 int ossl_quic_hdr_protector_decrypt_fields(QUIC_HDR_PROTECTOR *hpr, 137 const unsigned char *sample, 138 size_t sample_len, 139 unsigned char *first_byte, 140 unsigned char *pn_bytes) 141 { 142 unsigned char mask[5], pn_len, i; 143 144 if (!hdr_generate_mask(hpr, sample, sample_len, mask)) 145 return 0; 146 147 *first_byte ^= mask[0] & ((*first_byte & 0x80) != 0 ? 0xf : 0x1f); 148 pn_len = (*first_byte & 0x3) + 1; 149 150 for (i = 0; i < pn_len; ++i) 151 pn_bytes[i] ^= mask[i + 1]; 152 153 return 1; 154 } 155 156 int ossl_quic_hdr_protector_encrypt(QUIC_HDR_PROTECTOR *hpr, 157 QUIC_PKT_HDR_PTRS *ptrs) 158 { 159 return ossl_quic_hdr_protector_encrypt_fields(hpr, 160 ptrs->raw_sample, 161 ptrs->raw_sample_len, 162 ptrs->raw_start, 163 ptrs->raw_pn); 164 } 165 166 int ossl_quic_hdr_protector_encrypt_fields(QUIC_HDR_PROTECTOR *hpr, 167 const unsigned char *sample, 168 size_t sample_len, 169 unsigned char *first_byte, 170 unsigned char *pn_bytes) 171 { 172 unsigned char mask[5], pn_len, i; 173 174 if (!hdr_generate_mask(hpr, sample, sample_len, mask)) 175 return 0; 176 177 pn_len = (*first_byte & 0x3) + 1; 178 for (i = 0; i < pn_len; ++i) 179 pn_bytes[i] ^= mask[i + 1]; 180 181 *first_byte ^= mask[0] & ((*first_byte & 0x80) != 0 ? 0xf : 0x1f); 182 return 1; 183 } 184 185 int ossl_quic_wire_decode_pkt_hdr(PACKET *pkt, 186 size_t short_conn_id_len, 187 int partial, 188 int nodata, 189 QUIC_PKT_HDR *hdr, 190 QUIC_PKT_HDR_PTRS *ptrs, 191 uint64_t *fail_cause) 192 { 193 unsigned int b0; 194 unsigned char *pn = NULL; 195 size_t l = PACKET_remaining(pkt); 196 197 if (fail_cause != NULL) 198 *fail_cause = QUIC_PKT_HDR_DECODE_DECODE_ERR; 199 200 if (ptrs != NULL) { 201 ptrs->raw_start = (unsigned char *)PACKET_data(pkt); 202 ptrs->raw_sample = NULL; 203 ptrs->raw_sample_len = 0; 204 ptrs->raw_pn = NULL; 205 } 206 207 if (l < QUIC_MIN_VALID_PKT_LEN 208 || !PACKET_get_1(pkt, &b0)) 209 return 0; 210 211 hdr->partial = partial; 212 hdr->unused = 0; 213 hdr->reserved = 0; 214 215 if ((b0 & 0x80) == 0) { 216 /* Short header. */ 217 if (short_conn_id_len > QUIC_MAX_CONN_ID_LEN) 218 return 0; 219 220 if ((b0 & 0x40) == 0 /* fixed bit not set? */ 221 || l < QUIC_MIN_VALID_PKT_LEN_CRYPTO) 222 return 0; 223 224 hdr->type = QUIC_PKT_TYPE_1RTT; 225 hdr->fixed = 1; 226 hdr->spin_bit = (b0 & 0x20) != 0; 227 if (partial) { 228 hdr->key_phase = 0; /* protected, zero for now */ 229 hdr->pn_len = 0; /* protected, zero for now */ 230 hdr->reserved = 0; /* protected, zero for now */ 231 } else { 232 hdr->key_phase = (b0 & 0x04) != 0; 233 hdr->pn_len = (b0 & 0x03) + 1; 234 hdr->reserved = (b0 & 0x18) >> 3; 235 } 236 237 /* Copy destination connection ID field to header structure. */ 238 if (!PACKET_copy_bytes(pkt, hdr->dst_conn_id.id, short_conn_id_len)) 239 return 0; 240 241 hdr->dst_conn_id.id_len = (unsigned char)short_conn_id_len; 242 243 /* 244 * Skip over the PN. If this is a partial decode, the PN length field 245 * currently has header protection applied. Thus we do not know the 246 * length of the PN but we are allowed to assume it is 4 bytes long at 247 * this stage. 248 */ 249 memset(hdr->pn, 0, sizeof(hdr->pn)); 250 pn = (unsigned char *)PACKET_data(pkt); 251 if (partial) { 252 if (!PACKET_forward(pkt, sizeof(hdr->pn))) 253 return 0; 254 } else { 255 if (!PACKET_copy_bytes(pkt, hdr->pn, hdr->pn_len)) 256 return 0; 257 } 258 259 /* Fields not used in short-header packets. */ 260 hdr->version = 0; 261 hdr->src_conn_id.id_len = 0; 262 hdr->token = NULL; 263 hdr->token_len = 0; 264 265 /* 266 * Short-header packets always come last in a datagram, the length 267 * is the remainder of the buffer. 268 */ 269 hdr->len = PACKET_remaining(pkt); 270 hdr->data = PACKET_data(pkt); 271 272 /* 273 * Skip over payload. Since this is a short header packet, which cannot 274 * be followed by any other kind of packet, this advances us to the end 275 * of the datagram. 276 */ 277 if (!PACKET_forward(pkt, hdr->len)) 278 return 0; 279 } else { 280 /* Long header. */ 281 unsigned long version; 282 unsigned int dst_conn_id_len, src_conn_id_len, raw_type; 283 284 if (!PACKET_get_net_4(pkt, &version)) 285 return 0; 286 287 /* 288 * All QUIC packets must have the fixed bit set, except exceptionally 289 * for Version Negotiation packets. 290 */ 291 if (version != 0 && (b0 & 0x40) == 0) 292 return 0; 293 294 if (!PACKET_get_1(pkt, &dst_conn_id_len) 295 || dst_conn_id_len > QUIC_MAX_CONN_ID_LEN 296 || !PACKET_copy_bytes(pkt, hdr->dst_conn_id.id, dst_conn_id_len) 297 || !PACKET_get_1(pkt, &src_conn_id_len) 298 || src_conn_id_len > QUIC_MAX_CONN_ID_LEN 299 || !PACKET_copy_bytes(pkt, hdr->src_conn_id.id, src_conn_id_len)) 300 return 0; 301 302 hdr->version = (uint32_t)version; 303 hdr->dst_conn_id.id_len = (unsigned char)dst_conn_id_len; 304 hdr->src_conn_id.id_len = (unsigned char)src_conn_id_len; 305 306 if (version == 0) { 307 /* 308 * Version negotiation packet. Version negotiation packets are 309 * identified by a version field of 0 and the type bits in the first 310 * byte are ignored (they may take any value, and we ignore them). 311 */ 312 hdr->type = QUIC_PKT_TYPE_VERSION_NEG; 313 hdr->fixed = (b0 & 0x40) != 0; 314 315 hdr->data = PACKET_data(pkt); 316 hdr->len = PACKET_remaining(pkt); 317 318 /* 319 * Version negotiation packets must contain an array of u32s, so it 320 * is invalid for their payload length to not be divisible by 4. 321 */ 322 if ((hdr->len % 4) != 0) 323 return 0; 324 325 /* Version negotiation packets are always fully decoded. */ 326 hdr->partial = 0; 327 328 /* Fields not used in version negotiation packets. */ 329 hdr->pn_len = 0; 330 hdr->spin_bit = 0; 331 hdr->key_phase = 0; 332 hdr->token = NULL; 333 hdr->token_len = 0; 334 memset(hdr->pn, 0, sizeof(hdr->pn)); 335 336 if (!PACKET_forward(pkt, hdr->len)) 337 return 0; 338 } else if (version != QUIC_VERSION_1) { 339 if (fail_cause != NULL) 340 *fail_cause |= QUIC_PKT_HDR_DECODE_BAD_VERSION; 341 /* Unknown version, do not decode. */ 342 return 0; 343 } else { 344 if (l < QUIC_MIN_VALID_PKT_LEN_CRYPTO) 345 return 0; 346 347 /* Get long packet type and decode to QUIC_PKT_TYPE_*. */ 348 raw_type = ((b0 >> 4) & 0x3); 349 350 switch (raw_type) { 351 case 0: 352 hdr->type = QUIC_PKT_TYPE_INITIAL; 353 break; 354 case 1: 355 hdr->type = QUIC_PKT_TYPE_0RTT; 356 break; 357 case 2: 358 hdr->type = QUIC_PKT_TYPE_HANDSHAKE; 359 break; 360 case 3: 361 hdr->type = QUIC_PKT_TYPE_RETRY; 362 break; 363 } 364 365 hdr->pn_len = 0; 366 hdr->fixed = 1; 367 368 /* Fields not used in long-header packets. */ 369 hdr->spin_bit = 0; 370 hdr->key_phase = 0; 371 372 if (hdr->type == QUIC_PKT_TYPE_INITIAL) { 373 /* Initial packet. */ 374 uint64_t token_len; 375 376 if (!PACKET_get_quic_vlint(pkt, &token_len) 377 || token_len > SIZE_MAX 378 || !PACKET_get_bytes(pkt, &hdr->token, (size_t)token_len)) 379 return 0; 380 381 hdr->token_len = (size_t)token_len; 382 if (token_len == 0) 383 hdr->token = NULL; 384 } else { 385 hdr->token = NULL; 386 hdr->token_len = 0; 387 } 388 389 if (hdr->type == QUIC_PKT_TYPE_RETRY) { 390 /* Retry packet. */ 391 hdr->data = PACKET_data(pkt); 392 hdr->len = PACKET_remaining(pkt); 393 394 /* Retry packets are always fully decoded. */ 395 hdr->partial = 0; 396 397 /* Unused bits in Retry header. */ 398 hdr->unused = b0 & 0x0f; 399 400 /* Fields not used in Retry packets. */ 401 memset(hdr->pn, 0, sizeof(hdr->pn)); 402 403 if (!PACKET_forward(pkt, hdr->len)) 404 return 0; 405 } else { 406 /* Initial, 0-RTT or Handshake packet. */ 407 uint64_t len; 408 409 hdr->pn_len = partial ? 0 : ((b0 & 0x03) + 1); 410 hdr->reserved = partial ? 0 : ((b0 & 0x0C) >> 2); 411 412 if (!PACKET_get_quic_vlint(pkt, &len) 413 || len < sizeof(hdr->pn)) 414 return 0; 415 416 if (!nodata && len > PACKET_remaining(pkt)) 417 return 0; 418 419 /* 420 * Skip over the PN. If this is a partial decode, the PN length 421 * field currently has header protection applied. Thus we do not 422 * know the length of the PN but we are allowed to assume it is 423 * 4 bytes long at this stage. 424 */ 425 pn = (unsigned char *)PACKET_data(pkt); 426 memset(hdr->pn, 0, sizeof(hdr->pn)); 427 if (partial) { 428 if (!PACKET_forward(pkt, sizeof(hdr->pn))) 429 return 0; 430 431 hdr->len = (size_t)(len - sizeof(hdr->pn)); 432 } else { 433 if (!PACKET_copy_bytes(pkt, hdr->pn, hdr->pn_len)) 434 return 0; 435 436 hdr->len = (size_t)(len - hdr->pn_len); 437 } 438 439 if (nodata) { 440 hdr->data = NULL; 441 } else { 442 hdr->data = PACKET_data(pkt); 443 444 /* Skip over packet body. */ 445 if (!PACKET_forward(pkt, hdr->len)) 446 return 0; 447 } 448 } 449 } 450 } 451 452 if (ptrs != NULL) { 453 ptrs->raw_pn = pn; 454 if (pn != NULL) { 455 ptrs->raw_sample = pn + 4; 456 ptrs->raw_sample_len = PACKET_end(pkt) - ptrs->raw_sample; 457 } 458 } 459 460 /* 461 * Good decode, clear the generic DECODE_ERR flag 462 */ 463 if (fail_cause != NULL) 464 *fail_cause &= ~QUIC_PKT_HDR_DECODE_DECODE_ERR; 465 466 return 1; 467 } 468 469 int ossl_quic_wire_encode_pkt_hdr(WPACKET *pkt, 470 size_t short_conn_id_len, 471 const QUIC_PKT_HDR *hdr, 472 QUIC_PKT_HDR_PTRS *ptrs) 473 { 474 unsigned char b0; 475 size_t off_start, off_sample, off_pn; 476 unsigned char *start = WPACKET_get_curr(pkt); 477 478 if (!WPACKET_get_total_written(pkt, &off_start)) 479 return 0; 480 481 if (ptrs != NULL) { 482 /* ptrs would not be stable on non-static WPACKET */ 483 if (!ossl_assert(pkt->staticbuf != NULL)) 484 return 0; 485 ptrs->raw_start = NULL; 486 ptrs->raw_sample = NULL; 487 ptrs->raw_sample_len = 0; 488 ptrs->raw_pn = 0; 489 } 490 491 /* Cannot serialize a partial header, or one whose DCID length is wrong. */ 492 if (hdr->partial 493 || (hdr->type == QUIC_PKT_TYPE_1RTT 494 && hdr->dst_conn_id.id_len != short_conn_id_len)) 495 return 0; 496 497 if (hdr->type == QUIC_PKT_TYPE_1RTT) { 498 /* Short header. */ 499 500 /* 501 * Cannot serialize a header whose DCID length is wrong, or with an 502 * invalid PN length. 503 */ 504 if (hdr->dst_conn_id.id_len != short_conn_id_len 505 || short_conn_id_len > QUIC_MAX_CONN_ID_LEN 506 || hdr->pn_len < 1 || hdr->pn_len > 4) 507 return 0; 508 509 b0 = (hdr->spin_bit << 5) 510 | (hdr->key_phase << 2) 511 | (hdr->pn_len - 1) 512 | (hdr->reserved << 3) 513 | 0x40; /* fixed bit */ 514 515 if (!WPACKET_put_bytes_u8(pkt, b0) 516 || !WPACKET_memcpy(pkt, hdr->dst_conn_id.id, short_conn_id_len) 517 || !WPACKET_get_total_written(pkt, &off_pn) 518 || !WPACKET_memcpy(pkt, hdr->pn, hdr->pn_len)) 519 return 0; 520 } else { 521 /* Long header. */ 522 unsigned int raw_type; 523 524 if (hdr->dst_conn_id.id_len > QUIC_MAX_CONN_ID_LEN 525 || hdr->src_conn_id.id_len > QUIC_MAX_CONN_ID_LEN) 526 return 0; 527 528 if (ossl_quic_pkt_type_has_pn(hdr->type) 529 && (hdr->pn_len < 1 || hdr->pn_len > 4)) 530 return 0; 531 532 switch (hdr->type) { 533 case QUIC_PKT_TYPE_VERSION_NEG: 534 if (hdr->version != 0) 535 return 0; 536 537 /* Version negotiation packets use zero for the type bits */ 538 raw_type = 0; 539 break; 540 541 case QUIC_PKT_TYPE_INITIAL: 542 raw_type = 0; 543 break; 544 case QUIC_PKT_TYPE_0RTT: 545 raw_type = 1; 546 break; 547 case QUIC_PKT_TYPE_HANDSHAKE: 548 raw_type = 2; 549 break; 550 case QUIC_PKT_TYPE_RETRY: 551 raw_type = 3; 552 break; 553 default: 554 return 0; 555 } 556 557 b0 = (raw_type << 4) | 0x80; /* long */ 558 if (hdr->type != QUIC_PKT_TYPE_VERSION_NEG || hdr->fixed) 559 b0 |= 0x40; /* fixed */ 560 if (ossl_quic_pkt_type_has_pn(hdr->type)) { 561 b0 |= hdr->pn_len - 1; 562 b0 |= (hdr->reserved << 2); 563 } 564 if (hdr->type == QUIC_PKT_TYPE_RETRY) 565 b0 |= hdr->unused; 566 567 if (!WPACKET_put_bytes_u8(pkt, b0) 568 || !WPACKET_put_bytes_u32(pkt, hdr->version) 569 || !WPACKET_put_bytes_u8(pkt, hdr->dst_conn_id.id_len) 570 || !WPACKET_memcpy(pkt, hdr->dst_conn_id.id, 571 hdr->dst_conn_id.id_len) 572 || !WPACKET_put_bytes_u8(pkt, hdr->src_conn_id.id_len) 573 || !WPACKET_memcpy(pkt, hdr->src_conn_id.id, 574 hdr->src_conn_id.id_len)) 575 return 0; 576 577 if (hdr->type == QUIC_PKT_TYPE_VERSION_NEG) { 578 if (hdr->len > 0 && !WPACKET_reserve_bytes(pkt, hdr->len, NULL)) 579 return 0; 580 581 return 1; 582 } 583 584 if (hdr->type == QUIC_PKT_TYPE_INITIAL) { 585 if (!WPACKET_quic_write_vlint(pkt, hdr->token_len) 586 || !WPACKET_memcpy(pkt, hdr->token, hdr->token_len)) 587 return 0; 588 } 589 590 if (hdr->type == QUIC_PKT_TYPE_RETRY) { 591 if (!WPACKET_memcpy(pkt, hdr->token, hdr->token_len)) 592 return 0; 593 return 1; 594 } 595 596 if (!WPACKET_quic_write_vlint(pkt, hdr->len + hdr->pn_len) 597 || !WPACKET_get_total_written(pkt, &off_pn) 598 || !WPACKET_memcpy(pkt, hdr->pn, hdr->pn_len)) 599 return 0; 600 } 601 602 if (hdr->len > 0 && !WPACKET_reserve_bytes(pkt, hdr->len, NULL)) 603 return 0; 604 605 off_sample = off_pn + 4; 606 607 if (ptrs != NULL) { 608 ptrs->raw_start = start; 609 ptrs->raw_sample = start + (off_sample - off_start); 610 ptrs->raw_sample_len 611 = WPACKET_get_curr(pkt) + hdr->len - ptrs->raw_sample; 612 ptrs->raw_pn = start + (off_pn - off_start); 613 } 614 615 return 1; 616 } 617 618 int ossl_quic_wire_get_encoded_pkt_hdr_len(size_t short_conn_id_len, 619 const QUIC_PKT_HDR *hdr) 620 { 621 size_t len = 0, enclen; 622 623 /* Cannot serialize a partial header, or one whose DCID length is wrong. */ 624 if (hdr->partial 625 || (hdr->type == QUIC_PKT_TYPE_1RTT 626 && hdr->dst_conn_id.id_len != short_conn_id_len)) 627 return 0; 628 629 if (hdr->type == QUIC_PKT_TYPE_1RTT) { 630 /* Short header. */ 631 632 /* 633 * Cannot serialize a header whose DCID length is wrong, or with an 634 * invalid PN length. 635 */ 636 if (hdr->dst_conn_id.id_len != short_conn_id_len 637 || short_conn_id_len > QUIC_MAX_CONN_ID_LEN 638 || hdr->pn_len < 1 || hdr->pn_len > 4) 639 return 0; 640 641 return 1 + short_conn_id_len + hdr->pn_len; 642 } else { 643 /* Long header. */ 644 if (hdr->dst_conn_id.id_len > QUIC_MAX_CONN_ID_LEN 645 || hdr->src_conn_id.id_len > QUIC_MAX_CONN_ID_LEN) 646 return 0; 647 648 len += 1 /* Initial byte */ + 4 /* Version */ 649 + 1 + hdr->dst_conn_id.id_len /* DCID Len, DCID */ 650 + 1 + hdr->src_conn_id.id_len /* SCID Len, SCID */ 651 ; 652 653 if (ossl_quic_pkt_type_has_pn(hdr->type)) { 654 if (hdr->pn_len < 1 || hdr->pn_len > 4) 655 return 0; 656 657 len += hdr->pn_len; 658 } 659 660 if (hdr->type == QUIC_PKT_TYPE_INITIAL) { 661 enclen = ossl_quic_vlint_encode_len(hdr->token_len); 662 if (!enclen) 663 return 0; 664 665 len += enclen + hdr->token_len; 666 } 667 668 if (!ossl_quic_pkt_type_must_be_last(hdr->type)) { 669 enclen = ossl_quic_vlint_encode_len(hdr->len + hdr->pn_len); 670 if (!enclen) 671 return 0; 672 673 len += enclen; 674 } 675 676 return len; 677 } 678 } 679 680 int ossl_quic_wire_get_pkt_hdr_dst_conn_id(const unsigned char *buf, 681 size_t buf_len, 682 size_t short_conn_id_len, 683 QUIC_CONN_ID *dst_conn_id) 684 { 685 unsigned char b0; 686 size_t blen; 687 688 if (buf_len < QUIC_MIN_VALID_PKT_LEN 689 || short_conn_id_len > QUIC_MAX_CONN_ID_LEN) 690 return 0; 691 692 b0 = buf[0]; 693 if ((b0 & 0x80) != 0) { 694 /* 695 * Long header. We need 6 bytes (initial byte, 4 version bytes, DCID 696 * length byte to begin with). This is covered by the buf_len test 697 * above. 698 */ 699 700 /* 701 * If the version field is non-zero (meaning that this is not a Version 702 * Negotiation packet), the fixed bit must be set. 703 */ 704 if ((buf[1] || buf[2] || buf[3] || buf[4]) && (b0 & 0x40) == 0) 705 return 0; 706 707 blen = (size_t)buf[5]; /* DCID Length */ 708 if (blen > QUIC_MAX_CONN_ID_LEN 709 || buf_len < QUIC_MIN_VALID_PKT_LEN + blen) 710 return 0; 711 712 dst_conn_id->id_len = (unsigned char)blen; 713 memcpy(dst_conn_id->id, buf + 6, blen); 714 return 1; 715 } else { 716 /* Short header. */ 717 if ((b0 & 0x40) == 0) 718 /* Fixed bit not set, not a valid QUIC packet header. */ 719 return 0; 720 721 if (buf_len < QUIC_MIN_VALID_PKT_LEN_CRYPTO + short_conn_id_len) 722 return 0; 723 724 dst_conn_id->id_len = (unsigned char)short_conn_id_len; 725 memcpy(dst_conn_id->id, buf + 1, short_conn_id_len); 726 return 1; 727 } 728 } 729 730 int ossl_quic_wire_decode_pkt_hdr_pn(const unsigned char *enc_pn, 731 size_t enc_pn_len, 732 QUIC_PN largest_pn, 733 QUIC_PN *res_pn) 734 { 735 int64_t expected_pn, truncated_pn, candidate_pn, pn_win, pn_hwin, pn_mask; 736 737 switch (enc_pn_len) { 738 case 1: 739 truncated_pn = enc_pn[0]; 740 break; 741 case 2: 742 truncated_pn = ((QUIC_PN)enc_pn[0] << 8) 743 | (QUIC_PN)enc_pn[1]; 744 break; 745 case 3: 746 truncated_pn = ((QUIC_PN)enc_pn[0] << 16) 747 | ((QUIC_PN)enc_pn[1] << 8) 748 | (QUIC_PN)enc_pn[2]; 749 break; 750 case 4: 751 truncated_pn = ((QUIC_PN)enc_pn[0] << 24) 752 | ((QUIC_PN)enc_pn[1] << 16) 753 | ((QUIC_PN)enc_pn[2] << 8) 754 | (QUIC_PN)enc_pn[3]; 755 break; 756 default: 757 return 0; 758 } 759 760 /* Implemented as per RFC 9000 Section A.3. */ 761 expected_pn = largest_pn + 1; 762 pn_win = ((int64_t)1) << (enc_pn_len * 8); 763 pn_hwin = pn_win / 2; 764 pn_mask = pn_win - 1; 765 candidate_pn = (expected_pn & ~pn_mask) | truncated_pn; 766 if (candidate_pn <= expected_pn - pn_hwin 767 && candidate_pn < (((int64_t)1) << 62) - pn_win) 768 *res_pn = candidate_pn + pn_win; 769 else if (candidate_pn > expected_pn + pn_hwin 770 && candidate_pn >= pn_win) 771 *res_pn = candidate_pn - pn_win; 772 else 773 *res_pn = candidate_pn; 774 return 1; 775 } 776 777 /* From RFC 9000 Section A.2. Simplified implementation. */ 778 int ossl_quic_wire_determine_pn_len(QUIC_PN pn, 779 QUIC_PN largest_acked) 780 { 781 uint64_t num_unacked 782 = (largest_acked == QUIC_PN_INVALID) ? pn + 1 : pn - largest_acked; 783 784 /* 785 * num_unacked \in [ 0, 2** 7] -> 1 byte 786 * num_unacked \in (2** 7, 2**15] -> 2 bytes 787 * num_unacked \in (2**15, 2**23] -> 3 bytes 788 * num_unacked \in (2**23, ] -> 4 bytes 789 */ 790 791 if (num_unacked <= (1U << 7)) 792 return 1; 793 if (num_unacked <= (1U << 15)) 794 return 2; 795 if (num_unacked <= (1U << 23)) 796 return 3; 797 return 4; 798 } 799 800 int ossl_quic_wire_encode_pkt_hdr_pn(QUIC_PN pn, 801 unsigned char *enc_pn, 802 size_t enc_pn_len) 803 { 804 switch (enc_pn_len) { 805 case 1: 806 enc_pn[0] = (unsigned char)pn; 807 break; 808 case 2: 809 enc_pn[1] = (unsigned char)pn; 810 enc_pn[0] = (unsigned char)(pn >> 8); 811 break; 812 case 3: 813 enc_pn[2] = (unsigned char)pn; 814 enc_pn[1] = (unsigned char)(pn >> 8); 815 enc_pn[0] = (unsigned char)(pn >> 16); 816 break; 817 case 4: 818 enc_pn[3] = (unsigned char)pn; 819 enc_pn[2] = (unsigned char)(pn >> 8); 820 enc_pn[1] = (unsigned char)(pn >> 16); 821 enc_pn[0] = (unsigned char)(pn >> 24); 822 break; 823 default: 824 return 0; 825 } 826 827 return 1; 828 } 829 830 int ossl_quic_validate_retry_integrity_tag(OSSL_LIB_CTX *libctx, 831 const char *propq, 832 const QUIC_PKT_HDR *hdr, 833 const QUIC_CONN_ID *client_initial_dcid) 834 { 835 unsigned char expected_tag[QUIC_RETRY_INTEGRITY_TAG_LEN]; 836 const unsigned char *actual_tag; 837 838 if (hdr == NULL || hdr->len < QUIC_RETRY_INTEGRITY_TAG_LEN) 839 return 0; 840 841 if (!ossl_quic_calculate_retry_integrity_tag(libctx, propq, 842 hdr, client_initial_dcid, 843 expected_tag)) 844 return 0; 845 846 actual_tag = hdr->data + hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN; 847 848 return !CRYPTO_memcmp(expected_tag, actual_tag, 849 QUIC_RETRY_INTEGRITY_TAG_LEN); 850 } 851 852 /* RFC 9001 s. 5.8 */ 853 static const unsigned char retry_integrity_key[] = { 854 0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a, 855 0x1d, 0x76, 0x6b, 0x54, 0xe3, 0x68, 0xc8, 0x4e 856 }; 857 858 static const unsigned char retry_integrity_nonce[] = { 859 0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 860 0x23, 0x98, 0x25, 0xbb 861 }; 862 863 int ossl_quic_calculate_retry_integrity_tag(OSSL_LIB_CTX *libctx, 864 const char *propq, 865 const QUIC_PKT_HDR *hdr, 866 const QUIC_CONN_ID *client_initial_dcid, 867 unsigned char *tag) 868 { 869 EVP_CIPHER *cipher = NULL; 870 EVP_CIPHER_CTX *cctx = NULL; 871 int ok = 0, l = 0, l2 = 0, wpkt_valid = 0; 872 WPACKET wpkt; 873 /* Worst case length of the Retry Psuedo-Packet header is 68 bytes. */ 874 unsigned char buf[128]; 875 QUIC_PKT_HDR hdr2; 876 size_t hdr_enc_len = 0; 877 878 if (hdr->type != QUIC_PKT_TYPE_RETRY || hdr->version == 0 879 || hdr->len < QUIC_RETRY_INTEGRITY_TAG_LEN 880 || hdr->data == NULL 881 || client_initial_dcid == NULL || tag == NULL 882 || client_initial_dcid->id_len > QUIC_MAX_CONN_ID_LEN) { 883 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); 884 goto err; 885 } 886 887 /* 888 * Do not reserve packet body in WPACKET. Retry packet header 889 * does not contain a Length field so this does not affect 890 * the serialized packet header. 891 */ 892 hdr2 = *hdr; 893 hdr2.len = 0; 894 895 /* Assemble retry psuedo-packet. */ 896 if (!WPACKET_init_static_len(&wpkt, buf, sizeof(buf), 0)) { 897 ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); 898 goto err; 899 } 900 901 wpkt_valid = 1; 902 903 /* Prepend original DCID to the packet. */ 904 if (!WPACKET_put_bytes_u8(&wpkt, client_initial_dcid->id_len) 905 || !WPACKET_memcpy(&wpkt, client_initial_dcid->id, 906 client_initial_dcid->id_len)) { 907 ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); 908 goto err; 909 } 910 911 /* Encode main retry header. */ 912 if (!ossl_quic_wire_encode_pkt_hdr(&wpkt, hdr2.dst_conn_id.id_len, 913 &hdr2, NULL)) 914 goto err; 915 916 if (!WPACKET_get_total_written(&wpkt, &hdr_enc_len)) { 917 ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); 918 goto err; 919 } 920 921 /* Create and initialise cipher context. */ 922 /* TODO(QUIC FUTURE): Cipher fetch caching. */ 923 if ((cipher = EVP_CIPHER_fetch(libctx, "AES-128-GCM", propq)) == NULL) { 924 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 925 goto err; 926 } 927 928 if ((cctx = EVP_CIPHER_CTX_new()) == NULL) { 929 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 930 goto err; 931 } 932 933 if (!EVP_CipherInit_ex(cctx, cipher, NULL, 934 retry_integrity_key, retry_integrity_nonce, /*enc=*/1)) { 935 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 936 goto err; 937 } 938 939 /* Feed packet header as AAD data. */ 940 if (EVP_CipherUpdate(cctx, NULL, &l, buf, hdr_enc_len) != 1) { 941 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 942 goto err; 943 } 944 945 /* Feed packet body as AAD data. */ 946 if (EVP_CipherUpdate(cctx, NULL, &l, hdr->data, 947 hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN) 948 != 1) { 949 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 950 goto err; 951 } 952 953 /* Finalise and get tag. */ 954 if (EVP_CipherFinal_ex(cctx, NULL, &l2) != 1) { 955 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 956 goto err; 957 } 958 959 if (EVP_CIPHER_CTX_ctrl(cctx, EVP_CTRL_AEAD_GET_TAG, 960 QUIC_RETRY_INTEGRITY_TAG_LEN, 961 tag) 962 != 1) { 963 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 964 goto err; 965 } 966 967 ok = 1; 968 err: 969 EVP_CIPHER_free(cipher); 970 EVP_CIPHER_CTX_free(cctx); 971 if (wpkt_valid) 972 WPACKET_finish(&wpkt); 973 974 return ok; 975 } 976