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