random.c (3217B)
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 29 int 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 54 int 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 67 int 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 102 int 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 }