common.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. #ifndef MBEDTLS_LIBRARY_COMMON_H
  23. #define MBEDTLS_LIBRARY_COMMON_H
  24. #include "mbedtls/build_info.h"
  25. #include "alignment.h"
  26. #include <assert.h>
  27. #include <stddef.h>
  28. #include <stdint.h>
  29. #include <stddef.h>
  30. /** Helper to define a function as static except when building invasive tests.
  31. *
  32. * If a function is only used inside its own source file and should be
  33. * declared `static` to allow the compiler to optimize for code size,
  34. * but that function has unit tests, define it with
  35. * ```
  36. * MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... }
  37. * ```
  38. * and declare it in a header in the `library/` directory with
  39. * ```
  40. * #if defined(MBEDTLS_TEST_HOOKS)
  41. * int mbedtls_foo(...);
  42. * #endif
  43. * ```
  44. */
  45. #if defined(MBEDTLS_TEST_HOOKS)
  46. #define MBEDTLS_STATIC_TESTABLE
  47. #else
  48. #define MBEDTLS_STATIC_TESTABLE static
  49. #endif
  50. #if defined(MBEDTLS_TEST_HOOKS)
  51. extern void (*mbedtls_test_hook_test_fail)(const char *test, int line, const char *file);
  52. #define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST) \
  53. do { \
  54. if ((!(TEST)) && ((*mbedtls_test_hook_test_fail) != NULL)) \
  55. { \
  56. (*mbedtls_test_hook_test_fail)( #TEST, __LINE__, __FILE__); \
  57. } \
  58. } while (0)
  59. #else
  60. #define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST)
  61. #endif /* defined(MBEDTLS_TEST_HOOKS) */
  62. /** Allow library to access its structs' private members.
  63. *
  64. * Although structs defined in header files are publicly available,
  65. * their members are private and should not be accessed by the user.
  66. */
  67. #define MBEDTLS_ALLOW_PRIVATE_ACCESS
  68. /** Return an offset into a buffer.
  69. *
  70. * This is just the addition of an offset to a pointer, except that this
  71. * function also accepts an offset of 0 into a buffer whose pointer is null.
  72. * (`p + n` has undefined behavior when `p` is null, even when `n == 0`.
  73. * A null pointer is a valid buffer pointer when the size is 0, for example
  74. * as the result of `malloc(0)` on some platforms.)
  75. *
  76. * \param p Pointer to a buffer of at least n bytes.
  77. * This may be \p NULL if \p n is zero.
  78. * \param n An offset in bytes.
  79. * \return Pointer to offset \p n in the buffer \p p.
  80. * Note that this is only a valid pointer if the size of the
  81. * buffer is at least \p n + 1.
  82. */
  83. static inline unsigned char *mbedtls_buffer_offset(
  84. unsigned char *p, size_t n)
  85. {
  86. return p == NULL ? NULL : p + n;
  87. }
  88. /** Return an offset into a read-only buffer.
  89. *
  90. * Similar to mbedtls_buffer_offset(), but for const pointers.
  91. *
  92. * \param p Pointer to a buffer of at least n bytes.
  93. * This may be \p NULL if \p n is zero.
  94. * \param n An offset in bytes.
  95. * \return Pointer to offset \p n in the buffer \p p.
  96. * Note that this is only a valid pointer if the size of the
  97. * buffer is at least \p n + 1.
  98. */
  99. static inline const unsigned char *mbedtls_buffer_offset_const(
  100. const unsigned char *p, size_t n)
  101. {
  102. return p == NULL ? NULL : p + n;
  103. }
  104. /**
  105. * Perform a fast block XOR operation, such that
  106. * r[i] = a[i] ^ b[i] where 0 <= i < n
  107. *
  108. * \param r Pointer to result (buffer of at least \p n bytes). \p r
  109. * may be equal to either \p a or \p b, but behaviour when
  110. * it overlaps in other ways is undefined.
  111. * \param a Pointer to input (buffer of at least \p n bytes)
  112. * \param b Pointer to input (buffer of at least \p n bytes)
  113. * \param n Number of bytes to process.
  114. */
  115. inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned char *b, size_t n)
  116. {
  117. size_t i = 0;
  118. #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
  119. for (; (i + 4) <= n; i += 4) {
  120. uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
  121. mbedtls_put_unaligned_uint32(r + i, x);
  122. }
  123. #endif
  124. for (; i < n; i++) {
  125. r[i] = a[i] ^ b[i];
  126. }
  127. }
  128. /* Fix MSVC C99 compatible issue
  129. * MSVC support __func__ from visual studio 2015( 1900 )
  130. * Use MSVC predefine macro to avoid name check fail.
  131. */
  132. #if (defined(_MSC_VER) && (_MSC_VER <= 1900))
  133. #define /*no-check-names*/ __func__ __FUNCTION__
  134. #endif
  135. /* Define `asm` for compilers which don't define it. */
  136. /* *INDENT-OFF* */
  137. #ifndef asm
  138. #define asm __asm__
  139. #endif
  140. /* *INDENT-ON* */
  141. /* Always provide a static assert macro, so it can be used unconditionally.
  142. * It will expand to nothing on some systems.
  143. * Can be used outside functions (but don't add a trailing ';' in that case:
  144. * the semicolon is included here to avoid triggering -Wextra-semi when
  145. * MBEDTLS_STATIC_ASSERT() expands to nothing).
  146. * Can't use the C11-style `defined(static_assert)` on FreeBSD, since it
  147. * defines static_assert even with -std=c99, but then complains about it.
  148. */
  149. #if defined(static_assert) && !defined(__FreeBSD__)
  150. #define MBEDTLS_STATIC_ASSERT(expr, msg) static_assert(expr, msg);
  151. #else
  152. #define MBEDTLS_STATIC_ASSERT(expr, msg)
  153. #endif
  154. #endif /* MBEDTLS_LIBRARY_COMMON_H */