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