• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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