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#include "internal/cryptlib.h" 11e1051a39Sopenharmony_ci#include "internal/packet.h" 12e1051a39Sopenharmony_ci#include <openssl/err.h> 13e1051a39Sopenharmony_ci 14e1051a39Sopenharmony_ci#define DEFAULT_BUF_SIZE 256 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ciint WPACKET_allocate_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes) 17e1051a39Sopenharmony_ci{ 18e1051a39Sopenharmony_ci if (!WPACKET_reserve_bytes(pkt, len, allocbytes)) 19e1051a39Sopenharmony_ci return 0; 20e1051a39Sopenharmony_ci 21e1051a39Sopenharmony_ci pkt->written += len; 22e1051a39Sopenharmony_ci pkt->curr += len; 23e1051a39Sopenharmony_ci return 1; 24e1051a39Sopenharmony_ci} 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_ciint WPACKET_sub_allocate_bytes__(WPACKET *pkt, size_t len, 27e1051a39Sopenharmony_ci unsigned char **allocbytes, size_t lenbytes) 28e1051a39Sopenharmony_ci{ 29e1051a39Sopenharmony_ci if (!WPACKET_start_sub_packet_len__(pkt, lenbytes) 30e1051a39Sopenharmony_ci || !WPACKET_allocate_bytes(pkt, len, allocbytes) 31e1051a39Sopenharmony_ci || !WPACKET_close(pkt)) 32e1051a39Sopenharmony_ci return 0; 33e1051a39Sopenharmony_ci 34e1051a39Sopenharmony_ci return 1; 35e1051a39Sopenharmony_ci} 36e1051a39Sopenharmony_ci 37e1051a39Sopenharmony_ci#define GETBUF(p) (((p)->staticbuf != NULL) \ 38e1051a39Sopenharmony_ci ? (p)->staticbuf \ 39e1051a39Sopenharmony_ci : ((p)->buf != NULL \ 40e1051a39Sopenharmony_ci ? (unsigned char *)(p)->buf->data \ 41e1051a39Sopenharmony_ci : NULL)) 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_ciint WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes) 44e1051a39Sopenharmony_ci{ 45e1051a39Sopenharmony_ci /* Internal API, so should not fail */ 46e1051a39Sopenharmony_ci if (!ossl_assert(pkt->subs != NULL && len != 0)) 47e1051a39Sopenharmony_ci return 0; 48e1051a39Sopenharmony_ci 49e1051a39Sopenharmony_ci if (pkt->maxsize - pkt->written < len) 50e1051a39Sopenharmony_ci return 0; 51e1051a39Sopenharmony_ci 52e1051a39Sopenharmony_ci if (pkt->buf != NULL && (pkt->buf->length - pkt->written < len)) { 53e1051a39Sopenharmony_ci size_t newlen; 54e1051a39Sopenharmony_ci size_t reflen; 55e1051a39Sopenharmony_ci 56e1051a39Sopenharmony_ci reflen = (len > pkt->buf->length) ? len : pkt->buf->length; 57e1051a39Sopenharmony_ci 58e1051a39Sopenharmony_ci if (reflen > SIZE_MAX / 2) { 59e1051a39Sopenharmony_ci newlen = SIZE_MAX; 60e1051a39Sopenharmony_ci } else { 61e1051a39Sopenharmony_ci newlen = reflen * 2; 62e1051a39Sopenharmony_ci if (newlen < DEFAULT_BUF_SIZE) 63e1051a39Sopenharmony_ci newlen = DEFAULT_BUF_SIZE; 64e1051a39Sopenharmony_ci } 65e1051a39Sopenharmony_ci if (BUF_MEM_grow(pkt->buf, newlen) == 0) 66e1051a39Sopenharmony_ci return 0; 67e1051a39Sopenharmony_ci } 68e1051a39Sopenharmony_ci if (allocbytes != NULL) { 69e1051a39Sopenharmony_ci *allocbytes = WPACKET_get_curr(pkt); 70e1051a39Sopenharmony_ci if (pkt->endfirst && *allocbytes != NULL) 71e1051a39Sopenharmony_ci *allocbytes -= len; 72e1051a39Sopenharmony_ci } 73e1051a39Sopenharmony_ci 74e1051a39Sopenharmony_ci return 1; 75e1051a39Sopenharmony_ci} 76e1051a39Sopenharmony_ci 77e1051a39Sopenharmony_ciint WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len, 78e1051a39Sopenharmony_ci unsigned char **allocbytes, size_t lenbytes) 79e1051a39Sopenharmony_ci{ 80e1051a39Sopenharmony_ci if (pkt->endfirst && lenbytes > 0) 81e1051a39Sopenharmony_ci return 0; 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_ci if (!WPACKET_reserve_bytes(pkt, lenbytes + len, allocbytes)) 84e1051a39Sopenharmony_ci return 0; 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci if (*allocbytes != NULL) 87e1051a39Sopenharmony_ci *allocbytes += lenbytes; 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ci return 1; 90e1051a39Sopenharmony_ci} 91e1051a39Sopenharmony_ci 92e1051a39Sopenharmony_cistatic size_t maxmaxsize(size_t lenbytes) 93e1051a39Sopenharmony_ci{ 94e1051a39Sopenharmony_ci if (lenbytes >= sizeof(size_t) || lenbytes == 0) 95e1051a39Sopenharmony_ci return SIZE_MAX; 96e1051a39Sopenharmony_ci 97e1051a39Sopenharmony_ci return ((size_t)1 << (lenbytes * 8)) - 1 + lenbytes; 98e1051a39Sopenharmony_ci} 99e1051a39Sopenharmony_ci 100e1051a39Sopenharmony_cistatic int wpacket_intern_init_len(WPACKET *pkt, size_t lenbytes) 101e1051a39Sopenharmony_ci{ 102e1051a39Sopenharmony_ci unsigned char *lenchars; 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ci pkt->curr = 0; 105e1051a39Sopenharmony_ci pkt->written = 0; 106e1051a39Sopenharmony_ci 107e1051a39Sopenharmony_ci if ((pkt->subs = OPENSSL_zalloc(sizeof(*pkt->subs))) == NULL) { 108e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 109e1051a39Sopenharmony_ci return 0; 110e1051a39Sopenharmony_ci } 111e1051a39Sopenharmony_ci 112e1051a39Sopenharmony_ci if (lenbytes == 0) 113e1051a39Sopenharmony_ci return 1; 114e1051a39Sopenharmony_ci 115e1051a39Sopenharmony_ci pkt->subs->pwritten = lenbytes; 116e1051a39Sopenharmony_ci pkt->subs->lenbytes = lenbytes; 117e1051a39Sopenharmony_ci 118e1051a39Sopenharmony_ci if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars)) { 119e1051a39Sopenharmony_ci OPENSSL_free(pkt->subs); 120e1051a39Sopenharmony_ci pkt->subs = NULL; 121e1051a39Sopenharmony_ci return 0; 122e1051a39Sopenharmony_ci } 123e1051a39Sopenharmony_ci pkt->subs->packet_len = 0; 124e1051a39Sopenharmony_ci 125e1051a39Sopenharmony_ci return 1; 126e1051a39Sopenharmony_ci} 127e1051a39Sopenharmony_ci 128e1051a39Sopenharmony_ciint WPACKET_init_static_len(WPACKET *pkt, unsigned char *buf, size_t len, 129e1051a39Sopenharmony_ci size_t lenbytes) 130e1051a39Sopenharmony_ci{ 131e1051a39Sopenharmony_ci size_t max = maxmaxsize(lenbytes); 132e1051a39Sopenharmony_ci 133e1051a39Sopenharmony_ci /* Internal API, so should not fail */ 134e1051a39Sopenharmony_ci if (!ossl_assert(buf != NULL && len > 0)) 135e1051a39Sopenharmony_ci return 0; 136e1051a39Sopenharmony_ci 137e1051a39Sopenharmony_ci pkt->staticbuf = buf; 138e1051a39Sopenharmony_ci pkt->buf = NULL; 139e1051a39Sopenharmony_ci pkt->maxsize = (max < len) ? max : len; 140e1051a39Sopenharmony_ci pkt->endfirst = 0; 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ci return wpacket_intern_init_len(pkt, lenbytes); 143e1051a39Sopenharmony_ci} 144e1051a39Sopenharmony_ci 145e1051a39Sopenharmony_ciint WPACKET_init_der(WPACKET *pkt, unsigned char *buf, size_t len) 146e1051a39Sopenharmony_ci{ 147e1051a39Sopenharmony_ci /* Internal API, so should not fail */ 148e1051a39Sopenharmony_ci if (!ossl_assert(buf != NULL && len > 0)) 149e1051a39Sopenharmony_ci return 0; 150e1051a39Sopenharmony_ci 151e1051a39Sopenharmony_ci pkt->staticbuf = buf; 152e1051a39Sopenharmony_ci pkt->buf = NULL; 153e1051a39Sopenharmony_ci pkt->maxsize = len; 154e1051a39Sopenharmony_ci pkt->endfirst = 1; 155e1051a39Sopenharmony_ci 156e1051a39Sopenharmony_ci return wpacket_intern_init_len(pkt, 0); 157e1051a39Sopenharmony_ci} 158e1051a39Sopenharmony_ci 159e1051a39Sopenharmony_ciint WPACKET_init_len(WPACKET *pkt, BUF_MEM *buf, size_t lenbytes) 160e1051a39Sopenharmony_ci{ 161e1051a39Sopenharmony_ci /* Internal API, so should not fail */ 162e1051a39Sopenharmony_ci if (!ossl_assert(buf != NULL)) 163e1051a39Sopenharmony_ci return 0; 164e1051a39Sopenharmony_ci 165e1051a39Sopenharmony_ci pkt->staticbuf = NULL; 166e1051a39Sopenharmony_ci pkt->buf = buf; 167e1051a39Sopenharmony_ci pkt->maxsize = maxmaxsize(lenbytes); 168e1051a39Sopenharmony_ci pkt->endfirst = 0; 169e1051a39Sopenharmony_ci 170e1051a39Sopenharmony_ci return wpacket_intern_init_len(pkt, lenbytes); 171e1051a39Sopenharmony_ci} 172e1051a39Sopenharmony_ci 173e1051a39Sopenharmony_ciint WPACKET_init(WPACKET *pkt, BUF_MEM *buf) 174e1051a39Sopenharmony_ci{ 175e1051a39Sopenharmony_ci return WPACKET_init_len(pkt, buf, 0); 176e1051a39Sopenharmony_ci} 177e1051a39Sopenharmony_ci 178e1051a39Sopenharmony_ciint WPACKET_init_null(WPACKET *pkt, size_t lenbytes) 179e1051a39Sopenharmony_ci{ 180e1051a39Sopenharmony_ci pkt->staticbuf = NULL; 181e1051a39Sopenharmony_ci pkt->buf = NULL; 182e1051a39Sopenharmony_ci pkt->maxsize = maxmaxsize(lenbytes); 183e1051a39Sopenharmony_ci pkt->endfirst = 0; 184e1051a39Sopenharmony_ci 185e1051a39Sopenharmony_ci return wpacket_intern_init_len(pkt, 0); 186e1051a39Sopenharmony_ci} 187e1051a39Sopenharmony_ci 188e1051a39Sopenharmony_ciint WPACKET_init_null_der(WPACKET *pkt) 189e1051a39Sopenharmony_ci{ 190e1051a39Sopenharmony_ci pkt->staticbuf = NULL; 191e1051a39Sopenharmony_ci pkt->buf = NULL; 192e1051a39Sopenharmony_ci pkt->maxsize = SIZE_MAX; 193e1051a39Sopenharmony_ci pkt->endfirst = 1; 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ci return wpacket_intern_init_len(pkt, 0); 196e1051a39Sopenharmony_ci} 197e1051a39Sopenharmony_ci 198e1051a39Sopenharmony_ciint WPACKET_set_flags(WPACKET *pkt, unsigned int flags) 199e1051a39Sopenharmony_ci{ 200e1051a39Sopenharmony_ci /* Internal API, so should not fail */ 201e1051a39Sopenharmony_ci if (!ossl_assert(pkt->subs != NULL)) 202e1051a39Sopenharmony_ci return 0; 203e1051a39Sopenharmony_ci 204e1051a39Sopenharmony_ci pkt->subs->flags = flags; 205e1051a39Sopenharmony_ci 206e1051a39Sopenharmony_ci return 1; 207e1051a39Sopenharmony_ci} 208e1051a39Sopenharmony_ci 209e1051a39Sopenharmony_ci/* Store the |value| of length |len| at location |data| */ 210e1051a39Sopenharmony_cistatic int put_value(unsigned char *data, uint64_t value, size_t len) 211e1051a39Sopenharmony_ci{ 212e1051a39Sopenharmony_ci if (data == NULL) 213e1051a39Sopenharmony_ci return 1; 214e1051a39Sopenharmony_ci 215e1051a39Sopenharmony_ci for (data += len - 1; len > 0; len--) { 216e1051a39Sopenharmony_ci *data = (unsigned char)(value & 0xff); 217e1051a39Sopenharmony_ci data--; 218e1051a39Sopenharmony_ci value >>= 8; 219e1051a39Sopenharmony_ci } 220e1051a39Sopenharmony_ci 221e1051a39Sopenharmony_ci /* Check whether we could fit the value in the assigned number of bytes */ 222e1051a39Sopenharmony_ci if (value > 0) 223e1051a39Sopenharmony_ci return 0; 224e1051a39Sopenharmony_ci 225e1051a39Sopenharmony_ci return 1; 226e1051a39Sopenharmony_ci} 227e1051a39Sopenharmony_ci 228e1051a39Sopenharmony_ci 229e1051a39Sopenharmony_ci/* 230e1051a39Sopenharmony_ci * Internal helper function used by WPACKET_close(), WPACKET_finish() and 231e1051a39Sopenharmony_ci * WPACKET_fill_lengths() to close a sub-packet and write out its length if 232e1051a39Sopenharmony_ci * necessary. If |doclose| is 0 then it goes through the motions of closing 233e1051a39Sopenharmony_ci * (i.e. it fills in all the lengths), but doesn't actually close anything. 234e1051a39Sopenharmony_ci */ 235e1051a39Sopenharmony_cistatic int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose) 236e1051a39Sopenharmony_ci{ 237e1051a39Sopenharmony_ci size_t packlen = pkt->written - sub->pwritten; 238e1051a39Sopenharmony_ci 239e1051a39Sopenharmony_ci if (packlen == 0 240e1051a39Sopenharmony_ci && (sub->flags & WPACKET_FLAGS_NON_ZERO_LENGTH) != 0) 241e1051a39Sopenharmony_ci return 0; 242e1051a39Sopenharmony_ci 243e1051a39Sopenharmony_ci if (packlen == 0 244e1051a39Sopenharmony_ci && sub->flags & WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) { 245e1051a39Sopenharmony_ci /* We can't handle this case. Return an error */ 246e1051a39Sopenharmony_ci if (!doclose) 247e1051a39Sopenharmony_ci return 0; 248e1051a39Sopenharmony_ci 249e1051a39Sopenharmony_ci /* Deallocate any bytes allocated for the length of the WPACKET */ 250e1051a39Sopenharmony_ci if ((pkt->curr - sub->lenbytes) == sub->packet_len) { 251e1051a39Sopenharmony_ci pkt->written -= sub->lenbytes; 252e1051a39Sopenharmony_ci pkt->curr -= sub->lenbytes; 253e1051a39Sopenharmony_ci } 254e1051a39Sopenharmony_ci 255e1051a39Sopenharmony_ci /* Don't write out the packet length */ 256e1051a39Sopenharmony_ci sub->packet_len = 0; 257e1051a39Sopenharmony_ci sub->lenbytes = 0; 258e1051a39Sopenharmony_ci } 259e1051a39Sopenharmony_ci 260e1051a39Sopenharmony_ci /* Write out the WPACKET length if needed */ 261e1051a39Sopenharmony_ci if (sub->lenbytes > 0) { 262e1051a39Sopenharmony_ci unsigned char *buf = GETBUF(pkt); 263e1051a39Sopenharmony_ci 264e1051a39Sopenharmony_ci if (buf != NULL 265e1051a39Sopenharmony_ci && !put_value(&buf[sub->packet_len], packlen, 266e1051a39Sopenharmony_ci sub->lenbytes)) 267e1051a39Sopenharmony_ci return 0; 268e1051a39Sopenharmony_ci } else if (pkt->endfirst && sub->parent != NULL 269e1051a39Sopenharmony_ci && (packlen != 0 270e1051a39Sopenharmony_ci || (sub->flags 271e1051a39Sopenharmony_ci & WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) == 0)) { 272e1051a39Sopenharmony_ci size_t tmplen = packlen; 273e1051a39Sopenharmony_ci size_t numlenbytes = 1; 274e1051a39Sopenharmony_ci 275e1051a39Sopenharmony_ci while ((tmplen = tmplen >> 8) > 0) 276e1051a39Sopenharmony_ci numlenbytes++; 277e1051a39Sopenharmony_ci if (!WPACKET_put_bytes__(pkt, packlen, numlenbytes)) 278e1051a39Sopenharmony_ci return 0; 279e1051a39Sopenharmony_ci if (packlen > 0x7f) { 280e1051a39Sopenharmony_ci numlenbytes |= 0x80; 281e1051a39Sopenharmony_ci if (!WPACKET_put_bytes_u8(pkt, numlenbytes)) 282e1051a39Sopenharmony_ci return 0; 283e1051a39Sopenharmony_ci } 284e1051a39Sopenharmony_ci } 285e1051a39Sopenharmony_ci 286e1051a39Sopenharmony_ci if (doclose) { 287e1051a39Sopenharmony_ci pkt->subs = sub->parent; 288e1051a39Sopenharmony_ci OPENSSL_free(sub); 289e1051a39Sopenharmony_ci } 290e1051a39Sopenharmony_ci 291e1051a39Sopenharmony_ci return 1; 292e1051a39Sopenharmony_ci} 293e1051a39Sopenharmony_ci 294e1051a39Sopenharmony_ciint WPACKET_fill_lengths(WPACKET *pkt) 295e1051a39Sopenharmony_ci{ 296e1051a39Sopenharmony_ci WPACKET_SUB *sub; 297e1051a39Sopenharmony_ci 298e1051a39Sopenharmony_ci if (!ossl_assert(pkt->subs != NULL)) 299e1051a39Sopenharmony_ci return 0; 300e1051a39Sopenharmony_ci 301e1051a39Sopenharmony_ci for (sub = pkt->subs; sub != NULL; sub = sub->parent) { 302e1051a39Sopenharmony_ci if (!wpacket_intern_close(pkt, sub, 0)) 303e1051a39Sopenharmony_ci return 0; 304e1051a39Sopenharmony_ci } 305e1051a39Sopenharmony_ci 306e1051a39Sopenharmony_ci return 1; 307e1051a39Sopenharmony_ci} 308e1051a39Sopenharmony_ci 309e1051a39Sopenharmony_ciint WPACKET_close(WPACKET *pkt) 310e1051a39Sopenharmony_ci{ 311e1051a39Sopenharmony_ci /* 312e1051a39Sopenharmony_ci * Internal API, so should not fail - but we do negative testing of this 313e1051a39Sopenharmony_ci * so no assert (otherwise the tests fail) 314e1051a39Sopenharmony_ci */ 315e1051a39Sopenharmony_ci if (pkt->subs == NULL || pkt->subs->parent == NULL) 316e1051a39Sopenharmony_ci return 0; 317e1051a39Sopenharmony_ci 318e1051a39Sopenharmony_ci return wpacket_intern_close(pkt, pkt->subs, 1); 319e1051a39Sopenharmony_ci} 320e1051a39Sopenharmony_ci 321e1051a39Sopenharmony_ciint WPACKET_finish(WPACKET *pkt) 322e1051a39Sopenharmony_ci{ 323e1051a39Sopenharmony_ci int ret; 324e1051a39Sopenharmony_ci 325e1051a39Sopenharmony_ci /* 326e1051a39Sopenharmony_ci * Internal API, so should not fail - but we do negative testing of this 327e1051a39Sopenharmony_ci * so no assert (otherwise the tests fail) 328e1051a39Sopenharmony_ci */ 329e1051a39Sopenharmony_ci if (pkt->subs == NULL || pkt->subs->parent != NULL) 330e1051a39Sopenharmony_ci return 0; 331e1051a39Sopenharmony_ci 332e1051a39Sopenharmony_ci ret = wpacket_intern_close(pkt, pkt->subs, 1); 333e1051a39Sopenharmony_ci if (ret) { 334e1051a39Sopenharmony_ci OPENSSL_free(pkt->subs); 335e1051a39Sopenharmony_ci pkt->subs = NULL; 336e1051a39Sopenharmony_ci } 337e1051a39Sopenharmony_ci 338e1051a39Sopenharmony_ci return ret; 339e1051a39Sopenharmony_ci} 340e1051a39Sopenharmony_ci 341e1051a39Sopenharmony_ciint WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes) 342e1051a39Sopenharmony_ci{ 343e1051a39Sopenharmony_ci WPACKET_SUB *sub; 344e1051a39Sopenharmony_ci unsigned char *lenchars; 345e1051a39Sopenharmony_ci 346e1051a39Sopenharmony_ci /* Internal API, so should not fail */ 347e1051a39Sopenharmony_ci if (!ossl_assert(pkt->subs != NULL)) 348e1051a39Sopenharmony_ci return 0; 349e1051a39Sopenharmony_ci 350e1051a39Sopenharmony_ci /* We don't support lenbytes greater than 0 when doing endfirst writing */ 351e1051a39Sopenharmony_ci if (lenbytes > 0 && pkt->endfirst) 352e1051a39Sopenharmony_ci return 0; 353e1051a39Sopenharmony_ci 354e1051a39Sopenharmony_ci if ((sub = OPENSSL_zalloc(sizeof(*sub))) == NULL) { 355e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 356e1051a39Sopenharmony_ci return 0; 357e1051a39Sopenharmony_ci } 358e1051a39Sopenharmony_ci 359e1051a39Sopenharmony_ci sub->parent = pkt->subs; 360e1051a39Sopenharmony_ci pkt->subs = sub; 361e1051a39Sopenharmony_ci sub->pwritten = pkt->written + lenbytes; 362e1051a39Sopenharmony_ci sub->lenbytes = lenbytes; 363e1051a39Sopenharmony_ci 364e1051a39Sopenharmony_ci if (lenbytes == 0) { 365e1051a39Sopenharmony_ci sub->packet_len = 0; 366e1051a39Sopenharmony_ci return 1; 367e1051a39Sopenharmony_ci } 368e1051a39Sopenharmony_ci 369e1051a39Sopenharmony_ci sub->packet_len = pkt->written; 370e1051a39Sopenharmony_ci 371e1051a39Sopenharmony_ci if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars)) 372e1051a39Sopenharmony_ci return 0; 373e1051a39Sopenharmony_ci 374e1051a39Sopenharmony_ci return 1; 375e1051a39Sopenharmony_ci} 376e1051a39Sopenharmony_ci 377e1051a39Sopenharmony_ciint WPACKET_start_sub_packet(WPACKET *pkt) 378e1051a39Sopenharmony_ci{ 379e1051a39Sopenharmony_ci return WPACKET_start_sub_packet_len__(pkt, 0); 380e1051a39Sopenharmony_ci} 381e1051a39Sopenharmony_ci 382e1051a39Sopenharmony_ciint WPACKET_put_bytes__(WPACKET *pkt, uint64_t val, size_t size) 383e1051a39Sopenharmony_ci{ 384e1051a39Sopenharmony_ci unsigned char *data; 385e1051a39Sopenharmony_ci 386e1051a39Sopenharmony_ci /* Internal API, so should not fail */ 387e1051a39Sopenharmony_ci if (!ossl_assert(size <= sizeof(uint64_t)) 388e1051a39Sopenharmony_ci || !WPACKET_allocate_bytes(pkt, size, &data) 389e1051a39Sopenharmony_ci || !put_value(data, val, size)) 390e1051a39Sopenharmony_ci return 0; 391e1051a39Sopenharmony_ci 392e1051a39Sopenharmony_ci return 1; 393e1051a39Sopenharmony_ci} 394e1051a39Sopenharmony_ci 395e1051a39Sopenharmony_ciint WPACKET_set_max_size(WPACKET *pkt, size_t maxsize) 396e1051a39Sopenharmony_ci{ 397e1051a39Sopenharmony_ci WPACKET_SUB *sub; 398e1051a39Sopenharmony_ci size_t lenbytes; 399e1051a39Sopenharmony_ci 400e1051a39Sopenharmony_ci /* Internal API, so should not fail */ 401e1051a39Sopenharmony_ci if (!ossl_assert(pkt->subs != NULL)) 402e1051a39Sopenharmony_ci return 0; 403e1051a39Sopenharmony_ci 404e1051a39Sopenharmony_ci /* Find the WPACKET_SUB for the top level */ 405e1051a39Sopenharmony_ci for (sub = pkt->subs; sub->parent != NULL; sub = sub->parent) 406e1051a39Sopenharmony_ci continue; 407e1051a39Sopenharmony_ci 408e1051a39Sopenharmony_ci lenbytes = sub->lenbytes; 409e1051a39Sopenharmony_ci if (lenbytes == 0) 410e1051a39Sopenharmony_ci lenbytes = sizeof(pkt->maxsize); 411e1051a39Sopenharmony_ci 412e1051a39Sopenharmony_ci if (maxmaxsize(lenbytes) < maxsize || maxsize < pkt->written) 413e1051a39Sopenharmony_ci return 0; 414e1051a39Sopenharmony_ci 415e1051a39Sopenharmony_ci pkt->maxsize = maxsize; 416e1051a39Sopenharmony_ci 417e1051a39Sopenharmony_ci return 1; 418e1051a39Sopenharmony_ci} 419e1051a39Sopenharmony_ci 420e1051a39Sopenharmony_ciint WPACKET_memset(WPACKET *pkt, int ch, size_t len) 421e1051a39Sopenharmony_ci{ 422e1051a39Sopenharmony_ci unsigned char *dest; 423e1051a39Sopenharmony_ci 424e1051a39Sopenharmony_ci if (len == 0) 425e1051a39Sopenharmony_ci return 1; 426e1051a39Sopenharmony_ci 427e1051a39Sopenharmony_ci if (!WPACKET_allocate_bytes(pkt, len, &dest)) 428e1051a39Sopenharmony_ci return 0; 429e1051a39Sopenharmony_ci 430e1051a39Sopenharmony_ci if (dest != NULL) 431e1051a39Sopenharmony_ci memset(dest, ch, len); 432e1051a39Sopenharmony_ci 433e1051a39Sopenharmony_ci return 1; 434e1051a39Sopenharmony_ci} 435e1051a39Sopenharmony_ci 436e1051a39Sopenharmony_ciint WPACKET_memcpy(WPACKET *pkt, const void *src, size_t len) 437e1051a39Sopenharmony_ci{ 438e1051a39Sopenharmony_ci unsigned char *dest; 439e1051a39Sopenharmony_ci 440e1051a39Sopenharmony_ci if (len == 0) 441e1051a39Sopenharmony_ci return 1; 442e1051a39Sopenharmony_ci 443e1051a39Sopenharmony_ci if (!WPACKET_allocate_bytes(pkt, len, &dest)) 444e1051a39Sopenharmony_ci return 0; 445e1051a39Sopenharmony_ci 446e1051a39Sopenharmony_ci if (dest != NULL) 447e1051a39Sopenharmony_ci memcpy(dest, src, len); 448e1051a39Sopenharmony_ci 449e1051a39Sopenharmony_ci return 1; 450e1051a39Sopenharmony_ci} 451e1051a39Sopenharmony_ci 452e1051a39Sopenharmony_ciint WPACKET_sub_memcpy__(WPACKET *pkt, const void *src, size_t len, 453e1051a39Sopenharmony_ci size_t lenbytes) 454e1051a39Sopenharmony_ci{ 455e1051a39Sopenharmony_ci if (!WPACKET_start_sub_packet_len__(pkt, lenbytes) 456e1051a39Sopenharmony_ci || !WPACKET_memcpy(pkt, src, len) 457e1051a39Sopenharmony_ci || !WPACKET_close(pkt)) 458e1051a39Sopenharmony_ci return 0; 459e1051a39Sopenharmony_ci 460e1051a39Sopenharmony_ci return 1; 461e1051a39Sopenharmony_ci} 462e1051a39Sopenharmony_ci 463e1051a39Sopenharmony_ciint WPACKET_get_total_written(WPACKET *pkt, size_t *written) 464e1051a39Sopenharmony_ci{ 465e1051a39Sopenharmony_ci /* Internal API, so should not fail */ 466e1051a39Sopenharmony_ci if (!ossl_assert(written != NULL)) 467e1051a39Sopenharmony_ci return 0; 468e1051a39Sopenharmony_ci 469e1051a39Sopenharmony_ci *written = pkt->written; 470e1051a39Sopenharmony_ci 471e1051a39Sopenharmony_ci return 1; 472e1051a39Sopenharmony_ci} 473e1051a39Sopenharmony_ci 474e1051a39Sopenharmony_ciint WPACKET_get_length(WPACKET *pkt, size_t *len) 475e1051a39Sopenharmony_ci{ 476e1051a39Sopenharmony_ci /* Internal API, so should not fail */ 477e1051a39Sopenharmony_ci if (!ossl_assert(pkt->subs != NULL && len != NULL)) 478e1051a39Sopenharmony_ci return 0; 479e1051a39Sopenharmony_ci 480e1051a39Sopenharmony_ci *len = pkt->written - pkt->subs->pwritten; 481e1051a39Sopenharmony_ci 482e1051a39Sopenharmony_ci return 1; 483e1051a39Sopenharmony_ci} 484e1051a39Sopenharmony_ci 485e1051a39Sopenharmony_ciunsigned char *WPACKET_get_curr(WPACKET *pkt) 486e1051a39Sopenharmony_ci{ 487e1051a39Sopenharmony_ci unsigned char *buf = GETBUF(pkt); 488e1051a39Sopenharmony_ci 489e1051a39Sopenharmony_ci if (buf == NULL) 490e1051a39Sopenharmony_ci return NULL; 491e1051a39Sopenharmony_ci 492e1051a39Sopenharmony_ci if (pkt->endfirst) 493e1051a39Sopenharmony_ci return buf + pkt->maxsize - pkt->curr; 494e1051a39Sopenharmony_ci 495e1051a39Sopenharmony_ci return buf + pkt->curr; 496e1051a39Sopenharmony_ci} 497e1051a39Sopenharmony_ci 498e1051a39Sopenharmony_ciint WPACKET_is_null_buf(WPACKET *pkt) 499e1051a39Sopenharmony_ci{ 500e1051a39Sopenharmony_ci return pkt->buf == NULL && pkt->staticbuf == NULL; 501e1051a39Sopenharmony_ci} 502e1051a39Sopenharmony_ci 503e1051a39Sopenharmony_civoid WPACKET_cleanup(WPACKET *pkt) 504e1051a39Sopenharmony_ci{ 505e1051a39Sopenharmony_ci WPACKET_SUB *sub, *parent; 506e1051a39Sopenharmony_ci 507e1051a39Sopenharmony_ci for (sub = pkt->subs; sub != NULL; sub = parent) { 508e1051a39Sopenharmony_ci parent = sub->parent; 509e1051a39Sopenharmony_ci OPENSSL_free(sub); 510e1051a39Sopenharmony_ci } 511e1051a39Sopenharmony_ci pkt->subs = NULL; 512e1051a39Sopenharmony_ci} 513