• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
mbedtls_test_rnd_std_rand(void * rng_state,unsigned char * output,size_t len)28 int mbedtls_test_rnd_std_rand(void *rng_state,
29                               unsigned char *output,
30                               size_t len)
31 {
32 #if !defined(__OpenBSD__) && !defined(__NetBSD__)
33     size_t i;
34 
35     if (rng_state != NULL) {
36         rng_state  = NULL;
37     }
38 
39     for (i = 0; i < len; ++i) {
40         output[i] = rand();
41     }
42 #else
43     if (rng_state != NULL) {
44         rng_state = NULL;
45     }
46 
47     arc4random_buf(output, len);
48 #endif /* !OpenBSD && !NetBSD */
49 
50     return 0;
51 }
52 
mbedtls_test_rnd_zero_rand(void * rng_state,unsigned char * output,size_t len)53 int mbedtls_test_rnd_zero_rand(void *rng_state,
54                                unsigned char *output,
55                                size_t len)
56 {
57     if (rng_state != NULL) {
58         rng_state  = NULL;
59     }
60 
61     memset(output, 0, len);
62 
63     return 0;
64 }
65 
mbedtls_test_rnd_buffer_rand(void * rng_state,unsigned char * output,size_t len)66 int mbedtls_test_rnd_buffer_rand(void *rng_state,
67                                  unsigned char *output,
68                                  size_t len)
69 {
70     mbedtls_test_rnd_buf_info *info = (mbedtls_test_rnd_buf_info *) rng_state;
71     size_t use_len;
72 
73     if (rng_state == NULL) {
74         return mbedtls_test_rnd_std_rand(NULL, output, len);
75     }
76 
77     use_len = len;
78     if (len > info->length) {
79         use_len = info->length;
80     }
81 
82     if (use_len) {
83         memcpy(output, info->buf, use_len);
84         info->buf += use_len;
85         info->length -= use_len;
86     }
87 
88     if (len - use_len > 0) {
89         if (info->fallback_f_rng != NULL) {
90             return info->fallback_f_rng(info->fallback_p_rng,
91                                         output + use_len,
92                                         len - use_len);
93         } else {
94             return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
95         }
96     }
97 
98     return 0;
99 }
100 
mbedtls_test_rnd_pseudo_rand(void * rng_state,unsigned char * output,size_t len)101 int mbedtls_test_rnd_pseudo_rand(void *rng_state,
102                                  unsigned char *output,
103                                  size_t len)
104 {
105     mbedtls_test_rnd_pseudo_info *info =
106         (mbedtls_test_rnd_pseudo_info *) rng_state;
107     uint32_t i, *k, sum, delta = 0x9E3779B9;
108     unsigned char result[4], *out = output;
109 
110     if (rng_state == NULL) {
111         return mbedtls_test_rnd_std_rand(NULL, output, len);
112     }
113 
114     k = info->key;
115 
116     while (len > 0) {
117         size_t use_len = (len > 4) ? 4 : len;
118         sum = 0;
119 
120         for (i = 0; i < 32; i++) {
121             info->v0 += (((info->v1 << 4) ^ (info->v1 >> 5))
122                          + info->v1) ^ (sum + k[sum & 3]);
123             sum += delta;
124             info->v1 += (((info->v0 << 4) ^ (info->v0 >> 5))
125                          + info->v0) ^ (sum + k[(sum>>11) & 3]);
126         }
127 
128         PUT_UINT32_BE(info->v0, result, 0);
129         memcpy(out, result, use_len);
130         len -= use_len;
131         out += 4;
132     }
133 
134     return 0;
135 }
136