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