• 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
11  *
12  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
13  *  not use this file except in compliance with the License.
14  *  You may obtain a copy of the License at
15  *
16  *  http://www.apache.org/licenses/LICENSE-2.0
17  *
18  *  Unless required by applicable law or agreed to in writing, software
19  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
20  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  *  See the License for the specific language governing permissions and
22  *  limitations under the License.
23  */
24 
25 /*
26  * for arc4random_buf() from <stdlib.h>
27  */
28 #if defined(__NetBSD__)
29 #define _NETBSD_SOURCE 1
30 #elif defined(__OpenBSD__)
31 #define _BSD_SOURCE 1
32 #endif
33 
34 #include <test/macros.h>
35 #include <test/random.h>
36 #include <string.h>
37 
38 #include <mbedtls/entropy.h>
39 #include "../../library/alignment.h"
40 
mbedtls_test_rnd_std_rand(void * rng_state,unsigned char * output,size_t len)41 int mbedtls_test_rnd_std_rand(void *rng_state,
42                               unsigned char *output,
43                               size_t len)
44 {
45 #if !defined(__OpenBSD__) && !defined(__NetBSD__)
46     size_t i;
47 
48     if (rng_state != NULL) {
49         rng_state  = NULL;
50     }
51 
52     for (i = 0; i < len; ++i) {
53         output[i] = rand();
54     }
55 #else
56     if (rng_state != NULL) {
57         rng_state = NULL;
58     }
59 
60     arc4random_buf(output, len);
61 #endif /* !OpenBSD && !NetBSD */
62 
63     return 0;
64 }
65 
mbedtls_test_rnd_zero_rand(void * rng_state,unsigned char * output,size_t len)66 int mbedtls_test_rnd_zero_rand(void *rng_state,
67                                unsigned char *output,
68                                size_t len)
69 {
70     if (rng_state != NULL) {
71         rng_state  = NULL;
72     }
73 
74     memset(output, 0, len);
75 
76     return 0;
77 }
78 
mbedtls_test_rnd_buffer_rand(void * rng_state,unsigned char * output,size_t len)79 int mbedtls_test_rnd_buffer_rand(void *rng_state,
80                                  unsigned char *output,
81                                  size_t len)
82 {
83     mbedtls_test_rnd_buf_info *info = (mbedtls_test_rnd_buf_info *) rng_state;
84     size_t use_len;
85 
86     if (rng_state == NULL) {
87         return mbedtls_test_rnd_std_rand(NULL, output, len);
88     }
89 
90     use_len = len;
91     if (len > info->length) {
92         use_len = info->length;
93     }
94 
95     if (use_len) {
96         memcpy(output, info->buf, use_len);
97         info->buf += use_len;
98         info->length -= use_len;
99     }
100 
101     if (len - use_len > 0) {
102         if (info->fallback_f_rng != NULL) {
103             return info->fallback_f_rng(info->fallback_p_rng,
104                                         output + use_len,
105                                         len - use_len);
106         } else {
107             return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
108         }
109     }
110 
111     return 0;
112 }
113 
mbedtls_test_rnd_pseudo_rand(void * rng_state,unsigned char * output,size_t len)114 int mbedtls_test_rnd_pseudo_rand(void *rng_state,
115                                  unsigned char *output,
116                                  size_t len)
117 {
118     mbedtls_test_rnd_pseudo_info *info =
119         (mbedtls_test_rnd_pseudo_info *) rng_state;
120     uint32_t i, *k, sum, delta = 0x9E3779B9;
121     unsigned char result[4], *out = output;
122 
123     if (rng_state == NULL) {
124         return mbedtls_test_rnd_std_rand(NULL, output, len);
125     }
126 
127     k = info->key;
128 
129     while (len > 0) {
130         size_t use_len = (len > 4) ? 4 : len;
131         sum = 0;
132 
133         for (i = 0; i < 32; i++) {
134             info->v0 += (((info->v1 << 4) ^ (info->v1 >> 5))
135                          + info->v1) ^ (sum + k[sum & 3]);
136             sum += delta;
137             info->v1 += (((info->v0 << 4) ^ (info->v0 >> 5))
138                          + info->v0) ^ (sum + k[(sum>>11) & 3]);
139         }
140 
141         MBEDTLS_PUT_UINT32_BE(info->v0, result, 0);
142         memcpy(out, result, use_len);
143         len -= use_len;
144         out += 4;
145     }
146 
147     return 0;
148 }
149