Home | History | Annotate | Line # | Download | only in internal
      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