blob: 012044c68bdee3bd00885599f415bf9ee5eb7480 [file] [log] [blame]
Gilles Peskinec4672fd2019-09-11 13:39:11 +02001/**
2 * \file common.h
3 *
4 * \brief Utility macros for internal use in the library
5 */
6/*
Bence Szépkúti1e148272020-08-07 13:07:28 +02007 * Copyright The Mbed TLS Contributors
Gilles Peskinec4672fd2019-09-11 13:39:11 +02008 * 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.
Gilles Peskinec4672fd2019-09-11 13:39:11 +020021 */
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
Tom Cosgrovebdd01a72023-03-08 14:19:51 +000032#include <assert.h>
Gilles Peskine01bf6312022-11-23 14:15:57 +010033#include <stddef.h>
Joe Subbianic045dc12021-07-14 12:31:31 +010034#include <stdint.h>
35
Gilles Peskine8fe23a02022-11-23 17:24:37 +010036/* Define `inline` on some non-C99-compliant compilers. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010037#if (defined(__ARMCC_VERSION) || defined(_MSC_VER)) && \
Gilles Peskine8fe23a02022-11-23 17:24:37 +010038 !defined(inline) && !defined(__cplusplus)
39#define inline __inline
40#endif
41
Gilles Peskinec4672fd2019-09-11 13:39:11 +020042/** 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
Gilles Peskine01bf6312022-11-23 14:15:57 +010063/** 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.
Gilles Peskineff97f332022-11-25 13:34:59 +010067 * (`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.)
Gilles Peskine01bf6312022-11-23 14:15:57 +010070 *
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(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010079 unsigned char *p, size_t n)
Gilles Peskine01bf6312022-11-23 14:15:57 +010080{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010081 return p == NULL ? NULL : p + n;
Gilles Peskine01bf6312022-11-23 14:15:57 +010082}
83
84/** Return an offset into a read-only buffer.
85 *
Gilles Peskineff97f332022-11-25 13:34:59 +010086 * Similar to mbedtls_buffer_offset(), but for const pointers.
Gilles Peskine01bf6312022-11-23 14:15:57 +010087 *
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(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010096 const unsigned char *p, size_t n)
Gilles Peskine01bf6312022-11-23 14:15:57 +010097{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010098 return p == NULL ? NULL : p + n;
Gilles Peskine01bf6312022-11-23 14:15:57 +010099}
100
Joe Subbianiba486b02021-06-22 15:51:53 +0100101/** Byte Reading Macros
Joe Subbiani61f7d732021-06-24 09:06:23 +0100102 *
Joe Subbiani8799e542021-07-21 16:35:48 +0100103 * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th
Joe Subbianid3a3f212021-07-21 15:22:47 +0100104 * byte from x, where byte 0 is the least significant byte.
Joe Subbianiba486b02021-06-22 15:51:53 +0100105 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100106#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))
Joe Subbiani6b897c92021-07-08 14:59:52 +0100114
Joe Subbiani266476d2021-07-07 15:16:56 +0100115/**
Joe Subbiani6350d3a2021-07-13 12:13:19 +0100116 * Get the unsigned 32 bits integer corresponding to four bytes in
Joe Subbiani0a65d532021-07-14 11:53:07 +0100117 * big-endian order (MSB first).
Joe Subbiani266476d2021-07-07 15:16:56 +0100118 *
Joe Subbiani0a65d532021-07-14 11:53:07 +0100119 * \param data Base address of the memory to get the four bytes from.
Joe Subbiani6350d3a2021-07-13 12:13:19 +0100120 * \param offset Offset from \p base of the first and most significant
121 * byte of the four bytes to build the 32 bits unsigned
Joe Subbiani0a65d532021-07-14 11:53:07 +0100122 * integer from.
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100123 */
124#ifndef MBEDTLS_GET_UINT32_BE
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100125#define MBEDTLS_GET_UINT32_BE(data, offset) \
Joe Subbiani896f4ee2021-07-19 15:29:18 +0100126 ( \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100127 ((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]) \
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100131 )
132#endif
133
134/**
Joe Subbiani0a65d532021-07-14 11:53:07 +0100135 * Put in memory a 32 bits unsigned integer in big-endian order.
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100136 *
Joe Subbiani6350d3a2021-07-13 12:13:19 +0100137 * \param n 32 bits unsigned integer to put in memory.
138 * \param data Base address of the memory where to put the 32
Joe Subbiani0a65d532021-07-14 11:53:07 +0100139 * bits unsigned integer in.
Joe Subbiani6350d3a2021-07-13 12:13:19 +0100140 * \param offset Offset from \p base where to put the most significant
Joe Subbiani0a65d532021-07-14 11:53:07 +0100141 * byte of the 32 bits unsigned integer \p n.
Joe Subbiani266476d2021-07-07 15:16:56 +0100142 */
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100143#ifndef MBEDTLS_PUT_UINT32_BE
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100144#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 }
Joe Subbianiaa5f6a62021-06-23 11:49:03 +0100151#endif
152
Joe Subbiani266476d2021-07-07 15:16:56 +0100153/**
Joe Subbiani6350d3a2021-07-13 12:13:19 +0100154 * Get the unsigned 32 bits integer corresponding to four bytes in
Joe Subbiani0a65d532021-07-14 11:53:07 +0100155 * little-endian order (LSB first).
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100156 *
Joe Subbiani0a65d532021-07-14 11:53:07 +0100157 * \param data Base address of the memory to get the four bytes from.
Joe Subbiani6350d3a2021-07-13 12:13:19 +0100158 * \param offset Offset from \p base of the first and least significant
159 * byte of the four bytes to build the 32 bits unsigned
Joe Subbiani0a65d532021-07-14 11:53:07 +0100160 * integer from.
Joe Subbiani4fb75552021-06-23 12:16:47 +0100161 */
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100162#ifndef MBEDTLS_GET_UINT32_LE
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100163#define MBEDTLS_GET_UINT32_LE(data, offset) \
Joe Subbiani896f4ee2021-07-19 15:29:18 +0100164 ( \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100165 ((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) \
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100169 )
Joe Subbiani4fb75552021-06-23 12:16:47 +0100170#endif
171
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100172/**
Joe Subbiani0a65d532021-07-14 11:53:07 +0100173 * Put in memory a 32 bits unsigned integer in little-endian order.
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100174 *
Joe Subbiani6350d3a2021-07-13 12:13:19 +0100175 * \param n 32 bits unsigned integer to put in memory.
176 * \param data Base address of the memory where to put the 32
Joe Subbiani0a65d532021-07-14 11:53:07 +0100177 * bits unsigned integer in.
Joe Subbiani6350d3a2021-07-13 12:13:19 +0100178 * \param offset Offset from \p base where to put the least significant
Joe Subbiani0a65d532021-07-14 11:53:07 +0100179 * byte of the 32 bits unsigned integer \p n.
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100180 */
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100181#ifndef MBEDTLS_PUT_UINT32_LE
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100182#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 }
Joe Subbiani4fb75552021-06-23 12:16:47 +0100189#endif
190
Joe Subbiani61f7d732021-06-24 09:06:23 +0100191/**
Joe Subbiani5b96e672021-07-14 12:05:51 +0100192 * Get the unsigned 16 bits integer corresponding to two bytes in
Joe Subbiani0a65d532021-07-14 11:53:07 +0100193 * little-endian order (LSB first).
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100194 *
Joe Subbiani5b96e672021-07-14 12:05:51 +0100195 * \param data Base address of the memory to get the two bytes from.
Joe Subbiani6350d3a2021-07-13 12:13:19 +0100196 * \param offset Offset from \p base of the first and least significant
Joe Subbiani5b96e672021-07-14 12:05:51 +0100197 * byte of the two bytes to build the 16 bits unsigned
Joe Subbiani0a65d532021-07-14 11:53:07 +0100198 * integer from.
Joe Subbiani927488e2021-06-23 11:23:44 +0100199 */
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100200#ifndef MBEDTLS_GET_UINT16_LE
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100201#define MBEDTLS_GET_UINT16_LE(data, offset) \
Joe Subbiani896f4ee2021-07-19 15:29:18 +0100202 ( \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100203 ((uint16_t) (data)[(offset)]) \
204 | ((uint16_t) (data)[(offset) + 1] << 8) \
Joe Subbiani927488e2021-06-23 11:23:44 +0100205 )
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100206#endif
Joe Subbiani927488e2021-06-23 11:23:44 +0100207
Joe Subbiani266476d2021-07-07 15:16:56 +0100208/**
Joe Subbiani0a65d532021-07-14 11:53:07 +0100209 * Put in memory a 16 bits unsigned integer in little-endian order.
Joe Subbiani266476d2021-07-07 15:16:56 +0100210 *
Joe Subbiani6350d3a2021-07-13 12:13:19 +0100211 * \param n 16 bits unsigned integer to put in memory.
212 * \param data Base address of the memory where to put the 16
Joe Subbiani0a65d532021-07-14 11:53:07 +0100213 * bits unsigned integer in.
Joe Subbiani6350d3a2021-07-13 12:13:19 +0100214 * \param offset Offset from \p base where to put the least significant
Joe Subbiani0a65d532021-07-14 11:53:07 +0100215 * byte of the 16 bits unsigned integer \p n.
Joe Subbiani266476d2021-07-07 15:16:56 +0100216 */
Joe Subbiani4530b272021-07-05 15:37:39 +0100217#ifndef MBEDTLS_PUT_UINT16_LE
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100218#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 }
Joe Subbiani4530b272021-07-05 15:37:39 +0100223#endif
224
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +0100225/**
Joe Subbianic54e9082021-07-19 11:56:54 +0100226 * Get the unsigned 16 bits integer corresponding to two bytes in
Joe Subbiani896f4ee2021-07-19 15:29:18 +0100227 * big-endian order (MSB first).
Joe Subbianic54e9082021-07-19 11:56:54 +0100228 *
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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100235#define MBEDTLS_GET_UINT16_BE(data, offset) \
Joe Subbiani896f4ee2021-07-19 15:29:18 +0100236 ( \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100237 ((uint16_t) (data)[(offset)] << 8) \
238 | ((uint16_t) (data)[(offset) + 1]) \
Joe Subbianic54e9082021-07-19 11:56:54 +0100239 )
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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100252#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 }
Joe Subbianic54e9082021-07-19 11:56:54 +0100257#endif
258
259/**
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +0100260 * 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100269#define MBEDTLS_GET_UINT64_BE(data, offset) \
Joe Subbiani896f4ee2021-07-19 15:29:18 +0100270 ( \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100271 ((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]) \
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +0100279 )
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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100292#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 }
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +0100303#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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100315#define MBEDTLS_GET_UINT64_LE(data, offset) \
Joe Subbiani896f4ee2021-07-19 15:29:18 +0100316 ( \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100317 ((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)]) \
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +0100325 )
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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100338#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 }
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +0100349#endif
Joe Subbiani4530b272021-07-05 15:37:39 +0100350
Tom Cosgrovebdd01a72023-03-08 14:19:51 +0000351/* Always provide a static assert macro, so it can be used unconditionally.
352 * Note that 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#elif defined(__COUNTER__)
362/* gcc will say "size of array ‘mbedtls_static_assert_failedN’ is negative"
363 * (and with -pedantic will complain further);
364 * clang will say "'mbedtls_static_assert_failedN' declared as an array with a
365 * negative size";
366 * Visual Studio will just say "error C2118: negative subscript" (without the
367 * mbedtls_static_assert_failedN part)
368 */
369#if defined(__GNUC__)
370#define MBEDTLS_UNUSED __attribute__((unused))
371#else
372#define MBEDTLS_UNUSED
373#endif
374#define MBEDTLS_STATIC_ASSERT2(expr, count) extern int MBEDTLS_UNUSED mbedtls_static_assert_failed ## count [2 * !!(expr) - 1];
375#define MBEDTLS_STATIC_ASSERT1(expr, count) MBEDTLS_STATIC_ASSERT2(expr, count)
376#define MBEDTLS_STATIC_ASSERT(expr, msg) MBEDTLS_STATIC_ASSERT1(expr, __COUNTER__)
377#else
378#define MBEDTLS_STATIC_ASSERT(expr, msg)
379#endif
380
Gilles Peskinec4672fd2019-09-11 13:39:11 +0200381#endif /* MBEDTLS_LIBRARY_COMMON_H */