1 /**
2  * \file platform.h
3  *
4  * \brief This file contains the definitions and functions of the
5  *        Mbed TLS platform abstraction layer.
6  *
7  *        The platform abstraction layer removes the need for the library
8  *        to directly link to standard C library functions or operating
9  *        system services, making the library easier to port and embed.
10  *        Application developers and users of the library can provide their own
11  *        implementations of these functions, or implementations specific to
12  *        their platform, which can be statically linked to the library or
13  *        dynamically configured at runtime.
14  */
15 /*
16  *  Copyright The Mbed TLS Contributors
17  *  SPDX-License-Identifier: Apache-2.0
18  *
19  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
20  *  not use this file except in compliance with the License.
21  *  You may obtain a copy of the License at
22  *
23  *  http://www.apache.org/licenses/LICENSE-2.0
24  *
25  *  Unless required by applicable law or agreed to in writing, software
26  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
27  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28  *  See the License for the specific language governing permissions and
29  *  limitations under the License.
30  */
31 #ifndef MBEDTLS_PLATFORM_H
32 #define MBEDTLS_PLATFORM_H
33 #include "mbedtls/private_access.h"
34 
35 #include "mbedtls/build_info.h"
36 
37 #if defined(MBEDTLS_HAVE_TIME)
38 #include "mbedtls/platform_time.h"
39 #endif
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 /**
46  * \name SECTION: Module settings
47  *
48  * The configuration options you can set for this module are in this section.
49  * Either change them in mbedtls_config.h or define them on the compiler command line.
50  * \{
51  */
52 
53 /* The older Microsoft Windows common runtime provides non-conforming
54  * implementations of some standard library functions, including snprintf
55  * and vsnprintf. This affects MSVC and MinGW builds.
56  */
57 #if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900)
58 #define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF
59 #define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF
60 #endif
61 
62 #if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <time.h>
66 #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
67 #if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
68 #define MBEDTLS_PLATFORM_STD_SNPRINTF   mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use.  */
69 #else
70 #define MBEDTLS_PLATFORM_STD_SNPRINTF   snprintf /**< The default \c snprintf function to use.  */
71 #endif
72 #endif
73 #if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF)
74 #if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
75 #define MBEDTLS_PLATFORM_STD_VSNPRINTF   mbedtls_platform_win32_vsnprintf /**< The default \c vsnprintf function to use.  */
76 #else
77 #define MBEDTLS_PLATFORM_STD_VSNPRINTF   vsnprintf /**< The default \c vsnprintf function to use.  */
78 #endif
79 #endif
80 #if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
81 #define MBEDTLS_PLATFORM_STD_PRINTF   printf /**< The default \c printf function to use. */
82 #endif
83 #if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
84 #define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */
85 #endif
86 #if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
87 #define MBEDTLS_PLATFORM_STD_CALLOC   calloc /**< The default \c calloc function to use. */
88 #endif
89 #if !defined(MBEDTLS_PLATFORM_STD_FREE)
90 #define MBEDTLS_PLATFORM_STD_FREE       free /**< The default \c free function to use. */
91 #endif
92 #if !defined(MBEDTLS_PLATFORM_STD_EXIT)
93 #define MBEDTLS_PLATFORM_STD_EXIT      exit /**< The default \c exit function to use. */
94 #endif
95 #if !defined(MBEDTLS_PLATFORM_STD_TIME)
96 #define MBEDTLS_PLATFORM_STD_TIME       time    /**< The default \c time function to use. */
97 #endif
98 #if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
99 #define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS  EXIT_SUCCESS /**< The default exit value to use. */
100 #endif
101 #if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
102 #define MBEDTLS_PLATFORM_STD_EXIT_FAILURE  EXIT_FAILURE /**< The default exit value to use. */
103 #endif
104 #if defined(MBEDTLS_FS_IO)
105 #if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
106 #define MBEDTLS_PLATFORM_STD_NV_SEED_READ   mbedtls_platform_std_nv_seed_read
107 #endif
108 #if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
109 #define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE  mbedtls_platform_std_nv_seed_write
110 #endif
111 #if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE)
112 #define MBEDTLS_PLATFORM_STD_NV_SEED_FILE   "seedfile"
113 #endif
114 #endif /* MBEDTLS_FS_IO */
115 #else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
116 #if defined(MBEDTLS_PLATFORM_STD_MEM_HDR)
117 #include MBEDTLS_PLATFORM_STD_MEM_HDR
118 #endif
119 #endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
120 
121 
122 /* \} name SECTION: Module settings */
123 
124 /*
125  * The function pointers for calloc and free.
126  */
127 #if defined(MBEDTLS_PLATFORM_MEMORY)
128 #if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
129     defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
130 #define mbedtls_free       MBEDTLS_PLATFORM_FREE_MACRO
131 #define mbedtls_calloc     MBEDTLS_PLATFORM_CALLOC_MACRO
132 #else
133 /* For size_t */
134 #include <stddef.h>
135 extern void *mbedtls_calloc( size_t n, size_t size );
136 extern void mbedtls_free( void *ptr );
137 
138 /**
139  * \brief               This function dynamically sets the memory-management
140  *                      functions used by the library, during runtime.
141  *
142  * \param calloc_func   The \c calloc function implementation.
143  * \param free_func     The \c free function implementation.
144  *
145  * \return              \c 0.
146  */
147 int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
148                               void (*free_func)( void * ) );
149 #endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */
150 #else /* !MBEDTLS_PLATFORM_MEMORY */
151 #define mbedtls_free       free
152 #define mbedtls_calloc     calloc
153 #endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */
154 
155 /*
156  * The function pointers for fprintf
157  */
158 #if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
159 /* We need FILE * */
160 #include <stdio.h>
161 extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... );
162 
163 /**
164  * \brief                This function dynamically configures the fprintf
165  *                       function that is called when the
166  *                       mbedtls_fprintf() function is invoked by the library.
167  *
168  * \param fprintf_func   The \c fprintf function implementation.
169  *
170  * \return               \c 0.
171  */
172 int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *,
173                                                ... ) );
174 #else
175 #if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO)
176 #define mbedtls_fprintf    MBEDTLS_PLATFORM_FPRINTF_MACRO
177 #else
178 #define mbedtls_fprintf    fprintf
179 #endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */
180 #endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
181 
182 /*
183  * The function pointers for printf
184  */
185 #if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
186 extern int (*mbedtls_printf)( const char *format, ... );
187 
188 /**
189  * \brief               This function dynamically configures the snprintf
190  *                      function that is called when the mbedtls_snprintf()
191  *                      function is invoked by the library.
192  *
193  * \param printf_func   The \c printf function implementation.
194  *
195  * \return              \c 0 on success.
196  */
197 int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) );
198 #else /* !MBEDTLS_PLATFORM_PRINTF_ALT */
199 #if defined(MBEDTLS_PLATFORM_PRINTF_MACRO)
200 #define mbedtls_printf     MBEDTLS_PLATFORM_PRINTF_MACRO
201 #else
202 #define mbedtls_printf     printf
203 #endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */
204 #endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
205 
206 /*
207  * The function pointers for snprintf
208  *
209  * The snprintf implementation should conform to C99:
210  * - it *must* always correctly zero-terminate the buffer
211  *   (except when n == 0, then it must leave the buffer untouched)
212  * - however it is acceptable to return -1 instead of the required length when
213  *   the destination buffer is too short.
214  */
215 #if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
216 /* For Windows (inc. MSYS2), we provide our own fixed implementation */
217 int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... );
218 #endif
219 
220 #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
221 extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... );
222 
223 /**
224  * \brief                 This function allows configuring a custom
225  *                        \c snprintf function pointer.
226  *
227  * \param snprintf_func   The \c snprintf function implementation.
228  *
229  * \return                \c 0 on success.
230  */
231 int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
232                                                  const char * format, ... ) );
233 #else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
234 #if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
235 #define mbedtls_snprintf   MBEDTLS_PLATFORM_SNPRINTF_MACRO
236 #else
237 #define mbedtls_snprintf   MBEDTLS_PLATFORM_STD_SNPRINTF
238 #endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */
239 #endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
240 
241 /*
242  * The function pointers for vsnprintf
243  *
244  * The vsnprintf implementation should conform to C99:
245  * - it *must* always correctly zero-terminate the buffer
246  *   (except when n == 0, then it must leave the buffer untouched)
247  * - however it is acceptable to return -1 instead of the required length when
248  *   the destination buffer is too short.
249  */
250 #if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
251 #include <stdarg.h>
252 /* For Older Windows (inc. MSYS2), we provide our own fixed implementation */
253 int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg );
254 #endif
255 
256 #if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
257 #include <stdarg.h>
258 extern int (*mbedtls_vsnprintf)( char * s, size_t n, const char * format, va_list arg );
259 
260 /**
261  * \brief   Set your own snprintf function pointer
262  *
263  * \param   vsnprintf_func   The \c vsnprintf function implementation
264  *
265  * \return  \c 0
266  */
267 int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n,
268                                                  const char * format, va_list arg ) );
269 #else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
270 #if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
271 #define mbedtls_vsnprintf   MBEDTLS_PLATFORM_VSNPRINTF_MACRO
272 #else
273 #define mbedtls_vsnprintf   vsnprintf
274 #endif /* MBEDTLS_PLATFORM_VSNPRINTF_MACRO */
275 #endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
276 
277 /*
278  * The function pointers for exit
279  */
280 #if defined(MBEDTLS_PLATFORM_EXIT_ALT)
281 extern void (*mbedtls_exit)( int status );
282 
283 /**
284  * \brief             This function dynamically configures the exit
285  *                    function that is called when the mbedtls_exit()
286  *                    function is invoked by the library.
287  *
288  * \param exit_func   The \c exit function implementation.
289  *
290  * \return            \c 0 on success.
291  */
292 int mbedtls_platform_set_exit( void (*exit_func)( int status ) );
293 #else
294 #if defined(MBEDTLS_PLATFORM_EXIT_MACRO)
295 #define mbedtls_exit   MBEDTLS_PLATFORM_EXIT_MACRO
296 #else
297 #define mbedtls_exit   exit
298 #endif /* MBEDTLS_PLATFORM_EXIT_MACRO */
299 #endif /* MBEDTLS_PLATFORM_EXIT_ALT */
300 
301 /*
302  * The default exit values
303  */
304 #if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
305 #define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS
306 #else
307 #define MBEDTLS_EXIT_SUCCESS 0
308 #endif
309 #if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
310 #define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE
311 #else
312 #define MBEDTLS_EXIT_FAILURE 1
313 #endif
314 
315 /*
316  * The function pointers for reading from and writing a seed file to
317  * Non-Volatile storage (NV) in a platform-independent way
318  *
319  * Only enabled when the NV seed entropy source is enabled
320  */
321 #if defined(MBEDTLS_ENTROPY_NV_SEED)
322 #if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
323 /* Internal standard platform definitions */
324 int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len );
325 int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len );
326 #endif
327 
328 #if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
329 extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len );
330 extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len );
331 
332 /**
333  * \brief   This function allows configuring custom seed file writing and
334  *          reading functions.
335  *
336  * \param   nv_seed_read_func   The seed reading function implementation.
337  * \param   nv_seed_write_func  The seed writing function implementation.
338  *
339  * \return  \c 0 on success.
340  */
341 int mbedtls_platform_set_nv_seed(
342             int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
343             int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len )
344             );
345 #else
346 #if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \
347     defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO)
348 #define mbedtls_nv_seed_read    MBEDTLS_PLATFORM_NV_SEED_READ_MACRO
349 #define mbedtls_nv_seed_write   MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO
350 #else
351 #define mbedtls_nv_seed_read    mbedtls_platform_std_nv_seed_read
352 #define mbedtls_nv_seed_write   mbedtls_platform_std_nv_seed_write
353 #endif
354 #endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
355 #endif /* MBEDTLS_ENTROPY_NV_SEED */
356 
357 #if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT)
358 
359 /**
360  * \brief   The platform context structure.
361  *
362  * \note    This structure may be used to assist platform-specific
363  *          setup or teardown operations.
364  */
365 typedef struct mbedtls_platform_context
366 {
367     char MBEDTLS_PRIVATE(dummy); /**< A placeholder member, as empty structs are not portable. */
368 }
369 mbedtls_platform_context;
370 
371 #else
372 #include "platform_alt.h"
373 #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
374 
375 /**
376  * \brief   This function performs any platform-specific initialization
377  *          operations.
378  *
379  * \note    This function should be called before any other library functions.
380  *
381  *          Its implementation is platform-specific, and unless
382  *          platform-specific code is provided, it does nothing.
383  *
384  * \note    The usage and necessity of this function is dependent on the platform.
385  *
386  * \param   ctx     The platform context.
387  *
388  * \return  \c 0 on success.
389  */
390 int mbedtls_platform_setup( mbedtls_platform_context *ctx );
391 /**
392  * \brief   This function performs any platform teardown operations.
393  *
394  * \note    This function should be called after every other Mbed TLS module
395  *          has been correctly freed using the appropriate free function.
396  *
397  *          Its implementation is platform-specific, and unless
398  *          platform-specific code is provided, it does nothing.
399  *
400  * \note    The usage and necessity of this function is dependent on the platform.
401  *
402  * \param   ctx     The platform context.
403  *
404  */
405 void mbedtls_platform_teardown( mbedtls_platform_context *ctx );
406 
407 #ifdef __cplusplus
408 }
409 #endif
410 
411 #endif /* platform.h */
412