17901324dSJerome Forissier /** 27901324dSJerome Forissier * \file common.h 37901324dSJerome Forissier * 47901324dSJerome Forissier * \brief Utility macros for internal use in the library 57901324dSJerome Forissier */ 67901324dSJerome Forissier /* 77901324dSJerome Forissier * Copyright The Mbed TLS Contributors 8*b0563631STom Van Eyck * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 97901324dSJerome Forissier */ 107901324dSJerome Forissier 117901324dSJerome Forissier #ifndef MBEDTLS_LIBRARY_COMMON_H 127901324dSJerome Forissier #define MBEDTLS_LIBRARY_COMMON_H 137901324dSJerome Forissier 1432b31808SJens Wiklander #include "mbedtls/build_info.h" 1532b31808SJens Wiklander #include "alignment.h" 167901324dSJerome Forissier 1732b31808SJens Wiklander #include <assert.h> 1832b31808SJens Wiklander #include <stddef.h> 19039e02dfSJerome Forissier #include <stdint.h> 2032b31808SJens Wiklander #include <stddef.h> 21039e02dfSJerome Forissier 22*b0563631STom Van Eyck #if defined(__ARM_NEON) 23*b0563631STom Van Eyck /* 24*b0563631STom Van Eyck * Undefine and restore __section and __data from compiler.h to prevent 25*b0563631STom Van Eyck * collision with arm_neon.h 26*b0563631STom Van Eyck */ 27*b0563631STom Van Eyck #pragma push_macro("__section") 28*b0563631STom Van Eyck #pragma push_macro("__data") 29*b0563631STom Van Eyck #undef __section 30*b0563631STom Van Eyck #undef __data 31*b0563631STom Van Eyck #include <arm_neon.h> 32*b0563631STom Van Eyck #pragma pop_macro("__data") 33*b0563631STom Van Eyck #pragma pop_macro("__section") 34*b0563631STom Van Eyck #define MBEDTLS_HAVE_NEON_INTRINSICS 35*b0563631STom Van Eyck #elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) 36*b0563631STom Van Eyck #include <arm64_neon.h> 37*b0563631STom Van Eyck #define MBEDTLS_HAVE_NEON_INTRINSICS 38*b0563631STom Van Eyck #endif 39*b0563631STom Van Eyck 407901324dSJerome Forissier /** Helper to define a function as static except when building invasive tests. 417901324dSJerome Forissier * 427901324dSJerome Forissier * If a function is only used inside its own source file and should be 437901324dSJerome Forissier * declared `static` to allow the compiler to optimize for code size, 447901324dSJerome Forissier * but that function has unit tests, define it with 457901324dSJerome Forissier * ``` 467901324dSJerome Forissier * MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... } 477901324dSJerome Forissier * ``` 487901324dSJerome Forissier * and declare it in a header in the `library/` directory with 497901324dSJerome Forissier * ``` 507901324dSJerome Forissier * #if defined(MBEDTLS_TEST_HOOKS) 517901324dSJerome Forissier * int mbedtls_foo(...); 527901324dSJerome Forissier * #endif 537901324dSJerome Forissier * ``` 547901324dSJerome Forissier */ 557901324dSJerome Forissier #if defined(MBEDTLS_TEST_HOOKS) 567901324dSJerome Forissier #define MBEDTLS_STATIC_TESTABLE 577901324dSJerome Forissier #else 587901324dSJerome Forissier #define MBEDTLS_STATIC_TESTABLE static 597901324dSJerome Forissier #endif 607901324dSJerome Forissier 6132b31808SJens Wiklander #if defined(MBEDTLS_TEST_HOOKS) 6232b31808SJens Wiklander extern void (*mbedtls_test_hook_test_fail)(const char *test, int line, const char *file); 6332b31808SJens Wiklander #define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST) \ 6432b31808SJens Wiklander do { \ 6532b31808SJens Wiklander if ((!(TEST)) && ((*mbedtls_test_hook_test_fail) != NULL)) \ 66039e02dfSJerome Forissier { \ 6732b31808SJens Wiklander (*mbedtls_test_hook_test_fail)( #TEST, __LINE__, __FILE__); \ 6832b31808SJens Wiklander } \ 6932b31808SJens Wiklander } while (0) 7032b31808SJens Wiklander #else 7132b31808SJens Wiklander #define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST) 7232b31808SJens Wiklander #endif /* defined(MBEDTLS_TEST_HOOKS) */ 7332b31808SJens Wiklander 74*b0563631STom Van Eyck /** \def ARRAY_LENGTH 75*b0563631STom Van Eyck * Return the number of elements of a static or stack array. 76*b0563631STom Van Eyck * 77*b0563631STom Van Eyck * \param array A value of array (not pointer) type. 78*b0563631STom Van Eyck * 79*b0563631STom Van Eyck * \return The number of elements of the array. 80*b0563631STom Van Eyck */ 81*b0563631STom Van Eyck /* A correct implementation of ARRAY_LENGTH, but which silently gives 82*b0563631STom Van Eyck * a nonsensical result if called with a pointer rather than an array. */ 83*b0563631STom Van Eyck #define ARRAY_LENGTH_UNSAFE(array) \ 84*b0563631STom Van Eyck (sizeof(array) / sizeof(*(array))) 85*b0563631STom Van Eyck 86*b0563631STom Van Eyck #if defined(__GNUC__) 87*b0563631STom Van Eyck /* Test if arg and &(arg)[0] have the same type. This is true if arg is 88*b0563631STom Van Eyck * an array but not if it's a pointer. */ 89*b0563631STom Van Eyck #define IS_ARRAY_NOT_POINTER(arg) \ 90*b0563631STom Van Eyck (!__builtin_types_compatible_p(__typeof__(arg), \ 91*b0563631STom Van Eyck __typeof__(&(arg)[0]))) 92*b0563631STom Van Eyck /* A compile-time constant with the value 0. If `const_expr` is not a 93*b0563631STom Van Eyck * compile-time constant with a nonzero value, cause a compile-time error. */ 94*b0563631STom Van Eyck #define STATIC_ASSERT_EXPR(const_expr) \ 95*b0563631STom Van Eyck (0 && sizeof(struct { unsigned int STATIC_ASSERT : 1 - 2 * !(const_expr); })) 96*b0563631STom Van Eyck 97*b0563631STom Van Eyck /* Return the scalar value `value` (possibly promoted). This is a compile-time 98*b0563631STom Van Eyck * constant if `value` is. `condition` must be a compile-time constant. 99*b0563631STom Van Eyck * If `condition` is false, arrange to cause a compile-time error. */ 100*b0563631STom Van Eyck #define STATIC_ASSERT_THEN_RETURN(condition, value) \ 101*b0563631STom Van Eyck (STATIC_ASSERT_EXPR(condition) ? 0 : (value)) 102*b0563631STom Van Eyck 103*b0563631STom Van Eyck #define ARRAY_LENGTH(array) \ 104*b0563631STom Van Eyck (STATIC_ASSERT_THEN_RETURN(IS_ARRAY_NOT_POINTER(array), \ 105*b0563631STom Van Eyck ARRAY_LENGTH_UNSAFE(array))) 106*b0563631STom Van Eyck 107*b0563631STom Van Eyck #else 108*b0563631STom Van Eyck /* If we aren't sure the compiler supports our non-standard tricks, 109*b0563631STom Van Eyck * fall back to the unsafe implementation. */ 110*b0563631STom Van Eyck #define ARRAY_LENGTH(array) ARRAY_LENGTH_UNSAFE(array) 111*b0563631STom Van Eyck #endif 11232b31808SJens Wiklander /** Allow library to access its structs' private members. 11332b31808SJens Wiklander * 11432b31808SJens Wiklander * Although structs defined in header files are publicly available, 11532b31808SJens Wiklander * their members are private and should not be accessed by the user. 11632b31808SJens Wiklander */ 11732b31808SJens Wiklander #define MBEDTLS_ALLOW_PRIVATE_ACCESS 11832b31808SJens Wiklander 119*b0563631STom Van Eyck /** 120*b0563631STom Van Eyck * \brief Securely zeroize a buffer then free it. 121*b0563631STom Van Eyck * 122*b0563631STom Van Eyck * Similar to making consecutive calls to 123*b0563631STom Van Eyck * \c mbedtls_platform_zeroize() and \c mbedtls_free(), but has 124*b0563631STom Van Eyck * code size savings, and potential for optimisation in the future. 125*b0563631STom Van Eyck * 126*b0563631STom Van Eyck * Guaranteed to be a no-op if \p buf is \c NULL and \p len is 0. 127*b0563631STom Van Eyck * 128*b0563631STom Van Eyck * \param buf Buffer to be zeroized then freed. 129*b0563631STom Van Eyck * \param len Length of the buffer in bytes 130*b0563631STom Van Eyck */ 131*b0563631STom Van Eyck void mbedtls_zeroize_and_free(void *buf, size_t len); 132*b0563631STom Van Eyck 13332b31808SJens Wiklander /** Return an offset into a buffer. 13432b31808SJens Wiklander * 13532b31808SJens Wiklander * This is just the addition of an offset to a pointer, except that this 13632b31808SJens Wiklander * function also accepts an offset of 0 into a buffer whose pointer is null. 13732b31808SJens Wiklander * (`p + n` has undefined behavior when `p` is null, even when `n == 0`. 13832b31808SJens Wiklander * A null pointer is a valid buffer pointer when the size is 0, for example 13932b31808SJens Wiklander * as the result of `malloc(0)` on some platforms.) 14032b31808SJens Wiklander * 14132b31808SJens Wiklander * \param p Pointer to a buffer of at least n bytes. 14232b31808SJens Wiklander * This may be \p NULL if \p n is zero. 14332b31808SJens Wiklander * \param n An offset in bytes. 14432b31808SJens Wiklander * \return Pointer to offset \p n in the buffer \p p. 14532b31808SJens Wiklander * Note that this is only a valid pointer if the size of the 14632b31808SJens Wiklander * buffer is at least \p n + 1. 14732b31808SJens Wiklander */ 14832b31808SJens Wiklander static inline unsigned char *mbedtls_buffer_offset( 14932b31808SJens Wiklander unsigned char *p, size_t n) 15032b31808SJens Wiklander { 15132b31808SJens Wiklander return p == NULL ? NULL : p + n; 15232b31808SJens Wiklander } 15332b31808SJens Wiklander 15432b31808SJens Wiklander /** Return an offset into a read-only buffer. 15532b31808SJens Wiklander * 15632b31808SJens Wiklander * Similar to mbedtls_buffer_offset(), but for const pointers. 15732b31808SJens Wiklander * 15832b31808SJens Wiklander * \param p Pointer to a buffer of at least n bytes. 15932b31808SJens Wiklander * This may be \p NULL if \p n is zero. 16032b31808SJens Wiklander * \param n An offset in bytes. 16132b31808SJens Wiklander * \return Pointer to offset \p n in the buffer \p p. 16232b31808SJens Wiklander * Note that this is only a valid pointer if the size of the 16332b31808SJens Wiklander * buffer is at least \p n + 1. 16432b31808SJens Wiklander */ 16532b31808SJens Wiklander static inline const unsigned char *mbedtls_buffer_offset_const( 16632b31808SJens Wiklander const unsigned char *p, size_t n) 16732b31808SJens Wiklander { 16832b31808SJens Wiklander return p == NULL ? NULL : p + n; 16932b31808SJens Wiklander } 17032b31808SJens Wiklander 171*b0563631STom Van Eyck /* Always inline mbedtls_xor() for similar reasons as mbedtls_xor_no_simd(). */ 172*b0563631STom Van Eyck #if defined(__IAR_SYSTEMS_ICC__) 173*b0563631STom Van Eyck #pragma inline = forced 174*b0563631STom Van Eyck #elif defined(__GNUC__) 175*b0563631STom Van Eyck __attribute__((always_inline)) 176*b0563631STom Van Eyck #endif 17732b31808SJens Wiklander /** 17832b31808SJens Wiklander * Perform a fast block XOR operation, such that 17932b31808SJens Wiklander * r[i] = a[i] ^ b[i] where 0 <= i < n 18032b31808SJens Wiklander * 18132b31808SJens Wiklander * \param r Pointer to result (buffer of at least \p n bytes). \p r 18232b31808SJens Wiklander * may be equal to either \p a or \p b, but behaviour when 18332b31808SJens Wiklander * it overlaps in other ways is undefined. 18432b31808SJens Wiklander * \param a Pointer to input (buffer of at least \p n bytes) 18532b31808SJens Wiklander * \param b Pointer to input (buffer of at least \p n bytes) 18632b31808SJens Wiklander * \param n Number of bytes to process. 187*b0563631STom Van Eyck * 188*b0563631STom Van Eyck * \note Depending on the situation, it may be faster to use either mbedtls_xor() or 189*b0563631STom Van Eyck * mbedtls_xor_no_simd() (these are functionally equivalent). 190*b0563631STom Van Eyck * If the result is used immediately after the xor operation in non-SIMD code (e.g, in 191*b0563631STom Van Eyck * AES-CBC), there may be additional latency to transfer the data from SIMD to scalar 192*b0563631STom Van Eyck * registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where 193*b0563631STom Van Eyck * the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster. 194*b0563631STom Van Eyck * For targets without SIMD support, they will behave the same. 19532b31808SJens Wiklander */ 196*b0563631STom Van Eyck static inline void mbedtls_xor(unsigned char *r, 197*b0563631STom Van Eyck const unsigned char *a, 198*b0563631STom Van Eyck const unsigned char *b, 199*b0563631STom Van Eyck size_t n) 20032b31808SJens Wiklander { 20132b31808SJens Wiklander size_t i = 0; 20232b31808SJens Wiklander #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) 203*b0563631STom Van Eyck #if defined(MBEDTLS_HAVE_NEON_INTRINSICS) && \ 204*b0563631STom Van Eyck (!(defined(MBEDTLS_COMPILER_IS_GCC) && MBEDTLS_GCC_VERSION < 70300)) 205*b0563631STom Van Eyck /* Old GCC versions generate a warning here, so disable the NEON path for these compilers */ 206*b0563631STom Van Eyck for (; (i + 16) <= n; i += 16) { 207*b0563631STom Van Eyck uint8x16_t v1 = vld1q_u8(a + i); 208*b0563631STom Van Eyck uint8x16_t v2 = vld1q_u8(b + i); 209*b0563631STom Van Eyck uint8x16_t x = veorq_u8(v1, v2); 210*b0563631STom Van Eyck vst1q_u8(r + i, x); 211*b0563631STom Van Eyck } 212*b0563631STom Van Eyck #if defined(__IAR_SYSTEMS_ICC__) 213*b0563631STom Van Eyck /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case 214*b0563631STom Van Eyck * where n is a constant multiple of 16. 215*b0563631STom Van Eyck * For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time 216*b0563631STom Van Eyck * constant, and is a very small perf regression if n is not a compile-time constant. */ 217*b0563631STom Van Eyck if (n % 16 == 0) { 218*b0563631STom Van Eyck return; 219*b0563631STom Van Eyck } 220*b0563631STom Van Eyck #endif 221*b0563631STom Van Eyck #elif defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64) 222*b0563631STom Van Eyck /* This codepath probably only makes sense on architectures with 64-bit registers */ 223*b0563631STom Van Eyck for (; (i + 8) <= n; i += 8) { 224*b0563631STom Van Eyck uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i); 225*b0563631STom Van Eyck mbedtls_put_unaligned_uint64(r + i, x); 226*b0563631STom Van Eyck } 227*b0563631STom Van Eyck #if defined(__IAR_SYSTEMS_ICC__) 228*b0563631STom Van Eyck if (n % 8 == 0) { 229*b0563631STom Van Eyck return; 230*b0563631STom Van Eyck } 231*b0563631STom Van Eyck #endif 232*b0563631STom Van Eyck #else 23332b31808SJens Wiklander for (; (i + 4) <= n; i += 4) { 23432b31808SJens Wiklander uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i); 23532b31808SJens Wiklander mbedtls_put_unaligned_uint32(r + i, x); 236039e02dfSJerome Forissier } 237*b0563631STom Van Eyck #if defined(__IAR_SYSTEMS_ICC__) 238*b0563631STom Van Eyck if (n % 4 == 0) { 239*b0563631STom Van Eyck return; 240*b0563631STom Van Eyck } 241*b0563631STom Van Eyck #endif 242*b0563631STom Van Eyck #endif 243*b0563631STom Van Eyck #endif 244*b0563631STom Van Eyck for (; i < n; i++) { 245*b0563631STom Van Eyck r[i] = a[i] ^ b[i]; 246*b0563631STom Van Eyck } 247*b0563631STom Van Eyck } 248*b0563631STom Van Eyck 249*b0563631STom Van Eyck /* Always inline mbedtls_xor_no_simd() as we see significant perf regressions when it does not get 250*b0563631STom Van Eyck * inlined (e.g., observed about 3x perf difference in gcm_mult_largetable with gcc 7 - 12) */ 251*b0563631STom Van Eyck #if defined(__IAR_SYSTEMS_ICC__) 252*b0563631STom Van Eyck #pragma inline = forced 253*b0563631STom Van Eyck #elif defined(__GNUC__) 254*b0563631STom Van Eyck __attribute__((always_inline)) 255*b0563631STom Van Eyck #endif 256*b0563631STom Van Eyck /** 257*b0563631STom Van Eyck * Perform a fast block XOR operation, such that 258*b0563631STom Van Eyck * r[i] = a[i] ^ b[i] where 0 <= i < n 259*b0563631STom Van Eyck * 260*b0563631STom Van Eyck * In some situations, this can perform better than mbedtls_xor() (e.g., it's about 5% 261*b0563631STom Van Eyck * better in AES-CBC). 262*b0563631STom Van Eyck * 263*b0563631STom Van Eyck * \param r Pointer to result (buffer of at least \p n bytes). \p r 264*b0563631STom Van Eyck * may be equal to either \p a or \p b, but behaviour when 265*b0563631STom Van Eyck * it overlaps in other ways is undefined. 266*b0563631STom Van Eyck * \param a Pointer to input (buffer of at least \p n bytes) 267*b0563631STom Van Eyck * \param b Pointer to input (buffer of at least \p n bytes) 268*b0563631STom Van Eyck * \param n Number of bytes to process. 269*b0563631STom Van Eyck * 270*b0563631STom Van Eyck * \note Depending on the situation, it may be faster to use either mbedtls_xor() or 271*b0563631STom Van Eyck * mbedtls_xor_no_simd() (these are functionally equivalent). 272*b0563631STom Van Eyck * If the result is used immediately after the xor operation in non-SIMD code (e.g, in 273*b0563631STom Van Eyck * AES-CBC), there may be additional latency to transfer the data from SIMD to scalar 274*b0563631STom Van Eyck * registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where 275*b0563631STom Van Eyck * the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster. 276*b0563631STom Van Eyck * For targets without SIMD support, they will behave the same. 277*b0563631STom Van Eyck */ 278*b0563631STom Van Eyck static inline void mbedtls_xor_no_simd(unsigned char *r, 279*b0563631STom Van Eyck const unsigned char *a, 280*b0563631STom Van Eyck const unsigned char *b, 281*b0563631STom Van Eyck size_t n) 282*b0563631STom Van Eyck { 283*b0563631STom Van Eyck size_t i = 0; 284*b0563631STom Van Eyck #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) 285*b0563631STom Van Eyck #if defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64) 286*b0563631STom Van Eyck /* This codepath probably only makes sense on architectures with 64-bit registers */ 287*b0563631STom Van Eyck for (; (i + 8) <= n; i += 8) { 288*b0563631STom Van Eyck uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i); 289*b0563631STom Van Eyck mbedtls_put_unaligned_uint64(r + i, x); 290*b0563631STom Van Eyck } 291*b0563631STom Van Eyck #if defined(__IAR_SYSTEMS_ICC__) 292*b0563631STom Van Eyck /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case 293*b0563631STom Van Eyck * where n is a constant multiple of 8. 294*b0563631STom Van Eyck * For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time 295*b0563631STom Van Eyck * constant, and is a very small perf regression if n is not a compile-time constant. */ 296*b0563631STom Van Eyck if (n % 8 == 0) { 297*b0563631STom Van Eyck return; 298*b0563631STom Van Eyck } 299*b0563631STom Van Eyck #endif 300*b0563631STom Van Eyck #else 301*b0563631STom Van Eyck for (; (i + 4) <= n; i += 4) { 302*b0563631STom Van Eyck uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i); 303*b0563631STom Van Eyck mbedtls_put_unaligned_uint32(r + i, x); 304*b0563631STom Van Eyck } 305*b0563631STom Van Eyck #if defined(__IAR_SYSTEMS_ICC__) 306*b0563631STom Van Eyck if (n % 4 == 0) { 307*b0563631STom Van Eyck return; 308*b0563631STom Van Eyck } 309*b0563631STom Van Eyck #endif 310*b0563631STom Van Eyck #endif 311039e02dfSJerome Forissier #endif 31232b31808SJens Wiklander for (; i < n; i++) { 31332b31808SJens Wiklander r[i] = a[i] ^ b[i]; 314039e02dfSJerome Forissier } 315039e02dfSJerome Forissier } 31632b31808SJens Wiklander 31732b31808SJens Wiklander /* Fix MSVC C99 compatible issue 31832b31808SJens Wiklander * MSVC support __func__ from visual studio 2015( 1900 ) 31932b31808SJens Wiklander * Use MSVC predefine macro to avoid name check fail. 32032b31808SJens Wiklander */ 32132b31808SJens Wiklander #if (defined(_MSC_VER) && (_MSC_VER <= 1900)) 32232b31808SJens Wiklander #define /*no-check-names*/ __func__ __FUNCTION__ 323039e02dfSJerome Forissier #endif 324039e02dfSJerome Forissier 32532b31808SJens Wiklander /* Define `asm` for compilers which don't define it. */ 32632b31808SJens Wiklander /* *INDENT-OFF* */ 32732b31808SJens Wiklander #ifndef asm 328*b0563631STom Van Eyck #if defined(__IAR_SYSTEMS_ICC__) 329*b0563631STom Van Eyck #define asm __asm 330*b0563631STom Van Eyck #else 33132b31808SJens Wiklander #define asm __asm__ 332039e02dfSJerome Forissier #endif 333*b0563631STom Van Eyck #endif 33432b31808SJens Wiklander /* *INDENT-ON* */ 335039e02dfSJerome Forissier 336*b0563631STom Van Eyck /* 337*b0563631STom Van Eyck * Define the constraint used for read-only pointer operands to aarch64 asm. 338*b0563631STom Van Eyck * 339*b0563631STom Van Eyck * This is normally the usual "r", but for aarch64_32 (aka ILP32, 340*b0563631STom Van Eyck * as found in watchos), "p" is required to avoid warnings from clang. 341*b0563631STom Van Eyck * 342*b0563631STom Van Eyck * Note that clang does not recognise '+p' or '=p', and armclang 343*b0563631STom Van Eyck * does not recognise 'p' at all. Therefore, to update a pointer from 344*b0563631STom Van Eyck * aarch64 assembly, it is necessary to use something like: 345*b0563631STom Van Eyck * 346*b0563631STom Van Eyck * uintptr_t uptr = (uintptr_t) ptr; 347*b0563631STom Van Eyck * asm( "ldr x4, [%x0], #8" ... : "+r" (uptr) : : ) 348*b0563631STom Van Eyck * ptr = (void*) uptr; 349*b0563631STom Van Eyck * 350*b0563631STom Van Eyck * Note that the "x" in "%x0" is neccessary; writing "%0" will cause warnings. 351*b0563631STom Van Eyck */ 352*b0563631STom Van Eyck #if defined(__aarch64__) && defined(MBEDTLS_HAVE_ASM) 353*b0563631STom Van Eyck #if UINTPTR_MAX == 0xfffffffful 354*b0563631STom Van Eyck /* ILP32: Specify the pointer operand slightly differently, as per #7787. */ 355*b0563631STom Van Eyck #define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "p" 356*b0563631STom Van Eyck #elif UINTPTR_MAX == 0xfffffffffffffffful 357*b0563631STom Van Eyck /* Normal case (64-bit pointers): use "r" as the constraint for pointer operands to asm */ 358*b0563631STom Van Eyck #define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "r" 359*b0563631STom Van Eyck #else 360*b0563631STom Van Eyck #error "Unrecognised pointer size for aarch64" 361*b0563631STom Van Eyck #endif 362*b0563631STom Van Eyck #endif 363*b0563631STom Van Eyck 36432b31808SJens Wiklander /* Always provide a static assert macro, so it can be used unconditionally. 36532b31808SJens Wiklander * It will expand to nothing on some systems. 36632b31808SJens Wiklander * Can be used outside functions (but don't add a trailing ';' in that case: 36732b31808SJens Wiklander * the semicolon is included here to avoid triggering -Wextra-semi when 36832b31808SJens Wiklander * MBEDTLS_STATIC_ASSERT() expands to nothing). 36932b31808SJens Wiklander * Can't use the C11-style `defined(static_assert)` on FreeBSD, since it 37032b31808SJens Wiklander * defines static_assert even with -std=c99, but then complains about it. 371039e02dfSJerome Forissier */ 37232b31808SJens Wiklander #if defined(static_assert) && !defined(__FreeBSD__) 37332b31808SJens Wiklander #define MBEDTLS_STATIC_ASSERT(expr, msg) static_assert(expr, msg); 37432b31808SJens Wiklander #else 37532b31808SJens Wiklander #define MBEDTLS_STATIC_ASSERT(expr, msg) 376039e02dfSJerome Forissier #endif 377039e02dfSJerome Forissier 378*b0563631STom Van Eyck #if defined(__has_builtin) 379*b0563631STom Van Eyck #define MBEDTLS_HAS_BUILTIN(x) __has_builtin(x) 380*b0563631STom Van Eyck #else 381*b0563631STom Van Eyck #define MBEDTLS_HAS_BUILTIN(x) 0 382*b0563631STom Van Eyck #endif 383*b0563631STom Van Eyck 384*b0563631STom Van Eyck /* Define compiler branch hints */ 385*b0563631STom Van Eyck #if MBEDTLS_HAS_BUILTIN(__builtin_expect) 386*b0563631STom Van Eyck #define MBEDTLS_LIKELY(x) __builtin_expect(!!(x), 1) 387*b0563631STom Van Eyck #define MBEDTLS_UNLIKELY(x) __builtin_expect(!!(x), 0) 388*b0563631STom Van Eyck #else 389*b0563631STom Van Eyck #define MBEDTLS_LIKELY(x) x 390*b0563631STom Van Eyck #define MBEDTLS_UNLIKELY(x) x 391*b0563631STom Van Eyck #endif 392*b0563631STom Van Eyck 393*b0563631STom Van Eyck /* MBEDTLS_ASSUME may be used to provide additional information to the compiler 394*b0563631STom Van Eyck * which can result in smaller code-size. */ 395*b0563631STom Van Eyck #if MBEDTLS_HAS_BUILTIN(__builtin_assume) 396*b0563631STom Van Eyck /* clang provides __builtin_assume */ 397*b0563631STom Van Eyck #define MBEDTLS_ASSUME(x) __builtin_assume(x) 398*b0563631STom Van Eyck #elif MBEDTLS_HAS_BUILTIN(__builtin_unreachable) 399*b0563631STom Van Eyck /* gcc and IAR can use __builtin_unreachable */ 400*b0563631STom Van Eyck #define MBEDTLS_ASSUME(x) do { if (!(x)) __builtin_unreachable(); } while (0) 401*b0563631STom Van Eyck #elif defined(_MSC_VER) 402*b0563631STom Van Eyck /* Supported by MSVC since VS 2005 */ 403*b0563631STom Van Eyck #define MBEDTLS_ASSUME(x) __assume(x) 404*b0563631STom Van Eyck #else 405*b0563631STom Van Eyck #define MBEDTLS_ASSUME(x) do { } while (0) 406*b0563631STom Van Eyck #endif 407*b0563631STom Van Eyck 408*b0563631STom Van Eyck /* For gcc -Os, override with -O2 for a given function. 409*b0563631STom Van Eyck * 410*b0563631STom Van Eyck * This will not affect behaviour for other optimisation settings, e.g. -O0. 411*b0563631STom Van Eyck */ 412*b0563631STom Van Eyck #if defined(MBEDTLS_COMPILER_IS_GCC) && defined(__OPTIMIZE_SIZE__) 413*b0563631STom Van Eyck #define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE __attribute__((optimize("-O2"))) 414*b0563631STom Van Eyck #else 415*b0563631STom Van Eyck #define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE 416*b0563631STom Van Eyck #endif 417*b0563631STom Van Eyck 418*b0563631STom Van Eyck /* Suppress compiler warnings for unused functions and variables. */ 419*b0563631STom Van Eyck #if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__has_attribute) 420*b0563631STom Van Eyck # if __has_attribute(unused) 421*b0563631STom Van Eyck # define MBEDTLS_MAYBE_UNUSED __attribute__((unused)) 422*b0563631STom Van Eyck # endif 423*b0563631STom Van Eyck #endif 424*b0563631STom Van Eyck #if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__GNUC__) 425*b0563631STom Van Eyck # define MBEDTLS_MAYBE_UNUSED __attribute__((unused)) 426*b0563631STom Van Eyck #endif 427*b0563631STom Van Eyck #if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__IAR_SYSTEMS_ICC__) && defined(__VER__) 428*b0563631STom Van Eyck /* IAR does support __attribute__((unused)), but only if the -e flag (extended language support) 429*b0563631STom Van Eyck * is given; the pragma always works. 430*b0563631STom Van Eyck * Unfortunately the pragma affects the rest of the file where it is used, but this is harmless. 431*b0563631STom Van Eyck * Check for version 5.2 or later - this pragma may be supported by earlier versions, but I wasn't 432*b0563631STom Van Eyck * able to find documentation). 433*b0563631STom Van Eyck */ 434*b0563631STom Van Eyck # if (__VER__ >= 5020000) 435*b0563631STom Van Eyck # define MBEDTLS_MAYBE_UNUSED _Pragma("diag_suppress=Pe177") 436*b0563631STom Van Eyck # endif 437*b0563631STom Van Eyck #endif 438*b0563631STom Van Eyck #if !defined(MBEDTLS_MAYBE_UNUSED) && defined(_MSC_VER) 439*b0563631STom Van Eyck # define MBEDTLS_MAYBE_UNUSED __pragma(warning(suppress:4189)) 440*b0563631STom Van Eyck #endif 441*b0563631STom Van Eyck #if !defined(MBEDTLS_MAYBE_UNUSED) 442*b0563631STom Van Eyck # define MBEDTLS_MAYBE_UNUSED 443*b0563631STom Van Eyck #endif 444*b0563631STom Van Eyck 4457901324dSJerome Forissier #endif /* MBEDTLS_LIBRARY_COMMON_H */ 446