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 "internal/quic_record_tx.h" 11 #include "internal/qlog_event_helpers.h" 12 #include "internal/bio_addr.h" 13 #include "internal/common.h" 14 #include "quic_record_shared.h" 15 #include "internal/list.h" 16 #include "../ssl_local.h" 17 18 /* 19 * TXE 20 * === 21 * Encrypted packets awaiting transmission are kept in TX Entries (TXEs), which 22 * are queued in linked lists just like TXEs. 23 */ 24 typedef struct txe_st TXE; 25 26 struct txe_st { 27 OSSL_LIST_MEMBER(txe, TXE); 28 size_t data_len, alloc_len; 29 30 /* 31 * Destination and local addresses, as applicable. Both of these are only 32 * used if the family is not AF_UNSPEC. 33 */ 34 BIO_ADDR peer, local; 35 36 /* 37 * alloc_len allocated bytes (of which data_len bytes are valid) follow this 38 * structure. 39 */ 40 }; 41 42 DEFINE_LIST_OF(txe, TXE); 43 typedef OSSL_LIST(txe) TXE_LIST; 44 45 static ossl_inline unsigned char *txe_data(const TXE *e) 46 { 47 return (unsigned char *)(e + 1); 48 } 49 50 /* 51 * QTX 52 * === 53 */ 54 struct ossl_qtx_st { 55 OSSL_LIB_CTX *libctx; 56 const char *propq; 57 58 /* Per encryption-level state. */ 59 OSSL_QRL_ENC_LEVEL_SET el_set; 60 61 /* TX BIO. */ 62 BIO *bio; 63 64 /* QLOG instance retrieval callback if in use, or NULL. */ 65 QLOG *(*get_qlog_cb)(void *arg); 66 void *get_qlog_cb_arg; 67 68 /* TX maximum datagram payload length. */ 69 size_t mdpl; 70 71 /* 72 * List of TXEs which are not currently in use. These are moved to the 73 * pending list (possibly via tx_cons first) as they are filled. 74 */ 75 TXE_LIST free; 76 77 /* 78 * List of TXEs which are filled with completed datagrams ready to be 79 * transmitted. 80 */ 81 TXE_LIST pending; 82 size_t pending_count; /* items in list */ 83 size_t pending_bytes; /* sum(txe->data_len) in pending */ 84 85 /* 86 * TXE which is under construction for coalescing purposes, if any. 87 * This TXE is neither on the free nor pending list. Once the datagram 88 * is completed, it is moved to the pending list. 89 */ 90 TXE *cons; 91 size_t cons_count; /* num packets */ 92 93 /* 94 * Number of packets transmitted in this key epoch. Used to enforce AEAD 95 * confidentiality limit. 96 */ 97 uint64_t epoch_pkt_count; 98 99 /* Datagram counter. Increases monotonically per datagram (not per packet). */ 100 uint64_t datagram_count; 101 102 ossl_mutate_packet_cb mutatecb; 103 ossl_finish_mutate_cb finishmutatecb; 104 void *mutatearg; 105 106 /* Message callback related arguments */ 107 ossl_msg_cb msg_callback; 108 void *msg_callback_arg; 109 SSL *msg_callback_ssl; 110 }; 111 112 /* Instantiates a new QTX. */ 113 OSSL_QTX *ossl_qtx_new(const OSSL_QTX_ARGS *args) 114 { 115 OSSL_QTX *qtx; 116 117 if (args->mdpl < QUIC_MIN_INITIAL_DGRAM_LEN) 118 return 0; 119 120 qtx = OPENSSL_zalloc(sizeof(OSSL_QTX)); 121 if (qtx == NULL) 122 return 0; 123 124 qtx->libctx = args->libctx; 125 qtx->propq = args->propq; 126 qtx->bio = args->bio; 127 qtx->mdpl = args->mdpl; 128 qtx->get_qlog_cb = args->get_qlog_cb; 129 qtx->get_qlog_cb_arg = args->get_qlog_cb_arg; 130 131 return qtx; 132 } 133 134 static void qtx_cleanup_txl(TXE_LIST *l) 135 { 136 TXE *e, *enext; 137 138 for (e = ossl_list_txe_head(l); e != NULL; e = enext) { 139 enext = ossl_list_txe_next(e); 140 OPENSSL_free(e); 141 } 142 } 143 144 /* Frees the QTX. */ 145 void ossl_qtx_free(OSSL_QTX *qtx) 146 { 147 uint32_t i; 148 149 if (qtx == NULL) 150 return; 151 152 /* Free TXE queue data. */ 153 qtx_cleanup_txl(&qtx->pending); 154 qtx_cleanup_txl(&qtx->free); 155 OPENSSL_free(qtx->cons); 156 157 /* Drop keying material and crypto resources. */ 158 for (i = 0; i < QUIC_ENC_LEVEL_NUM; ++i) 159 ossl_qrl_enc_level_set_discard(&qtx->el_set, i); 160 161 OPENSSL_free(qtx); 162 } 163 164 /* Set mutator callbacks for test framework support */ 165 void ossl_qtx_set_mutator(OSSL_QTX *qtx, ossl_mutate_packet_cb mutatecb, 166 ossl_finish_mutate_cb finishmutatecb, void *mutatearg) 167 { 168 qtx->mutatecb = mutatecb; 169 qtx->finishmutatecb = finishmutatecb; 170 qtx->mutatearg = mutatearg; 171 } 172 173 void ossl_qtx_set_qlog_cb(OSSL_QTX *qtx, QLOG *(*get_qlog_cb)(void *arg), 174 void *get_qlog_cb_arg) 175 { 176 qtx->get_qlog_cb = get_qlog_cb; 177 qtx->get_qlog_cb_arg = get_qlog_cb_arg; 178 } 179 180 int ossl_qtx_provide_secret(OSSL_QTX *qtx, 181 uint32_t enc_level, 182 uint32_t suite_id, 183 EVP_MD *md, 184 const unsigned char *secret, 185 size_t secret_len) 186 { 187 if (enc_level >= QUIC_ENC_LEVEL_NUM) 188 return 0; 189 190 return ossl_qrl_enc_level_set_provide_secret(&qtx->el_set, 191 qtx->libctx, 192 qtx->propq, 193 enc_level, 194 suite_id, 195 md, 196 secret, 197 secret_len, 198 0, 199 /*is_tx=*/1); 200 } 201 202 int ossl_qtx_discard_enc_level(OSSL_QTX *qtx, uint32_t enc_level) 203 { 204 if (enc_level >= QUIC_ENC_LEVEL_NUM) 205 return 0; 206 207 ossl_qrl_enc_level_set_discard(&qtx->el_set, enc_level); 208 return 1; 209 } 210 211 int ossl_qtx_is_enc_level_provisioned(OSSL_QTX *qtx, uint32_t enc_level) 212 { 213 return ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1) != NULL; 214 } 215 216 /* Allocate a new TXE. */ 217 static TXE *qtx_alloc_txe(size_t alloc_len) 218 { 219 TXE *txe; 220 221 if (alloc_len >= SIZE_MAX - sizeof(TXE)) 222 return NULL; 223 224 txe = OPENSSL_malloc(sizeof(TXE) + alloc_len); 225 if (txe == NULL) 226 return NULL; 227 228 ossl_list_txe_init_elem(txe); 229 txe->alloc_len = alloc_len; 230 txe->data_len = 0; 231 return txe; 232 } 233 234 /* 235 * Ensures there is at least one TXE in the free list, allocating a new entry 236 * if necessary. The returned TXE is in the free list; it is not popped. 237 * 238 * alloc_len is a hint which may be used to determine the TXE size if allocation 239 * is necessary. Returns NULL on allocation failure. 240 */ 241 static TXE *qtx_ensure_free_txe(OSSL_QTX *qtx, size_t alloc_len) 242 { 243 TXE *txe; 244 245 txe = ossl_list_txe_head(&qtx->free); 246 if (txe != NULL) 247 return txe; 248 249 txe = qtx_alloc_txe(alloc_len); 250 if (txe == NULL) 251 return NULL; 252 253 ossl_list_txe_insert_tail(&qtx->free, txe); 254 return txe; 255 } 256 257 /* 258 * Resize the data buffer attached to an TXE to be n bytes in size. The address 259 * of the TXE might change; the new address is returned, or NULL on failure, in 260 * which case the original TXE remains valid. 261 */ 262 static TXE *qtx_resize_txe(OSSL_QTX *qtx, TXE_LIST *txl, TXE *txe, size_t n) 263 { 264 TXE *txe2, *p; 265 266 /* Should never happen. */ 267 if (txe == NULL) 268 return NULL; 269 270 if (n >= SIZE_MAX - sizeof(TXE)) 271 return NULL; 272 273 /* Remove the item from the list to avoid accessing freed memory */ 274 p = ossl_list_txe_prev(txe); 275 ossl_list_txe_remove(txl, txe); 276 277 /* 278 * NOTE: We do not clear old memory, although it does contain decrypted 279 * data. 280 */ 281 txe2 = OPENSSL_realloc(txe, sizeof(TXE) + n); 282 if (txe2 == NULL) { 283 if (p == NULL) 284 ossl_list_txe_insert_head(txl, txe); 285 else 286 ossl_list_txe_insert_after(txl, p, txe); 287 return NULL; 288 } 289 290 if (p == NULL) 291 ossl_list_txe_insert_head(txl, txe2); 292 else 293 ossl_list_txe_insert_after(txl, p, txe2); 294 295 if (qtx->cons == txe) 296 qtx->cons = txe2; 297 298 txe2->alloc_len = n; 299 return txe2; 300 } 301 302 /* 303 * Ensure the data buffer attached to an TXE is at least n bytes in size. 304 * Returns NULL on failure. 305 */ 306 static TXE *qtx_reserve_txe(OSSL_QTX *qtx, TXE_LIST *txl, 307 TXE *txe, size_t n) 308 { 309 if (txe->alloc_len >= n) 310 return txe; 311 312 return qtx_resize_txe(qtx, txl, txe, n); 313 } 314 315 /* Move a TXE from pending to free. */ 316 static void qtx_pending_to_free(OSSL_QTX *qtx) 317 { 318 TXE *txe = ossl_list_txe_head(&qtx->pending); 319 320 assert(txe != NULL); 321 ossl_list_txe_remove(&qtx->pending, txe); 322 --qtx->pending_count; 323 qtx->pending_bytes -= txe->data_len; 324 ossl_list_txe_insert_tail(&qtx->free, txe); 325 } 326 327 /* Add a TXE not currently in any list to the pending list. */ 328 static void qtx_add_to_pending(OSSL_QTX *qtx, TXE *txe) 329 { 330 ossl_list_txe_insert_tail(&qtx->pending, txe); 331 ++qtx->pending_count; 332 qtx->pending_bytes += txe->data_len; 333 } 334 335 struct iovec_cur { 336 const OSSL_QTX_IOVEC *iovec; 337 size_t num_iovec, idx, byte_off, bytes_remaining; 338 }; 339 340 static size_t iovec_total_bytes(const OSSL_QTX_IOVEC *iovec, 341 size_t num_iovec) 342 { 343 size_t i, l = 0; 344 345 for (i = 0; i < num_iovec; ++i) 346 l += iovec[i].buf_len; 347 348 return l; 349 } 350 351 static void iovec_cur_init(struct iovec_cur *cur, 352 const OSSL_QTX_IOVEC *iovec, 353 size_t num_iovec) 354 { 355 cur->iovec = iovec; 356 cur->num_iovec = num_iovec; 357 cur->idx = 0; 358 cur->byte_off = 0; 359 cur->bytes_remaining = iovec_total_bytes(iovec, num_iovec); 360 } 361 362 /* 363 * Get an extent of bytes from the iovec cursor. *buf is set to point to the 364 * buffer and the number of bytes in length of the buffer is returned. This 365 * value may be less than the max_buf_len argument. If no more data is 366 * available, returns 0. 367 */ 368 static size_t iovec_cur_get_buffer(struct iovec_cur *cur, 369 const unsigned char **buf, 370 size_t max_buf_len) 371 { 372 size_t l; 373 374 if (max_buf_len == 0) { 375 *buf = NULL; 376 return 0; 377 } 378 379 for (;;) { 380 if (cur->idx >= cur->num_iovec) 381 return 0; 382 383 l = cur->iovec[cur->idx].buf_len - cur->byte_off; 384 if (l > max_buf_len) 385 l = max_buf_len; 386 387 if (l > 0) { 388 *buf = cur->iovec[cur->idx].buf + cur->byte_off; 389 cur->byte_off += l; 390 cur->bytes_remaining -= l; 391 return l; 392 } 393 394 /* 395 * Zero-length iovec entry or we already consumed all of it, try the 396 * next iovec. 397 */ 398 ++cur->idx; 399 cur->byte_off = 0; 400 } 401 } 402 403 /* Determines the size of the AEAD output given the input size. */ 404 int ossl_qtx_calculate_ciphertext_payload_len(OSSL_QTX *qtx, uint32_t enc_level, 405 size_t plaintext_len, 406 size_t *ciphertext_len) 407 { 408 OSSL_QRL_ENC_LEVEL *el 409 = ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1); 410 size_t tag_len; 411 412 if (el == NULL) { 413 *ciphertext_len = 0; 414 return 0; 415 } 416 417 /* 418 * We currently only support ciphers with a 1:1 mapping between plaintext 419 * and ciphertext size, save for authentication tag. 420 */ 421 tag_len = ossl_qrl_get_suite_cipher_tag_len(el->suite_id); 422 423 *ciphertext_len = plaintext_len + tag_len; 424 return 1; 425 } 426 427 /* Determines the size of the AEAD input given the output size. */ 428 int ossl_qtx_calculate_plaintext_payload_len(OSSL_QTX *qtx, uint32_t enc_level, 429 size_t ciphertext_len, 430 size_t *plaintext_len) 431 { 432 OSSL_QRL_ENC_LEVEL *el 433 = ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1); 434 size_t tag_len; 435 436 if (el == NULL) { 437 *plaintext_len = 0; 438 return 0; 439 } 440 441 tag_len = ossl_qrl_get_suite_cipher_tag_len(el->suite_id); 442 443 if (ciphertext_len <= tag_len) { 444 *plaintext_len = 0; 445 return 0; 446 } 447 448 *plaintext_len = ciphertext_len - tag_len; 449 return 1; 450 } 451 452 /* Any other error (including packet being too big for MDPL). */ 453 #define QTX_FAIL_GENERIC (-1) 454 455 /* 456 * Returned where there is insufficient room in the datagram to write the 457 * packet. 458 */ 459 #define QTX_FAIL_INSUFFICIENT_LEN (-2) 460 461 static int qtx_write_hdr(OSSL_QTX *qtx, const QUIC_PKT_HDR *hdr, TXE *txe, 462 QUIC_PKT_HDR_PTRS *ptrs) 463 { 464 WPACKET wpkt; 465 size_t l = 0; 466 unsigned char *data = txe_data(txe) + txe->data_len; 467 468 if (!WPACKET_init_static_len(&wpkt, data, txe->alloc_len - txe->data_len, 0)) 469 return 0; 470 471 if (!ossl_quic_wire_encode_pkt_hdr(&wpkt, hdr->dst_conn_id.id_len, 472 hdr, ptrs) 473 || !WPACKET_get_total_written(&wpkt, &l)) { 474 WPACKET_finish(&wpkt); 475 return 0; 476 } 477 WPACKET_finish(&wpkt); 478 479 if (qtx->msg_callback != NULL) 480 qtx->msg_callback(1, OSSL_QUIC1_VERSION, SSL3_RT_QUIC_PACKET, data, l, 481 qtx->msg_callback_ssl, qtx->msg_callback_arg); 482 483 txe->data_len += l; 484 485 return 1; 486 } 487 488 static int qtx_encrypt_into_txe(OSSL_QTX *qtx, struct iovec_cur *cur, TXE *txe, 489 uint32_t enc_level, QUIC_PN pn, 490 const unsigned char *hdr, size_t hdr_len, 491 QUIC_PKT_HDR_PTRS *ptrs) 492 { 493 int l = 0, l2 = 0, nonce_len; 494 OSSL_QRL_ENC_LEVEL *el 495 = ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1); 496 unsigned char nonce[EVP_MAX_IV_LENGTH]; 497 size_t i; 498 EVP_CIPHER_CTX *cctx = NULL; 499 500 /* We should not have been called if we do not have key material. */ 501 if (!ossl_assert(el != NULL)) { 502 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); 503 return 0; 504 } 505 506 /* 507 * Have we already encrypted the maximum number of packets using the current 508 * key? 509 */ 510 if (el->op_count >= ossl_qrl_get_suite_max_pkt(el->suite_id)) { 511 ERR_raise(ERR_LIB_SSL, SSL_R_MAXIMUM_ENCRYPTED_PKTS_REACHED); 512 return 0; 513 } 514 515 /* 516 * TX key update is simpler than for RX; once we initiate a key update, we 517 * never need the old keys, as we never deliberately send a packet with old 518 * keys. Thus the EL always uses keyslot 0 for the TX side. 519 */ 520 cctx = el->cctx[0]; 521 if (!ossl_assert(cctx != NULL)) { 522 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); 523 return 0; 524 } 525 526 /* Construct nonce (nonce=IV ^ PN). */ 527 nonce_len = EVP_CIPHER_CTX_get_iv_length(cctx); 528 if (!ossl_assert(nonce_len >= (int)sizeof(QUIC_PN))) { 529 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); 530 return 0; 531 } 532 533 memcpy(nonce, el->iv[0], (size_t)nonce_len); 534 for (i = 0; i < sizeof(QUIC_PN); ++i) 535 nonce[nonce_len - i - 1] ^= (unsigned char)(pn >> (i * 8)); 536 537 /* type and key will already have been setup; feed the IV. */ 538 if (EVP_CipherInit_ex(cctx, NULL, NULL, NULL, nonce, /*enc=*/1) != 1) { 539 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 540 return 0; 541 } 542 543 /* Feed AAD data. */ 544 if (EVP_CipherUpdate(cctx, NULL, &l, hdr, hdr_len) != 1) { 545 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 546 return 0; 547 } 548 549 /* Encrypt plaintext directly into TXE. */ 550 for (;;) { 551 const unsigned char *src; 552 size_t src_len; 553 554 src_len = iovec_cur_get_buffer(cur, &src, SIZE_MAX); 555 if (src_len == 0) 556 break; 557 558 if (EVP_CipherUpdate(cctx, txe_data(txe) + txe->data_len, 559 &l, src, src_len) 560 != 1) { 561 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 562 return 0; 563 } 564 565 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 566 /* Ignore what we just encrypted and overwrite it with the plaintext */ 567 memcpy(txe_data(txe) + txe->data_len, src, l); 568 #endif 569 570 assert(l > 0 && src_len == (size_t)l); 571 txe->data_len += src_len; 572 } 573 574 /* Finalise and get tag. */ 575 if (EVP_CipherFinal_ex(cctx, NULL, &l2) != 1) { 576 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 577 return 0; 578 } 579 580 if (EVP_CIPHER_CTX_ctrl(cctx, EVP_CTRL_AEAD_GET_TAG, 581 el->tag_len, txe_data(txe) + txe->data_len) 582 != 1) { 583 ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); 584 return 0; 585 } 586 587 txe->data_len += el->tag_len; 588 589 /* Apply header protection. */ 590 if (!ossl_quic_hdr_protector_encrypt(&el->hpr, ptrs)) 591 return 0; 592 593 ++el->op_count; 594 return 1; 595 } 596 597 /* 598 * Append a packet to the TXE buffer, serializing and encrypting it in the 599 * process. 600 */ 601 static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe, 602 uint32_t enc_level, QUIC_PKT_HDR *hdr, 603 const OSSL_QTX_IOVEC *iovec, size_t num_iovec) 604 { 605 int ret, needs_encrypt; 606 size_t hdr_len, pred_hdr_len, payload_len, pkt_len, space_left; 607 size_t min_len, orig_data_len; 608 struct iovec_cur cur; 609 QUIC_PKT_HDR_PTRS ptrs; 610 unsigned char *hdr_start; 611 OSSL_QRL_ENC_LEVEL *el = NULL; 612 613 /* 614 * Determine if the packet needs encryption and the minimum conceivable 615 * serialization length. 616 */ 617 if (!ossl_quic_pkt_type_is_encrypted(hdr->type)) { 618 needs_encrypt = 0; 619 min_len = QUIC_MIN_VALID_PKT_LEN; 620 } else { 621 needs_encrypt = 1; 622 min_len = QUIC_MIN_VALID_PKT_LEN_CRYPTO; 623 el = ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1); 624 if (!ossl_assert(el != NULL)) /* should already have been checked */ 625 return 0; 626 } 627 628 orig_data_len = txe->data_len; 629 space_left = txe->alloc_len - txe->data_len; 630 if (space_left < min_len) { 631 /* Not even a possibility of it fitting. */ 632 ret = QTX_FAIL_INSUFFICIENT_LEN; 633 goto err; 634 } 635 636 /* Set some fields in the header we are responsible for. */ 637 if (hdr->type == QUIC_PKT_TYPE_1RTT) 638 hdr->key_phase = (unsigned char)(el->key_epoch & 1); 639 640 /* Walk the iovecs to determine actual input payload length. */ 641 iovec_cur_init(&cur, iovec, num_iovec); 642 643 if (cur.bytes_remaining == 0) { 644 /* No zero-length payloads allowed. */ 645 ret = QTX_FAIL_GENERIC; 646 goto err; 647 } 648 649 /* Determine encrypted payload length. */ 650 if (needs_encrypt) 651 ossl_qtx_calculate_ciphertext_payload_len(qtx, enc_level, 652 cur.bytes_remaining, 653 &payload_len); 654 else 655 payload_len = cur.bytes_remaining; 656 657 /* Determine header length. */ 658 hdr->data = NULL; 659 hdr->len = payload_len; 660 pred_hdr_len = ossl_quic_wire_get_encoded_pkt_hdr_len(hdr->dst_conn_id.id_len, 661 hdr); 662 if (pred_hdr_len == 0) { 663 ret = QTX_FAIL_GENERIC; 664 goto err; 665 } 666 667 /* We now definitively know our packet length. */ 668 pkt_len = pred_hdr_len + payload_len; 669 670 if (pkt_len > space_left) { 671 ret = QTX_FAIL_INSUFFICIENT_LEN; 672 goto err; 673 } 674 675 if (ossl_quic_pkt_type_has_pn(hdr->type)) { 676 if (!ossl_quic_wire_encode_pkt_hdr_pn(pkt->pn, 677 hdr->pn, 678 hdr->pn_len)) { 679 ret = QTX_FAIL_GENERIC; 680 goto err; 681 } 682 } 683 684 /* Append the header to the TXE. */ 685 hdr_start = txe_data(txe) + txe->data_len; 686 if (!qtx_write_hdr(qtx, hdr, txe, &ptrs)) { 687 ret = QTX_FAIL_GENERIC; 688 goto err; 689 } 690 691 hdr_len = (txe_data(txe) + txe->data_len) - hdr_start; 692 assert(hdr_len == pred_hdr_len); 693 694 if (!needs_encrypt) { 695 /* Just copy the payload across. */ 696 const unsigned char *src; 697 size_t src_len; 698 699 for (;;) { 700 /* Buffer length has already been checked above. */ 701 src_len = iovec_cur_get_buffer(&cur, &src, SIZE_MAX); 702 if (src_len == 0) 703 break; 704 705 memcpy(txe_data(txe) + txe->data_len, src, src_len); 706 txe->data_len += src_len; 707 } 708 } else { 709 /* Encrypt into TXE. */ 710 if (!qtx_encrypt_into_txe(qtx, &cur, txe, enc_level, pkt->pn, 711 hdr_start, hdr_len, &ptrs)) { 712 ret = QTX_FAIL_GENERIC; 713 goto err; 714 } 715 716 assert(txe->data_len - orig_data_len == pkt_len); 717 } 718 719 return 1; 720 721 err: 722 /* 723 * Restore original length so we don't leave a half-written packet in the 724 * TXE. 725 */ 726 txe->data_len = orig_data_len; 727 return ret; 728 } 729 730 static TXE *qtx_ensure_cons(OSSL_QTX *qtx) 731 { 732 TXE *txe = qtx->cons; 733 734 if (txe != NULL) 735 return txe; 736 737 txe = qtx_ensure_free_txe(qtx, qtx->mdpl); 738 if (txe == NULL) 739 return NULL; 740 741 ossl_list_txe_remove(&qtx->free, txe); 742 qtx->cons = txe; 743 qtx->cons_count = 0; 744 txe->data_len = 0; 745 return txe; 746 } 747 748 static QLOG *qtx_get_qlog(OSSL_QTX *qtx) 749 { 750 if (qtx->get_qlog_cb == NULL) 751 return NULL; 752 753 return qtx->get_qlog_cb(qtx->get_qlog_cb_arg); 754 } 755 756 static int qtx_mutate_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe, 757 uint32_t enc_level) 758 { 759 int ret; 760 QUIC_PKT_HDR *hdr; 761 const OSSL_QTX_IOVEC *iovec; 762 size_t num_iovec; 763 764 /* If we are running tests then mutate_packet may be non NULL */ 765 if (qtx->mutatecb != NULL) { 766 if (!qtx->mutatecb(pkt->hdr, pkt->iovec, pkt->num_iovec, &hdr, 767 &iovec, &num_iovec, qtx->mutatearg)) 768 return QTX_FAIL_GENERIC; 769 } else { 770 hdr = pkt->hdr; 771 iovec = pkt->iovec; 772 num_iovec = pkt->num_iovec; 773 } 774 775 ret = qtx_write(qtx, pkt, txe, enc_level, 776 hdr, iovec, num_iovec); 777 if (ret == 1) 778 ossl_qlog_event_transport_packet_sent(qtx_get_qlog(qtx), hdr, pkt->pn, 779 iovec, num_iovec, 780 qtx->datagram_count); 781 782 if (qtx->finishmutatecb != NULL) 783 qtx->finishmutatecb(qtx->mutatearg); 784 785 return ret; 786 } 787 788 static int addr_eq(const BIO_ADDR *a, const BIO_ADDR *b) 789 { 790 return ((a == NULL || BIO_ADDR_family(a) == AF_UNSPEC) 791 && (b == NULL || BIO_ADDR_family(b) == AF_UNSPEC)) 792 || (a != NULL && b != NULL && memcmp(a, b, sizeof(*a)) == 0); 793 } 794 795 int ossl_qtx_write_pkt(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt) 796 { 797 int ret; 798 int coalescing = (pkt->flags & OSSL_QTX_PKT_FLAG_COALESCE) != 0; 799 int was_coalescing; 800 TXE *txe; 801 uint32_t enc_level; 802 803 /* Must have EL configured, must have header. */ 804 if (pkt->hdr == NULL) 805 return 0; 806 807 enc_level = ossl_quic_pkt_type_to_enc_level(pkt->hdr->type); 808 809 /* Some packet types must be in a packet all by themselves. */ 810 if (!ossl_quic_pkt_type_can_share_dgram(pkt->hdr->type)) 811 ossl_qtx_finish_dgram(qtx); 812 else if (enc_level >= QUIC_ENC_LEVEL_NUM 813 || ossl_qrl_enc_level_set_have_el(&qtx->el_set, enc_level) != 1) { 814 /* All other packet types are encrypted. */ 815 return 0; 816 } 817 818 was_coalescing = (qtx->cons != NULL && qtx->cons->data_len > 0); 819 if (was_coalescing) 820 if (!addr_eq(&qtx->cons->peer, pkt->peer) 821 || !addr_eq(&qtx->cons->local, pkt->local)) { 822 /* Must stop coalescing if addresses have changed */ 823 ossl_qtx_finish_dgram(qtx); 824 was_coalescing = 0; 825 } 826 827 for (;;) { 828 /* 829 * Start a new coalescing session or continue using the existing one and 830 * serialize/encrypt the packet. We always encrypt packets as soon as 831 * our caller gives them to us, which relieves the caller of any need to 832 * keep the plaintext around. 833 */ 834 txe = qtx_ensure_cons(qtx); 835 if (txe == NULL) 836 return 0; /* allocation failure */ 837 838 /* 839 * Ensure TXE has at least MDPL bytes allocated. This should only be 840 * possible if the MDPL has increased. 841 */ 842 if (!qtx_reserve_txe(qtx, NULL, txe, qtx->mdpl)) 843 return 0; 844 845 if (!was_coalescing) { 846 /* Set addresses in TXE. */ 847 if (pkt->peer != NULL) { 848 if (!BIO_ADDR_copy(&txe->peer, pkt->peer)) 849 return 0; 850 } else { 851 BIO_ADDR_clear(&txe->peer); 852 } 853 854 if (pkt->local != NULL) { 855 if (!BIO_ADDR_copy(&txe->local, pkt->local)) 856 return 0; 857 } else { 858 BIO_ADDR_clear(&txe->local); 859 } 860 } 861 862 ret = qtx_mutate_write(qtx, pkt, txe, enc_level); 863 if (ret == 1) { 864 break; 865 } else if (ret == QTX_FAIL_INSUFFICIENT_LEN) { 866 if (was_coalescing) { 867 /* 868 * We failed due to insufficient length, so end the current 869 * datagram and try again. 870 */ 871 ossl_qtx_finish_dgram(qtx); 872 was_coalescing = 0; 873 } else { 874 /* 875 * We failed due to insufficient length, but we were not 876 * coalescing/started with an empty datagram, so any future 877 * attempt to write this packet must also fail. 878 */ 879 return 0; 880 } 881 } else { 882 return 0; /* other error */ 883 } 884 } 885 886 ++qtx->cons_count; 887 888 /* 889 * Some packet types cannot have another packet come after them. 890 */ 891 if (ossl_quic_pkt_type_must_be_last(pkt->hdr->type)) 892 coalescing = 0; 893 894 if (!coalescing) 895 ossl_qtx_finish_dgram(qtx); 896 897 return 1; 898 } 899 900 /* 901 * Finish any incomplete datagrams for transmission which were flagged for 902 * coalescing. If there is no current coalescing datagram, this is a no-op. 903 */ 904 void ossl_qtx_finish_dgram(OSSL_QTX *qtx) 905 { 906 TXE *txe = qtx->cons; 907 908 if (txe == NULL) 909 return; 910 911 if (txe->data_len == 0) 912 /* 913 * If we did not put anything in the datagram, just move it back to the 914 * free list. 915 */ 916 ossl_list_txe_insert_tail(&qtx->free, txe); 917 else 918 qtx_add_to_pending(qtx, txe); 919 920 qtx->cons = NULL; 921 qtx->cons_count = 0; 922 ++qtx->datagram_count; 923 } 924 925 static void txe_to_msg(TXE *txe, BIO_MSG *msg) 926 { 927 msg->data = txe_data(txe); 928 msg->data_len = txe->data_len; 929 msg->flags = 0; 930 msg->peer 931 = BIO_ADDR_family(&txe->peer) != AF_UNSPEC ? &txe->peer : NULL; 932 msg->local 933 = BIO_ADDR_family(&txe->local) != AF_UNSPEC ? &txe->local : NULL; 934 } 935 936 #define MAX_MSGS_PER_SEND 32 937 938 int ossl_qtx_flush_net(OSSL_QTX *qtx) 939 { 940 BIO_MSG msg[MAX_MSGS_PER_SEND]; 941 size_t wr, i, total_written = 0; 942 TXE *txe; 943 int res; 944 945 if (ossl_list_txe_head(&qtx->pending) == NULL) 946 return QTX_FLUSH_NET_RES_OK; /* Nothing to send. */ 947 948 if (qtx->bio == NULL) 949 return QTX_FLUSH_NET_RES_PERMANENT_FAIL; 950 951 for (;;) { 952 for (txe = ossl_list_txe_head(&qtx->pending), i = 0; 953 txe != NULL && i < OSSL_NELEM(msg); 954 txe = ossl_list_txe_next(txe), ++i) 955 txe_to_msg(txe, &msg[i]); 956 957 if (!i) 958 /* Nothing to send. */ 959 break; 960 961 ERR_set_mark(); 962 res = BIO_sendmmsg(qtx->bio, msg, sizeof(BIO_MSG), i, 0, &wr); 963 if (res && wr == 0) { 964 /* 965 * Treat 0 messages sent as a transient error and just stop for now. 966 */ 967 ERR_clear_last_mark(); 968 break; 969 } else if (!res) { 970 /* 971 * We did not get anything, so further calls will probably not 972 * succeed either. 973 */ 974 if (BIO_err_is_non_fatal(ERR_peek_last_error())) { 975 /* Transient error, just stop for now, clearing the error. */ 976 ERR_pop_to_mark(); 977 break; 978 } else { 979 /* Non-transient error, fail and do not clear the error. */ 980 ERR_clear_last_mark(); 981 return QTX_FLUSH_NET_RES_PERMANENT_FAIL; 982 } 983 } 984 985 ERR_clear_last_mark(); 986 987 /* 988 * Remove everything which was successfully sent from the pending queue. 989 */ 990 for (i = 0; i < wr; ++i) { 991 if (qtx->msg_callback != NULL) 992 qtx->msg_callback(1, OSSL_QUIC1_VERSION, SSL3_RT_QUIC_DATAGRAM, 993 msg[i].data, msg[i].data_len, 994 qtx->msg_callback_ssl, 995 qtx->msg_callback_arg); 996 qtx_pending_to_free(qtx); 997 } 998 999 total_written += wr; 1000 } 1001 1002 return total_written > 0 1003 ? QTX_FLUSH_NET_RES_OK 1004 : QTX_FLUSH_NET_RES_TRANSIENT_FAIL; 1005 } 1006 1007 int ossl_qtx_pop_net(OSSL_QTX *qtx, BIO_MSG *msg) 1008 { 1009 TXE *txe = ossl_list_txe_head(&qtx->pending); 1010 1011 if (txe == NULL) 1012 return 0; 1013 1014 txe_to_msg(txe, msg); 1015 qtx_pending_to_free(qtx); 1016 return 1; 1017 } 1018 1019 void ossl_qtx_set_bio(OSSL_QTX *qtx, BIO *bio) 1020 { 1021 qtx->bio = bio; 1022 } 1023 1024 int ossl_qtx_set_mdpl(OSSL_QTX *qtx, size_t mdpl) 1025 { 1026 if (mdpl < QUIC_MIN_INITIAL_DGRAM_LEN) 1027 return 0; 1028 1029 qtx->mdpl = mdpl; 1030 return 1; 1031 } 1032 1033 size_t ossl_qtx_get_mdpl(OSSL_QTX *qtx) 1034 { 1035 return qtx->mdpl; 1036 } 1037 1038 size_t ossl_qtx_get_queue_len_datagrams(OSSL_QTX *qtx) 1039 { 1040 return qtx->pending_count; 1041 } 1042 1043 size_t ossl_qtx_get_queue_len_bytes(OSSL_QTX *qtx) 1044 { 1045 return qtx->pending_bytes; 1046 } 1047 1048 size_t ossl_qtx_get_cur_dgram_len_bytes(OSSL_QTX *qtx) 1049 { 1050 return qtx->cons != NULL ? qtx->cons->data_len : 0; 1051 } 1052 1053 size_t ossl_qtx_get_unflushed_pkt_count(OSSL_QTX *qtx) 1054 { 1055 return qtx->cons_count; 1056 } 1057 1058 int ossl_qtx_trigger_key_update(OSSL_QTX *qtx) 1059 { 1060 return ossl_qrl_enc_level_set_key_update(&qtx->el_set, 1061 QUIC_ENC_LEVEL_1RTT); 1062 } 1063 1064 uint64_t ossl_qtx_get_cur_epoch_pkt_count(OSSL_QTX *qtx, uint32_t enc_level) 1065 { 1066 OSSL_QRL_ENC_LEVEL *el; 1067 1068 el = ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1); 1069 if (el == NULL) 1070 return UINT64_MAX; 1071 1072 return el->op_count; 1073 } 1074 1075 uint64_t ossl_qtx_get_max_epoch_pkt_count(OSSL_QTX *qtx, uint32_t enc_level) 1076 { 1077 OSSL_QRL_ENC_LEVEL *el; 1078 1079 el = ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1); 1080 if (el == NULL) 1081 return UINT64_MAX; 1082 1083 return ossl_qrl_get_suite_max_pkt(el->suite_id); 1084 } 1085 1086 void ossl_qtx_set_msg_callback(OSSL_QTX *qtx, ossl_msg_cb msg_callback, 1087 SSL *msg_callback_ssl) 1088 { 1089 qtx->msg_callback = msg_callback; 1090 qtx->msg_callback_ssl = msg_callback_ssl; 1091 } 1092 1093 void ossl_qtx_set_msg_callback_arg(OSSL_QTX *qtx, void *msg_callback_arg) 1094 { 1095 qtx->msg_callback_arg = msg_callback_arg; 1096 } 1097 1098 uint64_t ossl_qtx_get_key_epoch(OSSL_QTX *qtx) 1099 { 1100 OSSL_QRL_ENC_LEVEL *el; 1101 1102 el = ossl_qrl_enc_level_set_get(&qtx->el_set, QUIC_ENC_LEVEL_1RTT, 1); 1103 if (el == NULL) 1104 return 0; 1105 1106 return el->key_epoch; 1107 } 1108