1 /*
2    Copyright (c) 2021 Fraunhofer AISEC. See the COPYRIGHT
3    file at the top-level directory of this distribution.
4 
5    Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6    http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7    <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8    option. This file may not be copied, modified, or distributed
9    except according to those terms.
10 */
11 
12 #ifndef BYTE_ARRAY_H
13 #define BYTE_ARRAY_H
14 
15 #include <stdbool.h>
16 #include <stddef.h>
17 #include <stdint.h>
18 
19 #include "oscore_edhoc_error.h"
20 #include "memcpy_s.h"
21 
22 /* Array with pointer and length.*/
23 struct byte_array {
24 	uint32_t len;
25 	uint8_t *ptr;
26 };
27 
28 struct const_byte_array {
29 	uint32_t len;
30 	const uint8_t *ptr;
31 };
32 
33 /* Empty Array with len=0 but with a non-null pointer.*/
34 extern struct byte_array EMPTY_ARRAY;
35 
36 /* Null Array with len=0 and a null pointer.*/
37 extern struct byte_array NULL_ARRAY;
38 
39 /**
40  * @brief                       Appends a source byte array at the end of dest
41  *                              byte array.
42  *
43  * @param dest                  Destination array. dest.len MUST indicate the
44  *                              position at which the source byte array will be
45  *                              appended.
46  * @param source                The byte array that will be appended
47  * @param capacity              The total buffer capacity of the dest byte array
48  * @return enum err             Ok or error code.
49  */
50 enum err byte_array_append(struct byte_array *dest,
51 			   const struct byte_array *source, uint32_t capacity);
52 
53 /**
54  * @brief			Compares if the given two arrays have equal
55  * 				content.
56  *
57  * @param[in] a 		Array "a".
58  * @param[in] b 		Array "b".
59  * @return  			True if the contents of both arrays is equal.
60  */
61 bool array_equals(const struct byte_array *a, const struct byte_array *b);
62 
63 /**
64  * @brief 			Creates a copy of a byte array.
65  *
66  * @param[out] dest 		The destination byte array.
67  * @param[in] src		The source byte array.
68  * @param dest_max_len 		The maximal length of the destination array.
69  * @return enum err 		Ok or error code.
70  */
71 enum err byte_array_cpy(struct byte_array *dest, const struct byte_array *src,
72 			const uint32_t dest_max_len);
73 
74 /**
75  * @brief   			Initializes a byte array variable with a
76  * 				pointer to a buffer and length of the buffer.
77  *
78  * @param PTR			pointer
79  * @param LEN			Length of the buffer in bytes
80  */
81 #define BYTE_ARRAY_INIT(PTR, LEN)                                              \
82 	{                                                                      \
83 		.len = LEN, .ptr = PTR                                         \
84 	}
85 
86 /**
87  * @brief   Creates a variable of type byte_array.
88  *          In addition a buffer is created to hold the data.
89  *          If Variable Length Array (VLA) is NOT used, before the creation of
90  *          the buffer it is checked if the size of the buffer (BUF_SIZE) will
91  *          be sufficient for the size of the byte_array (SIZE).
92 */
93 #ifdef VLA
94 #define BYTE_ARRAY_NEW(NAME, BUF_SIZE, SIZE)                                   \
95 	if (SIZE < 0 || SIZE > BUF_SIZE) {                                     \
96 		return vla_insufficient_size;                                  \
97 	}                                                                      \
98 	struct byte_array NAME;                                                \
99 	uint8_t NAME##_buf[SIZE];                                              \
100 	if (SIZE == 0) {                                                       \
101 		NAME = NULL_ARRAY;                                             \
102 	} else {                                                               \
103 		NAME.ptr = NAME##_buf;                                         \
104 		NAME.len = SIZE;                                               \
105 	};
106 
107 #else
108 #define BYTE_ARRAY_NEW(NAME, BUF_SIZE, SIZE)                                   \
109 	TRY(check_buffer_size(BUF_SIZE, SIZE));                                \
110 	struct byte_array NAME;                                                \
111 	uint8_t NAME##_buf[BUF_SIZE];                                          \
112 	if (SIZE == 0) {                                                       \
113 		NAME = NULL_ARRAY;                                             \
114 	} else {                                                               \
115 		NAME.ptr = NAME##_buf;                                         \
116 		NAME.len = SIZE;                                               \
117 	};
118 #endif
119 
120 #endif //BYTE_ARRAY_H
121