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