]>
Commit | Line | Data |
---|---|---|
e613b1ef | 1 | /* |
760e2d60 | 2 | * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved. |
e613b1ef | 3 | * |
909f1a2e | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
e613b1ef PS |
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> | |
18 | #include "../crypto/rand/rand_lcl.h" | |
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 | ||
8bf36651 | 74 | if ((td->flags & USE_DF) == 0) |
e613b1ef | 75 | flags |= RAND_DRBG_FLAG_CTR_NO_DF; |
8bf36651 SL |
76 | if ((td->flags & USE_HMAC) != 0) |
77 | flags |= RAND_DRBG_FLAG_HMAC; | |
e613b1ef PS |
78 | |
79 | if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL))) | |
80 | return 0; | |
81 | ||
82 | if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL, | |
83 | kat_nonce, NULL))) { | |
84 | failures++; | |
85 | goto err; | |
86 | } | |
87 | memset(&t, 0, sizeof(t)); | |
88 | t.entropy = data->entropyin; | |
89 | t.entropylen = td->entropyinlen; | |
90 | t.nonce = data->nonce; | |
91 | t.noncelen = td->noncelen; | |
92 | RAND_DRBG_set_ex_data(drbg, app_data_index, &t); | |
93 | ||
94 | buff = OPENSSL_malloc(td->retbyteslen); | |
95 | if (buff == NULL) | |
96 | goto err; | |
97 | ||
98 | if (!TEST_true(RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen)) | |
99 | || !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0, | |
100 | data->addin1, td->addinlen)) | |
101 | || !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0, | |
102 | data->addin2, td->addinlen)) | |
103 | || !TEST_true(RAND_DRBG_uninstantiate(drbg)) | |
104 | || !TEST_mem_eq(data->retbytes, td->retbyteslen, buff, | |
105 | td->retbyteslen)) | |
106 | failures++; | |
107 | ||
108 | err: | |
760e2d60 F |
109 | OPENSSL_free(buff); |
110 | RAND_DRBG_uninstantiate(drbg); | |
111 | RAND_DRBG_free(drbg); | |
e613b1ef PS |
112 | return failures == 0; |
113 | } | |
114 | ||
115 | /*- | |
116 | * Do a single PR_FALSE KAT: | |
117 | * | |
118 | * Instantiate | |
119 | * Reseed | |
120 | * Generate Random Bits (pr=false) | |
121 | * Generate Random Bits (pr=false) | |
122 | * Uninstantiate | |
123 | * | |
124 | * Return 0 on failure. | |
125 | */ | |
126 | static int single_kat_pr_false(const struct drbg_kat *td) | |
127 | { | |
128 | struct drbg_kat_pr_false *data = (struct drbg_kat_pr_false *)td->t; | |
129 | RAND_DRBG *drbg = NULL; | |
130 | unsigned char *buff = NULL; | |
131 | unsigned int flags = 0; | |
132 | int failures = 0; | |
133 | TEST_CTX t; | |
134 | ||
8bf36651 | 135 | if ((td->flags & USE_DF) == 0) |
e613b1ef | 136 | flags |= RAND_DRBG_FLAG_CTR_NO_DF; |
8bf36651 SL |
137 | if ((td->flags & USE_HMAC) != 0) |
138 | flags |= RAND_DRBG_FLAG_HMAC; | |
e613b1ef PS |
139 | |
140 | if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL))) | |
141 | return 0; | |
142 | ||
143 | if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL, | |
144 | kat_nonce, NULL))) { | |
145 | failures++; | |
146 | goto err; | |
147 | } | |
148 | memset(&t, 0, sizeof(t)); | |
149 | t.entropy = data->entropyin; | |
150 | t.entropylen = td->entropyinlen; | |
151 | t.nonce = data->nonce; | |
152 | t.noncelen = td->noncelen; | |
153 | RAND_DRBG_set_ex_data(drbg, app_data_index, &t); | |
154 | ||
155 | buff = OPENSSL_malloc(td->retbyteslen); | |
156 | if (buff == NULL) | |
157 | goto err; | |
158 | ||
159 | if (!TEST_true(RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen))) | |
160 | failures++; | |
161 | ||
162 | t.entropy = data->entropyinreseed; | |
163 | t.entropylen = td->entropyinlen; | |
164 | ||
165 | if (!TEST_true(RAND_DRBG_reseed(drbg, data->addinreseed, td->addinlen, 0)) | |
166 | || !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0, | |
167 | data->addin1, td->addinlen)) | |
168 | || !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0, | |
169 | data->addin2, td->addinlen)) | |
170 | || !TEST_true(RAND_DRBG_uninstantiate(drbg)) | |
171 | || !TEST_mem_eq(data->retbytes, td->retbyteslen, buff, | |
172 | td->retbyteslen)) | |
173 | failures++; | |
174 | ||
175 | err: | |
760e2d60 F |
176 | OPENSSL_free(buff); |
177 | RAND_DRBG_uninstantiate(drbg); | |
178 | RAND_DRBG_free(drbg); | |
e613b1ef PS |
179 | return failures == 0; |
180 | } | |
181 | ||
182 | /*- | |
183 | * Do a single PR_TRUE KAT: | |
184 | * | |
185 | * Instantiate | |
186 | * Generate Random Bits (pr=true) | |
187 | * Generate Random Bits (pr=true) | |
188 | * Uninstantiate | |
189 | * | |
190 | * Return 0 on failure. | |
191 | */ | |
192 | static int single_kat_pr_true(const struct drbg_kat *td) | |
193 | { | |
194 | struct drbg_kat_pr_true *data = (struct drbg_kat_pr_true *)td->t; | |
195 | RAND_DRBG *drbg = NULL; | |
196 | unsigned char *buff = NULL; | |
197 | unsigned int flags = 0; | |
198 | int failures = 0; | |
199 | TEST_CTX t; | |
200 | ||
8bf36651 | 201 | if ((td->flags & USE_DF) == 0) |
e613b1ef | 202 | flags |= RAND_DRBG_FLAG_CTR_NO_DF; |
8bf36651 SL |
203 | if ((td->flags & USE_HMAC) != 0) |
204 | flags |= RAND_DRBG_FLAG_HMAC; | |
e613b1ef PS |
205 | |
206 | if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL))) | |
207 | return 0; | |
208 | ||
209 | if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL, | |
210 | kat_nonce, NULL))) { | |
211 | failures++; | |
212 | goto err; | |
213 | } | |
214 | memset(&t, 0, sizeof(t)); | |
215 | t.nonce = data->nonce; | |
216 | t.noncelen = td->noncelen; | |
217 | t.entropy = data->entropyin; | |
218 | t.entropylen = td->entropyinlen; | |
219 | RAND_DRBG_set_ex_data(drbg, app_data_index, &t); | |
220 | ||
221 | buff = OPENSSL_malloc(td->retbyteslen); | |
222 | if (buff == NULL) | |
223 | goto err; | |
224 | ||
225 | if (!TEST_true(RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen))) | |
226 | failures++; | |
227 | ||
228 | t.entropy = data->entropyinpr1; | |
229 | t.entropylen = td->entropyinlen; | |
230 | ||
231 | if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 1, | |
232 | data->addin1, td->addinlen))) | |
233 | failures++; | |
234 | ||
235 | t.entropy = data->entropyinpr2; | |
236 | t.entropylen = td->entropyinlen; | |
237 | ||
238 | if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 1, | |
239 | data->addin2, td->addinlen)) | |
240 | || !TEST_true(RAND_DRBG_uninstantiate(drbg)) | |
241 | || !TEST_mem_eq(data->retbytes, td->retbyteslen, buff, | |
242 | td->retbyteslen)) | |
243 | failures++; | |
244 | ||
245 | err: | |
760e2d60 F |
246 | OPENSSL_free(buff); |
247 | RAND_DRBG_uninstantiate(drbg); | |
248 | RAND_DRBG_free(drbg); | |
e613b1ef PS |
249 | return failures == 0; |
250 | } | |
251 | ||
8bf36651 | 252 | static int test_cavs_kats(const struct drbg_kat *test[], int i) |
e613b1ef | 253 | { |
8bf36651 | 254 | const struct drbg_kat *td = test[i]; |
e613b1ef PS |
255 | int rv = 0; |
256 | ||
6c7d80ab P |
257 | #ifdef FIPS_MODE |
258 | /* FIPS mode doesn't support instantiating without a derivation function */ | |
259 | if ((td->flags & USE_DF) == 0) | |
1fb3c0af P |
260 | return TEST_skip("instantiating without derivation function " |
261 | "is not supported in FIPS mode"); | |
6c7d80ab | 262 | #endif |
e613b1ef PS |
263 | switch (td->type) { |
264 | case NO_RESEED: | |
265 | if (!single_kat_no_reseed(td)) | |
266 | goto err; | |
267 | break; | |
268 | case PR_FALSE: | |
269 | if (!single_kat_pr_false(td)) | |
270 | goto err; | |
271 | break; | |
272 | case PR_TRUE: | |
273 | if (!single_kat_pr_true(td)) | |
274 | goto err; | |
275 | break; | |
dd6b2706 | 276 | default: /* cant happen */ |
e613b1ef PS |
277 | goto err; |
278 | } | |
279 | rv = 1; | |
280 | err: | |
281 | return rv; | |
282 | } | |
283 | ||
8bf36651 SL |
284 | static int test_cavs_ctr(int i) |
285 | { | |
286 | return test_cavs_kats(drbg_ctr_test, i); | |
287 | } | |
288 | ||
289 | static int test_cavs_hmac(int i) | |
290 | { | |
291 | return test_cavs_kats(drbg_hmac_test, i); | |
292 | } | |
293 | ||
294 | static int test_cavs_hash(int i) | |
295 | { | |
296 | return test_cavs_kats(drbg_hash_test, i); | |
297 | } | |
298 | ||
e613b1ef PS |
299 | int setup_tests(void) |
300 | { | |
301 | app_data_index = RAND_DRBG_get_ex_new_index(0L, NULL, NULL, NULL, NULL); | |
302 | ||
8bf36651 SL |
303 | ADD_ALL_TESTS(test_cavs_ctr, drbg_ctr_nelem); |
304 | ADD_ALL_TESTS(test_cavs_hmac, drbg_hmac_nelem); | |
305 | ADD_ALL_TESTS(test_cavs_hash, drbg_hash_nelem); | |
306 | ||
e613b1ef PS |
307 | return 1; |
308 | } |