1 /** 2 * \file platform_util.h 3 * 4 * \brief Common and shared functions used by multiple modules in the Mbed TLS 5 * library. 6 */ 7 /* 8 * Copyright The Mbed TLS Contributors 9 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 10 */ 11 #ifndef MBEDTLS_PLATFORM_UTIL_H 12 #define MBEDTLS_PLATFORM_UTIL_H 13 14 #if !defined(MBEDTLS_CONFIG_FILE) 15 #include "mbedtls/config.h" 16 #else 17 #include MBEDTLS_CONFIG_FILE 18 #endif 19 20 #include <stddef.h> 21 #if defined(MBEDTLS_HAVE_TIME_DATE) 22 #include "mbedtls/platform_time.h" 23 #include <time.h> 24 #endif /* MBEDTLS_HAVE_TIME_DATE */ 25 26 #ifdef __cplusplus 27 extern "C" { 28 #endif 29 30 #if defined(MBEDTLS_CHECK_PARAMS) 31 32 #if defined(MBEDTLS_CHECK_PARAMS_ASSERT) 33 /* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert 34 * (which is what our config.h suggests). */ 35 #include <assert.h> 36 #endif /* MBEDTLS_CHECK_PARAMS_ASSERT */ 37 38 #if defined(MBEDTLS_PARAM_FAILED) 39 /** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h. 40 * 41 * This flag can be used to check whether it is safe to assume that 42 * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed(). 43 */ 44 #define MBEDTLS_PARAM_FAILED_ALT 45 46 #elif defined(MBEDTLS_CHECK_PARAMS_ASSERT) 47 #define MBEDTLS_PARAM_FAILED(cond) assert(cond) 48 #define MBEDTLS_PARAM_FAILED_ALT 49 50 #else /* MBEDTLS_PARAM_FAILED */ 51 #define MBEDTLS_PARAM_FAILED(cond) \ 52 mbedtls_param_failed( #cond, __FILE__, __LINE__) 53 54 /** 55 * \brief User supplied callback function for parameter validation failure. 56 * See #MBEDTLS_CHECK_PARAMS for context. 57 * 58 * This function will be called unless an alternative treatment 59 * is defined through the #MBEDTLS_PARAM_FAILED macro. 60 * 61 * This function can return, and the operation will be aborted, or 62 * alternatively, through use of setjmp()/longjmp() can resume 63 * execution in the application code. 64 * 65 * \param failure_condition The assertion that didn't hold. 66 * \param file The file where the assertion failed. 67 * \param line The line in the file where the assertion failed. 68 */ 69 void mbedtls_param_failed(const char *failure_condition, 70 const char *file, 71 int line); 72 #endif /* MBEDTLS_PARAM_FAILED */ 73 74 /* Internal macro meant to be called only from within the library. */ 75 #define MBEDTLS_INTERNAL_VALIDATE_RET(cond, ret) \ 76 do { \ 77 if (!(cond)) \ 78 { \ 79 MBEDTLS_PARAM_FAILED(cond); \ 80 return ret; \ 81 } \ 82 } while (0) 83 84 /* Internal macro meant to be called only from within the library. */ 85 #define MBEDTLS_INTERNAL_VALIDATE(cond) \ 86 do { \ 87 if (!(cond)) \ 88 { \ 89 MBEDTLS_PARAM_FAILED(cond); \ 90 return; \ 91 } \ 92 } while (0) 93 94 #else /* MBEDTLS_CHECK_PARAMS */ 95 96 /* Internal macros meant to be called only from within the library. */ 97 #define MBEDTLS_INTERNAL_VALIDATE_RET(cond, ret) do { } while (0) 98 #define MBEDTLS_INTERNAL_VALIDATE(cond) do { } while (0) 99 100 #endif /* MBEDTLS_CHECK_PARAMS */ 101 102 /* Internal helper macros for deprecating API constants. */ 103 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 104 #if defined(MBEDTLS_DEPRECATED_WARNING) 105 /* Deliberately don't (yet) export MBEDTLS_DEPRECATED here 106 * to avoid conflict with other headers which define and use 107 * it, too. We might want to move all these definitions here at 108 * some point for uniformity. */ 109 #define MBEDTLS_DEPRECATED __attribute__((deprecated)) 110 MBEDTLS_DEPRECATED typedef char const *mbedtls_deprecated_string_constant_t; 111 #define MBEDTLS_DEPRECATED_STRING_CONSTANT(VAL) \ 112 ((mbedtls_deprecated_string_constant_t) (VAL)) 113 MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t; 114 #define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(VAL) \ 115 ((mbedtls_deprecated_numeric_constant_t) (VAL)) 116 #undef MBEDTLS_DEPRECATED 117 #else /* MBEDTLS_DEPRECATED_WARNING */ 118 #define MBEDTLS_DEPRECATED_STRING_CONSTANT(VAL) VAL 119 #define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(VAL) VAL 120 #endif /* MBEDTLS_DEPRECATED_WARNING */ 121 #endif /* MBEDTLS_DEPRECATED_REMOVED */ 122 123 /* Implementation of the check-return facility. 124 * See the user documentation in config.h. 125 * 126 * Do not use this macro directly to annotate function: instead, 127 * use one of MBEDTLS_CHECK_RETURN_CRITICAL or MBEDTLS_CHECK_RETURN_TYPICAL 128 * depending on how important it is to check the return value. 129 */ 130 #if !defined(MBEDTLS_CHECK_RETURN) 131 #if defined(__GNUC__) 132 #define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__)) 133 #elif defined(_MSC_VER) && _MSC_VER >= 1700 134 #include <sal.h> 135 #define MBEDTLS_CHECK_RETURN _Check_return_ 136 #else 137 #define MBEDTLS_CHECK_RETURN 138 #endif 139 #endif 140 141 /** Critical-failure function 142 * 143 * This macro appearing at the beginning of the declaration of a function 144 * indicates that its return value should be checked in all applications. 145 * Omitting the check is very likely to indicate a bug in the application 146 * and will result in a compile-time warning if #MBEDTLS_CHECK_RETURN 147 * is implemented for the compiler in use. 148 * 149 * \note The use of this macro is a work in progress. 150 * This macro may be added to more functions in the future. 151 * Such an extension is not considered an API break, provided that 152 * there are near-unavoidable circumstances under which the function 153 * can fail. For example, signature/MAC/AEAD verification functions, 154 * and functions that require a random generator, are considered 155 * return-check-critical. 156 */ 157 #define MBEDTLS_CHECK_RETURN_CRITICAL MBEDTLS_CHECK_RETURN 158 159 /** Ordinary-failure function 160 * 161 * This macro appearing at the beginning of the declaration of a function 162 * indicates that its return value should be generally be checked in portable 163 * applications. Omitting the check will result in a compile-time warning if 164 * #MBEDTLS_CHECK_RETURN is implemented for the compiler in use and 165 * #MBEDTLS_CHECK_RETURN_WARNING is enabled in the compile-time configuration. 166 * 167 * You can use #MBEDTLS_IGNORE_RETURN to explicitly ignore the return value 168 * of a function that is annotated with #MBEDTLS_CHECK_RETURN. 169 * 170 * \note The use of this macro is a work in progress. 171 * This macro will be added to more functions in the future. 172 * Eventually this should appear before most functions returning 173 * an error code (as \c int in the \c mbedtls_xxx API or 174 * as ::psa_status_t in the \c psa_xxx API). 175 */ 176 #if defined(MBEDTLS_CHECK_RETURN_WARNING) 177 #define MBEDTLS_CHECK_RETURN_TYPICAL MBEDTLS_CHECK_RETURN 178 #else 179 #define MBEDTLS_CHECK_RETURN_TYPICAL 180 #endif 181 182 /** Benign-failure function 183 * 184 * This macro appearing at the beginning of the declaration of a function 185 * indicates that it is rarely useful to check its return value. 186 * 187 * This macro has an empty expansion. It exists for documentation purposes: 188 * a #MBEDTLS_CHECK_RETURN_OPTIONAL annotation indicates that the function 189 * has been analyzed for return-check usefulness, whereas the lack of 190 * an annotation indicates that the function has not been analyzed and its 191 * return-check usefulness is unknown. 192 */ 193 #define MBEDTLS_CHECK_RETURN_OPTIONAL 194 195 /** \def MBEDTLS_IGNORE_RETURN 196 * 197 * Call this macro with one argument, a function call, to suppress a warning 198 * from #MBEDTLS_CHECK_RETURN due to that function call. 199 */ 200 #if !defined(MBEDTLS_IGNORE_RETURN) 201 /* GCC doesn't silence the warning with just (void)(result). 202 * (void)!(result) is known to work up at least up to GCC 10, as well 203 * as with Clang and MSVC. 204 * 205 * https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Non_002dbugs.html 206 * https://stackoverflow.com/questions/40576003/ignoring-warning-wunused-result 207 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425#c34 208 */ 209 #define MBEDTLS_IGNORE_RETURN(result) ((void) !(result)) 210 #endif 211 212 /* If the following macro is defined, the library is being built by the test 213 * framework, and the framework is going to provide a replacement 214 * mbedtls_platform_zeroize() using a preprocessor macro, so the function 215 * declaration should be omitted. */ 216 #if !defined(MBEDTLS_TEST_DEFINES_ZEROIZE) //no-check-names 217 /** 218 * \brief Securely zeroize a buffer 219 * 220 * The function is meant to wipe the data contained in a buffer so 221 * that it can no longer be recovered even if the program memory 222 * is later compromised. Call this function on sensitive data 223 * stored on the stack before returning from a function, and on 224 * sensitive data stored on the heap before freeing the heap 225 * object. 226 * 227 * It is extremely difficult to guarantee that calls to 228 * mbedtls_platform_zeroize() are not removed by aggressive 229 * compiler optimizations in a portable way. For this reason, Mbed 230 * TLS provides the configuration option 231 * MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure 232 * mbedtls_platform_zeroize() to use a suitable implementation for 233 * their platform and needs 234 * 235 * \param buf Buffer to be zeroized 236 * \param len Length of the buffer in bytes 237 * 238 */ 239 void mbedtls_platform_zeroize(void *buf, size_t len); 240 #endif 241 242 #if defined(MBEDTLS_HAVE_TIME_DATE) 243 /** 244 * \brief Platform-specific implementation of gmtime_r() 245 * 246 * The function is a thread-safe abstraction that behaves 247 * similarly to the gmtime_r() function from Unix/POSIX. 248 * 249 * Mbed TLS will try to identify the underlying platform and 250 * make use of an appropriate underlying implementation (e.g. 251 * gmtime_r() for POSIX and gmtime_s() for Windows). If this is 252 * not possible, then gmtime() will be used. In this case, calls 253 * from the library to gmtime() will be guarded by the mutex 254 * mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is 255 * enabled. It is recommended that calls from outside the library 256 * are also guarded by this mutex. 257 * 258 * If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will 259 * unconditionally use the alternative implementation for 260 * mbedtls_platform_gmtime_r() supplied by the user at compile time. 261 * 262 * \param tt Pointer to an object containing time (in seconds) since the 263 * epoch to be converted 264 * \param tm_buf Pointer to an object where the results will be stored 265 * 266 * \return Pointer to an object of type struct tm on success, otherwise 267 * NULL 268 */ 269 struct tm *mbedtls_platform_gmtime_r(const mbedtls_time_t *tt, 270 struct tm *tm_buf); 271 #endif /* MBEDTLS_HAVE_TIME_DATE */ 272 273 #ifdef __cplusplus 274 } 275 #endif 276 277 #endif /* MBEDTLS_PLATFORM_UTIL_H */ 278