1 // SPDX-License-Identifier: Apache-2.0 2 /* 3 * Platform abstraction layer 4 * 5 * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may 8 * not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 * This file is part of mbed TLS (https://tls.mbed.org) 20 */ 21 22 #if !defined(MBEDTLS_CONFIG_FILE) 23 #include "mbedtls/config.h" 24 #else 25 #include MBEDTLS_CONFIG_FILE 26 #endif 27 28 #if defined(MBEDTLS_PLATFORM_C) 29 30 #include "mbedtls/platform.h" 31 #include "mbedtls/platform_util.h" 32 #include "mbedtls/error.h" 33 34 /* The compile time configuration of memory allocation via the macros 35 * MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime 36 * configuration via mbedtls_platform_set_calloc_free(). So, omit everything 37 * related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */ 38 #if defined(MBEDTLS_PLATFORM_MEMORY) && \ 39 !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && \ 40 defined(MBEDTLS_PLATFORM_FREE_MACRO) ) 41 42 #if !defined(MBEDTLS_PLATFORM_STD_CALLOC) 43 static void *platform_calloc_uninit( size_t n, size_t size ) 44 { 45 ((void) n); 46 ((void) size); 47 return( NULL ); 48 } 49 50 #define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit 51 #endif /* !MBEDTLS_PLATFORM_STD_CALLOC */ 52 53 #if !defined(MBEDTLS_PLATFORM_STD_FREE) 54 static void platform_free_uninit( void *ptr ) 55 { 56 ((void) ptr); 57 } 58 59 #define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit 60 #endif /* !MBEDTLS_PLATFORM_STD_FREE */ 61 62 static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC; 63 static void (*mbedtls_free_func)( void * ) = MBEDTLS_PLATFORM_STD_FREE; 64 65 void * mbedtls_calloc( size_t nmemb, size_t size ) 66 { 67 return (*mbedtls_calloc_func)( nmemb, size ); 68 } 69 70 void mbedtls_free( void * ptr ) 71 { 72 (*mbedtls_free_func)( ptr ); 73 } 74 75 int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), 76 void (*free_func)( void * ) ) 77 { 78 mbedtls_calloc_func = calloc_func; 79 mbedtls_free_func = free_func; 80 return( 0 ); 81 } 82 #endif /* MBEDTLS_PLATFORM_MEMORY && 83 !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && 84 defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */ 85 86 #if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) 87 #include <stdarg.h> 88 int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ) 89 { 90 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 91 va_list argp; 92 93 va_start( argp, fmt ); 94 ret = mbedtls_vsnprintf( s, n, fmt, argp ); 95 va_end( argp ); 96 97 return( ret ); 98 } 99 #endif 100 101 #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) 102 #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) 103 /* 104 * Make dummy function to prevent NULL pointer dereferences 105 */ 106 static int platform_snprintf_uninit( char * s, size_t n, 107 const char * format, ... ) 108 { 109 ((void) s); 110 ((void) n); 111 ((void) format); 112 return( 0 ); 113 } 114 115 #define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit 116 #endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */ 117 118 int (*mbedtls_snprintf)( char * s, size_t n, 119 const char * format, 120 ... ) = MBEDTLS_PLATFORM_STD_SNPRINTF; 121 122 int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, 123 const char * format, 124 ... ) ) 125 { 126 mbedtls_snprintf = snprintf_func; 127 return( 0 ); 128 } 129 #endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ 130 131 #if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) 132 #include <stdarg.h> 133 int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg ) 134 { 135 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 136 137 /* Avoid calling the invalid parameter handler by checking ourselves */ 138 if( s == NULL || n == 0 || fmt == NULL ) 139 return( -1 ); 140 141 #if defined(_TRUNCATE) 142 ret = vsnprintf_s( s, n, _TRUNCATE, fmt, arg ); 143 #else 144 ret = vsnprintf( s, n, fmt, arg ); 145 if( ret < 0 || (size_t) ret == n ) 146 { 147 s[n-1] = '\0'; 148 ret = -1; 149 } 150 #endif 151 152 return( ret ); 153 } 154 #endif 155 156 #if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) 157 #if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) 158 /* 159 * Make dummy function to prevent NULL pointer dereferences 160 */ 161 static int platform_vsnprintf_uninit( char * s, size_t n, 162 const char * format, va_list arg ) 163 { 164 ((void) s); 165 ((void) n); 166 ((void) format); 167 ((void) arg); 168 return( -1 ); 169 } 170 171 #define MBEDTLS_PLATFORM_STD_VSNPRINTF platform_vsnprintf_uninit 172 #endif /* !MBEDTLS_PLATFORM_STD_VSNPRINTF */ 173 174 int (*mbedtls_vsnprintf)( char * s, size_t n, 175 const char * format, 176 va_list arg ) = MBEDTLS_PLATFORM_STD_VSNPRINTF; 177 178 int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n, 179 const char * format, 180 va_list arg ) ) 181 { 182 mbedtls_vsnprintf = vsnprintf_func; 183 return( 0 ); 184 } 185 #endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ 186 187 #if defined(MBEDTLS_PLATFORM_PRINTF_ALT) 188 #if !defined(MBEDTLS_PLATFORM_STD_PRINTF) 189 /* 190 * Make dummy function to prevent NULL pointer dereferences 191 */ 192 static int platform_printf_uninit( const char *format, ... ) 193 { 194 ((void) format); 195 return( 0 ); 196 } 197 198 #define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit 199 #endif /* !MBEDTLS_PLATFORM_STD_PRINTF */ 200 201 int (*mbedtls_printf)( const char *, ... ) = MBEDTLS_PLATFORM_STD_PRINTF; 202 203 int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ) 204 { 205 mbedtls_printf = printf_func; 206 return( 0 ); 207 } 208 #endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ 209 210 #if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) 211 #if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) 212 /* 213 * Make dummy function to prevent NULL pointer dereferences 214 */ 215 static int platform_fprintf_uninit( FILE *stream, const char *format, ... ) 216 { 217 ((void) stream); 218 ((void) format); 219 return( 0 ); 220 } 221 222 #define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit 223 #endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */ 224 225 int (*mbedtls_fprintf)( FILE *, const char *, ... ) = 226 MBEDTLS_PLATFORM_STD_FPRINTF; 227 228 int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) ) 229 { 230 mbedtls_fprintf = fprintf_func; 231 return( 0 ); 232 } 233 #endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ 234 235 #if defined(MBEDTLS_PLATFORM_EXIT_ALT) 236 #if !defined(MBEDTLS_PLATFORM_STD_EXIT) 237 /* 238 * Make dummy function to prevent NULL pointer dereferences 239 */ 240 static void platform_exit_uninit( int status ) 241 { 242 ((void) status); 243 } 244 245 #define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit 246 #endif /* !MBEDTLS_PLATFORM_STD_EXIT */ 247 248 void (*mbedtls_exit)( int status ) = MBEDTLS_PLATFORM_STD_EXIT; 249 250 int mbedtls_platform_set_exit( void (*exit_func)( int status ) ) 251 { 252 mbedtls_exit = exit_func; 253 return( 0 ); 254 } 255 #endif /* MBEDTLS_PLATFORM_EXIT_ALT */ 256 257 #if defined(MBEDTLS_HAVE_TIME) 258 259 #if defined(MBEDTLS_PLATFORM_TIME_ALT) 260 #if !defined(MBEDTLS_PLATFORM_STD_TIME) 261 /* 262 * Make dummy function to prevent NULL pointer dereferences 263 */ 264 static mbedtls_time_t platform_time_uninit( mbedtls_time_t* timer ) 265 { 266 ((void) timer); 267 return( 0 ); 268 } 269 270 #define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit 271 #endif /* !MBEDTLS_PLATFORM_STD_TIME */ 272 273 mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* timer ) = MBEDTLS_PLATFORM_STD_TIME; 274 275 int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* timer ) ) 276 { 277 mbedtls_time = time_func; 278 return( 0 ); 279 } 280 #endif /* MBEDTLS_PLATFORM_TIME_ALT */ 281 282 #endif /* MBEDTLS_HAVE_TIME */ 283 284 #if defined(MBEDTLS_ENTROPY_NV_SEED) 285 #if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) 286 /* Default implementations for the platform independent seed functions use 287 * standard libc file functions to read from and write to a pre-defined filename 288 */ 289 int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ) 290 { 291 FILE *file; 292 size_t n; 293 294 if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL ) 295 return( -1 ); 296 297 if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len ) 298 { 299 fclose( file ); 300 mbedtls_platform_zeroize( buf, buf_len ); 301 return( -1 ); 302 } 303 304 fclose( file ); 305 return( (int)n ); 306 } 307 308 int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ) 309 { 310 FILE *file; 311 size_t n; 312 313 if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL ) 314 return -1; 315 316 if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len ) 317 { 318 fclose( file ); 319 return -1; 320 } 321 322 fclose( file ); 323 return( (int)n ); 324 } 325 #endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ 326 327 #if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) 328 #if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) 329 /* 330 * Make dummy function to prevent NULL pointer dereferences 331 */ 332 static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len ) 333 { 334 ((void) buf); 335 ((void) buf_len); 336 return( -1 ); 337 } 338 339 #define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit 340 #endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */ 341 342 #if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) 343 /* 344 * Make dummy function to prevent NULL pointer dereferences 345 */ 346 static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len ) 347 { 348 ((void) buf); 349 ((void) buf_len); 350 return( -1 ); 351 } 352 353 #define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit 354 #endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */ 355 356 int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) = 357 MBEDTLS_PLATFORM_STD_NV_SEED_READ; 358 int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) = 359 MBEDTLS_PLATFORM_STD_NV_SEED_WRITE; 360 361 int mbedtls_platform_set_nv_seed( 362 int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), 363 int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) ) 364 { 365 mbedtls_nv_seed_read = nv_seed_read_func; 366 mbedtls_nv_seed_write = nv_seed_write_func; 367 return( 0 ); 368 } 369 #endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ 370 #endif /* MBEDTLS_ENTROPY_NV_SEED */ 371 372 #if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) 373 /* 374 * Placeholder platform setup that does nothing by default 375 */ 376 int mbedtls_platform_setup( mbedtls_platform_context *ctx ) 377 { 378 (void)ctx; 379 380 return( 0 ); 381 } 382 383 /* 384 * Placeholder platform teardown that does nothing by default 385 */ 386 void mbedtls_platform_teardown( mbedtls_platform_context *ctx ) 387 { 388 (void)ctx; 389 } 390 #endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ 391 392 #endif /* MBEDTLS_PLATFORM_C */ 393