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