1 /** 2 * \file platform.h 3 * 4 * \brief This file contains the definitions and functions of the 5 * Mbed TLS platform abstraction layer. 6 * 7 * The platform abstraction layer removes the need for the library 8 * to directly link to standard C library functions or operating 9 * system services, making the library easier to port and embed. 10 * Application developers and users of the library can provide their own 11 * implementations of these functions, or implementations specific to 12 * their platform, which can be statically linked to the library or 13 * dynamically configured at runtime. 14 * 15 * When all compilation options related to platform abstraction are 16 * disabled, this header just defines `mbedtls_xxx` function names 17 * as aliases to the standard `xxx` function. 18 * 19 * Most modules in the library and example programs are expected to 20 * include this header. 21 */ 22 /* 23 * Copyright The Mbed TLS Contributors 24 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 25 */ 26 #ifndef MBEDTLS_PLATFORM_H 27 #define MBEDTLS_PLATFORM_H 28 #include "mbedtls/private_access.h" 29 30 #include "mbedtls/build_info.h" 31 32 #if defined(MBEDTLS_HAVE_TIME) 33 #include "mbedtls/platform_time.h" 34 #endif 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 /** 41 * \name SECTION: Module settings 42 * 43 * The configuration options you can set for this module are in this section. 44 * Either change them in mbedtls_config.h or define them on the compiler command line. 45 * \{ 46 */ 47 48 /* The older Microsoft Windows common runtime provides non-conforming 49 * implementations of some standard library functions, including snprintf 50 * and vsnprintf. This affects MSVC and MinGW builds. 51 */ 52 #if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900) 53 #define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF 54 #define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF 55 #endif 56 57 #if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) 58 #include <stdio.h> 59 #include <stdlib.h> 60 #if defined(MBEDTLS_HAVE_TIME) 61 #include <time.h> 62 #endif 63 #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) 64 #if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) 65 #define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */ 66 #else 67 #define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */ 68 #endif 69 #endif 70 #if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) 71 #if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) 72 #define MBEDTLS_PLATFORM_STD_VSNPRINTF mbedtls_platform_win32_vsnprintf /**< The default \c vsnprintf function to use. */ 73 #else 74 #define MBEDTLS_PLATFORM_STD_VSNPRINTF vsnprintf /**< The default \c vsnprintf function to use. */ 75 #endif 76 #endif 77 #if !defined(MBEDTLS_PLATFORM_STD_PRINTF) 78 #define MBEDTLS_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */ 79 #endif 80 #if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) 81 #define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */ 82 #endif 83 #if !defined(MBEDTLS_PLATFORM_STD_CALLOC) 84 #define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< The default \c calloc function to use. */ 85 #endif 86 #if !defined(MBEDTLS_PLATFORM_STD_FREE) 87 #define MBEDTLS_PLATFORM_STD_FREE free /**< The default \c free function to use. */ 88 #endif 89 #if !defined(MBEDTLS_PLATFORM_STD_SETBUF) 90 #define MBEDTLS_PLATFORM_STD_SETBUF setbuf /**< The default \c setbuf function to use. */ 91 #endif 92 #if !defined(MBEDTLS_PLATFORM_STD_EXIT) 93 #define MBEDTLS_PLATFORM_STD_EXIT exit /**< The default \c exit function to use. */ 94 #endif 95 #if !defined(MBEDTLS_PLATFORM_STD_TIME) 96 #define MBEDTLS_PLATFORM_STD_TIME time /**< The default \c time function to use. */ 97 #endif 98 #if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) 99 #define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< The default exit value to use. */ 100 #endif 101 #if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) 102 #define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< The default exit value to use. */ 103 #endif 104 #if defined(MBEDTLS_FS_IO) 105 #if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) 106 #define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read 107 #endif 108 #if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) 109 #define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write 110 #endif 111 #if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE) 112 #define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" 113 #endif 114 #endif /* MBEDTLS_FS_IO */ 115 #else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ 116 #if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) 117 #include MBEDTLS_PLATFORM_STD_MEM_HDR 118 #endif 119 #endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ 120 121 /* Enable certain documented defines only when generating doxygen to avoid 122 * an "unrecognized define" error. */ 123 #if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_CALLOC) 124 #define MBEDTLS_PLATFORM_STD_CALLOC 125 #endif 126 127 #if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_FREE) 128 #define MBEDTLS_PLATFORM_STD_FREE 129 #endif 130 131 /** \} name SECTION: Module settings */ 132 133 /* 134 * The function pointers for calloc and free. 135 * Please see MBEDTLS_PLATFORM_STD_CALLOC and MBEDTLS_PLATFORM_STD_FREE 136 * in mbedtls_config.h for more information about behaviour and requirements. 137 */ 138 #if defined(MBEDTLS_PLATFORM_MEMORY) 139 #if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \ 140 defined(MBEDTLS_PLATFORM_CALLOC_MACRO) 141 #undef mbedtls_free 142 #undef mbedtls_calloc 143 #define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO 144 #define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO 145 #else 146 /* For size_t */ 147 #include <stddef.h> 148 extern void *mbedtls_calloc(size_t n, size_t size); 149 extern void mbedtls_free(void *ptr); 150 151 /** 152 * \brief This function dynamically sets the memory-management 153 * functions used by the library, during runtime. 154 * 155 * \param calloc_func The \c calloc function implementation. 156 * \param free_func The \c free function implementation. 157 * 158 * \return \c 0. 159 */ 160 int mbedtls_platform_set_calloc_free(void *(*calloc_func)(size_t, size_t), 161 void (*free_func)(void *)); 162 #endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */ 163 #else /* !MBEDTLS_PLATFORM_MEMORY */ 164 #undef mbedtls_free 165 #undef mbedtls_calloc 166 #define mbedtls_free free 167 #define mbedtls_calloc calloc 168 #endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */ 169 170 /* 171 * The function pointers for fprintf 172 */ 173 #if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) 174 /* We need FILE * */ 175 #include <stdio.h> 176 extern int (*mbedtls_fprintf)(FILE *stream, const char *format, ...); 177 178 /** 179 * \brief This function dynamically configures the fprintf 180 * function that is called when the 181 * mbedtls_fprintf() function is invoked by the library. 182 * 183 * \param fprintf_func The \c fprintf function implementation. 184 * 185 * \return \c 0. 186 */ 187 int mbedtls_platform_set_fprintf(int (*fprintf_func)(FILE *stream, const char *, 188 ...)); 189 #else 190 #undef mbedtls_fprintf 191 #if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) 192 #define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO 193 #else 194 #define mbedtls_fprintf fprintf 195 #endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */ 196 #endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ 197 198 /* 199 * The function pointers for printf 200 */ 201 #if defined(MBEDTLS_PLATFORM_PRINTF_ALT) 202 extern int (*mbedtls_printf)(const char *format, ...); 203 204 /** 205 * \brief This function dynamically configures the snprintf 206 * function that is called when the mbedtls_snprintf() 207 * function is invoked by the library. 208 * 209 * \param printf_func The \c printf function implementation. 210 * 211 * \return \c 0 on success. 212 */ 213 int mbedtls_platform_set_printf(int (*printf_func)(const char *, ...)); 214 #else /* !MBEDTLS_PLATFORM_PRINTF_ALT */ 215 #undef mbedtls_printf 216 #if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) 217 #define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO 218 #else 219 #define mbedtls_printf printf 220 #endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */ 221 #endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ 222 223 /* 224 * The function pointers for snprintf 225 * 226 * The snprintf implementation should conform to C99: 227 * - it *must* always correctly zero-terminate the buffer 228 * (except when n == 0, then it must leave the buffer untouched) 229 * - however it is acceptable to return -1 instead of the required length when 230 * the destination buffer is too short. 231 */ 232 #if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) 233 /* For Windows (inc. MSYS2), we provide our own fixed implementation */ 234 int mbedtls_platform_win32_snprintf(char *s, size_t n, const char *fmt, ...); 235 #endif 236 237 #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) 238 extern int (*mbedtls_snprintf)(char *s, size_t n, const char *format, ...); 239 240 /** 241 * \brief This function allows configuring a custom 242 * \c snprintf function pointer. 243 * 244 * \param snprintf_func The \c snprintf function implementation. 245 * 246 * \return \c 0 on success. 247 */ 248 int mbedtls_platform_set_snprintf(int (*snprintf_func)(char *s, size_t n, 249 const char *format, ...)); 250 #else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ 251 #undef mbedtls_snprintf 252 #if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) 253 #define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO 254 #else 255 #define mbedtls_snprintf MBEDTLS_PLATFORM_STD_SNPRINTF 256 #endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */ 257 #endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ 258 259 /* 260 * The function pointers for vsnprintf 261 * 262 * The vsnprintf implementation should conform to C99: 263 * - it *must* always correctly zero-terminate the buffer 264 * (except when n == 0, then it must leave the buffer untouched) 265 * - however it is acceptable to return -1 instead of the required length when 266 * the destination buffer is too short. 267 */ 268 #if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) 269 #include <stdarg.h> 270 /* For Older Windows (inc. MSYS2), we provide our own fixed implementation */ 271 int mbedtls_platform_win32_vsnprintf(char *s, size_t n, const char *fmt, va_list arg); 272 #endif 273 274 #if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) 275 #include <stdarg.h> 276 extern int (*mbedtls_vsnprintf)(char *s, size_t n, const char *format, va_list arg); 277 278 /** 279 * \brief Set your own snprintf function pointer 280 * 281 * \param vsnprintf_func The \c vsnprintf function implementation 282 * 283 * \return \c 0 284 */ 285 int mbedtls_platform_set_vsnprintf(int (*vsnprintf_func)(char *s, size_t n, 286 const char *format, va_list arg)); 287 #else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ 288 #undef mbedtls_vsnprintf 289 #if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) 290 #define mbedtls_vsnprintf MBEDTLS_PLATFORM_VSNPRINTF_MACRO 291 #else 292 #define mbedtls_vsnprintf vsnprintf 293 #endif /* MBEDTLS_PLATFORM_VSNPRINTF_MACRO */ 294 #endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ 295 296 /* 297 * The function pointers for setbuf 298 */ 299 #if defined(MBEDTLS_PLATFORM_SETBUF_ALT) 300 #include <stdio.h> 301 /** 302 * \brief Function pointer to call for `setbuf()` functionality 303 * (changing the internal buffering on stdio calls). 304 * 305 * \note The library calls this function to disable 306 * buffering when reading or writing sensitive data, 307 * to avoid having extra copies of sensitive data 308 * remaining in stdio buffers after the file is 309 * closed. If this is not a concern, for example if 310 * your platform's stdio doesn't have any buffering, 311 * you can set mbedtls_setbuf to a function that 312 * does nothing. 313 * 314 * The library always calls this function with 315 * `buf` equal to `NULL`. 316 */ 317 extern void (*mbedtls_setbuf)(FILE *stream, char *buf); 318 319 /** 320 * \brief Dynamically configure the function that is called 321 * when the mbedtls_setbuf() function is called by the 322 * library. 323 * 324 * \param setbuf_func The \c setbuf function implementation 325 * 326 * \return \c 0 327 */ 328 int mbedtls_platform_set_setbuf(void (*setbuf_func)( 329 FILE *stream, char *buf)); 330 #else 331 #undef mbedtls_setbuf 332 #if defined(MBEDTLS_PLATFORM_SETBUF_MACRO) 333 /** 334 * \brief Macro defining the function for the library to 335 * call for `setbuf` functionality (changing the 336 * internal buffering on stdio calls). 337 * 338 * \note See extra comments on the mbedtls_setbuf() function 339 * pointer above. 340 * 341 * \return \c 0 on success, negative on error. 342 */ 343 #define mbedtls_setbuf MBEDTLS_PLATFORM_SETBUF_MACRO 344 #else 345 #define mbedtls_setbuf setbuf 346 #endif /* MBEDTLS_PLATFORM_SETBUF_MACRO */ 347 #endif /* MBEDTLS_PLATFORM_SETBUF_ALT */ 348 349 /* 350 * The function pointers for exit 351 */ 352 #if defined(MBEDTLS_PLATFORM_EXIT_ALT) 353 extern void (*mbedtls_exit)(int status); 354 355 /** 356 * \brief This function dynamically configures the exit 357 * function that is called when the mbedtls_exit() 358 * function is invoked by the library. 359 * 360 * \param exit_func The \c exit function implementation. 361 * 362 * \return \c 0 on success. 363 */ 364 int mbedtls_platform_set_exit(void (*exit_func)(int status)); 365 #else 366 #undef mbedtls_exit 367 #if defined(MBEDTLS_PLATFORM_EXIT_MACRO) 368 #define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO 369 #else 370 #define mbedtls_exit exit 371 #endif /* MBEDTLS_PLATFORM_EXIT_MACRO */ 372 #endif /* MBEDTLS_PLATFORM_EXIT_ALT */ 373 374 /* 375 * The default exit values 376 */ 377 #if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) 378 #define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 379 #else 380 #define MBEDTLS_EXIT_SUCCESS 0 381 #endif 382 #if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) 383 #define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE 384 #else 385 #define MBEDTLS_EXIT_FAILURE 1 386 #endif 387 388 /* 389 * The function pointers for reading from and writing a seed file to 390 * Non-Volatile storage (NV) in a platform-independent way 391 * 392 * Only enabled when the NV seed entropy source is enabled 393 */ 394 #if defined(MBEDTLS_ENTROPY_NV_SEED) 395 #if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) 396 /* Internal standard platform definitions */ 397 int mbedtls_platform_std_nv_seed_read(unsigned char *buf, size_t buf_len); 398 int mbedtls_platform_std_nv_seed_write(unsigned char *buf, size_t buf_len); 399 #endif 400 401 #if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) 402 extern int (*mbedtls_nv_seed_read)(unsigned char *buf, size_t buf_len); 403 extern int (*mbedtls_nv_seed_write)(unsigned char *buf, size_t buf_len); 404 405 /** 406 * \brief This function allows configuring custom seed file writing and 407 * reading functions. 408 * 409 * \param nv_seed_read_func The seed reading function implementation. 410 * \param nv_seed_write_func The seed writing function implementation. 411 * 412 * \return \c 0 on success. 413 */ 414 int mbedtls_platform_set_nv_seed( 415 int (*nv_seed_read_func)(unsigned char *buf, size_t buf_len), 416 int (*nv_seed_write_func)(unsigned char *buf, size_t buf_len) 417 ); 418 #else 419 #undef mbedtls_nv_seed_read 420 #undef mbedtls_nv_seed_write 421 #if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \ 422 defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) 423 #define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO 424 #define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO 425 #else 426 #define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read 427 #define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write 428 #endif 429 #endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ 430 #endif /* MBEDTLS_ENTROPY_NV_SEED */ 431 432 #if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) 433 434 /** 435 * \brief The platform context structure. 436 * 437 * \note This structure may be used to assist platform-specific 438 * setup or teardown operations. 439 */ 440 typedef struct mbedtls_platform_context { 441 char MBEDTLS_PRIVATE(dummy); /**< A placeholder member, as empty structs are not portable. */ 442 } 443 mbedtls_platform_context; 444 445 #else 446 #include "platform_alt.h" 447 #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ 448 449 /** 450 * \brief This function performs any platform-specific initialization 451 * operations. 452 * 453 * \note This function should be called before any other library functions. 454 * 455 * Its implementation is platform-specific, and unless 456 * platform-specific code is provided, it does nothing. 457 * 458 * \note The usage and necessity of this function is dependent on the platform. 459 * 460 * \param ctx The platform context. 461 * 462 * \return \c 0 on success. 463 */ 464 int mbedtls_platform_setup(mbedtls_platform_context *ctx); 465 /** 466 * \brief This function performs any platform teardown operations. 467 * 468 * \note This function should be called after every other Mbed TLS module 469 * has been correctly freed using the appropriate free function. 470 * 471 * Its implementation is platform-specific, and unless 472 * platform-specific code is provided, it does nothing. 473 * 474 * \note The usage and necessity of this function is dependent on the platform. 475 * 476 * \param ctx The platform context. 477 * 478 */ 479 void mbedtls_platform_teardown(mbedtls_platform_context *ctx); 480 481 #ifdef __cplusplus 482 } 483 #endif 484 485 #endif /* platform.h */ 486