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