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