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