1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * Self-test demonstration program 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 5a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6a8e1175bSopenharmony_ci */ 7a8e1175bSopenharmony_ci 8a8e1175bSopenharmony_ci#include "mbedtls/build_info.h" 9a8e1175bSopenharmony_ci 10a8e1175bSopenharmony_ci#include "mbedtls/entropy.h" 11a8e1175bSopenharmony_ci#include "mbedtls/hmac_drbg.h" 12a8e1175bSopenharmony_ci#include "mbedtls/ctr_drbg.h" 13a8e1175bSopenharmony_ci#include "mbedtls/dhm.h" 14a8e1175bSopenharmony_ci#include "mbedtls/gcm.h" 15a8e1175bSopenharmony_ci#include "mbedtls/ccm.h" 16a8e1175bSopenharmony_ci#include "mbedtls/cmac.h" 17a8e1175bSopenharmony_ci#include "mbedtls/md5.h" 18a8e1175bSopenharmony_ci#include "mbedtls/ripemd160.h" 19a8e1175bSopenharmony_ci#include "mbedtls/sha1.h" 20a8e1175bSopenharmony_ci#include "mbedtls/sha256.h" 21a8e1175bSopenharmony_ci#include "mbedtls/sha512.h" 22a8e1175bSopenharmony_ci#include "mbedtls/sha3.h" 23a8e1175bSopenharmony_ci#include "mbedtls/des.h" 24a8e1175bSopenharmony_ci#include "mbedtls/aes.h" 25a8e1175bSopenharmony_ci#include "mbedtls/camellia.h" 26a8e1175bSopenharmony_ci#include "mbedtls/aria.h" 27a8e1175bSopenharmony_ci#include "mbedtls/chacha20.h" 28a8e1175bSopenharmony_ci#include "mbedtls/poly1305.h" 29a8e1175bSopenharmony_ci#include "mbedtls/chachapoly.h" 30a8e1175bSopenharmony_ci#include "mbedtls/base64.h" 31a8e1175bSopenharmony_ci#include "mbedtls/bignum.h" 32a8e1175bSopenharmony_ci#include "mbedtls/rsa.h" 33a8e1175bSopenharmony_ci#include "mbedtls/x509.h" 34a8e1175bSopenharmony_ci#include "mbedtls/pkcs5.h" 35a8e1175bSopenharmony_ci#include "mbedtls/ecp.h" 36a8e1175bSopenharmony_ci#include "mbedtls/ecjpake.h" 37a8e1175bSopenharmony_ci#include "mbedtls/timing.h" 38a8e1175bSopenharmony_ci#include "mbedtls/nist_kw.h" 39a8e1175bSopenharmony_ci#include "mbedtls/debug.h" 40a8e1175bSopenharmony_ci 41a8e1175bSopenharmony_ci#include <limits.h> 42a8e1175bSopenharmony_ci#include <string.h> 43a8e1175bSopenharmony_ci 44a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 45a8e1175bSopenharmony_ci 46a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) 47a8e1175bSopenharmony_ci#include "mbedtls/memory_buffer_alloc.h" 48a8e1175bSopenharmony_ci#endif 49a8e1175bSopenharmony_ci 50a8e1175bSopenharmony_ci 51a8e1175bSopenharmony_ci#if defined MBEDTLS_SELF_TEST 52a8e1175bSopenharmony_ci/* Sanity check for malloc. This is not expected to fail, and is rather 53a8e1175bSopenharmony_ci * intended to display potentially useful information about the platform, 54a8e1175bSopenharmony_ci * in particular the behavior of malloc(0). */ 55a8e1175bSopenharmony_cistatic int calloc_self_test(int verbose) 56a8e1175bSopenharmony_ci{ 57a8e1175bSopenharmony_ci int failures = 0; 58a8e1175bSopenharmony_ci void *empty1 = mbedtls_calloc(0, 1); 59a8e1175bSopenharmony_ci void *empty2 = mbedtls_calloc(0, 1); 60a8e1175bSopenharmony_ci void *buffer1 = mbedtls_calloc(1, 1); 61a8e1175bSopenharmony_ci void *buffer2 = mbedtls_calloc(1, 1); 62a8e1175bSopenharmony_ci unsigned int buffer_3_size = 256; 63a8e1175bSopenharmony_ci unsigned int buffer_4_size = 4097; /* Allocate more than the usual page size */ 64a8e1175bSopenharmony_ci unsigned char *buffer3 = mbedtls_calloc(buffer_3_size, 1); 65a8e1175bSopenharmony_ci unsigned char *buffer4 = mbedtls_calloc(buffer_4_size, 1); 66a8e1175bSopenharmony_ci 67a8e1175bSopenharmony_ci if (empty1 == NULL && empty2 == NULL) { 68a8e1175bSopenharmony_ci if (verbose) { 69a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(0,1): passed (NULL)\n"); 70a8e1175bSopenharmony_ci } 71a8e1175bSopenharmony_ci } else if (empty1 == NULL || empty2 == NULL) { 72a8e1175bSopenharmony_ci if (verbose) { 73a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(0,1): failed (mix of NULL and non-NULL)\n"); 74a8e1175bSopenharmony_ci } 75a8e1175bSopenharmony_ci ++failures; 76a8e1175bSopenharmony_ci } else if (empty1 == empty2) { 77a8e1175bSopenharmony_ci if (verbose) { 78a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(0,1): passed (same non-null)\n"); 79a8e1175bSopenharmony_ci } 80a8e1175bSopenharmony_ci empty2 = NULL; 81a8e1175bSopenharmony_ci } else { 82a8e1175bSopenharmony_ci if (verbose) { 83a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(0,1): passed (distinct non-null)\n"); 84a8e1175bSopenharmony_ci } 85a8e1175bSopenharmony_ci } 86a8e1175bSopenharmony_ci 87a8e1175bSopenharmony_ci mbedtls_free(empty1); 88a8e1175bSopenharmony_ci mbedtls_free(empty2); 89a8e1175bSopenharmony_ci 90a8e1175bSopenharmony_ci empty1 = mbedtls_calloc(1, 0); 91a8e1175bSopenharmony_ci empty2 = mbedtls_calloc(1, 0); 92a8e1175bSopenharmony_ci if (empty1 == NULL && empty2 == NULL) { 93a8e1175bSopenharmony_ci if (verbose) { 94a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(1,0): passed (NULL)\n"); 95a8e1175bSopenharmony_ci } 96a8e1175bSopenharmony_ci } else if (empty1 == NULL || empty2 == NULL) { 97a8e1175bSopenharmony_ci if (verbose) { 98a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(1,0): failed (mix of NULL and non-NULL)\n"); 99a8e1175bSopenharmony_ci } 100a8e1175bSopenharmony_ci ++failures; 101a8e1175bSopenharmony_ci } else if (empty1 == empty2) { 102a8e1175bSopenharmony_ci if (verbose) { 103a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(1,0): passed (same non-null)\n"); 104a8e1175bSopenharmony_ci } 105a8e1175bSopenharmony_ci empty2 = NULL; 106a8e1175bSopenharmony_ci } else { 107a8e1175bSopenharmony_ci if (verbose) { 108a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(1,0): passed (distinct non-null)\n"); 109a8e1175bSopenharmony_ci } 110a8e1175bSopenharmony_ci } 111a8e1175bSopenharmony_ci 112a8e1175bSopenharmony_ci if (buffer1 == NULL || buffer2 == NULL) { 113a8e1175bSopenharmony_ci if (verbose) { 114a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(1): failed (NULL)\n"); 115a8e1175bSopenharmony_ci } 116a8e1175bSopenharmony_ci ++failures; 117a8e1175bSopenharmony_ci } else if (buffer1 == buffer2) { 118a8e1175bSopenharmony_ci if (verbose) { 119a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(1): failed (same buffer twice)\n"); 120a8e1175bSopenharmony_ci } 121a8e1175bSopenharmony_ci ++failures; 122a8e1175bSopenharmony_ci buffer2 = NULL; 123a8e1175bSopenharmony_ci } else { 124a8e1175bSopenharmony_ci if (verbose) { 125a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(1): passed\n"); 126a8e1175bSopenharmony_ci } 127a8e1175bSopenharmony_ci } 128a8e1175bSopenharmony_ci 129a8e1175bSopenharmony_ci mbedtls_free(buffer1); 130a8e1175bSopenharmony_ci buffer1 = mbedtls_calloc(1, 1); 131a8e1175bSopenharmony_ci if (buffer1 == NULL) { 132a8e1175bSopenharmony_ci if (verbose) { 133a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(1 again): failed (NULL)\n"); 134a8e1175bSopenharmony_ci } 135a8e1175bSopenharmony_ci ++failures; 136a8e1175bSopenharmony_ci } else { 137a8e1175bSopenharmony_ci if (verbose) { 138a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(1 again): passed\n"); 139a8e1175bSopenharmony_ci } 140a8e1175bSopenharmony_ci } 141a8e1175bSopenharmony_ci 142a8e1175bSopenharmony_ci for (unsigned int i = 0; i < buffer_3_size; i++) { 143a8e1175bSopenharmony_ci if (buffer3[i] != 0) { 144a8e1175bSopenharmony_ci ++failures; 145a8e1175bSopenharmony_ci if (verbose) { 146a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(%u): failed (memory not initialized to 0)\n", 147a8e1175bSopenharmony_ci buffer_3_size); 148a8e1175bSopenharmony_ci } 149a8e1175bSopenharmony_ci break; 150a8e1175bSopenharmony_ci } 151a8e1175bSopenharmony_ci } 152a8e1175bSopenharmony_ci 153a8e1175bSopenharmony_ci for (unsigned int i = 0; i < buffer_4_size; i++) { 154a8e1175bSopenharmony_ci if (buffer4[i] != 0) { 155a8e1175bSopenharmony_ci ++failures; 156a8e1175bSopenharmony_ci if (verbose) { 157a8e1175bSopenharmony_ci mbedtls_printf(" CALLOC(%u): failed (memory not initialized to 0)\n", 158a8e1175bSopenharmony_ci buffer_4_size); 159a8e1175bSopenharmony_ci } 160a8e1175bSopenharmony_ci break; 161a8e1175bSopenharmony_ci } 162a8e1175bSopenharmony_ci } 163a8e1175bSopenharmony_ci 164a8e1175bSopenharmony_ci if (verbose) { 165a8e1175bSopenharmony_ci mbedtls_printf("\n"); 166a8e1175bSopenharmony_ci } 167a8e1175bSopenharmony_ci mbedtls_free(empty1); 168a8e1175bSopenharmony_ci mbedtls_free(empty2); 169a8e1175bSopenharmony_ci mbedtls_free(buffer1); 170a8e1175bSopenharmony_ci mbedtls_free(buffer2); 171a8e1175bSopenharmony_ci mbedtls_free(buffer3); 172a8e1175bSopenharmony_ci mbedtls_free(buffer4); 173a8e1175bSopenharmony_ci return failures; 174a8e1175bSopenharmony_ci} 175a8e1175bSopenharmony_ci#endif /* MBEDTLS_SELF_TEST */ 176a8e1175bSopenharmony_ci 177a8e1175bSopenharmony_cistatic int test_snprintf(size_t n, const char *ref_buf, int ref_ret) 178a8e1175bSopenharmony_ci{ 179a8e1175bSopenharmony_ci int ret; 180a8e1175bSopenharmony_ci char buf[10] = "xxxxxxxxx"; 181a8e1175bSopenharmony_ci const char ref[10] = "xxxxxxxxx"; 182a8e1175bSopenharmony_ci 183a8e1175bSopenharmony_ci ret = mbedtls_snprintf(buf, n, "%s", "123"); 184a8e1175bSopenharmony_ci if (ret < 0 || (size_t) ret >= n) { 185a8e1175bSopenharmony_ci ret = -1; 186a8e1175bSopenharmony_ci } 187a8e1175bSopenharmony_ci 188a8e1175bSopenharmony_ci if (strncmp(ref_buf, buf, sizeof(buf)) != 0 || 189a8e1175bSopenharmony_ci ref_ret != ret || 190a8e1175bSopenharmony_ci memcmp(buf + n, ref + n, sizeof(buf) - n) != 0) { 191a8e1175bSopenharmony_ci return 1; 192a8e1175bSopenharmony_ci } 193a8e1175bSopenharmony_ci 194a8e1175bSopenharmony_ci return 0; 195a8e1175bSopenharmony_ci} 196a8e1175bSopenharmony_ci 197a8e1175bSopenharmony_cistatic int run_test_snprintf(void) 198a8e1175bSopenharmony_ci{ 199a8e1175bSopenharmony_ci return test_snprintf(0, "xxxxxxxxx", -1) != 0 || 200a8e1175bSopenharmony_ci test_snprintf(1, "", -1) != 0 || 201a8e1175bSopenharmony_ci test_snprintf(2, "1", -1) != 0 || 202a8e1175bSopenharmony_ci test_snprintf(3, "12", -1) != 0 || 203a8e1175bSopenharmony_ci test_snprintf(4, "123", 3) != 0 || 204a8e1175bSopenharmony_ci test_snprintf(5, "123", 3) != 0; 205a8e1175bSopenharmony_ci} 206a8e1175bSopenharmony_ci 207a8e1175bSopenharmony_ci/* 208a8e1175bSopenharmony_ci * Check if a seed file is present, and if not create one for the entropy 209a8e1175bSopenharmony_ci * self-test. If this fails, we attempt the test anyway, so no error is passed 210a8e1175bSopenharmony_ci * back. 211a8e1175bSopenharmony_ci */ 212a8e1175bSopenharmony_ci#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_ENTROPY_C) 213a8e1175bSopenharmony_ci#if defined(MBEDTLS_ENTROPY_NV_SEED) && !defined(MBEDTLS_NO_PLATFORM_ENTROPY) 214a8e1175bSopenharmony_cistatic void create_entropy_seed_file(void) 215a8e1175bSopenharmony_ci{ 216a8e1175bSopenharmony_ci int result; 217a8e1175bSopenharmony_ci size_t output_len = 0; 218a8e1175bSopenharmony_ci unsigned char seed_value[MBEDTLS_ENTROPY_BLOCK_SIZE]; 219a8e1175bSopenharmony_ci 220a8e1175bSopenharmony_ci /* Attempt to read the entropy seed file. If this fails - attempt to write 221a8e1175bSopenharmony_ci * to the file to ensure one is present. */ 222a8e1175bSopenharmony_ci result = mbedtls_platform_std_nv_seed_read(seed_value, 223a8e1175bSopenharmony_ci MBEDTLS_ENTROPY_BLOCK_SIZE); 224a8e1175bSopenharmony_ci if (0 == result) { 225a8e1175bSopenharmony_ci return; 226a8e1175bSopenharmony_ci } 227a8e1175bSopenharmony_ci 228a8e1175bSopenharmony_ci result = mbedtls_platform_entropy_poll(NULL, 229a8e1175bSopenharmony_ci seed_value, 230a8e1175bSopenharmony_ci MBEDTLS_ENTROPY_BLOCK_SIZE, 231a8e1175bSopenharmony_ci &output_len); 232a8e1175bSopenharmony_ci if (0 != result) { 233a8e1175bSopenharmony_ci return; 234a8e1175bSopenharmony_ci } 235a8e1175bSopenharmony_ci 236a8e1175bSopenharmony_ci if (MBEDTLS_ENTROPY_BLOCK_SIZE != output_len) { 237a8e1175bSopenharmony_ci return; 238a8e1175bSopenharmony_ci } 239a8e1175bSopenharmony_ci 240a8e1175bSopenharmony_ci mbedtls_platform_std_nv_seed_write(seed_value, MBEDTLS_ENTROPY_BLOCK_SIZE); 241a8e1175bSopenharmony_ci} 242a8e1175bSopenharmony_ci#endif 243a8e1175bSopenharmony_ci 244a8e1175bSopenharmony_ciint mbedtls_entropy_self_test_wrapper(int verbose) 245a8e1175bSopenharmony_ci{ 246a8e1175bSopenharmony_ci#if defined(MBEDTLS_ENTROPY_NV_SEED) && !defined(MBEDTLS_NO_PLATFORM_ENTROPY) 247a8e1175bSopenharmony_ci create_entropy_seed_file(); 248a8e1175bSopenharmony_ci#endif 249a8e1175bSopenharmony_ci return mbedtls_entropy_self_test(verbose); 250a8e1175bSopenharmony_ci} 251a8e1175bSopenharmony_ci#endif 252a8e1175bSopenharmony_ci 253a8e1175bSopenharmony_ci#if defined(MBEDTLS_SELF_TEST) 254a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) 255a8e1175bSopenharmony_ciint mbedtls_memory_buffer_alloc_free_and_self_test(int verbose) 256a8e1175bSopenharmony_ci{ 257a8e1175bSopenharmony_ci if (verbose != 0) { 258a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 259a8e1175bSopenharmony_ci mbedtls_memory_buffer_alloc_status(); 260a8e1175bSopenharmony_ci#endif 261a8e1175bSopenharmony_ci } 262a8e1175bSopenharmony_ci mbedtls_memory_buffer_alloc_free(); 263a8e1175bSopenharmony_ci return mbedtls_memory_buffer_alloc_self_test(verbose); 264a8e1175bSopenharmony_ci} 265a8e1175bSopenharmony_ci#endif 266a8e1175bSopenharmony_ci 267a8e1175bSopenharmony_citypedef struct { 268a8e1175bSopenharmony_ci const char *name; 269a8e1175bSopenharmony_ci int (*function)(int); 270a8e1175bSopenharmony_ci} selftest_t; 271a8e1175bSopenharmony_ci 272a8e1175bSopenharmony_ciconst selftest_t selftests[] = 273a8e1175bSopenharmony_ci{ 274a8e1175bSopenharmony_ci { "calloc", calloc_self_test }, 275a8e1175bSopenharmony_ci#if defined(MBEDTLS_MD5_C) 276a8e1175bSopenharmony_ci { "md5", mbedtls_md5_self_test }, 277a8e1175bSopenharmony_ci#endif 278a8e1175bSopenharmony_ci#if defined(MBEDTLS_RIPEMD160_C) 279a8e1175bSopenharmony_ci { "ripemd160", mbedtls_ripemd160_self_test }, 280a8e1175bSopenharmony_ci#endif 281a8e1175bSopenharmony_ci#if defined(MBEDTLS_SHA1_C) 282a8e1175bSopenharmony_ci { "sha1", mbedtls_sha1_self_test }, 283a8e1175bSopenharmony_ci#endif 284a8e1175bSopenharmony_ci#if defined(MBEDTLS_SHA224_C) 285a8e1175bSopenharmony_ci { "sha224", mbedtls_sha224_self_test }, 286a8e1175bSopenharmony_ci#endif 287a8e1175bSopenharmony_ci#if defined(MBEDTLS_SHA256_C) 288a8e1175bSopenharmony_ci { "sha256", mbedtls_sha256_self_test }, 289a8e1175bSopenharmony_ci#endif 290a8e1175bSopenharmony_ci#if defined(MBEDTLS_SHA384_C) 291a8e1175bSopenharmony_ci { "sha384", mbedtls_sha384_self_test }, 292a8e1175bSopenharmony_ci#endif 293a8e1175bSopenharmony_ci#if defined(MBEDTLS_SHA512_C) 294a8e1175bSopenharmony_ci { "sha512", mbedtls_sha512_self_test }, 295a8e1175bSopenharmony_ci#endif 296a8e1175bSopenharmony_ci#if defined(MBEDTLS_SHA3_C) 297a8e1175bSopenharmony_ci { "sha3", mbedtls_sha3_self_test }, 298a8e1175bSopenharmony_ci#endif 299a8e1175bSopenharmony_ci#if defined(MBEDTLS_DES_C) 300a8e1175bSopenharmony_ci { "des", mbedtls_des_self_test }, 301a8e1175bSopenharmony_ci#endif 302a8e1175bSopenharmony_ci#if defined(MBEDTLS_AES_C) 303a8e1175bSopenharmony_ci { "aes", mbedtls_aes_self_test }, 304a8e1175bSopenharmony_ci#endif 305a8e1175bSopenharmony_ci#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_AES_C) 306a8e1175bSopenharmony_ci { "gcm", mbedtls_gcm_self_test }, 307a8e1175bSopenharmony_ci#endif 308a8e1175bSopenharmony_ci#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_AES_C) 309a8e1175bSopenharmony_ci { "ccm", mbedtls_ccm_self_test }, 310a8e1175bSopenharmony_ci#endif 311a8e1175bSopenharmony_ci#if defined(MBEDTLS_NIST_KW_C) && defined(MBEDTLS_AES_C) 312a8e1175bSopenharmony_ci { "nist_kw", mbedtls_nist_kw_self_test }, 313a8e1175bSopenharmony_ci#endif 314a8e1175bSopenharmony_ci#if defined(MBEDTLS_CMAC_C) 315a8e1175bSopenharmony_ci { "cmac", mbedtls_cmac_self_test }, 316a8e1175bSopenharmony_ci#endif 317a8e1175bSopenharmony_ci#if defined(MBEDTLS_CHACHA20_C) 318a8e1175bSopenharmony_ci { "chacha20", mbedtls_chacha20_self_test }, 319a8e1175bSopenharmony_ci#endif 320a8e1175bSopenharmony_ci#if defined(MBEDTLS_POLY1305_C) 321a8e1175bSopenharmony_ci { "poly1305", mbedtls_poly1305_self_test }, 322a8e1175bSopenharmony_ci#endif 323a8e1175bSopenharmony_ci#if defined(MBEDTLS_CHACHAPOLY_C) 324a8e1175bSopenharmony_ci { "chacha20-poly1305", mbedtls_chachapoly_self_test }, 325a8e1175bSopenharmony_ci#endif 326a8e1175bSopenharmony_ci#if defined(MBEDTLS_BASE64_C) 327a8e1175bSopenharmony_ci { "base64", mbedtls_base64_self_test }, 328a8e1175bSopenharmony_ci#endif 329a8e1175bSopenharmony_ci#if defined(MBEDTLS_BIGNUM_C) 330a8e1175bSopenharmony_ci { "mpi", mbedtls_mpi_self_test }, 331a8e1175bSopenharmony_ci#endif 332a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) 333a8e1175bSopenharmony_ci { "rsa", mbedtls_rsa_self_test }, 334a8e1175bSopenharmony_ci#endif 335a8e1175bSopenharmony_ci#if defined(MBEDTLS_CAMELLIA_C) 336a8e1175bSopenharmony_ci { "camellia", mbedtls_camellia_self_test }, 337a8e1175bSopenharmony_ci#endif 338a8e1175bSopenharmony_ci#if defined(MBEDTLS_ARIA_C) 339a8e1175bSopenharmony_ci { "aria", mbedtls_aria_self_test }, 340a8e1175bSopenharmony_ci#endif 341a8e1175bSopenharmony_ci#if defined(MBEDTLS_CTR_DRBG_C) 342a8e1175bSopenharmony_ci { "ctr_drbg", mbedtls_ctr_drbg_self_test }, 343a8e1175bSopenharmony_ci#endif 344a8e1175bSopenharmony_ci#if defined(MBEDTLS_HMAC_DRBG_C) 345a8e1175bSopenharmony_ci { "hmac_drbg", mbedtls_hmac_drbg_self_test }, 346a8e1175bSopenharmony_ci#endif 347a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_C) 348a8e1175bSopenharmony_ci { "ecp", mbedtls_ecp_self_test }, 349a8e1175bSopenharmony_ci#endif 350a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECJPAKE_C) 351a8e1175bSopenharmony_ci { "ecjpake", mbedtls_ecjpake_self_test }, 352a8e1175bSopenharmony_ci#endif 353a8e1175bSopenharmony_ci#if defined(MBEDTLS_DHM_C) 354a8e1175bSopenharmony_ci { "dhm", mbedtls_dhm_self_test }, 355a8e1175bSopenharmony_ci#endif 356a8e1175bSopenharmony_ci#if defined(MBEDTLS_ENTROPY_C) 357a8e1175bSopenharmony_ci { "entropy", mbedtls_entropy_self_test_wrapper }, 358a8e1175bSopenharmony_ci#endif 359a8e1175bSopenharmony_ci#if defined(MBEDTLS_PKCS5_C) 360a8e1175bSopenharmony_ci { "pkcs5", mbedtls_pkcs5_self_test }, 361a8e1175bSopenharmony_ci#endif 362a8e1175bSopenharmony_ci/* Heap test comes last */ 363a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) 364a8e1175bSopenharmony_ci { "memory_buffer_alloc", mbedtls_memory_buffer_alloc_free_and_self_test }, 365a8e1175bSopenharmony_ci#endif 366a8e1175bSopenharmony_ci { NULL, NULL } 367a8e1175bSopenharmony_ci}; 368a8e1175bSopenharmony_ci#endif /* MBEDTLS_SELF_TEST */ 369a8e1175bSopenharmony_ci 370a8e1175bSopenharmony_ciint main(int argc, char *argv[]) 371a8e1175bSopenharmony_ci{ 372a8e1175bSopenharmony_ci#if defined(MBEDTLS_SELF_TEST) 373a8e1175bSopenharmony_ci const selftest_t *test; 374a8e1175bSopenharmony_ci#endif /* MBEDTLS_SELF_TEST */ 375a8e1175bSopenharmony_ci char **argp; 376a8e1175bSopenharmony_ci int v = 1; /* v=1 for verbose mode */ 377a8e1175bSopenharmony_ci int exclude_mode = 0; 378a8e1175bSopenharmony_ci int suites_tested = 0, suites_failed = 0; 379a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && defined(MBEDTLS_SELF_TEST) 380a8e1175bSopenharmony_ci unsigned char buf[1000000]; 381a8e1175bSopenharmony_ci#endif 382a8e1175bSopenharmony_ci void *pointer; 383a8e1175bSopenharmony_ci 384a8e1175bSopenharmony_ci /* 385a8e1175bSopenharmony_ci * Check some basic platform requirements as specified in README.md 386a8e1175bSopenharmony_ci */ 387a8e1175bSopenharmony_ci if (SIZE_MAX < INT_MAX || SIZE_MAX < UINT_MAX) { 388a8e1175bSopenharmony_ci mbedtls_printf("SIZE_MAX must be at least as big as INT_MAX and UINT_MAX\n"); 389a8e1175bSopenharmony_ci mbedtls_exit(MBEDTLS_EXIT_FAILURE); 390a8e1175bSopenharmony_ci } 391a8e1175bSopenharmony_ci 392a8e1175bSopenharmony_ci if (sizeof(int) < 4) { 393a8e1175bSopenharmony_ci mbedtls_printf("int must be at least 32 bits\n"); 394a8e1175bSopenharmony_ci mbedtls_exit(MBEDTLS_EXIT_FAILURE); 395a8e1175bSopenharmony_ci } 396a8e1175bSopenharmony_ci 397a8e1175bSopenharmony_ci if (sizeof(size_t) < 4) { 398a8e1175bSopenharmony_ci mbedtls_printf("size_t must be at least 32 bits\n"); 399a8e1175bSopenharmony_ci mbedtls_exit(MBEDTLS_EXIT_FAILURE); 400a8e1175bSopenharmony_ci } 401a8e1175bSopenharmony_ci 402a8e1175bSopenharmony_ci uint32_t endian_test = 0x12345678; 403a8e1175bSopenharmony_ci char *p = (char *) &endian_test; 404a8e1175bSopenharmony_ci if (!(p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78) && 405a8e1175bSopenharmony_ci !(p[3] == 0x12 && p[2] == 0x34 && p[1] == 0x56 && p[0] == 0x78)) { 406a8e1175bSopenharmony_ci mbedtls_printf("Mixed-endian platforms are not supported\n"); 407a8e1175bSopenharmony_ci mbedtls_exit(MBEDTLS_EXIT_FAILURE); 408a8e1175bSopenharmony_ci } 409a8e1175bSopenharmony_ci 410a8e1175bSopenharmony_ci /* 411a8e1175bSopenharmony_ci * The C standard doesn't guarantee that all-bits-0 is the representation 412a8e1175bSopenharmony_ci * of a NULL pointer. We do however use that in our code for initializing 413a8e1175bSopenharmony_ci * structures, which should work on every modern platform. Let's be sure. 414a8e1175bSopenharmony_ci */ 415a8e1175bSopenharmony_ci memset(&pointer, 0, sizeof(void *)); 416a8e1175bSopenharmony_ci if (pointer != NULL) { 417a8e1175bSopenharmony_ci mbedtls_printf("all-bits-zero is not a NULL pointer\n"); 418a8e1175bSopenharmony_ci mbedtls_exit(MBEDTLS_EXIT_FAILURE); 419a8e1175bSopenharmony_ci } 420a8e1175bSopenharmony_ci 421a8e1175bSopenharmony_ci /* 422a8e1175bSopenharmony_ci * The C standard allows padding bits in the representation 423a8e1175bSopenharmony_ci * of standard integer types, but our code does currently not 424a8e1175bSopenharmony_ci * support them. 425a8e1175bSopenharmony_ci * 426a8e1175bSopenharmony_ci * Here we check that the underlying C implementation doesn't 427a8e1175bSopenharmony_ci * use padding bits, and fail cleanly if it does. 428a8e1175bSopenharmony_ci * 429a8e1175bSopenharmony_ci * The check works by casting the maximum value representable 430a8e1175bSopenharmony_ci * by a given integer type into the unpadded integer type of the 431a8e1175bSopenharmony_ci * same bit-width and checking that it agrees with the maximum value 432a8e1175bSopenharmony_ci * of that unpadded type. For example, for a 4-byte int, 433a8e1175bSopenharmony_ci * MAX_INT should be 0x7fffffff in int32_t. This assumes that 434a8e1175bSopenharmony_ci * CHAR_BIT == 8, which is checked in check_config.h. 435a8e1175bSopenharmony_ci * 436a8e1175bSopenharmony_ci * We assume that [u]intxx_t exist and that they don't 437a8e1175bSopenharmony_ci * have padding bits, as the standard requires. 438a8e1175bSopenharmony_ci */ 439a8e1175bSopenharmony_ci 440a8e1175bSopenharmony_ci#define CHECK_PADDING_SIGNED(TYPE, NAME) \ 441a8e1175bSopenharmony_ci do \ 442a8e1175bSopenharmony_ci { \ 443a8e1175bSopenharmony_ci if (sizeof(TYPE) == 2 || sizeof(TYPE) == 4 || \ 444a8e1175bSopenharmony_ci sizeof(TYPE) == 8) { \ 445a8e1175bSopenharmony_ci if ((sizeof(TYPE) == 2 && \ 446a8e1175bSopenharmony_ci (int16_t) NAME ## _MAX != 0x7FFF) || \ 447a8e1175bSopenharmony_ci (sizeof(TYPE) == 4 && \ 448a8e1175bSopenharmony_ci (int32_t) NAME ## _MAX != 0x7FFFFFFF) || \ 449a8e1175bSopenharmony_ci (sizeof(TYPE) == 8 && \ 450a8e1175bSopenharmony_ci (int64_t) NAME ## _MAX != 0x7FFFFFFFFFFFFFFF)) \ 451a8e1175bSopenharmony_ci { \ 452a8e1175bSopenharmony_ci mbedtls_printf("Type '" #TYPE "' has padding bits\n"); \ 453a8e1175bSopenharmony_ci mbedtls_exit(MBEDTLS_EXIT_FAILURE); \ 454a8e1175bSopenharmony_ci } \ 455a8e1175bSopenharmony_ci } else { \ 456a8e1175bSopenharmony_ci mbedtls_printf("Padding checks only implemented for types of size 2, 4 or 8" \ 457a8e1175bSopenharmony_ci " - cannot check type '" #TYPE "' of size %" MBEDTLS_PRINTF_SIZET "\n", \ 458a8e1175bSopenharmony_ci sizeof(TYPE)); \ 459a8e1175bSopenharmony_ci mbedtls_exit(MBEDTLS_EXIT_FAILURE); \ 460a8e1175bSopenharmony_ci } \ 461a8e1175bSopenharmony_ci } while (0) 462a8e1175bSopenharmony_ci 463a8e1175bSopenharmony_ci#define CHECK_PADDING_UNSIGNED(TYPE, NAME) \ 464a8e1175bSopenharmony_ci do \ 465a8e1175bSopenharmony_ci { \ 466a8e1175bSopenharmony_ci if ((sizeof(TYPE) == 2 && \ 467a8e1175bSopenharmony_ci (uint16_t) NAME ## _MAX != 0xFFFF) || \ 468a8e1175bSopenharmony_ci (sizeof(TYPE) == 4 && \ 469a8e1175bSopenharmony_ci (uint32_t) NAME ## _MAX != 0xFFFFFFFF) || \ 470a8e1175bSopenharmony_ci (sizeof(TYPE) == 8 && \ 471a8e1175bSopenharmony_ci (uint64_t) NAME ## _MAX != 0xFFFFFFFFFFFFFFFF)) \ 472a8e1175bSopenharmony_ci { \ 473a8e1175bSopenharmony_ci mbedtls_printf("Type '" #TYPE "' has padding bits\n"); \ 474a8e1175bSopenharmony_ci mbedtls_exit(MBEDTLS_EXIT_FAILURE); \ 475a8e1175bSopenharmony_ci } \ 476a8e1175bSopenharmony_ci } while (0) 477a8e1175bSopenharmony_ci 478a8e1175bSopenharmony_ci CHECK_PADDING_SIGNED(short, SHRT); 479a8e1175bSopenharmony_ci CHECK_PADDING_SIGNED(int, INT); 480a8e1175bSopenharmony_ci CHECK_PADDING_SIGNED(long, LONG); 481a8e1175bSopenharmony_ci CHECK_PADDING_SIGNED(long long, LLONG); 482a8e1175bSopenharmony_ci CHECK_PADDING_SIGNED(ptrdiff_t, PTRDIFF); 483a8e1175bSopenharmony_ci 484a8e1175bSopenharmony_ci CHECK_PADDING_UNSIGNED(unsigned short, USHRT); 485a8e1175bSopenharmony_ci CHECK_PADDING_UNSIGNED(unsigned, UINT); 486a8e1175bSopenharmony_ci CHECK_PADDING_UNSIGNED(unsigned long, ULONG); 487a8e1175bSopenharmony_ci CHECK_PADDING_UNSIGNED(unsigned long long, ULLONG); 488a8e1175bSopenharmony_ci CHECK_PADDING_UNSIGNED(size_t, SIZE); 489a8e1175bSopenharmony_ci 490a8e1175bSopenharmony_ci#undef CHECK_PADDING_SIGNED 491a8e1175bSopenharmony_ci#undef CHECK_PADDING_UNSIGNED 492a8e1175bSopenharmony_ci 493a8e1175bSopenharmony_ci /* 494a8e1175bSopenharmony_ci * Make sure we have a snprintf that correctly zero-terminates 495a8e1175bSopenharmony_ci */ 496a8e1175bSopenharmony_ci if (run_test_snprintf() != 0) { 497a8e1175bSopenharmony_ci mbedtls_printf("the snprintf implementation is broken\n"); 498a8e1175bSopenharmony_ci mbedtls_exit(MBEDTLS_EXIT_FAILURE); 499a8e1175bSopenharmony_ci } 500a8e1175bSopenharmony_ci 501a8e1175bSopenharmony_ci for (argp = argv + (argc >= 1 ? 1 : argc); *argp != NULL; ++argp) { 502a8e1175bSopenharmony_ci if (strcmp(*argp, "--quiet") == 0 || 503a8e1175bSopenharmony_ci strcmp(*argp, "-q") == 0) { 504a8e1175bSopenharmony_ci v = 0; 505a8e1175bSopenharmony_ci } else if (strcmp(*argp, "--exclude") == 0 || 506a8e1175bSopenharmony_ci strcmp(*argp, "-x") == 0) { 507a8e1175bSopenharmony_ci exclude_mode = 1; 508a8e1175bSopenharmony_ci } else { 509a8e1175bSopenharmony_ci break; 510a8e1175bSopenharmony_ci } 511a8e1175bSopenharmony_ci } 512a8e1175bSopenharmony_ci 513a8e1175bSopenharmony_ci if (v != 0) { 514a8e1175bSopenharmony_ci mbedtls_printf("\n"); 515a8e1175bSopenharmony_ci } 516a8e1175bSopenharmony_ci 517a8e1175bSopenharmony_ci#if defined(MBEDTLS_SELF_TEST) 518a8e1175bSopenharmony_ci 519a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) 520a8e1175bSopenharmony_ci mbedtls_memory_buffer_alloc_init(buf, sizeof(buf)); 521a8e1175bSopenharmony_ci#endif 522a8e1175bSopenharmony_ci 523a8e1175bSopenharmony_ci if (*argp != NULL && exclude_mode == 0) { 524a8e1175bSopenharmony_ci /* Run the specified tests */ 525a8e1175bSopenharmony_ci for (; *argp != NULL; argp++) { 526a8e1175bSopenharmony_ci for (test = selftests; test->name != NULL; test++) { 527a8e1175bSopenharmony_ci if (!strcmp(*argp, test->name)) { 528a8e1175bSopenharmony_ci if (test->function(v) != 0) { 529a8e1175bSopenharmony_ci suites_failed++; 530a8e1175bSopenharmony_ci } 531a8e1175bSopenharmony_ci suites_tested++; 532a8e1175bSopenharmony_ci break; 533a8e1175bSopenharmony_ci } 534a8e1175bSopenharmony_ci } 535a8e1175bSopenharmony_ci if (test->name == NULL) { 536a8e1175bSopenharmony_ci mbedtls_printf(" Test suite %s not available -> failed\n\n", *argp); 537a8e1175bSopenharmony_ci suites_failed++; 538a8e1175bSopenharmony_ci } 539a8e1175bSopenharmony_ci } 540a8e1175bSopenharmony_ci } else { 541a8e1175bSopenharmony_ci /* Run all the tests except excluded ones */ 542a8e1175bSopenharmony_ci for (test = selftests; test->name != NULL; test++) { 543a8e1175bSopenharmony_ci if (exclude_mode) { 544a8e1175bSopenharmony_ci char **excluded; 545a8e1175bSopenharmony_ci for (excluded = argp; *excluded != NULL; ++excluded) { 546a8e1175bSopenharmony_ci if (!strcmp(*excluded, test->name)) { 547a8e1175bSopenharmony_ci break; 548a8e1175bSopenharmony_ci } 549a8e1175bSopenharmony_ci } 550a8e1175bSopenharmony_ci if (*excluded) { 551a8e1175bSopenharmony_ci if (v) { 552a8e1175bSopenharmony_ci mbedtls_printf(" Skip: %s\n", test->name); 553a8e1175bSopenharmony_ci } 554a8e1175bSopenharmony_ci continue; 555a8e1175bSopenharmony_ci } 556a8e1175bSopenharmony_ci } 557a8e1175bSopenharmony_ci if (test->function(v) != 0) { 558a8e1175bSopenharmony_ci suites_failed++; 559a8e1175bSopenharmony_ci } 560a8e1175bSopenharmony_ci suites_tested++; 561a8e1175bSopenharmony_ci } 562a8e1175bSopenharmony_ci } 563a8e1175bSopenharmony_ci 564a8e1175bSopenharmony_ci#else 565a8e1175bSopenharmony_ci (void) exclude_mode; 566a8e1175bSopenharmony_ci mbedtls_printf(" MBEDTLS_SELF_TEST not defined.\n"); 567a8e1175bSopenharmony_ci#endif 568a8e1175bSopenharmony_ci 569a8e1175bSopenharmony_ci if (v != 0) { 570a8e1175bSopenharmony_ci mbedtls_printf(" Executed %d test suites\n\n", suites_tested); 571a8e1175bSopenharmony_ci 572a8e1175bSopenharmony_ci if (suites_failed > 0) { 573a8e1175bSopenharmony_ci mbedtls_printf(" [ %d tests FAIL ]\n\n", suites_failed); 574a8e1175bSopenharmony_ci } else { 575a8e1175bSopenharmony_ci mbedtls_printf(" [ All tests PASS ]\n\n"); 576a8e1175bSopenharmony_ci } 577a8e1175bSopenharmony_ci } 578a8e1175bSopenharmony_ci 579a8e1175bSopenharmony_ci if (suites_failed > 0) { 580a8e1175bSopenharmony_ci mbedtls_exit(MBEDTLS_EXIT_FAILURE); 581a8e1175bSopenharmony_ci } 582a8e1175bSopenharmony_ci 583a8e1175bSopenharmony_ci mbedtls_exit(MBEDTLS_EXIT_SUCCESS); 584a8e1175bSopenharmony_ci} 585