1a8e1175bSopenharmony_ci/** 2a8e1175bSopenharmony_ci * \file random.c 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * \brief This file contains the helper functions to generate random numbers 5a8e1175bSopenharmony_ci * for the purpose of testing. 6a8e1175bSopenharmony_ci */ 7a8e1175bSopenharmony_ci 8a8e1175bSopenharmony_ci/* 9a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 10a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 11a8e1175bSopenharmony_ci */ 12a8e1175bSopenharmony_ci 13a8e1175bSopenharmony_ci/* 14a8e1175bSopenharmony_ci * for arc4random_buf() from <stdlib.h> 15a8e1175bSopenharmony_ci */ 16a8e1175bSopenharmony_ci#if defined(__NetBSD__) 17a8e1175bSopenharmony_ci#define _NETBSD_SOURCE 1 18a8e1175bSopenharmony_ci#elif defined(__OpenBSD__) 19a8e1175bSopenharmony_ci#define _BSD_SOURCE 1 20a8e1175bSopenharmony_ci#endif 21a8e1175bSopenharmony_ci 22a8e1175bSopenharmony_ci#include <test/macros.h> 23a8e1175bSopenharmony_ci#include <test/random.h> 24a8e1175bSopenharmony_ci#include <string.h> 25a8e1175bSopenharmony_ci 26a8e1175bSopenharmony_ci#include <mbedtls/entropy.h> 27a8e1175bSopenharmony_ci#include <alignment.h> 28a8e1175bSopenharmony_ci 29a8e1175bSopenharmony_ciint mbedtls_test_rnd_std_rand(void *rng_state, 30a8e1175bSopenharmony_ci unsigned char *output, 31a8e1175bSopenharmony_ci size_t len) 32a8e1175bSopenharmony_ci{ 33a8e1175bSopenharmony_ci#if !defined(__OpenBSD__) && !defined(__NetBSD__) 34a8e1175bSopenharmony_ci size_t i; 35a8e1175bSopenharmony_ci 36a8e1175bSopenharmony_ci if (rng_state != NULL) { 37a8e1175bSopenharmony_ci rng_state = NULL; 38a8e1175bSopenharmony_ci } 39a8e1175bSopenharmony_ci 40a8e1175bSopenharmony_ci for (i = 0; i < len; ++i) { 41a8e1175bSopenharmony_ci output[i] = rand(); 42a8e1175bSopenharmony_ci } 43a8e1175bSopenharmony_ci#else 44a8e1175bSopenharmony_ci if (rng_state != NULL) { 45a8e1175bSopenharmony_ci rng_state = NULL; 46a8e1175bSopenharmony_ci } 47a8e1175bSopenharmony_ci 48a8e1175bSopenharmony_ci arc4random_buf(output, len); 49a8e1175bSopenharmony_ci#endif /* !OpenBSD && !NetBSD */ 50a8e1175bSopenharmony_ci 51a8e1175bSopenharmony_ci return 0; 52a8e1175bSopenharmony_ci} 53a8e1175bSopenharmony_ci 54a8e1175bSopenharmony_ciint mbedtls_test_rnd_zero_rand(void *rng_state, 55a8e1175bSopenharmony_ci unsigned char *output, 56a8e1175bSopenharmony_ci size_t len) 57a8e1175bSopenharmony_ci{ 58a8e1175bSopenharmony_ci if (rng_state != NULL) { 59a8e1175bSopenharmony_ci rng_state = NULL; 60a8e1175bSopenharmony_ci } 61a8e1175bSopenharmony_ci 62a8e1175bSopenharmony_ci memset(output, 0, len); 63a8e1175bSopenharmony_ci 64a8e1175bSopenharmony_ci return 0; 65a8e1175bSopenharmony_ci} 66a8e1175bSopenharmony_ci 67a8e1175bSopenharmony_ciint mbedtls_test_rnd_buffer_rand(void *rng_state, 68a8e1175bSopenharmony_ci unsigned char *output, 69a8e1175bSopenharmony_ci size_t len) 70a8e1175bSopenharmony_ci{ 71a8e1175bSopenharmony_ci mbedtls_test_rnd_buf_info *info = (mbedtls_test_rnd_buf_info *) rng_state; 72a8e1175bSopenharmony_ci size_t use_len; 73a8e1175bSopenharmony_ci 74a8e1175bSopenharmony_ci if (rng_state == NULL) { 75a8e1175bSopenharmony_ci return mbedtls_test_rnd_std_rand(NULL, output, len); 76a8e1175bSopenharmony_ci } 77a8e1175bSopenharmony_ci 78a8e1175bSopenharmony_ci use_len = len; 79a8e1175bSopenharmony_ci if (len > info->length) { 80a8e1175bSopenharmony_ci use_len = info->length; 81a8e1175bSopenharmony_ci } 82a8e1175bSopenharmony_ci 83a8e1175bSopenharmony_ci if (use_len) { 84a8e1175bSopenharmony_ci memcpy(output, info->buf, use_len); 85a8e1175bSopenharmony_ci info->buf += use_len; 86a8e1175bSopenharmony_ci info->length -= use_len; 87a8e1175bSopenharmony_ci } 88a8e1175bSopenharmony_ci 89a8e1175bSopenharmony_ci if (len - use_len > 0) { 90a8e1175bSopenharmony_ci if (info->fallback_f_rng != NULL) { 91a8e1175bSopenharmony_ci return info->fallback_f_rng(info->fallback_p_rng, 92a8e1175bSopenharmony_ci output + use_len, 93a8e1175bSopenharmony_ci len - use_len); 94a8e1175bSopenharmony_ci } else { 95a8e1175bSopenharmony_ci return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; 96a8e1175bSopenharmony_ci } 97a8e1175bSopenharmony_ci } 98a8e1175bSopenharmony_ci 99a8e1175bSopenharmony_ci return 0; 100a8e1175bSopenharmony_ci} 101a8e1175bSopenharmony_ci 102a8e1175bSopenharmony_ciint mbedtls_test_rnd_pseudo_rand(void *rng_state, 103a8e1175bSopenharmony_ci unsigned char *output, 104a8e1175bSopenharmony_ci size_t len) 105a8e1175bSopenharmony_ci{ 106a8e1175bSopenharmony_ci mbedtls_test_rnd_pseudo_info *info = 107a8e1175bSopenharmony_ci (mbedtls_test_rnd_pseudo_info *) rng_state; 108a8e1175bSopenharmony_ci uint32_t i, *k, sum, delta = 0x9E3779B9; 109a8e1175bSopenharmony_ci unsigned char result[4], *out = output; 110a8e1175bSopenharmony_ci 111a8e1175bSopenharmony_ci if (rng_state == NULL) { 112a8e1175bSopenharmony_ci return mbedtls_test_rnd_std_rand(NULL, output, len); 113a8e1175bSopenharmony_ci } 114a8e1175bSopenharmony_ci 115a8e1175bSopenharmony_ci k = info->key; 116a8e1175bSopenharmony_ci 117a8e1175bSopenharmony_ci while (len > 0) { 118a8e1175bSopenharmony_ci size_t use_len = (len > 4) ? 4 : len; 119a8e1175bSopenharmony_ci sum = 0; 120a8e1175bSopenharmony_ci 121a8e1175bSopenharmony_ci for (i = 0; i < 32; i++) { 122a8e1175bSopenharmony_ci info->v0 += (((info->v1 << 4) ^ (info->v1 >> 5)) 123a8e1175bSopenharmony_ci + info->v1) ^ (sum + k[sum & 3]); 124a8e1175bSopenharmony_ci sum += delta; 125a8e1175bSopenharmony_ci info->v1 += (((info->v0 << 4) ^ (info->v0 >> 5)) 126a8e1175bSopenharmony_ci + info->v0) ^ (sum + k[(sum>>11) & 3]); 127a8e1175bSopenharmony_ci } 128a8e1175bSopenharmony_ci 129a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT32_BE(info->v0, result, 0); 130a8e1175bSopenharmony_ci memcpy(out, result, use_len); 131a8e1175bSopenharmony_ci len -= use_len; 132a8e1175bSopenharmony_ci out += 4; 133a8e1175bSopenharmony_ci } 134a8e1175bSopenharmony_ci 135a8e1175bSopenharmony_ci return 0; 136a8e1175bSopenharmony_ci} 137