DTLS: remove unused cookie field
[openssl.git] / ssl / packet_locl.h
1 /* ssl/packet_locl.h */
2 /*
3  * Written by Matt Caswell for the OpenSSL project.
4  */
5 /* ====================================================================
6  * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    openssl-core@openssl.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58
59 #ifndef HEADER_PACKET_LOCL_H
60 # define HEADER_PACKET_LOCL_H
61
62 # include <string.h>
63 # include <openssl/bn.h>
64 # include <openssl/buffer.h>
65 # include <openssl/crypto.h>
66 # include "e_os.h"
67
68 # ifdef __cplusplus
69 extern "C" {
70 # endif
71
72 typedef struct {
73     /* Pointer to where we are currently reading from */
74     unsigned char *curr;
75     /* Number of bytes remaining */
76     size_t remaining;
77 } PACKET;
78
79 /* Internal unchecked shorthand; don't use outside this file. */
80 static inline void packet_forward(PACKET *pkt, size_t len)
81 {
82     pkt->curr += len;
83     pkt->remaining -= len;
84 }
85
86 /*
87  * Returns the number of bytes remaining to be read in the PACKET
88  */
89 __owur static inline size_t PACKET_remaining(const PACKET *pkt)
90 {
91     return pkt->remaining;
92 }
93
94 /*
95  * Returns a pointer to the PACKET's current position.
96  * For use in non-PACKETized APIs.
97  * TODO(openssl-team): this should return 'const unsigned char*' but can't
98  * currently because legacy code passes 'unsigned char*'s around.
99  */
100 static inline unsigned char *PACKET_data(const PACKET *pkt)
101 {
102     return pkt->curr;
103 }
104
105 /*
106  * Initialise a PACKET with |len| bytes held in |buf|. This does not make a
107  * copy of the data so |buf| must be present for the whole time that the PACKET
108  * is being used.
109  */
110 static inline int PACKET_buf_init(PACKET *pkt, unsigned char *buf, size_t len)
111 {
112     /* Sanity check for negative values. */
113     if (buf + len < buf)
114         return 0;
115
116     pkt->curr = buf;
117     pkt->remaining = len;
118     return 1;
119 }
120
121 /* Initialize a PACKET to hold zero bytes. */
122 static inline void PACKET_null_init(PACKET *pkt)
123 {
124     pkt->curr = NULL;
125     pkt->remaining = 0;
126 }
127
128 /*
129  * Returns 1 if the packet has length |num| and its contents equal the |num|
130  * bytes read from |ptr|. Returns 0 otherwise (lengths or contents not equal).
131  * If lengths are equal, performs the comparison in constant time.
132  */
133 __owur static inline int PACKET_equal(const PACKET *pkt, const void *ptr,
134                                       size_t num) {
135     if (PACKET_remaining(pkt) != num)
136         return 0;
137     return CRYPTO_memcmp(pkt->curr, ptr, num) == 0;
138 }
139
140 /*
141  * Peek ahead and initialize |subpkt| with the next |len| bytes read from |pkt|.
142  * Data is not copied: the |subpkt| packet will share its underlying buffer with
143  * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
144  */
145 __owur static inline int PACKET_peek_sub_packet(const PACKET *pkt,
146                                                 PACKET *subpkt, size_t len)
147 {
148     if (PACKET_remaining(pkt) < len)
149         return 0;
150
151     PACKET_buf_init(subpkt, pkt->curr, len);
152
153     return 1;
154 }
155
156 /*
157  * Initialize |subpkt| with the next |len| bytes read from |pkt|. Data is not
158  * copied: the |subpkt| packet will share its underlying buffer with the
159  * original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
160  */
161 __owur static inline int PACKET_get_sub_packet(PACKET *pkt, PACKET *subpkt,
162                                                size_t len)
163 {
164     if (!PACKET_peek_sub_packet(pkt, subpkt, len))
165         return 0;
166
167     packet_forward(pkt, len);
168
169     return 1;
170 }
171
172 /* Peek ahead at 2 bytes in network order from |pkt| and store the value in
173  * |*data|
174  */
175 __owur static inline int PACKET_peek_net_2(const PACKET *pkt,
176                                            unsigned int *data)
177 {
178     if (PACKET_remaining(pkt) < 2)
179         return 0;
180
181     *data  = ((unsigned int)(*pkt->curr)) <<  8;
182     *data |= *(pkt->curr + 1);
183
184     return 1;
185 }
186
187 /* Equivalent of n2s */
188 /* Get 2 bytes in network order from |pkt| and store the value in |*data| */
189 __owur static inline int PACKET_get_net_2(PACKET *pkt, unsigned int *data)
190 {
191     if (!PACKET_peek_net_2(pkt, data))
192         return 0;
193
194     packet_forward(pkt, 2);
195
196     return 1;
197 }
198
199 /* Peek ahead at 3 bytes in network order from |pkt| and store the value in
200  * |*data|
201  */
202 __owur static inline int PACKET_peek_net_3(const PACKET *pkt,
203                                            unsigned long *data)
204 {
205     if (PACKET_remaining(pkt) < 3)
206         return 0;
207
208     *data  = ((unsigned long)(*pkt->curr)) << 16;
209     *data |= ((unsigned long)(*(pkt->curr + 1))) <<  8;
210     *data |= *(pkt->curr + 2);
211
212     return 1;
213 }
214
215 /* Equivalent of n2l3 */
216 /* Get 3 bytes in network order from |pkt| and store the value in |*data| */
217 __owur static inline int PACKET_get_net_3(PACKET *pkt, unsigned long *data)
218 {
219     if (!PACKET_peek_net_3(pkt, data))
220         return 0;
221
222     packet_forward(pkt, 3);
223
224     return 1;
225 }
226
227 /* Peek ahead at 4 bytes in network order from |pkt| and store the value in
228  * |*data|
229  */
230 __owur static inline int PACKET_peek_net_4(const PACKET *pkt,
231                                            unsigned long *data)
232 {
233     if (PACKET_remaining(pkt) < 4)
234         return 0;
235
236     *data  = ((unsigned long)(*pkt->curr)) << 24;
237     *data |= ((unsigned long)(*(pkt->curr + 1))) << 16;
238     *data |= ((unsigned long)(*(pkt->curr + 2))) <<  8;
239     *data |= *(pkt->curr+3);
240
241     return 1;
242 }
243
244 /* Equivalent of n2l */
245 /* Get 4 bytes in network order from |pkt| and store the value in |*data| */
246 __owur static inline int PACKET_get_net_4(PACKET *pkt, unsigned long *data)
247 {
248     if (!PACKET_peek_net_4(pkt, data))
249         return 0;
250
251     packet_forward(pkt, 4);
252
253     return 1;
254 }
255
256 /* Peek ahead at 1 byte from |pkt| and store the value in |*data| */
257 __owur static inline int PACKET_peek_1(const PACKET *pkt, unsigned int *data)
258 {
259     if (!PACKET_remaining(pkt))
260         return 0;
261
262     *data = *pkt->curr;
263
264     return 1;
265 }
266
267 /* Get 1 byte from |pkt| and store the value in |*data| */
268 __owur static inline int PACKET_get_1(PACKET *pkt, unsigned int *data)
269 {
270     if (!PACKET_peek_1(pkt, data))
271         return 0;
272
273     packet_forward(pkt, 1);
274
275     return 1;
276 }
277
278 /*
279  * Peek ahead at 4 bytes in reverse network order from |pkt| and store the value
280  * in |*data|
281  */
282 __owur static inline int PACKET_peek_4(const PACKET *pkt, unsigned long *data)
283 {
284     if (PACKET_remaining(pkt) < 4)
285         return 0;
286
287     *data  = *pkt->curr;
288     *data |= ((unsigned long)(*(pkt->curr + 1))) <<  8;
289     *data |= ((unsigned long)(*(pkt->curr + 2))) << 16;
290     *data |= ((unsigned long)(*(pkt->curr + 3))) << 24;
291
292     return 1;
293 }
294
295 /* Equivalent of c2l */
296 /*
297  * Get 4 bytes in reverse network order from |pkt| and store the value in
298  * |*data|
299  */
300 __owur static inline int PACKET_get_4(PACKET *pkt, unsigned long *data)
301 {
302     if (!PACKET_peek_4(pkt, data))
303         return 0;
304
305     packet_forward(pkt, 4);
306
307     return 1;
308 }
309
310 /*
311  * Peek ahead at |len| bytes from the |pkt| and store a pointer to them in
312  * |*data|. This just points at the underlying buffer that |pkt| is using. The
313  * caller should not free this data directly (it will be freed when the
314  * underlying buffer gets freed
315  */
316 __owur static inline int PACKET_peek_bytes(const PACKET *pkt, unsigned char **data,
317                                            size_t len)
318 {
319     if (PACKET_remaining(pkt) < len)
320         return 0;
321
322     *data = pkt->curr;
323
324     return 1;
325 }
326
327 /*
328  * Read |len| bytes from the |pkt| and store a pointer to them in |*data|. This
329  * just points at the underlying buffer that |pkt| is using. The caller should
330  * not free this data directly (it will be freed when the underlying buffer gets
331  * freed
332  */
333 __owur static inline int PACKET_get_bytes(PACKET *pkt, unsigned char **data,
334                                           size_t len)
335 {
336     if (!PACKET_peek_bytes(pkt, data, len))
337         return 0;
338
339     packet_forward(pkt, len);
340
341     return 1;
342 }
343
344 /* Peek ahead at |len| bytes from |pkt| and copy them to |data| */
345 __owur static inline int PACKET_peek_copy_bytes(const PACKET *pkt,
346                                                 unsigned char *data, size_t len)
347 {
348     if (PACKET_remaining(pkt) < len)
349         return 0;
350
351     memcpy(data, pkt->curr, len);
352
353     return 1;
354 }
355
356 /*
357  * Read |len| bytes from |pkt| and copy them to |data|.
358  * The caller is responsible for ensuring that |data| can hold |len| bytes.
359  */
360 __owur static inline int PACKET_copy_bytes(PACKET *pkt, unsigned char *data,
361                                            size_t len)
362 {
363     if (!PACKET_peek_copy_bytes(pkt, data, len))
364         return 0;
365
366     packet_forward(pkt, len);
367
368     return 1;
369 }
370
371 /*
372  * Copy packet data to |dest|, and set |len| to the number of copied bytes.
373  * If the packet has more than |dest_len| bytes, nothing is copied.
374  * Returns 1 if the packet data fits in |dest_len| bytes, 0 otherwise.
375  * Does not forward PACKET position (because it is typically the last thing
376  * done with a given PACKET).
377  */
378 __owur static inline int PACKET_copy_all(const PACKET *pkt, unsigned char *dest,
379                                          size_t dest_len, size_t *len) {
380     if (PACKET_remaining(pkt) > dest_len) {
381         *len = 0;
382         return 0;
383     }
384     *len = pkt->remaining;
385     memcpy(dest, pkt->curr, pkt->remaining);
386     return 1;
387 }
388
389 /*
390  * Copy |pkt| bytes to a newly allocated buffer and store a pointer to the
391  * result in |*data|, and the length in |len|.
392  * If |*data| is not NULL, the old data is OPENSSL_free'd.
393  * If the packet is empty, or malloc fails, |*data| will be set to NULL.
394  * Returns 1 if the malloc succeeds and 0 otherwise.
395  * Does not forward PACKET position (because it is typically the last thing
396  * done with a given PACKET).
397  */
398 __owur static inline int PACKET_memdup(const PACKET *pkt, unsigned char **data,
399                                        size_t *len)
400 {
401     size_t length;
402
403     OPENSSL_free(*data);
404     *data = NULL;
405     *len = 0;
406
407     length = PACKET_remaining(pkt);
408
409     if (length == 0)
410         return 1;
411
412     *data = BUF_memdup(pkt->curr, length);
413
414     if (*data == NULL)
415         return 0;
416
417     *len = length;
418     return 1;
419 }
420
421 /*
422  * Read a C string from |pkt| and copy to a newly allocated, NUL-terminated
423  * buffer. Store a pointer to the result in |*data|.
424  * If |*data| is not NULL, the old data is OPENSSL_free'd.
425  * If the data in |pkt| does not contain a NUL-byte, the entire data is
426  * copied and NUL-terminated.
427  * Returns 1 if the malloc succeeds and 0 otherwise.
428  * Does not forward PACKET position (because it is typically the last thing done
429  * with a given PACKET).
430  */
431 __owur static inline int PACKET_strndup(const PACKET *pkt, char **data)
432 {
433     OPENSSL_free(*data);
434
435     /* This will succeed on an empty packet, unless pkt->curr == NULL. */
436     *data = BUF_strndup((const char*)pkt->curr, PACKET_remaining(pkt));
437     return (*data != NULL);
438 }
439
440 /* Move the current reading position forward |len| bytes */
441 __owur static inline int PACKET_forward(PACKET *pkt, size_t len)
442 {
443     if (PACKET_remaining(pkt) < len)
444         return 0;
445
446     packet_forward(pkt, len);
447
448     return 1;
449 }
450
451 /*
452  * Reads a variable-length vector prefixed with a one-byte length, and stores
453  * the contents in |subpkt|. |pkt| can equal |subpkt|.
454  * Data is not copied: the |subpkt| packet will share its underlying buffer with
455  * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
456  * Upon failure, the original |pkt| and |subpkt| are not modified.
457  */
458 __owur static inline int PACKET_get_length_prefixed_1(PACKET *pkt, PACKET *subpkt)
459 {
460   unsigned int length;
461   unsigned char *data;
462   PACKET tmp = *pkt;
463   if (!PACKET_get_1(&tmp, &length) ||
464       !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
465       return 0;
466   }
467
468   *pkt = tmp;
469   subpkt->curr = data;
470   subpkt->remaining = length;
471
472   return 1;
473 }
474
475 /*
476  * Reads a variable-length vector prefixed with a two-byte length, and stores
477  * the contents in |subpkt|. |pkt| can equal |subpkt|.
478  * Data is not copied: the |subpkt| packet will share its underlying buffer with
479  * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
480  * Upon failure, the original |pkt| and |subpkt| are not modified.
481  */
482 __owur static inline int PACKET_get_length_prefixed_2(PACKET *pkt, PACKET *subpkt)
483 {
484   unsigned int length;
485   unsigned char *data;
486   PACKET tmp = *pkt;
487   if (!PACKET_get_net_2(&tmp, &length) ||
488       !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
489       return 0;
490   }
491
492   *pkt = tmp;
493   subpkt->curr = data;
494   subpkt->remaining = length;
495
496   return 1;
497 }
498
499 /*
500  * Reads a variable-length vector prefixed with a three-byte length, and stores
501  * the contents in |subpkt|. |pkt| can equal |subpkt|.
502  * Data is not copied: the |subpkt| packet will share its underlying buffer with
503  * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
504  * Upon failure, the original |pkt| and |subpkt| are not modified.
505  */
506 __owur static inline int PACKET_get_length_prefixed_3(PACKET *pkt, PACKET *subpkt)
507 {
508   unsigned long length;
509   unsigned char *data;
510   PACKET tmp = *pkt;
511   if (!PACKET_get_net_3(&tmp, &length) ||
512       !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
513       return 0;
514   }
515
516   *pkt = tmp;
517   subpkt->curr = data;
518   subpkt->remaining = length;
519
520   return 1;
521 }
522 # ifdef __cplusplus
523 }
524 # endif
525
526 #endif /* HEADER_PACKET_LOCL_H */