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 | */ |
78 | static 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 | */ |
95 | static 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 | |