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