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