2
0

common.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  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. #ifndef MBEDTLS_LIBRARY_COMMON_H
  11. #define MBEDTLS_LIBRARY_COMMON_H
  12. #include "mbedtls/build_info.h"
  13. #include "alignment.h"
  14. #include <assert.h>
  15. #include <stddef.h>
  16. #include <stdint.h>
  17. #include <stddef.h>
  18. #if defined(__ARM_NEON)
  19. #include <arm_neon.h>
  20. #define MBEDTLS_HAVE_NEON_INTRINSICS
  21. #elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
  22. #include <arm64_neon.h>
  23. #define MBEDTLS_HAVE_NEON_INTRINSICS
  24. #endif
  25. /** Helper to define a function as static except when building invasive tests.
  26. *
  27. * If a function is only used inside its own source file and should be
  28. * declared `static` to allow the compiler to optimize for code size,
  29. * but that function has unit tests, define it with
  30. * ```
  31. * MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... }
  32. * ```
  33. * and declare it in a header in the `library/` directory with
  34. * ```
  35. * #if defined(MBEDTLS_TEST_HOOKS)
  36. * int mbedtls_foo(...);
  37. * #endif
  38. * ```
  39. */
  40. #if defined(MBEDTLS_TEST_HOOKS)
  41. #define MBEDTLS_STATIC_TESTABLE
  42. #else
  43. #define MBEDTLS_STATIC_TESTABLE static
  44. #endif
  45. #if defined(MBEDTLS_TEST_HOOKS)
  46. extern void (*mbedtls_test_hook_test_fail)(const char *test, int line, const char *file);
  47. #define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST) \
  48. do { \
  49. if ((!(TEST)) && ((*mbedtls_test_hook_test_fail) != NULL)) \
  50. { \
  51. (*mbedtls_test_hook_test_fail)( #TEST, __LINE__, __FILE__); \
  52. } \
  53. } while (0)
  54. #else
  55. #define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST)
  56. #endif /* defined(MBEDTLS_TEST_HOOKS) */
  57. /** \def ARRAY_LENGTH
  58. * Return the number of elements of a static or stack array.
  59. *
  60. * \param array A value of array (not pointer) type.
  61. *
  62. * \return The number of elements of the array.
  63. */
  64. /* A correct implementation of ARRAY_LENGTH, but which silently gives
  65. * a nonsensical result if called with a pointer rather than an array. */
  66. #define ARRAY_LENGTH_UNSAFE(array) \
  67. (sizeof(array) / sizeof(*(array)))
  68. #if defined(__GNUC__)
  69. /* Test if arg and &(arg)[0] have the same type. This is true if arg is
  70. * an array but not if it's a pointer. */
  71. #define IS_ARRAY_NOT_POINTER(arg) \
  72. (!__builtin_types_compatible_p(__typeof__(arg), \
  73. __typeof__(&(arg)[0])))
  74. /* A compile-time constant with the value 0. If `const_expr` is not a
  75. * compile-time constant with a nonzero value, cause a compile-time error. */
  76. #define STATIC_ASSERT_EXPR(const_expr) \
  77. (0 && sizeof(struct { unsigned int STATIC_ASSERT : 1 - 2 * !(const_expr); }))
  78. /* Return the scalar value `value` (possibly promoted). This is a compile-time
  79. * constant if `value` is. `condition` must be a compile-time constant.
  80. * If `condition` is false, arrange to cause a compile-time error. */
  81. #define STATIC_ASSERT_THEN_RETURN(condition, value) \
  82. (STATIC_ASSERT_EXPR(condition) ? 0 : (value))
  83. #define ARRAY_LENGTH(array) \
  84. (STATIC_ASSERT_THEN_RETURN(IS_ARRAY_NOT_POINTER(array), \
  85. ARRAY_LENGTH_UNSAFE(array)))
  86. #else
  87. /* If we aren't sure the compiler supports our non-standard tricks,
  88. * fall back to the unsafe implementation. */
  89. #define ARRAY_LENGTH(array) ARRAY_LENGTH_UNSAFE(array)
  90. #endif
  91. /** Allow library to access its structs' private members.
  92. *
  93. * Although structs defined in header files are publicly available,
  94. * their members are private and should not be accessed by the user.
  95. */
  96. #define MBEDTLS_ALLOW_PRIVATE_ACCESS
  97. /**
  98. * \brief Securely zeroize a buffer then free it.
  99. *
  100. * Similar to making consecutive calls to
  101. * \c mbedtls_platform_zeroize() and \c mbedtls_free(), but has
  102. * code size savings, and potential for optimisation in the future.
  103. *
  104. * Guaranteed to be a no-op if \p buf is \c NULL and \p len is 0.
  105. *
  106. * \param buf Buffer to be zeroized then freed.
  107. * \param len Length of the buffer in bytes
  108. */
  109. void mbedtls_zeroize_and_free(void *buf, size_t len);
  110. /** Return an offset into a buffer.
  111. *
  112. * This is just the addition of an offset to a pointer, except that this
  113. * function also accepts an offset of 0 into a buffer whose pointer is null.
  114. * (`p + n` has undefined behavior when `p` is null, even when `n == 0`.
  115. * A null pointer is a valid buffer pointer when the size is 0, for example
  116. * as the result of `malloc(0)` on some platforms.)
  117. *
  118. * \param p Pointer to a buffer of at least n bytes.
  119. * This may be \p NULL if \p n is zero.
  120. * \param n An offset in bytes.
  121. * \return Pointer to offset \p n in the buffer \p p.
  122. * Note that this is only a valid pointer if the size of the
  123. * buffer is at least \p n + 1.
  124. */
  125. static inline unsigned char *mbedtls_buffer_offset(
  126. unsigned char *p, size_t n)
  127. {
  128. return p == NULL ? NULL : p + n;
  129. }
  130. /** Return an offset into a read-only buffer.
  131. *
  132. * Similar to mbedtls_buffer_offset(), but for const pointers.
  133. *
  134. * \param p Pointer to a buffer of at least n bytes.
  135. * This may be \p NULL if \p n is zero.
  136. * \param n An offset in bytes.
  137. * \return Pointer to offset \p n in the buffer \p p.
  138. * Note that this is only a valid pointer if the size of the
  139. * buffer is at least \p n + 1.
  140. */
  141. static inline const unsigned char *mbedtls_buffer_offset_const(
  142. const unsigned char *p, size_t n)
  143. {
  144. return p == NULL ? NULL : p + n;
  145. }
  146. /* Always inline mbedtls_xor() for similar reasons as mbedtls_xor_no_simd(). */
  147. #if defined(__IAR_SYSTEMS_ICC__)
  148. #pragma inline = forced
  149. #elif defined(__GNUC__)
  150. __attribute__((always_inline))
  151. #endif
  152. /**
  153. * Perform a fast block XOR operation, such that
  154. * r[i] = a[i] ^ b[i] where 0 <= i < n
  155. *
  156. * \param r Pointer to result (buffer of at least \p n bytes). \p r
  157. * may be equal to either \p a or \p b, but behaviour when
  158. * it overlaps in other ways is undefined.
  159. * \param a Pointer to input (buffer of at least \p n bytes)
  160. * \param b Pointer to input (buffer of at least \p n bytes)
  161. * \param n Number of bytes to process.
  162. *
  163. * \note Depending on the situation, it may be faster to use either mbedtls_xor() or
  164. * mbedtls_xor_no_simd() (these are functionally equivalent).
  165. * If the result is used immediately after the xor operation in non-SIMD code (e.g, in
  166. * AES-CBC), there may be additional latency to transfer the data from SIMD to scalar
  167. * registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where
  168. * the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster.
  169. * For targets without SIMD support, they will behave the same.
  170. */
  171. static inline void mbedtls_xor(unsigned char *r,
  172. const unsigned char *a,
  173. const unsigned char *b,
  174. size_t n)
  175. {
  176. size_t i = 0;
  177. #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
  178. #if defined(MBEDTLS_HAVE_NEON_INTRINSICS) && \
  179. (!(defined(MBEDTLS_COMPILER_IS_GCC) && MBEDTLS_GCC_VERSION < 70300))
  180. /* Old GCC versions generate a warning here, so disable the NEON path for these compilers */
  181. for (; (i + 16) <= n; i += 16) {
  182. uint8x16_t v1 = vld1q_u8(a + i);
  183. uint8x16_t v2 = vld1q_u8(b + i);
  184. uint8x16_t x = veorq_u8(v1, v2);
  185. vst1q_u8(r + i, x);
  186. }
  187. #if defined(__IAR_SYSTEMS_ICC__)
  188. /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case
  189. * where n is a constant multiple of 16.
  190. * For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time
  191. * constant, and is a very small perf regression if n is not a compile-time constant. */
  192. if (n % 16 == 0) {
  193. return;
  194. }
  195. #endif
  196. #elif defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64)
  197. /* This codepath probably only makes sense on architectures with 64-bit registers */
  198. for (; (i + 8) <= n; i += 8) {
  199. uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
  200. mbedtls_put_unaligned_uint64(r + i, x);
  201. }
  202. #if defined(__IAR_SYSTEMS_ICC__)
  203. if (n % 8 == 0) {
  204. return;
  205. }
  206. #endif
  207. #else
  208. for (; (i + 4) <= n; i += 4) {
  209. uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
  210. mbedtls_put_unaligned_uint32(r + i, x);
  211. }
  212. #if defined(__IAR_SYSTEMS_ICC__)
  213. if (n % 4 == 0) {
  214. return;
  215. }
  216. #endif
  217. #endif
  218. #endif
  219. for (; i < n; i++) {
  220. r[i] = a[i] ^ b[i];
  221. }
  222. }
  223. /* Always inline mbedtls_xor_no_simd() as we see significant perf regressions when it does not get
  224. * inlined (e.g., observed about 3x perf difference in gcm_mult_largetable with gcc 7 - 12) */
  225. #if defined(__IAR_SYSTEMS_ICC__)
  226. #pragma inline = forced
  227. #elif defined(__GNUC__)
  228. __attribute__((always_inline))
  229. #endif
  230. /**
  231. * Perform a fast block XOR operation, such that
  232. * r[i] = a[i] ^ b[i] where 0 <= i < n
  233. *
  234. * In some situations, this can perform better than mbedtls_xor() (e.g., it's about 5%
  235. * better in AES-CBC).
  236. *
  237. * \param r Pointer to result (buffer of at least \p n bytes). \p r
  238. * may be equal to either \p a or \p b, but behaviour when
  239. * it overlaps in other ways is undefined.
  240. * \param a Pointer to input (buffer of at least \p n bytes)
  241. * \param b Pointer to input (buffer of at least \p n bytes)
  242. * \param n Number of bytes to process.
  243. *
  244. * \note Depending on the situation, it may be faster to use either mbedtls_xor() or
  245. * mbedtls_xor_no_simd() (these are functionally equivalent).
  246. * If the result is used immediately after the xor operation in non-SIMD code (e.g, in
  247. * AES-CBC), there may be additional latency to transfer the data from SIMD to scalar
  248. * registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where
  249. * the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster.
  250. * For targets without SIMD support, they will behave the same.
  251. */
  252. static inline void mbedtls_xor_no_simd(unsigned char *r,
  253. const unsigned char *a,
  254. const unsigned char *b,
  255. size_t n)
  256. {
  257. size_t i = 0;
  258. #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
  259. #if defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64)
  260. /* This codepath probably only makes sense on architectures with 64-bit registers */
  261. for (; (i + 8) <= n; i += 8) {
  262. uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
  263. mbedtls_put_unaligned_uint64(r + i, x);
  264. }
  265. #if defined(__IAR_SYSTEMS_ICC__)
  266. /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case
  267. * where n is a constant multiple of 8.
  268. * For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time
  269. * constant, and is a very small perf regression if n is not a compile-time constant. */
  270. if (n % 8 == 0) {
  271. return;
  272. }
  273. #endif
  274. #else
  275. for (; (i + 4) <= n; i += 4) {
  276. uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
  277. mbedtls_put_unaligned_uint32(r + i, x);
  278. }
  279. #if defined(__IAR_SYSTEMS_ICC__)
  280. if (n % 4 == 0) {
  281. return;
  282. }
  283. #endif
  284. #endif
  285. #endif
  286. for (; i < n; i++) {
  287. r[i] = a[i] ^ b[i];
  288. }
  289. }
  290. /* Fix MSVC C99 compatible issue
  291. * MSVC support __func__ from visual studio 2015( 1900 )
  292. * Use MSVC predefine macro to avoid name check fail.
  293. */
  294. #if (defined(_MSC_VER) && (_MSC_VER <= 1900))
  295. #define /*no-check-names*/ __func__ __FUNCTION__
  296. #endif
  297. /* Define `asm` for compilers which don't define it. */
  298. /* *INDENT-OFF* */
  299. #ifndef asm
  300. #if defined(__IAR_SYSTEMS_ICC__)
  301. #define asm __asm
  302. #else
  303. #define asm __asm__
  304. #endif
  305. #endif
  306. /* *INDENT-ON* */
  307. /*
  308. * Define the constraint used for read-only pointer operands to aarch64 asm.
  309. *
  310. * This is normally the usual "r", but for aarch64_32 (aka ILP32,
  311. * as found in watchos), "p" is required to avoid warnings from clang.
  312. *
  313. * Note that clang does not recognise '+p' or '=p', and armclang
  314. * does not recognise 'p' at all. Therefore, to update a pointer from
  315. * aarch64 assembly, it is necessary to use something like:
  316. *
  317. * uintptr_t uptr = (uintptr_t) ptr;
  318. * asm( "ldr x4, [%x0], #8" ... : "+r" (uptr) : : )
  319. * ptr = (void*) uptr;
  320. *
  321. * Note that the "x" in "%x0" is neccessary; writing "%0" will cause warnings.
  322. */
  323. #if defined(__aarch64__) && defined(MBEDTLS_HAVE_ASM)
  324. #if UINTPTR_MAX == 0xfffffffful
  325. /* ILP32: Specify the pointer operand slightly differently, as per #7787. */
  326. #define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "p"
  327. #elif UINTPTR_MAX == 0xfffffffffffffffful
  328. /* Normal case (64-bit pointers): use "r" as the constraint for pointer operands to asm */
  329. #define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "r"
  330. #else
  331. #error "Unrecognised pointer size for aarch64"
  332. #endif
  333. #endif
  334. /* Always provide a static assert macro, so it can be used unconditionally.
  335. * It does nothing on systems where we don't know how to define a static assert.
  336. */
  337. /* Can't use the C11-style `defined(static_assert)` on FreeBSD, since it
  338. * defines static_assert even with -std=c99, but then complains about it.
  339. */
  340. #if defined(static_assert) && !defined(__FreeBSD__)
  341. #define MBEDTLS_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
  342. #else
  343. /* Make sure `MBEDTLS_STATIC_ASSERT(expr, msg);` is valid both inside and
  344. * outside a function. We choose a struct declaration, which can be repeated
  345. * any number of times and does not need a matching definition. */
  346. #define MBEDTLS_STATIC_ASSERT(expr, msg) \
  347. struct ISO_C_does_not_allow_extra_semicolon_outside_of_a_function
  348. #endif
  349. #if defined(__has_builtin)
  350. #define MBEDTLS_HAS_BUILTIN(x) __has_builtin(x)
  351. #else
  352. #define MBEDTLS_HAS_BUILTIN(x) 0
  353. #endif
  354. /* Define compiler branch hints */
  355. #if MBEDTLS_HAS_BUILTIN(__builtin_expect)
  356. #define MBEDTLS_LIKELY(x) __builtin_expect(!!(x), 1)
  357. #define MBEDTLS_UNLIKELY(x) __builtin_expect(!!(x), 0)
  358. #else
  359. #define MBEDTLS_LIKELY(x) x
  360. #define MBEDTLS_UNLIKELY(x) x
  361. #endif
  362. /* MBEDTLS_ASSUME may be used to provide additional information to the compiler
  363. * which can result in smaller code-size. */
  364. #if MBEDTLS_HAS_BUILTIN(__builtin_assume)
  365. /* clang provides __builtin_assume */
  366. #define MBEDTLS_ASSUME(x) __builtin_assume(x)
  367. #elif MBEDTLS_HAS_BUILTIN(__builtin_unreachable)
  368. /* gcc and IAR can use __builtin_unreachable */
  369. #define MBEDTLS_ASSUME(x) do { if (!(x)) __builtin_unreachable(); } while (0)
  370. #elif defined(_MSC_VER)
  371. /* Supported by MSVC since VS 2005 */
  372. #define MBEDTLS_ASSUME(x) __assume(x)
  373. #else
  374. #define MBEDTLS_ASSUME(x) do { } while (0)
  375. #endif
  376. /* For gcc -Os, override with -O2 for a given function.
  377. *
  378. * This will not affect behaviour for other optimisation settings, e.g. -O0.
  379. */
  380. #if defined(MBEDTLS_COMPILER_IS_GCC) && defined(__OPTIMIZE_SIZE__)
  381. #define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE __attribute__((optimize("-O2")))
  382. #else
  383. #define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
  384. #endif
  385. /* Suppress compiler warnings for unused functions and variables. */
  386. #if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__has_attribute)
  387. # if __has_attribute(unused)
  388. # define MBEDTLS_MAYBE_UNUSED __attribute__((unused))
  389. # endif
  390. #endif
  391. #if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__GNUC__)
  392. # define MBEDTLS_MAYBE_UNUSED __attribute__((unused))
  393. #endif
  394. #if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__IAR_SYSTEMS_ICC__) && defined(__VER__)
  395. /* IAR does support __attribute__((unused)), but only if the -e flag (extended language support)
  396. * is given; the pragma always works.
  397. * Unfortunately the pragma affects the rest of the file where it is used, but this is harmless.
  398. * Check for version 5.2 or later - this pragma may be supported by earlier versions, but I wasn't
  399. * able to find documentation).
  400. */
  401. # if (__VER__ >= 5020000)
  402. # define MBEDTLS_MAYBE_UNUSED _Pragma("diag_suppress=Pe177")
  403. # endif
  404. #endif
  405. #if !defined(MBEDTLS_MAYBE_UNUSED) && defined(_MSC_VER)
  406. # define MBEDTLS_MAYBE_UNUSED __pragma(warning(suppress:4189))
  407. #endif
  408. #if !defined(MBEDTLS_MAYBE_UNUSED)
  409. # define MBEDTLS_MAYBE_UNUSED
  410. #endif
  411. #endif /* MBEDTLS_LIBRARY_COMMON_H */