5e0b202680f2bc78f6f425c75ffc00d7a4ddebbd
[openssl.git] / test / drbg_cavs_test.c
1 /*
2  * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
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>
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
74     if ((td->flags & USE_DF) == 0)
75         flags |= RAND_DRBG_FLAG_CTR_NO_DF;
76     if ((td->flags & USE_HMAC) != 0)
77         flags |= RAND_DRBG_FLAG_HMAC;
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:
109     if (buff != NULL)
110         OPENSSL_free(buff);
111     if (drbg != NULL) {
112         RAND_DRBG_uninstantiate(drbg);
113         RAND_DRBG_free(drbg);
114     }
115     return failures == 0;
116 }
117
118 /*-
119  * Do a single PR_FALSE KAT:
120  *
121  * Instantiate
122  * Reseed
123  * Generate Random Bits (pr=false)
124  * Generate Random Bits (pr=false)
125  * Uninstantiate
126  *
127  * Return 0 on failure.
128  */
129 static int single_kat_pr_false(const struct drbg_kat *td)
130 {
131     struct drbg_kat_pr_false *data = (struct drbg_kat_pr_false *)td->t;
132     RAND_DRBG *drbg = NULL;
133     unsigned char *buff = NULL;
134     unsigned int flags = 0;
135     int failures = 0;
136     TEST_CTX t;
137
138     if ((td->flags & USE_DF) == 0)
139         flags |= RAND_DRBG_FLAG_CTR_NO_DF;
140     if ((td->flags & USE_HMAC) != 0)
141         flags |= RAND_DRBG_FLAG_HMAC;
142
143     if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL)))
144         return 0;
145
146     if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
147                                            kat_nonce, NULL))) {
148         failures++;
149         goto err;
150     }
151     memset(&t, 0, sizeof(t));
152     t.entropy = data->entropyin;
153     t.entropylen = td->entropyinlen;
154     t.nonce = data->nonce;
155     t.noncelen = td->noncelen;
156     RAND_DRBG_set_ex_data(drbg, app_data_index, &t);
157
158     buff = OPENSSL_malloc(td->retbyteslen);
159     if (buff == NULL)
160         goto err;
161
162     if (!TEST_true(RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen)))
163         failures++;
164
165     t.entropy = data->entropyinreseed;
166     t.entropylen = td->entropyinlen;
167
168     if (!TEST_true(RAND_DRBG_reseed(drbg, data->addinreseed, td->addinlen, 0))
169         || !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
170                                          data->addin1, td->addinlen))
171         || !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
172                                          data->addin2, td->addinlen))
173         || !TEST_true(RAND_DRBG_uninstantiate(drbg))
174         || !TEST_mem_eq(data->retbytes, td->retbyteslen, buff,
175                         td->retbyteslen))
176         failures++;
177
178 err:
179     if (buff != NULL)
180         OPENSSL_free(buff);
181     if (drbg != NULL) {
182         RAND_DRBG_uninstantiate(drbg);
183         RAND_DRBG_free(drbg);
184     }
185     return failures == 0;
186 }
187
188 /*-
189  * Do a single PR_TRUE KAT:
190  *
191  * Instantiate
192  * Generate Random Bits (pr=true)
193  * Generate Random Bits (pr=true)
194  * Uninstantiate
195  *
196  * Return 0 on failure.
197  */
198 static int single_kat_pr_true(const struct drbg_kat *td)
199 {
200     struct drbg_kat_pr_true *data = (struct drbg_kat_pr_true *)td->t;
201     RAND_DRBG *drbg = NULL;
202     unsigned char *buff = NULL;
203     unsigned int flags = 0;
204     int failures = 0;
205     TEST_CTX t;
206
207     if ((td->flags & USE_DF) == 0)
208         flags |= RAND_DRBG_FLAG_CTR_NO_DF;
209     if ((td->flags & USE_HMAC) != 0)
210         flags |= RAND_DRBG_FLAG_HMAC;
211
212     if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL)))
213         return 0;
214
215     if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
216                                            kat_nonce, NULL))) {
217         failures++;
218         goto err;
219     }
220     memset(&t, 0, sizeof(t));
221     t.nonce = data->nonce;
222     t.noncelen = td->noncelen;
223     t.entropy = data->entropyin;
224     t.entropylen = td->entropyinlen;
225     RAND_DRBG_set_ex_data(drbg, app_data_index, &t);
226
227     buff = OPENSSL_malloc(td->retbyteslen);
228     if (buff == NULL)
229         goto err;
230
231     if (!TEST_true(RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen)))
232         failures++;
233
234     t.entropy = data->entropyinpr1;
235     t.entropylen = td->entropyinlen;
236
237     if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 1,
238                                       data->addin1, td->addinlen)))
239         failures++;
240
241     t.entropy = data->entropyinpr2;
242     t.entropylen = td->entropyinlen;
243
244     if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 1,
245                                       data->addin2, td->addinlen))
246         || !TEST_true(RAND_DRBG_uninstantiate(drbg))
247         || !TEST_mem_eq(data->retbytes, td->retbyteslen, buff,
248                         td->retbyteslen))
249         failures++;
250
251 err:
252     if (buff != NULL)
253         OPENSSL_free(buff);
254     if (drbg != NULL) {
255         RAND_DRBG_uninstantiate(drbg);
256         RAND_DRBG_free(drbg);
257     }
258     return failures == 0;
259 }
260
261 static int test_cavs_kats(const struct drbg_kat *test[], int i)
262 {
263     const struct drbg_kat *td = test[i];
264     int rv = 0;
265
266     switch (td->type) {
267     case NO_RESEED:
268         if (!single_kat_no_reseed(td))
269             goto err;
270         break;
271     case PR_FALSE:
272         if (!single_kat_pr_false(td))
273             goto err;
274         break;
275     case PR_TRUE:
276         if (!single_kat_pr_true(td))
277             goto err;
278         break;
279     default:    /* cant happen */
280         goto err;
281     }
282     rv = 1;
283 err:
284     return rv;
285 }
286
287 static int test_cavs_ctr(int i)
288 {
289     return test_cavs_kats(drbg_ctr_test, i);
290 }
291
292 static int test_cavs_hmac(int i)
293 {
294     return test_cavs_kats(drbg_hmac_test, i);
295 }
296
297 static int test_cavs_hash(int i)
298 {
299     return test_cavs_kats(drbg_hash_test, i);
300 }
301
302 int setup_tests(void)
303 {
304     app_data_index = RAND_DRBG_get_ex_new_index(0L, NULL, NULL, NULL, NULL);
305
306     ADD_ALL_TESTS(test_cavs_ctr,  drbg_ctr_nelem);
307     ADD_ALL_TESTS(test_cavs_hmac, drbg_hmac_nelem);
308     ADD_ALL_TESTS(test_cavs_hash, drbg_hash_nelem);
309
310     return 1;
311 }