1 /**
2 * \file common.h
3 *
4 * \brief Utility macros for internal use in the library
5 */
6 /*
7 * Copyright The Mbed TLS Contributors
8 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
9 */
10
11 #ifndef MBEDTLS_LIBRARY_COMMON_H
12 #define MBEDTLS_LIBRARY_COMMON_H
13
14 #if defined(MBEDTLS_CONFIG_FILE)
15 #include MBEDTLS_CONFIG_FILE
16 #else
17 #include "mbedtls/config.h"
18 #endif
19
20 #include <assert.h>
21 #include <stddef.h>
22 #include <stdint.h>
23
24 /* Define `inline` on some non-C99-compliant compilers. */
25 #if (defined(__ARMCC_VERSION) || defined(_MSC_VER)) && \
26 !defined(inline) && !defined(__cplusplus)
27 #define inline __inline
28 #endif
29
30 /** Helper to define a function as static except when building invasive tests.
31 *
32 * If a function is only used inside its own source file and should be
33 * declared `static` to allow the compiler to optimize for code size,
34 * but that function has unit tests, define it with
35 * ```
36 * MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... }
37 * ```
38 * and declare it in a header in the `library/` directory with
39 * ```
40 * #if defined(MBEDTLS_TEST_HOOKS)
41 * int mbedtls_foo(...);
42 * #endif
43 * ```
44 */
45 #if defined(MBEDTLS_TEST_HOOKS)
46 #define MBEDTLS_STATIC_TESTABLE
47 #else
48 #define MBEDTLS_STATIC_TESTABLE static
49 #endif
50
51 /** Return an offset into a buffer.
52 *
53 * This is just the addition of an offset to a pointer, except that this
54 * function also accepts an offset of 0 into a buffer whose pointer is null.
55 * (`p + n` has undefined behavior when `p` is null, even when `n == 0`.
56 * A null pointer is a valid buffer pointer when the size is 0, for example
57 * as the result of `malloc(0)` on some platforms.)
58 *
59 * \param p Pointer to a buffer of at least n bytes.
60 * This may be \p NULL if \p n is zero.
61 * \param n An offset in bytes.
62 * \return Pointer to offset \p n in the buffer \p p.
63 * Note that this is only a valid pointer if the size of the
64 * buffer is at least \p n + 1.
65 */
mbedtls_buffer_offset(unsigned char * p,size_t n)66 static inline unsigned char *mbedtls_buffer_offset(
67 unsigned char *p, size_t n)
68 {
69 return p == NULL ? NULL : p + n;
70 }
71
72 /** Return an offset into a read-only buffer.
73 *
74 * Similar to mbedtls_buffer_offset(), but for const pointers.
75 *
76 * \param p Pointer to a buffer of at least n bytes.
77 * This may be \p NULL if \p n is zero.
78 * \param n An offset in bytes.
79 * \return Pointer to offset \p n in the buffer \p p.
80 * Note that this is only a valid pointer if the size of the
81 * buffer is at least \p n + 1.
82 */
mbedtls_buffer_offset_const(const unsigned char * p,size_t n)83 static inline const unsigned char *mbedtls_buffer_offset_const(
84 const unsigned char *p, size_t n)
85 {
86 return p == NULL ? NULL : p + n;
87 }
88
89 /** Byte Reading Macros
90 *
91 * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th
92 * byte from x, where byte 0 is the least significant byte.
93 */
94 #define MBEDTLS_BYTE_0(x) ((uint8_t) ((x) & 0xff))
95 #define MBEDTLS_BYTE_1(x) ((uint8_t) (((x) >> 8) & 0xff))
96 #define MBEDTLS_BYTE_2(x) ((uint8_t) (((x) >> 16) & 0xff))
97 #define MBEDTLS_BYTE_3(x) ((uint8_t) (((x) >> 24) & 0xff))
98 #define MBEDTLS_BYTE_4(x) ((uint8_t) (((x) >> 32) & 0xff))
99 #define MBEDTLS_BYTE_5(x) ((uint8_t) (((x) >> 40) & 0xff))
100 #define MBEDTLS_BYTE_6(x) ((uint8_t) (((x) >> 48) & 0xff))
101 #define MBEDTLS_BYTE_7(x) ((uint8_t) (((x) >> 56) & 0xff))
102
103 /**
104 * Get the unsigned 32 bits integer corresponding to four bytes in
105 * big-endian order (MSB first).
106 *
107 * \param data Base address of the memory to get the four bytes from.
108 * \param offset Offset from \p base of the first and most significant
109 * byte of the four bytes to build the 32 bits unsigned
110 * integer from.
111 */
112 #ifndef MBEDTLS_GET_UINT32_BE
113 #define MBEDTLS_GET_UINT32_BE(data, offset) \
114 ( \
115 ((uint32_t) (data)[(offset)] << 24) \
116 | ((uint32_t) (data)[(offset) + 1] << 16) \
117 | ((uint32_t) (data)[(offset) + 2] << 8) \
118 | ((uint32_t) (data)[(offset) + 3]) \
119 )
120 #endif
121
122 /**
123 * Put in memory a 32 bits unsigned integer in big-endian order.
124 *
125 * \param n 32 bits unsigned integer to put in memory.
126 * \param data Base address of the memory where to put the 32
127 * bits unsigned integer in.
128 * \param offset Offset from \p base where to put the most significant
129 * byte of the 32 bits unsigned integer \p n.
130 */
131 #ifndef MBEDTLS_PUT_UINT32_BE
132 #define MBEDTLS_PUT_UINT32_BE(n, data, offset) \
133 { \
134 (data)[(offset)] = MBEDTLS_BYTE_3(n); \
135 (data)[(offset) + 1] = MBEDTLS_BYTE_2(n); \
136 (data)[(offset) + 2] = MBEDTLS_BYTE_1(n); \
137 (data)[(offset) + 3] = MBEDTLS_BYTE_0(n); \
138 }
139 #endif
140
141 /**
142 * Get the unsigned 32 bits integer corresponding to four bytes in
143 * little-endian order (LSB first).
144 *
145 * \param data Base address of the memory to get the four bytes from.
146 * \param offset Offset from \p base of the first and least significant
147 * byte of the four bytes to build the 32 bits unsigned
148 * integer from.
149 */
150 #ifndef MBEDTLS_GET_UINT32_LE
151 #define MBEDTLS_GET_UINT32_LE(data, offset) \
152 ( \
153 ((uint32_t) (data)[(offset)]) \
154 | ((uint32_t) (data)[(offset) + 1] << 8) \
155 | ((uint32_t) (data)[(offset) + 2] << 16) \
156 | ((uint32_t) (data)[(offset) + 3] << 24) \
157 )
158 #endif
159
160 /**
161 * Put in memory a 32 bits unsigned integer in little-endian order.
162 *
163 * \param n 32 bits unsigned integer to put in memory.
164 * \param data Base address of the memory where to put the 32
165 * bits unsigned integer in.
166 * \param offset Offset from \p base where to put the least significant
167 * byte of the 32 bits unsigned integer \p n.
168 */
169 #ifndef MBEDTLS_PUT_UINT32_LE
170 #define MBEDTLS_PUT_UINT32_LE(n, data, offset) \
171 { \
172 (data)[(offset)] = MBEDTLS_BYTE_0(n); \
173 (data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \
174 (data)[(offset) + 2] = MBEDTLS_BYTE_2(n); \
175 (data)[(offset) + 3] = MBEDTLS_BYTE_3(n); \
176 }
177 #endif
178
179 /**
180 * Get the unsigned 16 bits integer corresponding to two bytes in
181 * little-endian order (LSB first).
182 *
183 * \param data Base address of the memory to get the two bytes from.
184 * \param offset Offset from \p base of the first and least significant
185 * byte of the two bytes to build the 16 bits unsigned
186 * integer from.
187 */
188 #ifndef MBEDTLS_GET_UINT16_LE
189 #define MBEDTLS_GET_UINT16_LE(data, offset) \
190 ( \
191 ((uint16_t) (data)[(offset)]) \
192 | ((uint16_t) (data)[(offset) + 1] << 8) \
193 )
194 #endif
195
196 /**
197 * Put in memory a 16 bits unsigned integer in little-endian order.
198 *
199 * \param n 16 bits unsigned integer to put in memory.
200 * \param data Base address of the memory where to put the 16
201 * bits unsigned integer in.
202 * \param offset Offset from \p base where to put the least significant
203 * byte of the 16 bits unsigned integer \p n.
204 */
205 #ifndef MBEDTLS_PUT_UINT16_LE
206 #define MBEDTLS_PUT_UINT16_LE(n, data, offset) \
207 { \
208 (data)[(offset)] = MBEDTLS_BYTE_0(n); \
209 (data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \
210 }
211 #endif
212
213 /**
214 * Get the unsigned 16 bits integer corresponding to two bytes in
215 * big-endian order (MSB first).
216 *
217 * \param data Base address of the memory to get the two bytes from.
218 * \param offset Offset from \p base of the first and most significant
219 * byte of the two bytes to build the 16 bits unsigned
220 * integer from.
221 */
222 #ifndef MBEDTLS_GET_UINT16_BE
223 #define MBEDTLS_GET_UINT16_BE(data, offset) \
224 ( \
225 ((uint16_t) (data)[(offset)] << 8) \
226 | ((uint16_t) (data)[(offset) + 1]) \
227 )
228 #endif
229
230 /**
231 * Put in memory a 16 bits unsigned integer in big-endian order.
232 *
233 * \param n 16 bits unsigned integer to put in memory.
234 * \param data Base address of the memory where to put the 16
235 * bits unsigned integer in.
236 * \param offset Offset from \p base where to put the most significant
237 * byte of the 16 bits unsigned integer \p n.
238 */
239 #ifndef MBEDTLS_PUT_UINT16_BE
240 #define MBEDTLS_PUT_UINT16_BE(n, data, offset) \
241 { \
242 (data)[(offset)] = MBEDTLS_BYTE_1(n); \
243 (data)[(offset) + 1] = MBEDTLS_BYTE_0(n); \
244 }
245 #endif
246
247 /**
248 * Get the unsigned 64 bits integer corresponding to eight bytes in
249 * big-endian order (MSB first).
250 *
251 * \param data Base address of the memory to get the eight bytes from.
252 * \param offset Offset from \p base of the first and most significant
253 * byte of the eight bytes to build the 64 bits unsigned
254 * integer from.
255 */
256 #ifndef MBEDTLS_GET_UINT64_BE
257 #define MBEDTLS_GET_UINT64_BE(data, offset) \
258 ( \
259 ((uint64_t) (data)[(offset)] << 56) \
260 | ((uint64_t) (data)[(offset) + 1] << 48) \
261 | ((uint64_t) (data)[(offset) + 2] << 40) \
262 | ((uint64_t) (data)[(offset) + 3] << 32) \
263 | ((uint64_t) (data)[(offset) + 4] << 24) \
264 | ((uint64_t) (data)[(offset) + 5] << 16) \
265 | ((uint64_t) (data)[(offset) + 6] << 8) \
266 | ((uint64_t) (data)[(offset) + 7]) \
267 )
268 #endif
269
270 /**
271 * Put in memory a 64 bits unsigned integer in big-endian order.
272 *
273 * \param n 64 bits unsigned integer to put in memory.
274 * \param data Base address of the memory where to put the 64
275 * bits unsigned integer in.
276 * \param offset Offset from \p base where to put the most significant
277 * byte of the 64 bits unsigned integer \p n.
278 */
279 #ifndef MBEDTLS_PUT_UINT64_BE
280 #define MBEDTLS_PUT_UINT64_BE(n, data, offset) \
281 { \
282 (data)[(offset)] = MBEDTLS_BYTE_7(n); \
283 (data)[(offset) + 1] = MBEDTLS_BYTE_6(n); \
284 (data)[(offset) + 2] = MBEDTLS_BYTE_5(n); \
285 (data)[(offset) + 3] = MBEDTLS_BYTE_4(n); \
286 (data)[(offset) + 4] = MBEDTLS_BYTE_3(n); \
287 (data)[(offset) + 5] = MBEDTLS_BYTE_2(n); \
288 (data)[(offset) + 6] = MBEDTLS_BYTE_1(n); \
289 (data)[(offset) + 7] = MBEDTLS_BYTE_0(n); \
290 }
291 #endif
292
293 /**
294 * Get the unsigned 64 bits integer corresponding to eight bytes in
295 * little-endian order (LSB first).
296 *
297 * \param data Base address of the memory to get the eight bytes from.
298 * \param offset Offset from \p base of the first and least significant
299 * byte of the eight bytes to build the 64 bits unsigned
300 * integer from.
301 */
302 #ifndef MBEDTLS_GET_UINT64_LE
303 #define MBEDTLS_GET_UINT64_LE(data, offset) \
304 ( \
305 ((uint64_t) (data)[(offset) + 7] << 56) \
306 | ((uint64_t) (data)[(offset) + 6] << 48) \
307 | ((uint64_t) (data)[(offset) + 5] << 40) \
308 | ((uint64_t) (data)[(offset) + 4] << 32) \
309 | ((uint64_t) (data)[(offset) + 3] << 24) \
310 | ((uint64_t) (data)[(offset) + 2] << 16) \
311 | ((uint64_t) (data)[(offset) + 1] << 8) \
312 | ((uint64_t) (data)[(offset)]) \
313 )
314 #endif
315
316 /**
317 * Put in memory a 64 bits unsigned integer in little-endian order.
318 *
319 * \param n 64 bits unsigned integer to put in memory.
320 * \param data Base address of the memory where to put the 64
321 * bits unsigned integer in.
322 * \param offset Offset from \p base where to put the least significant
323 * byte of the 64 bits unsigned integer \p n.
324 */
325 #ifndef MBEDTLS_PUT_UINT64_LE
326 #define MBEDTLS_PUT_UINT64_LE(n, data, offset) \
327 { \
328 (data)[(offset)] = MBEDTLS_BYTE_0(n); \
329 (data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \
330 (data)[(offset) + 2] = MBEDTLS_BYTE_2(n); \
331 (data)[(offset) + 3] = MBEDTLS_BYTE_3(n); \
332 (data)[(offset) + 4] = MBEDTLS_BYTE_4(n); \
333 (data)[(offset) + 5] = MBEDTLS_BYTE_5(n); \
334 (data)[(offset) + 6] = MBEDTLS_BYTE_6(n); \
335 (data)[(offset) + 7] = MBEDTLS_BYTE_7(n); \
336 }
337 #endif
338
339 /* Always provide a static assert macro, so it can be used unconditionally.
340 * It will expand to nothing on some systems.
341 * Can be used outside functions (but don't add a trailing ';' in that case:
342 * the semicolon is included here to avoid triggering -Wextra-semi when
343 * MBEDTLS_STATIC_ASSERT() expands to nothing).
344 * Can't use the C11-style `defined(static_assert)` on FreeBSD, since it
345 * defines static_assert even with -std=c99, but then complains about it.
346 */
347 #if defined(static_assert) && !defined(__FreeBSD__)
348 #define MBEDTLS_STATIC_ASSERT(expr, msg) static_assert(expr, msg);
349 #else
350 #define MBEDTLS_STATIC_ASSERT(expr, msg)
351 #endif
352
353 #endif /* MBEDTLS_LIBRARY_COMMON_H */
354