xref: /optee_os/lib/libmbedtls/mbedtls/library/platform.c (revision 11fa71b9ddb429088f325cfda430183003ccd1db)
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