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