]>
Commit | Line | Data |
---|---|---|
e613b1ef | 1 | /* |
37cad7e6 | 2 | * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved. |
e613b1ef PS |
3 | * |
4 | * Licensed under the OpenSSL license (the "License"). You may not use | |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8 | */ | |
9 | ||
10 | #include <string.h> | |
11 | #include "internal/nelem.h" | |
12 | #include <openssl/crypto.h> | |
13 | #include <openssl/err.h> | |
14 | #include <openssl/rand.h> | |
15 | #include <openssl/obj_mac.h> | |
16 | #include <openssl/evp.h> | |
17 | #include <openssl/aes.h> | |
b5acbf91 | 18 | #include "../crypto/rand/rand_local.h" |
e613b1ef PS |
19 | |
20 | #include "testutil.h" | |
21 | #include "drbg_cavs_data.h" | |
22 | ||
23 | static int app_data_index; | |
24 | ||
25 | typedef struct test_ctx_st { | |
26 | const unsigned char *entropy; | |
27 | size_t entropylen; | |
28 | int entropycnt; | |
29 | const unsigned char *nonce; | |
30 | size_t noncelen; | |
31 | int noncecnt; | |
32 | } TEST_CTX; | |
33 | ||
34 | static size_t kat_entropy(RAND_DRBG *drbg, unsigned char **pout, | |
35 | int entropy, size_t min_len, size_t max_len, | |
36 | int prediction_resistance) | |
37 | { | |
38 | TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index); | |
39 | ||
40 | t->entropycnt++; | |
41 | *pout = (unsigned char *)t->entropy; | |
42 | return t->entropylen; | |
43 | } | |
44 | ||
45 | static size_t kat_nonce(RAND_DRBG *drbg, unsigned char **pout, | |
46 | int entropy, size_t min_len, size_t max_len) | |
47 | { | |
48 | TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index); | |
49 | ||
50 | t->noncecnt++; | |
51 | *pout = (unsigned char *)t->nonce; | |
52 | return t->noncelen; | |
53 | } | |
54 | ||
55 | /* | |
56 | * Do a single NO_RESEED KAT: | |
57 | * | |
58 | * Instantiate | |
59 | * Generate Random Bits (pr=false) | |
60 | * Generate Random Bits (pr=false) | |
61 | * Uninstantiate | |
62 | * | |
63 | * Return 0 on failure. | |
64 | */ | |
65 | static int single_kat_no_reseed(const struct drbg_kat *td) | |
66 | { | |
67 | struct drbg_kat_no_reseed *data = (struct drbg_kat_no_reseed *)td->t; | |
68 | RAND_DRBG *drbg = NULL; | |
69 | unsigned char *buff = NULL; | |
70 | unsigned int flags = 0; | |
71 | int failures = 0; | |
72 | TEST_CTX t; | |
73 | ||
74 | if (td->df != USE_DF) | |
75 | flags |= RAND_DRBG_FLAG_CTR_NO_DF; | |
76 | ||
77 | if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL))) | |
78 | return 0; | |
79 | ||
80 | if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL, | |
81 | kat_nonce, NULL))) { | |
82 | failures++; | |
83 | goto err; | |
84 | } | |
85 | memset(&t, 0, sizeof(t)); | |
86 | t.entropy = data->entropyin; | |
87 | t.entropylen = td->entropyinlen; | |
88 | t.nonce = data->nonce; | |
89 | t.noncelen = td->noncelen; | |
90 | RAND_DRBG_set_ex_data(drbg, app_data_index, &t); | |
91 | ||
92 | buff = OPENSSL_malloc(td->retbyteslen); | |
93 | if (buff == NULL) | |
94 | goto err; | |
95 | ||
96 | if (!TEST_true(RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen)) | |
97 | || !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0, | |
98 | data->addin1, td->addinlen)) | |
99 | || !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0, | |
100 | data->addin2, td->addinlen)) | |
101 | || !TEST_true(RAND_DRBG_uninstantiate(drbg)) | |
102 | || !TEST_mem_eq(data->retbytes, td->retbyteslen, buff, | |
103 | td->retbyteslen)) | |
104 | failures++; | |
105 | ||
106 | err: | |
37cad7e6 F |
107 | OPENSSL_free(buff); |
108 | RAND_DRBG_uninstantiate(drbg); | |
109 | RAND_DRBG_free(drbg); | |
e613b1ef PS |
110 | return failures == 0; |
111 | } | |
112 | ||
113 | /*- | |
114 | * Do a single PR_FALSE KAT: | |
115 | * | |
116 | * Instantiate | |
117 | * Reseed | |
118 | * Generate Random Bits (pr=false) | |
119 | * Generate Random Bits (pr=false) | |
120 | * Uninstantiate | |
121 | * | |
122 | * Return 0 on failure. | |
123 | */ | |
124 | static int single_kat_pr_false(const struct drbg_kat *td) | |
125 | { | |
126 | struct drbg_kat_pr_false *data = (struct drbg_kat_pr_false *)td->t; | |
127 | RAND_DRBG *drbg = NULL; | |
128 | unsigned char *buff = NULL; | |
129 | unsigned int flags = 0; | |
130 | int failures = 0; | |
131 | TEST_CTX t; | |
132 | ||
133 | if (td->df != USE_DF) | |
134 | flags |= RAND_DRBG_FLAG_CTR_NO_DF; | |
135 | ||
136 | if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL))) | |
137 | return 0; | |
138 | ||
139 | if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL, | |
140 | kat_nonce, NULL))) { | |
141 | failures++; | |
142 | goto err; | |
143 | } | |
144 | memset(&t, 0, sizeof(t)); | |
145 | t.entropy = data->entropyin; | |
146 | t.entropylen = td->entropyinlen; | |
147 | t.nonce = data->nonce; | |
148 | t.noncelen = td->noncelen; | |
149 | RAND_DRBG_set_ex_data(drbg, app_data_index, &t); | |
150 | ||
151 | buff = OPENSSL_malloc(td->retbyteslen); | |
152 | if (buff == NULL) | |
153 | goto err; | |
154 | ||
155 | if (!TEST_true(RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen))) | |
156 | failures++; | |
157 | ||
158 | t.entropy = data->entropyinreseed; | |
159 | t.entropylen = td->entropyinlen; | |
160 | ||
161 | if (!TEST_true(RAND_DRBG_reseed(drbg, data->addinreseed, td->addinlen, 0)) | |
162 | || !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0, | |
163 | data->addin1, td->addinlen)) | |
164 | || !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0, | |
165 | data->addin2, td->addinlen)) | |
166 | || !TEST_true(RAND_DRBG_uninstantiate(drbg)) | |
167 | || !TEST_mem_eq(data->retbytes, td->retbyteslen, buff, | |
168 | td->retbyteslen)) | |
169 | failures++; | |
170 | ||
171 | err: | |
37cad7e6 F |
172 | OPENSSL_free(buff); |
173 | RAND_DRBG_uninstantiate(drbg); | |
174 | RAND_DRBG_free(drbg); | |
e613b1ef PS |
175 | return failures == 0; |
176 | } | |
177 | ||
178 | /*- | |
179 | * Do a single PR_TRUE KAT: | |
180 | * | |
181 | * Instantiate | |
182 | * Generate Random Bits (pr=true) | |
183 | * Generate Random Bits (pr=true) | |
184 | * Uninstantiate | |
185 | * | |
186 | * Return 0 on failure. | |
187 | */ | |
188 | static int single_kat_pr_true(const struct drbg_kat *td) | |
189 | { | |
190 | struct drbg_kat_pr_true *data = (struct drbg_kat_pr_true *)td->t; | |
191 | RAND_DRBG *drbg = NULL; | |
192 | unsigned char *buff = NULL; | |
193 | unsigned int flags = 0; | |
194 | int failures = 0; | |
195 | TEST_CTX t; | |
196 | ||
197 | if (td->df != USE_DF) | |
198 | flags |= RAND_DRBG_FLAG_CTR_NO_DF; | |
199 | ||
200 | if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL))) | |
201 | return 0; | |
202 | ||
203 | if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL, | |
204 | kat_nonce, NULL))) { | |
205 | failures++; | |
206 | goto err; | |
207 | } | |
208 | memset(&t, 0, sizeof(t)); | |
209 | t.nonce = data->nonce; | |
210 | t.noncelen = td->noncelen; | |
211 | t.entropy = data->entropyin; | |
212 | t.entropylen = td->entropyinlen; | |
213 | RAND_DRBG_set_ex_data(drbg, app_data_index, &t); | |
214 | ||
215 | buff = OPENSSL_malloc(td->retbyteslen); | |
216 | if (buff == NULL) | |
217 | goto err; | |
218 | ||
219 | if (!TEST_true(RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen))) | |
220 | failures++; | |
221 | ||
222 | t.entropy = data->entropyinpr1; | |
223 | t.entropylen = td->entropyinlen; | |
224 | ||
225 | if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 1, | |
226 | data->addin1, td->addinlen))) | |
227 | failures++; | |
228 | ||
229 | t.entropy = data->entropyinpr2; | |
230 | t.entropylen = td->entropyinlen; | |
231 | ||
232 | if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 1, | |
233 | data->addin2, td->addinlen)) | |
234 | || !TEST_true(RAND_DRBG_uninstantiate(drbg)) | |
235 | || !TEST_mem_eq(data->retbytes, td->retbyteslen, buff, | |
236 | td->retbyteslen)) | |
237 | failures++; | |
238 | ||
239 | err: | |
37cad7e6 F |
240 | OPENSSL_free(buff); |
241 | RAND_DRBG_uninstantiate(drbg); | |
242 | RAND_DRBG_free(drbg); | |
e613b1ef PS |
243 | return failures == 0; |
244 | } | |
245 | ||
246 | static int test_cavs_kats(int i) | |
247 | { | |
248 | const struct drbg_kat *td = drbg_test[i]; | |
249 | int rv = 0; | |
250 | ||
251 | switch (td->type) { | |
252 | case NO_RESEED: | |
253 | if (!single_kat_no_reseed(td)) | |
254 | goto err; | |
255 | break; | |
256 | case PR_FALSE: | |
257 | if (!single_kat_pr_false(td)) | |
258 | goto err; | |
259 | break; | |
260 | case PR_TRUE: | |
261 | if (!single_kat_pr_true(td)) | |
262 | goto err; | |
263 | break; | |
264 | default: /* cant happen */ | |
265 | goto err; | |
266 | } | |
267 | rv = 1; | |
268 | err: | |
269 | return rv; | |
270 | } | |
271 | ||
272 | int setup_tests(void) | |
273 | { | |
274 | app_data_index = RAND_DRBG_get_ex_new_index(0L, NULL, NULL, NULL, NULL); | |
275 | ||
276 | ADD_ALL_TESTS(test_cavs_kats, drbg_test_nelem); | |
277 | return 1; | |
278 | } |