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