1 /* 2 * Copyright 2015-2024 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 #ifndef OSSL_INTERNAL_PACKET_H 11 #define OSSL_INTERNAL_PACKET_H 12 #pragma once 13 14 #include <string.h> 15 #include <openssl/bn.h> 16 #include <openssl/buffer.h> 17 #include <openssl/crypto.h> 18 #include <openssl/e_os2.h> 19 20 #include "internal/numbers.h" 21 22 typedef struct { 23 /* Pointer to where we are currently reading from */ 24 const unsigned char *curr; 25 /* Number of bytes remaining */ 26 size_t remaining; 27 } PACKET; 28 29 /* Internal unchecked shorthand; don't use outside this file. */ 30 static ossl_inline void packet_forward(PACKET *pkt, size_t len) 31 { 32 pkt->curr += len; 33 pkt->remaining -= len; 34 } 35 36 /* 37 * Returns the number of bytes remaining to be read in the PACKET 38 */ 39 static ossl_inline size_t PACKET_remaining(const PACKET *pkt) 40 { 41 return pkt->remaining; 42 } 43 44 /* 45 * Returns a pointer to the first byte after the packet data. 46 * Useful for integrating with non-PACKET parsing code. 47 * Specifically, we use PACKET_end() to verify that a d2i_... call 48 * has consumed the entire packet contents. 49 */ 50 static ossl_inline const unsigned char *PACKET_end(const PACKET *pkt) 51 { 52 return pkt->curr + pkt->remaining; 53 } 54 55 /* 56 * Returns a pointer to the PACKET's current position. 57 * For use in non-PACKETized APIs. 58 */ 59 static ossl_inline const unsigned char *PACKET_data(const PACKET *pkt) 60 { 61 return pkt->curr; 62 } 63 64 /* 65 * Initialise a PACKET with |len| bytes held in |buf|. This does not make a 66 * copy of the data so |buf| must be present for the whole time that the PACKET 67 * is being used. 68 */ 69 __owur static ossl_inline int PACKET_buf_init(PACKET *pkt, 70 const unsigned char *buf, 71 size_t len) 72 { 73 /* Sanity check for negative values. */ 74 if (len > (size_t)(SIZE_MAX / 2)) 75 return 0; 76 77 pkt->curr = buf; 78 pkt->remaining = len; 79 return 1; 80 } 81 82 /* Initialize a PACKET to hold zero bytes. */ 83 static ossl_inline void PACKET_null_init(PACKET *pkt) 84 { 85 pkt->curr = NULL; 86 pkt->remaining = 0; 87 } 88 89 /* 90 * Returns 1 if the packet has length |num| and its contents equal the |num| 91 * bytes read from |ptr|. Returns 0 otherwise (lengths or contents not equal). 92 * If lengths are equal, performs the comparison in constant time. 93 */ 94 __owur static ossl_inline int PACKET_equal(const PACKET *pkt, const void *ptr, 95 size_t num) 96 { 97 if (PACKET_remaining(pkt) != num) 98 return 0; 99 return CRYPTO_memcmp(pkt->curr, ptr, num) == 0; 100 } 101 102 /* 103 * Peek ahead and initialize |subpkt| with the next |len| bytes read from |pkt|. 104 * Data is not copied: the |subpkt| packet will share its underlying buffer with 105 * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. 106 */ 107 __owur static ossl_inline int PACKET_peek_sub_packet(const PACKET *pkt, 108 PACKET *subpkt, size_t len) 109 { 110 if (PACKET_remaining(pkt) < len) 111 return 0; 112 113 return PACKET_buf_init(subpkt, pkt->curr, len); 114 } 115 116 /* 117 * Initialize |subpkt| with the next |len| bytes read from |pkt|. Data is not 118 * copied: the |subpkt| packet will share its underlying buffer with the 119 * original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. 120 */ 121 __owur static ossl_inline int PACKET_get_sub_packet(PACKET *pkt, 122 PACKET *subpkt, size_t len) 123 { 124 if (!PACKET_peek_sub_packet(pkt, subpkt, len)) 125 return 0; 126 127 packet_forward(pkt, len); 128 129 return 1; 130 } 131 132 /* 133 * Peek ahead at 2 bytes in network order from |pkt| and store the value in 134 * |*data| 135 */ 136 __owur static ossl_inline int PACKET_peek_net_2(const PACKET *pkt, 137 unsigned int *data) 138 { 139 if (PACKET_remaining(pkt) < 2) 140 return 0; 141 142 *data = ((unsigned int)(*pkt->curr)) << 8; 143 *data |= *(pkt->curr + 1); 144 145 return 1; 146 } 147 148 /* Equivalent of n2s */ 149 /* Get 2 bytes in network order from |pkt| and store the value in |*data| */ 150 __owur static ossl_inline int PACKET_get_net_2(PACKET *pkt, unsigned int *data) 151 { 152 if (!PACKET_peek_net_2(pkt, data)) 153 return 0; 154 155 packet_forward(pkt, 2); 156 157 return 1; 158 } 159 160 /* Same as PACKET_get_net_2() but for a size_t */ 161 __owur static ossl_inline int PACKET_get_net_2_len(PACKET *pkt, size_t *data) 162 { 163 unsigned int i; 164 int ret = PACKET_get_net_2(pkt, &i); 165 166 if (ret) 167 *data = (size_t)i; 168 169 return ret; 170 } 171 172 /* 173 * Peek ahead at 3 bytes in network order from |pkt| and store the value in 174 * |*data| 175 */ 176 __owur static ossl_inline int PACKET_peek_net_3(const PACKET *pkt, 177 unsigned long *data) 178 { 179 if (PACKET_remaining(pkt) < 3) 180 return 0; 181 182 *data = ((unsigned long)(*pkt->curr)) << 16; 183 *data |= ((unsigned long)(*(pkt->curr + 1))) << 8; 184 *data |= *(pkt->curr + 2); 185 186 return 1; 187 } 188 189 /* Equivalent of n2l3 */ 190 /* Get 3 bytes in network order from |pkt| and store the value in |*data| */ 191 __owur static ossl_inline int PACKET_get_net_3(PACKET *pkt, unsigned long *data) 192 { 193 if (!PACKET_peek_net_3(pkt, data)) 194 return 0; 195 196 packet_forward(pkt, 3); 197 198 return 1; 199 } 200 201 /* Same as PACKET_get_net_3() but for a size_t */ 202 __owur static ossl_inline int PACKET_get_net_3_len(PACKET *pkt, size_t *data) 203 { 204 unsigned long i; 205 int ret = PACKET_get_net_3(pkt, &i); 206 207 if (ret) 208 *data = (size_t)i; 209 210 return ret; 211 } 212 213 /* 214 * Peek ahead at 4 bytes in network order from |pkt| and store the value in 215 * |*data| 216 */ 217 __owur static ossl_inline int PACKET_peek_net_4(const PACKET *pkt, 218 unsigned long *data) 219 { 220 if (PACKET_remaining(pkt) < 4) 221 return 0; 222 223 *data = ((unsigned long)(*pkt->curr)) << 24; 224 *data |= ((unsigned long)(*(pkt->curr + 1))) << 16; 225 *data |= ((unsigned long)(*(pkt->curr + 2))) << 8; 226 *data |= *(pkt->curr + 3); 227 228 return 1; 229 } 230 231 /* 232 * Peek ahead at 8 bytes in network order from |pkt| and store the value in 233 * |*data| 234 */ 235 __owur static ossl_inline int PACKET_peek_net_8(const PACKET *pkt, 236 uint64_t *data) 237 { 238 if (PACKET_remaining(pkt) < 8) 239 return 0; 240 241 *data = ((uint64_t)(*pkt->curr)) << 56; 242 *data |= ((uint64_t)(*(pkt->curr + 1))) << 48; 243 *data |= ((uint64_t)(*(pkt->curr + 2))) << 40; 244 *data |= ((uint64_t)(*(pkt->curr + 3))) << 32; 245 *data |= ((uint64_t)(*(pkt->curr + 4))) << 24; 246 *data |= ((uint64_t)(*(pkt->curr + 5))) << 16; 247 *data |= ((uint64_t)(*(pkt->curr + 6))) << 8; 248 *data |= *(pkt->curr + 7); 249 250 return 1; 251 } 252 253 /* Equivalent of n2l */ 254 /* Get 4 bytes in network order from |pkt| and store the value in |*data| */ 255 __owur static ossl_inline int PACKET_get_net_4(PACKET *pkt, unsigned long *data) 256 { 257 if (!PACKET_peek_net_4(pkt, data)) 258 return 0; 259 260 packet_forward(pkt, 4); 261 262 return 1; 263 } 264 265 /* Same as PACKET_get_net_4() but for a size_t */ 266 __owur static ossl_inline int PACKET_get_net_4_len(PACKET *pkt, size_t *data) 267 { 268 unsigned long i; 269 int ret = PACKET_get_net_4(pkt, &i); 270 271 if (ret) 272 *data = (size_t)i; 273 274 return ret; 275 } 276 277 /* Get 8 bytes in network order from |pkt| and store the value in |*data| */ 278 __owur static ossl_inline int PACKET_get_net_8(PACKET *pkt, uint64_t *data) 279 { 280 if (!PACKET_peek_net_8(pkt, data)) 281 return 0; 282 283 packet_forward(pkt, 8); 284 285 return 1; 286 } 287 288 /* Peek ahead at 1 byte from |pkt| and store the value in |*data| */ 289 __owur static ossl_inline int PACKET_peek_1(const PACKET *pkt, 290 unsigned int *data) 291 { 292 if (!PACKET_remaining(pkt)) 293 return 0; 294 295 *data = *pkt->curr; 296 297 return 1; 298 } 299 300 /* Get 1 byte from |pkt| and store the value in |*data| */ 301 __owur static ossl_inline int PACKET_get_1(PACKET *pkt, unsigned int *data) 302 { 303 if (!PACKET_peek_1(pkt, data)) 304 return 0; 305 306 packet_forward(pkt, 1); 307 308 return 1; 309 } 310 311 /* Same as PACKET_get_1() but for a size_t */ 312 __owur static ossl_inline int PACKET_get_1_len(PACKET *pkt, size_t *data) 313 { 314 unsigned int i; 315 int ret = PACKET_get_1(pkt, &i); 316 317 if (ret) 318 *data = (size_t)i; 319 320 return ret; 321 } 322 323 /* 324 * Peek ahead at 4 bytes in reverse network order from |pkt| and store the value 325 * in |*data| 326 */ 327 __owur static ossl_inline int PACKET_peek_4(const PACKET *pkt, 328 unsigned long *data) 329 { 330 if (PACKET_remaining(pkt) < 4) 331 return 0; 332 333 *data = *pkt->curr; 334 *data |= ((unsigned long)(*(pkt->curr + 1))) << 8; 335 *data |= ((unsigned long)(*(pkt->curr + 2))) << 16; 336 *data |= ((unsigned long)(*(pkt->curr + 3))) << 24; 337 338 return 1; 339 } 340 341 /* Equivalent of c2l */ 342 /* 343 * Get 4 bytes in reverse network order from |pkt| and store the value in 344 * |*data| 345 */ 346 __owur static ossl_inline int PACKET_get_4(PACKET *pkt, unsigned long *data) 347 { 348 if (!PACKET_peek_4(pkt, data)) 349 return 0; 350 351 packet_forward(pkt, 4); 352 353 return 1; 354 } 355 356 /* 357 * Peek ahead at |len| bytes from the |pkt| and store a pointer to them in 358 * |*data|. This just points at the underlying buffer that |pkt| is using. The 359 * caller should not free this data directly (it will be freed when the 360 * underlying buffer gets freed 361 */ 362 __owur static ossl_inline int PACKET_peek_bytes(const PACKET *pkt, 363 const unsigned char **data, 364 size_t len) 365 { 366 if (PACKET_remaining(pkt) < len) 367 return 0; 368 369 *data = pkt->curr; 370 371 return 1; 372 } 373 374 /* 375 * Read |len| bytes from the |pkt| and store a pointer to them in |*data|. This 376 * just points at the underlying buffer that |pkt| is using. The caller should 377 * not free this data directly (it will be freed when the underlying buffer gets 378 * freed 379 */ 380 __owur static ossl_inline int PACKET_get_bytes(PACKET *pkt, 381 const unsigned char **data, 382 size_t len) 383 { 384 if (!PACKET_peek_bytes(pkt, data, len)) 385 return 0; 386 387 packet_forward(pkt, len); 388 389 return 1; 390 } 391 392 /* Peek ahead at |len| bytes from |pkt| and copy them to |data| */ 393 __owur static ossl_inline int PACKET_peek_copy_bytes(const PACKET *pkt, 394 unsigned char *data, 395 size_t len) 396 { 397 if (PACKET_remaining(pkt) < len) 398 return 0; 399 400 memcpy(data, pkt->curr, len); 401 402 return 1; 403 } 404 405 /* 406 * Read |len| bytes from |pkt| and copy them to |data|. 407 * The caller is responsible for ensuring that |data| can hold |len| bytes. 408 */ 409 __owur static ossl_inline int PACKET_copy_bytes(PACKET *pkt, 410 unsigned char *data, size_t len) 411 { 412 if (!PACKET_peek_copy_bytes(pkt, data, len)) 413 return 0; 414 415 packet_forward(pkt, len); 416 417 return 1; 418 } 419 420 /* 421 * Copy packet data to |dest|, and set |len| to the number of copied bytes. 422 * If the packet has more than |dest_len| bytes, nothing is copied. 423 * Returns 1 if the packet data fits in |dest_len| bytes, 0 otherwise. 424 * Does not forward PACKET position (because it is typically the last thing 425 * done with a given PACKET). 426 */ 427 __owur static ossl_inline int PACKET_copy_all(const PACKET *pkt, 428 unsigned char *dest, 429 size_t dest_len, size_t *len) 430 { 431 if (PACKET_remaining(pkt) > dest_len) { 432 *len = 0; 433 return 0; 434 } 435 *len = pkt->remaining; 436 memcpy(dest, pkt->curr, pkt->remaining); 437 return 1; 438 } 439 440 /* 441 * Copy |pkt| bytes to a newly allocated buffer and store a pointer to the 442 * result in |*data|, and the length in |len|. 443 * If |*data| is not NULL, the old data is OPENSSL_free'd. 444 * If the packet is empty, or malloc fails, |*data| will be set to NULL. 445 * Returns 1 if the malloc succeeds and 0 otherwise. 446 * Does not forward PACKET position (because it is typically the last thing 447 * done with a given PACKET). 448 */ 449 __owur static ossl_inline int PACKET_memdup(const PACKET *pkt, 450 unsigned char **data, size_t *len) 451 { 452 size_t length; 453 454 OPENSSL_free(*data); 455 *data = NULL; 456 *len = 0; 457 458 length = PACKET_remaining(pkt); 459 460 if (length == 0) 461 return 1; 462 463 *data = OPENSSL_memdup(pkt->curr, length); 464 if (*data == NULL) 465 return 0; 466 467 *len = length; 468 return 1; 469 } 470 471 /* 472 * Read a C string from |pkt| and copy to a newly allocated, NUL-terminated 473 * buffer. Store a pointer to the result in |*data|. 474 * If |*data| is not NULL, the old data is OPENSSL_free'd. 475 * If the data in |pkt| does not contain a NUL-byte, the entire data is 476 * copied and NUL-terminated. 477 * Returns 1 if the malloc succeeds and 0 otherwise. 478 * Does not forward PACKET position (because it is typically the last thing done 479 * with a given PACKET). 480 */ 481 __owur static ossl_inline int PACKET_strndup(const PACKET *pkt, char **data) 482 { 483 OPENSSL_free(*data); 484 485 /* This will succeed on an empty packet, unless pkt->curr == NULL. */ 486 *data = OPENSSL_strndup((const char *)pkt->curr, PACKET_remaining(pkt)); 487 return (*data != NULL); 488 } 489 490 /* Returns 1 if |pkt| contains at least one 0-byte, 0 otherwise. */ 491 static ossl_inline int PACKET_contains_zero_byte(const PACKET *pkt) 492 { 493 return memchr(pkt->curr, 0, pkt->remaining) != NULL; 494 } 495 496 /* Move the current reading position forward |len| bytes */ 497 __owur static ossl_inline int PACKET_forward(PACKET *pkt, size_t len) 498 { 499 if (PACKET_remaining(pkt) < len) 500 return 0; 501 502 packet_forward(pkt, len); 503 504 return 1; 505 } 506 507 /* 508 * Reads a variable-length vector prefixed with a one-byte length, and stores 509 * the contents in |subpkt|. |pkt| can equal |subpkt|. 510 * Data is not copied: the |subpkt| packet will share its underlying buffer with 511 * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. 512 * Upon failure, the original |pkt| and |subpkt| are not modified. 513 */ 514 __owur static ossl_inline int PACKET_get_length_prefixed_1(PACKET *pkt, 515 PACKET *subpkt) 516 { 517 unsigned int length; 518 const unsigned char *data; 519 PACKET tmp = *pkt; 520 if (!PACKET_get_1(&tmp, &length) || !PACKET_get_bytes(&tmp, &data, (size_t)length)) { 521 return 0; 522 } 523 524 *pkt = tmp; 525 subpkt->curr = data; 526 subpkt->remaining = length; 527 528 return 1; 529 } 530 531 /* 532 * Like PACKET_get_length_prefixed_1, but additionally, fails when there are 533 * leftover bytes in |pkt|. 534 */ 535 __owur static ossl_inline int PACKET_as_length_prefixed_1(PACKET *pkt, 536 PACKET *subpkt) 537 { 538 unsigned int length; 539 const unsigned char *data; 540 PACKET tmp = *pkt; 541 if (!PACKET_get_1(&tmp, &length) || !PACKET_get_bytes(&tmp, &data, (size_t)length) || PACKET_remaining(&tmp) != 0) { 542 return 0; 543 } 544 545 *pkt = tmp; 546 subpkt->curr = data; 547 subpkt->remaining = length; 548 549 return 1; 550 } 551 552 /* 553 * Reads a variable-length vector prefixed with a two-byte length, and stores 554 * the contents in |subpkt|. |pkt| can equal |subpkt|. 555 * Data is not copied: the |subpkt| packet will share its underlying buffer with 556 * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. 557 * Upon failure, the original |pkt| and |subpkt| are not modified. 558 */ 559 __owur static ossl_inline int PACKET_get_length_prefixed_2(PACKET *pkt, 560 PACKET *subpkt) 561 { 562 unsigned int length; 563 const unsigned char *data; 564 PACKET tmp = *pkt; 565 566 if (!PACKET_get_net_2(&tmp, &length) || !PACKET_get_bytes(&tmp, &data, (size_t)length)) { 567 return 0; 568 } 569 570 *pkt = tmp; 571 subpkt->curr = data; 572 subpkt->remaining = length; 573 574 return 1; 575 } 576 577 /* 578 * Like PACKET_get_length_prefixed_2, but additionally, fails when there are 579 * leftover bytes in |pkt|. 580 */ 581 __owur static ossl_inline int PACKET_as_length_prefixed_2(PACKET *pkt, 582 PACKET *subpkt) 583 { 584 unsigned int length; 585 const unsigned char *data; 586 PACKET tmp = *pkt; 587 588 if (!PACKET_get_net_2(&tmp, &length) || !PACKET_get_bytes(&tmp, &data, (size_t)length) || PACKET_remaining(&tmp) != 0) { 589 return 0; 590 } 591 592 *pkt = tmp; 593 subpkt->curr = data; 594 subpkt->remaining = length; 595 596 return 1; 597 } 598 599 /* 600 * Reads a variable-length vector prefixed with a three-byte length, and stores 601 * the contents in |subpkt|. |pkt| can equal |subpkt|. 602 * Data is not copied: the |subpkt| packet will share its underlying buffer with 603 * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. 604 * Upon failure, the original |pkt| and |subpkt| are not modified. 605 */ 606 __owur static ossl_inline int PACKET_get_length_prefixed_3(PACKET *pkt, 607 PACKET *subpkt) 608 { 609 unsigned long length; 610 const unsigned char *data; 611 PACKET tmp = *pkt; 612 if (!PACKET_get_net_3(&tmp, &length) || !PACKET_get_bytes(&tmp, &data, (size_t)length)) { 613 return 0; 614 } 615 616 *pkt = tmp; 617 subpkt->curr = data; 618 subpkt->remaining = length; 619 620 return 1; 621 } 622 623 /* Writable packets */ 624 625 typedef struct wpacket_sub WPACKET_SUB; 626 struct wpacket_sub { 627 /* The parent WPACKET_SUB if we have one or NULL otherwise */ 628 WPACKET_SUB *parent; 629 630 /* 631 * Offset into the buffer where the length of this WPACKET goes. We use an 632 * offset in case the buffer grows and gets reallocated. 633 */ 634 size_t packet_len; 635 636 /* Number of bytes in the packet_len or 0 if we don't write the length */ 637 size_t lenbytes; 638 639 /* Number of bytes written to the buf prior to this packet starting */ 640 size_t pwritten; 641 642 /* Flags for this sub-packet */ 643 unsigned int flags; 644 }; 645 646 typedef struct wpacket_st WPACKET; 647 struct wpacket_st { 648 /* The buffer where we store the output data */ 649 BUF_MEM *buf; 650 651 /* Fixed sized buffer which can be used as an alternative to buf */ 652 unsigned char *staticbuf; 653 654 /* 655 * Offset into the buffer where we are currently writing. We use an offset 656 * in case the buffer grows and gets reallocated. 657 */ 658 size_t curr; 659 660 /* Number of bytes written so far */ 661 size_t written; 662 663 /* Maximum number of bytes we will allow to be written to this WPACKET */ 664 size_t maxsize; 665 666 /* Our sub-packets (always at least one if not finished) */ 667 WPACKET_SUB *subs; 668 669 /* Writing from the end first? */ 670 unsigned int endfirst : 1; 671 }; 672 673 /* Flags */ 674 675 /* Default */ 676 #define WPACKET_FLAGS_NONE 0 677 678 /* Error on WPACKET_close() if no data written to the WPACKET */ 679 #define WPACKET_FLAGS_NON_ZERO_LENGTH 1 680 681 /* 682 * Abandon all changes on WPACKET_close() if no data written to the WPACKET, 683 * i.e. this does not write out a zero packet length 684 */ 685 #define WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH 2 686 687 /* QUIC variable-length integer length prefix */ 688 #define WPACKET_FLAGS_QUIC_VLINT 4 689 690 /* 691 * Initialise a WPACKET with the buffer in |buf|. The buffer must exist 692 * for the whole time that the WPACKET is being used. Additionally |lenbytes| of 693 * data is preallocated at the start of the buffer to store the length of the 694 * WPACKET once we know it. 695 */ 696 int WPACKET_init_len(WPACKET *pkt, BUF_MEM *buf, size_t lenbytes); 697 698 /* 699 * Same as WPACKET_init_len except there is no preallocation of the WPACKET 700 * length. 701 */ 702 int WPACKET_init(WPACKET *pkt, BUF_MEM *buf); 703 704 /* 705 * Same as WPACKET_init_len except there is no underlying buffer. No data is 706 * ever actually written. We just keep track of how much data would have been 707 * written if a buffer was there. 708 */ 709 int WPACKET_init_null(WPACKET *pkt, size_t lenbytes); 710 711 /* 712 * Same as WPACKET_init_null except we set the WPACKET to assume DER length 713 * encoding for sub-packets. 714 */ 715 int WPACKET_init_null_der(WPACKET *pkt); 716 717 /* 718 * Same as WPACKET_init_len except we do not use a growable BUF_MEM structure. 719 * A fixed buffer of memory |buf| of size |len| is used instead. A failure will 720 * occur if you attempt to write beyond the end of the buffer 721 */ 722 int WPACKET_init_static_len(WPACKET *pkt, unsigned char *buf, size_t len, 723 size_t lenbytes); 724 725 /* 726 * Same as WPACKET_init_static_len except lenbytes is always 0, and we set the 727 * WPACKET to write to the end of the buffer moving towards the start and use 728 * DER length encoding for sub-packets. 729 */ 730 int WPACKET_init_der(WPACKET *pkt, unsigned char *buf, size_t len); 731 732 /* 733 * Set the flags to be applied to the current sub-packet 734 */ 735 int WPACKET_set_flags(WPACKET *pkt, unsigned int flags); 736 737 /* 738 * Closes the most recent sub-packet. It also writes out the length of the 739 * packet to the required location (normally the start of the WPACKET) if 740 * appropriate. The top level WPACKET should be closed using WPACKET_finish() 741 * instead of this function. 742 */ 743 int WPACKET_close(WPACKET *pkt); 744 745 /* 746 * The same as WPACKET_close() but only for the top most WPACKET. Additionally 747 * frees memory resources for this WPACKET. 748 */ 749 int WPACKET_finish(WPACKET *pkt); 750 751 /* 752 * Iterate through all the sub-packets and write out their lengths as if they 753 * were being closed. The lengths will be overwritten with the final lengths 754 * when the sub-packets are eventually closed (which may be different if more 755 * data is added to the WPACKET). This function fails if a sub-packet is of 0 756 * length and WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH is set. 757 */ 758 int WPACKET_fill_lengths(WPACKET *pkt); 759 760 /* 761 * Initialise a new sub-packet. Additionally |lenbytes| of data is preallocated 762 * at the start of the sub-packet to store its length once we know it. Don't 763 * call this directly. Use the convenience macros below instead. 764 */ 765 int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes); 766 767 /* 768 * Convenience macros for calling WPACKET_start_sub_packet_len with different 769 * lengths 770 */ 771 #define WPACKET_start_sub_packet_u8(pkt) \ 772 WPACKET_start_sub_packet_len__((pkt), 1) 773 #define WPACKET_start_sub_packet_u16(pkt) \ 774 WPACKET_start_sub_packet_len__((pkt), 2) 775 #define WPACKET_start_sub_packet_u24(pkt) \ 776 WPACKET_start_sub_packet_len__((pkt), 3) 777 #define WPACKET_start_sub_packet_u32(pkt) \ 778 WPACKET_start_sub_packet_len__((pkt), 4) 779 780 /* 781 * Same as WPACKET_start_sub_packet_len__() except no bytes are pre-allocated 782 * for the sub-packet length. 783 */ 784 int WPACKET_start_sub_packet(WPACKET *pkt); 785 786 /* 787 * Allocate bytes in the WPACKET for the output. This reserves the bytes 788 * and counts them as "written", but doesn't actually do the writing. A pointer 789 * to the allocated bytes is stored in |*allocbytes|. |allocbytes| may be NULL. 790 * WARNING: the allocated bytes must be filled in immediately, without further 791 * WPACKET_* calls. If not then the underlying buffer may be realloc'd and 792 * change its location. 793 */ 794 int WPACKET_allocate_bytes(WPACKET *pkt, size_t len, 795 unsigned char **allocbytes); 796 797 /* 798 * The same as WPACKET_allocate_bytes() except additionally a new sub-packet is 799 * started for the allocated bytes, and then closed immediately afterwards. The 800 * number of length bytes for the sub-packet is in |lenbytes|. Don't call this 801 * directly. Use the convenience macros below instead. 802 */ 803 int WPACKET_sub_allocate_bytes__(WPACKET *pkt, size_t len, 804 unsigned char **allocbytes, size_t lenbytes); 805 806 /* 807 * Convenience macros for calling WPACKET_sub_allocate_bytes with different 808 * lengths 809 */ 810 #define WPACKET_sub_allocate_bytes_u8(pkt, len, bytes) \ 811 WPACKET_sub_allocate_bytes__((pkt), (len), (bytes), 1) 812 #define WPACKET_sub_allocate_bytes_u16(pkt, len, bytes) \ 813 WPACKET_sub_allocate_bytes__((pkt), (len), (bytes), 2) 814 #define WPACKET_sub_allocate_bytes_u24(pkt, len, bytes) \ 815 WPACKET_sub_allocate_bytes__((pkt), (len), (bytes), 3) 816 #define WPACKET_sub_allocate_bytes_u32(pkt, len, bytes) \ 817 WPACKET_sub_allocate_bytes__((pkt), (len), (bytes), 4) 818 819 /* 820 * The same as WPACKET_allocate_bytes() except the reserved bytes are not 821 * actually counted as written. Typically this will be for when we don't know 822 * how big arbitrary data is going to be up front, but we do know what the 823 * maximum size will be. If this function is used, then it should be immediately 824 * followed by a WPACKET_allocate_bytes() call before any other WPACKET 825 * functions are called (unless the write to the allocated bytes is abandoned). 826 * 827 * For example: If we are generating a signature, then the size of that 828 * signature may not be known in advance. We can use WPACKET_reserve_bytes() to 829 * handle this: 830 * 831 * if (!WPACKET_sub_reserve_bytes_u16(&pkt, EVP_PKEY_get_size(pkey), &sigbytes1) 832 * || EVP_SignFinal(md_ctx, sigbytes1, &siglen, pkey) <= 0 833 * || !WPACKET_sub_allocate_bytes_u16(&pkt, siglen, &sigbytes2) 834 * || sigbytes1 != sigbytes2) 835 * goto err; 836 */ 837 int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes); 838 839 /* 840 * The "reserve_bytes" equivalent of WPACKET_sub_allocate_bytes__() 841 */ 842 int WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len, 843 unsigned char **allocbytes, size_t lenbytes); 844 845 /* 846 * Convenience macros for WPACKET_sub_reserve_bytes with different lengths 847 */ 848 #define WPACKET_sub_reserve_bytes_u8(pkt, len, bytes) \ 849 WPACKET_reserve_bytes__((pkt), (len), (bytes), 1) 850 #define WPACKET_sub_reserve_bytes_u16(pkt, len, bytes) \ 851 WPACKET_sub_reserve_bytes__((pkt), (len), (bytes), 2) 852 #define WPACKET_sub_reserve_bytes_u24(pkt, len, bytes) \ 853 WPACKET_sub_reserve_bytes__((pkt), (len), (bytes), 3) 854 #define WPACKET_sub_reserve_bytes_u32(pkt, len, bytes) \ 855 WPACKET_sub_reserve_bytes__((pkt), (len), (bytes), 4) 856 857 /* 858 * Write the value stored in |val| into the WPACKET. The value will consume 859 * |bytes| amount of storage. An error will occur if |val| cannot be 860 * accommodated in |bytes| storage, e.g. attempting to write the value 256 into 861 * 1 byte will fail. Don't call this directly. Use the convenience macros below 862 * instead. 863 */ 864 int WPACKET_put_bytes__(WPACKET *pkt, uint64_t val, size_t bytes); 865 866 /* 867 * Convenience macros for calling WPACKET_put_bytes with different 868 * lengths 869 */ 870 #define WPACKET_put_bytes_u8(pkt, val) \ 871 WPACKET_put_bytes__((pkt), (val), 1) 872 #define WPACKET_put_bytes_u16(pkt, val) \ 873 WPACKET_put_bytes__((pkt), (val), 2) 874 #define WPACKET_put_bytes_u24(pkt, val) \ 875 WPACKET_put_bytes__((pkt), (val), 3) 876 #define WPACKET_put_bytes_u32(pkt, val) \ 877 WPACKET_put_bytes__((pkt), (val), 4) 878 #define WPACKET_put_bytes_u64(pkt, val) \ 879 WPACKET_put_bytes__((pkt), (val), 8) 880 881 /* Set a maximum size that we will not allow the WPACKET to grow beyond */ 882 int WPACKET_set_max_size(WPACKET *pkt, size_t maxsize); 883 884 /* Copy |len| bytes of data from |*src| into the WPACKET. */ 885 int WPACKET_memcpy(WPACKET *pkt, const void *src, size_t len); 886 887 /* Set |len| bytes of data to |ch| into the WPACKET. */ 888 int WPACKET_memset(WPACKET *pkt, int ch, size_t len); 889 890 /* 891 * Copy |len| bytes of data from |*src| into the WPACKET and prefix with its 892 * length (consuming |lenbytes| of data for the length). Don't call this 893 * directly. Use the convenience macros below instead. 894 */ 895 int WPACKET_sub_memcpy__(WPACKET *pkt, const void *src, size_t len, 896 size_t lenbytes); 897 898 /* Convenience macros for calling WPACKET_sub_memcpy with different lengths */ 899 #define WPACKET_sub_memcpy_u8(pkt, src, len) \ 900 WPACKET_sub_memcpy__((pkt), (src), (len), 1) 901 #define WPACKET_sub_memcpy_u16(pkt, src, len) \ 902 WPACKET_sub_memcpy__((pkt), (src), (len), 2) 903 #define WPACKET_sub_memcpy_u24(pkt, src, len) \ 904 WPACKET_sub_memcpy__((pkt), (src), (len), 3) 905 #define WPACKET_sub_memcpy_u32(pkt, src, len) \ 906 WPACKET_sub_memcpy__((pkt), (src), (len), 4) 907 908 /* 909 * Return the total number of bytes written so far to the underlying buffer 910 * including any storage allocated for length bytes 911 */ 912 int WPACKET_get_total_written(WPACKET *pkt, size_t *written); 913 914 /* 915 * Returns the length of the current sub-packet. This excludes any bytes 916 * allocated for the length itself. 917 */ 918 int WPACKET_get_length(WPACKET *pkt, size_t *len); 919 920 /* 921 * Returns a pointer to the current write location, but does not allocate any 922 * bytes. 923 */ 924 unsigned char *WPACKET_get_curr(WPACKET *pkt); 925 926 /* Returns true if the underlying buffer is actually NULL */ 927 int WPACKET_is_null_buf(WPACKET *pkt); 928 929 /* Release resources in a WPACKET if a failure has occurred. */ 930 void WPACKET_cleanup(WPACKET *pkt); 931 932 #endif /* OSSL_INTERNAL_PACKET_H */ 933