1 /* Self-test demonstration program
2 *
3 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * This file is part of mbed TLS (https://tls.mbed.org)
8 */
9
10 #include <zephyr/sys/printk.h>
11 #define MBEDTLS_PRINT (int(*)(const char *, ...)) printk
12
13 #include <string.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16
17 #include <zephyr/kernel.h>
18 #include <zephyr/linker/sections.h>
19 #include <errno.h>
20
21 #include <zephyr/tc_util.h>
22 #include <zephyr/ztest.h>
23
24 #define MBEDTLS_ALLOW_PRIVATE_ACCESS
25
26 #include "mbedtls/build_info.h"
27
28
29 #include "mbedtls/entropy.h"
30 #include "mbedtls/hmac_drbg.h"
31 #include "mbedtls/ctr_drbg.h"
32 #include "mbedtls/dhm.h"
33 #include "mbedtls/gcm.h"
34 #include "mbedtls/ccm.h"
35 #include "mbedtls/cmac.h"
36 #include "mbedtls/md5.h"
37 #include "mbedtls/ripemd160.h"
38 #include "mbedtls/sha1.h"
39 #include "mbedtls/sha256.h"
40 #include "mbedtls/sha512.h"
41 #include "mbedtls/des.h"
42 #include "mbedtls/aes.h"
43 #include "mbedtls/camellia.h"
44 #include "mbedtls/aria.h"
45 #include "mbedtls/chacha20.h"
46 #include "mbedtls/poly1305.h"
47 #include "mbedtls/chachapoly.h"
48 #include "mbedtls/base64.h"
49 #include "mbedtls/bignum.h"
50 #include "mbedtls/rsa.h"
51 #include "mbedtls/x509.h"
52 #include "mbedtls/pkcs5.h"
53 #include "mbedtls/ecp.h"
54 #include "mbedtls/ecjpake.h"
55 #include "mbedtls/timing.h"
56 #include "mbedtls/nist_kw.h"
57
58 #if defined(MBEDTLS_PLATFORM_C)
59 #include "mbedtls/platform.h"
60 #else
61 #include <stdio.h>
62 #include <stdlib.h>
63 #define mbedtls_printf printf
64 #define mbedtls_snprintf snprintf
65 #define mbedtls_exit exit
66 #define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
67 #define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
68 #endif
69
70 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
71 #include "mbedtls/memory_buffer_alloc.h"
72 #endif
73
test_snprintf(size_t n,const char * ref_buf,int ref_ret)74 static int test_snprintf(size_t n, const char *ref_buf, int ref_ret)
75 {
76 int ret;
77 char buf[10] = "xxxxxxxxx";
78 const char ref[10] = "xxxxxxxxx";
79
80 ret = mbedtls_snprintf(buf, n, "%s", "123");
81 if (ret < 0 || (size_t) ret >= n) {
82 ret = -1;
83 }
84
85 if (strncmp(ref_buf, buf, sizeof(buf)) != 0 ||
86 ref_ret != ret || memcmp(buf + n, ref + n, sizeof(buf) - n) != 0) {
87 return 1;
88 }
89
90 return 0;
91 }
92
run_test_snprintf(void)93 static int run_test_snprintf(void)
94 {
95 return (test_snprintf(0, "xxxxxxxxx", -1) != 0 ||
96 test_snprintf(1, "", -1) != 0 ||
97 test_snprintf(2, "1", -1) != 0 ||
98 test_snprintf(3, "12", -1) != 0 ||
99 test_snprintf(4, "123", 3) != 0 ||
100 test_snprintf(5, "123", 3) != 0);
101 }
102
103 /*
104 * Check if a seed file is present, and if not create one for the entropy
105 * self-test. If this fails, we attempt the test anyway, so no error is passed
106 * back.
107 */
108 #if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_ENTROPY_NV_SEED) && \
109 !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
create_entropy_seed_file(void)110 static void create_entropy_seed_file(void)
111 {
112 int result;
113 size_t output_len = 0;
114 unsigned char seed_value[MBEDTLS_ENTROPY_BLOCK_SIZE];
115
116 /* Attempt to read the entropy seed file. If this fails - attempt to write
117 * to the file to ensure one is present.
118 */
119 result = mbedtls_platform_std_nv_seed_read(seed_value,
120 MBEDTLS_ENTROPY_BLOCK_SIZE);
121 if (result == 0) {
122 return;
123 }
124
125 result = mbedtls_platform_entropy_poll(NULL,
126 seed_value,
127 MBEDTLS_ENTROPY_BLOCK_SIZE,
128 &output_len);
129 if (result != 0) {
130 return;
131 }
132
133 if (output_len != MBEDTLS_ENTROPY_BLOCK_SIZE) {
134 return;
135 }
136
137 mbedtls_platform_std_nv_seed_write(seed_value,
138 MBEDTLS_ENTROPY_BLOCK_SIZE);
139 }
140 #endif
141
142 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
143 ZTEST_BMEM unsigned char buf[16000];
144 #endif
145
ZTEST_USER(mbedtls_fn,test_mbedtls)146 ZTEST_USER(mbedtls_fn, test_mbedtls)
147 {
148 int v, suites_tested = 0, suites_failed = 0;
149
150 void *pointer;
151
152 #if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
153 mbedtls_platform_set_printf(MBEDTLS_PRINT);
154 #endif
155
156 /*
157 * The C standard doesn't guarantee that all-bits-0 is the representation
158 * of a NULL pointer. We do however use that in our code for initializing
159 * structures, which should work on every modern platform. Let's be sure.
160 */
161 (void)memset(&pointer, 0, sizeof(void *));
162 if (pointer != NULL) {
163 mbedtls_printf("all-bits-zero is not a NULL pointer\n");
164 mbedtls_exit(MBEDTLS_EXIT_FAILURE);
165 }
166
167 /*
168 * Make sure we have a snprintf that correctly zero-terminates
169 */
170 if (run_test_snprintf() != 0) {
171 mbedtls_printf("the snprintf implementation is broken\n");
172 mbedtls_exit(MBEDTLS_EXIT_FAILURE);
173 }
174
175 v = 1;
176 mbedtls_printf("\n");
177
178 #if defined(MBEDTLS_SELF_TEST)
179
180 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
181 mbedtls_memory_buffer_alloc_init(buf, sizeof(buf));
182 #endif
183
184 #if defined(MBEDTLS_MD2_C)
185 if (mbedtls_md2_self_test(v) != 0) {
186 suites_failed++;
187 }
188 suites_tested++;
189 #endif
190
191 #if defined(MBEDTLS_MD4_C)
192 if (mbedtls_md4_self_test(v) != 0) {
193 suites_failed++;
194 }
195 suites_tested++;
196 #endif
197
198 #if defined(MBEDTLS_MD5_C)
199 if (mbedtls_md5_self_test(v) != 0) {
200 suites_failed++;
201 }
202 suites_tested++;
203 #endif
204
205 #if defined(MBEDTLS_RIPEMD160_C)
206 if (mbedtls_ripemd160_self_test(v) != 0) {
207 suites_failed++;
208 }
209 suites_tested++;
210 #endif
211
212 #if defined(MBEDTLS_SHA1_C)
213 if (mbedtls_sha1_self_test(v) != 0) {
214 suites_failed++;
215 }
216 suites_tested++;
217 #endif
218
219 #if defined(MBEDTLS_SHA256_C)
220 if (mbedtls_sha256_self_test(v) != 0) {
221 suites_failed++;
222 }
223 suites_tested++;
224 #endif
225
226 #if defined(MBEDTLS_SHA512_C)
227 if (mbedtls_sha512_self_test(v) != 0) {
228 suites_failed++;
229 }
230 suites_tested++;
231 #endif
232
233 #if defined(MBEDTLS_ARC4_C)
234 if (mbedtls_arc4_self_test(v) != 0) {
235 suites_failed++;
236 }
237 suites_tested++;
238 #endif
239
240 #if defined(MBEDTLS_DES_C)
241 if (mbedtls_des_self_test(v) != 0) {
242 suites_failed++;
243 }
244 suites_tested++;
245 #endif
246
247 #if defined(MBEDTLS_AES_C)
248 if (mbedtls_aes_self_test(v) != 0) {
249 suites_failed++;
250 }
251 suites_tested++;
252 #endif
253
254 #if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_AES_C)
255 if (mbedtls_gcm_self_test(v) != 0) {
256 suites_failed++;
257 }
258 suites_tested++;
259 #endif
260
261 #if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_AES_C)
262 if (mbedtls_ccm_self_test(v) != 0) {
263 suites_failed++;
264 }
265 suites_tested++;
266 #endif
267
268 #if defined(MBEDTLS_BASE64_C)
269 if (mbedtls_base64_self_test(v) != 0) {
270 suites_failed++;
271 }
272 suites_tested++;
273 #endif
274
275 #if defined(MBEDTLS_BIGNUM_C)
276 if (mbedtls_mpi_self_test(v) != 0) {
277 suites_failed++;
278 }
279 suites_tested++;
280 #endif
281
282 #if defined(MBEDTLS_RSA_C)
283 if (mbedtls_rsa_self_test(v) != 0) {
284 suites_failed++;
285 }
286 suites_tested++;
287 #endif
288
289 #if defined(MBEDTLS_CAMELLIA_C)
290 if (mbedtls_camellia_self_test(v) != 0) {
291 suites_failed++;
292 }
293 suites_tested++;
294 #endif
295
296 #if defined(MBEDTLS_ARIA_C)
297 if (mbedtls_aria_self_test(v) != 0) {
298 suites_failed++;
299 }
300 suites_tested++;
301 #endif
302
303 #if defined(MBEDTLS_CTR_DRBG_C)
304 if (mbedtls_ctr_drbg_self_test(v) != 0) {
305 suites_failed++;
306 }
307 suites_tested++;
308 #endif
309
310 #if defined(MBEDTLS_HMAC_DRBG_C)
311 if (mbedtls_hmac_drbg_self_test(v) != 0) {
312 suites_failed++;
313 }
314 suites_tested++;
315 #endif
316
317 #if defined(MBEDTLS_ECP_C)
318 if (mbedtls_ecp_self_test(v) != 0) {
319 suites_failed++;
320 }
321 suites_tested++;
322 #endif
323
324 #if defined(MBEDTLS_ECJPAKE_C)
325 if (mbedtls_ecjpake_self_test(v) != 0) {
326 suites_failed++;
327 }
328 suites_tested++;
329 #endif
330
331 #if defined(MBEDTLS_DHM_C)
332 if (mbedtls_dhm_self_test(v) != 0) {
333 suites_failed++;
334 }
335 suites_tested++;
336 #endif
337
338 #if defined(MBEDTLS_ENTROPY_C)
339
340 #if defined(MBEDTLS_ENTROPY_NV_SEED) && !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
341 create_entropy_seed_file();
342 #endif
343
344 if (mbedtls_entropy_self_test(v) != 0) {
345 suites_failed++;
346 }
347 suites_tested++;
348 #endif
349
350 #if defined(MBEDTLS_PKCS5_C)
351 if (mbedtls_pkcs5_self_test(v) != 0) {
352 suites_failed++;
353 }
354 suites_tested++;
355 #endif
356
357 #if defined(MBEDTLS_CMAC_C) \
358 && (defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C))
359 if (mbedtls_cmac_self_test(v) != 0) {
360 suites_failed++;
361 }
362 suites_tested++;
363 #endif
364
365 /* Slow tests last */
366
367 #if defined(MBEDTLS_TIMING_C)
368 if (mbedtls_timing_self_test(v) != 0) {
369 suites_failed++;
370 }
371 suites_tested++;
372 #endif
373
374 #else
375 mbedtls_printf(" MBEDTLS_SELF_TEST not defined.\n");
376 #endif
377
378 if (v != 0) {
379 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && defined(MBEDTLS_MEMORY_DEBUG)
380 mbedtls_memory_buffer_alloc_status();
381 #endif
382 }
383 #if defined(MBEDTLS_SELF_TEST)
384 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
385 mbedtls_memory_buffer_alloc_free();
386 if (mbedtls_memory_buffer_alloc_self_test(v) != 0) {
387 suites_failed++;
388 }
389 suites_tested++;
390 #endif
391 #endif
392
393 if (v != 0) {
394 mbedtls_printf(" Executed %d test suites\n\n", suites_tested);
395 if (suites_failed > 0) {
396 mbedtls_printf(" [ %d tests FAIL ]\n\n",
397 suites_failed);
398 } else {
399 mbedtls_printf(" [ All tests PASS ]\n\n");
400 }
401 zassert_not_equal(suites_tested, 0,
402 "ran %d tests", suites_tested);
403 zassert_equal(suites_failed, 0,
404 "%d tests failed", suites_failed);
405
406 #if defined(_WIN32)
407 mbedtls_printf(" Press Enter to exit this program.\n");
408 fflush(stdout);
409 getchar();
410 #endif
411 }
412
413 }
414