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