1/* 2 * Copyright 2017-2019 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_local.h" 19 20#include "testutil.h" 21#include "drbg_cavs_data.h" 22 23static int app_data_index; 24 25typedef 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 34static 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 45static 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 */ 65static 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 106err: 107 OPENSSL_free(buff); 108 RAND_DRBG_uninstantiate(drbg); 109 RAND_DRBG_free(drbg); 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 */ 124static 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 171err: 172 OPENSSL_free(buff); 173 RAND_DRBG_uninstantiate(drbg); 174 RAND_DRBG_free(drbg); 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 */ 188static 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 239err: 240 OPENSSL_free(buff); 241 RAND_DRBG_uninstantiate(drbg); 242 RAND_DRBG_free(drbg); 243 return failures == 0; 244} 245 246static 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; 268err: 269 return rv; 270} 271 272int 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} 279