RAND_F_RAND_DRBG_RESEED:110:RAND_DRBG_reseed
RAND_F_RAND_DRBG_RESTART:102:rand_drbg_restart
RAND_F_RAND_DRBG_SET:104:RAND_DRBG_set
+RAND_F_RAND_DRBG_UNINSTANTIATE:118:RAND_DRBG_uninstantiate
RAND_F_RAND_LOAD_FILE:111:RAND_load_file
RAND_F_RAND_POOL_ADD:103:RAND_POOL_add
RAND_F_RAND_POOL_ADD_BEGIN:113:RAND_POOL_add_begin
RAND_R_IN_ERROR_STATE:114:in error state
RAND_R_NOT_A_REGULAR_FILE:122:Not a regular file
RAND_R_NOT_INSTANTIATED:115:not instantiated
+RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED:128:no drbg implementation selected
RAND_R_PERSONALISATION_STRING_TOO_LONG:116:personalisation string too long
RAND_R_PRNG_NOT_SEEDED:100:PRNG not seeded
RAND_R_RANDOM_POOL_OVERFLOW:125:random pool overflow
const unsigned char *in2, size_t in2len,
const unsigned char *nonce, size_t noncelen)
{
- RAND_DRBG_CTR *ctr = &drbg->ctr;
+ RAND_DRBG_CTR *ctr = &drbg->data.ctr;
/* ks is already setup for correct key */
inc_128(ctr);
AES_set_encrypt_key(ctr->K, drbg->strength, &ctr->ks);
}
-int ctr_instantiate(RAND_DRBG *drbg,
- const unsigned char *entropy, size_t entropylen,
- const unsigned char *nonce, size_t noncelen,
- const unsigned char *pers, size_t perslen)
+static int drbg_ctr_instantiate(RAND_DRBG *drbg,
+ const unsigned char *entropy, size_t entropylen,
+ const unsigned char *nonce, size_t noncelen,
+ const unsigned char *pers, size_t perslen)
{
- RAND_DRBG_CTR *ctr = &drbg->ctr;
+ RAND_DRBG_CTR *ctr = &drbg->data.ctr;
if (entropy == NULL)
return 0;
return 1;
}
-int ctr_reseed(RAND_DRBG *drbg,
- const unsigned char *entropy, size_t entropylen,
- const unsigned char *adin, size_t adinlen)
+static int drbg_ctr_reseed(RAND_DRBG *drbg,
+ const unsigned char *entropy, size_t entropylen,
+ const unsigned char *adin, size_t adinlen)
{
if (entropy == NULL)
return 0;
return 1;
}
-int ctr_generate(RAND_DRBG *drbg,
- unsigned char *out, size_t outlen,
- const unsigned char *adin, size_t adinlen)
+static int drbg_ctr_generate(RAND_DRBG *drbg,
+ unsigned char *out, size_t outlen,
+ const unsigned char *adin, size_t adinlen)
{
- RAND_DRBG_CTR *ctr = &drbg->ctr;
+ RAND_DRBG_CTR *ctr = &drbg->data.ctr;
if (adin != NULL && adinlen != 0) {
ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0);
return 1;
}
-int ctr_uninstantiate(RAND_DRBG *drbg)
+static int drbg_ctr_uninstantiate(RAND_DRBG *drbg)
{
- OPENSSL_cleanse(&drbg->ctr, sizeof(drbg->ctr));
+ OPENSSL_cleanse(&drbg->data.ctr, sizeof(drbg->data.ctr));
return 1;
}
-int ctr_init(RAND_DRBG *drbg)
+static RAND_DRBG_METHOD drbg_ctr_meth = {
+ drbg_ctr_instantiate,
+ drbg_ctr_reseed,
+ drbg_ctr_generate,
+ drbg_ctr_uninstantiate
+};
+
+int drbg_ctr_init(RAND_DRBG *drbg)
{
- RAND_DRBG_CTR *ctr = &drbg->ctr;
+ RAND_DRBG_CTR *ctr = &drbg->data.ctr;
size_t keylen;
switch (drbg->nid) {
break;
}
+ drbg->meth = &drbg_ctr_meth;
+
ctr->keylen = keylen;
drbg->strength = keylen * 8;
drbg->seedlen = keylen + 16;
case NID_aes_128_ctr:
case NID_aes_192_ctr:
case NID_aes_256_ctr:
- ret = ctr_init(drbg);
+ ret = drbg_ctr_init(drbg);
break;
}
if (drbg == NULL)
return;
- ctr_uninstantiate(drbg);
+ if (drbg->meth != NULL)
+ drbg->meth->uninstantiate(drbg);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data);
OPENSSL_clear_free(drbg, sizeof(*drbg));
}
RAND_R_PERSONALISATION_STRING_TOO_LONG);
goto end;
}
+
+ if (drbg->meth == NULL)
+ {
+ RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
+ RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
+ goto end;
+ }
+
if (drbg->state != DRBG_UNINITIALISED) {
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
drbg->state == DRBG_ERROR ? RAND_R_IN_ERROR_STATE
}
}
- if (!ctr_instantiate(drbg, entropy, entropylen,
+ if (!drbg->meth->instantiate(drbg, entropy, entropylen,
nonce, noncelen, pers, perslen)) {
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_INSTANTIATING_DRBG);
goto end;
*/
int RAND_DRBG_uninstantiate(RAND_DRBG *drbg)
{
+ if (drbg->meth == NULL)
+ {
+ RANDerr(RAND_F_RAND_DRBG_UNINSTANTIATE,
+ RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
+ return 0;
+ }
+
/* Clear the entire drbg->ctr struct, then reset some important
* members of the drbg->ctr struct (e.g. keysize, df_ks) to their
* initial values.
*/
- ctr_uninstantiate(drbg);
+ drbg->meth->uninstantiate(drbg);
return RAND_DRBG_set(drbg, drbg->nid, drbg->flags);
}
goto end;
}
- if (!ctr_reseed(drbg, entropy, entropylen, adin, adinlen))
+ if (!drbg->meth->reseed(drbg, entropy, entropylen, adin, adinlen))
goto end;
drbg->state = DRBG_READY;
* entropy from the trusted entropy source using get_entropy().
* This is not a reseeding in the strict sense of NIST SP 800-90A.
*/
- ctr_reseed(drbg, adin, adinlen, NULL, 0);
+ drbg->meth->reseed(drbg, adin, adinlen, NULL, 0);
} else if (reseeded == 0) {
/* do a full reseeding if it has not been done yet above */
RAND_DRBG_reseed(drbg, NULL, 0);
adinlen = 0;
}
- if (!ctr_generate(drbg, out, outlen, adin, adinlen)) {
+ if (!drbg->meth->generate(drbg, out, outlen, adin, adinlen)) {
drbg->state = DRBG_ERROR;
RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_GENERATE_ERROR);
return 0;
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_RESEED, 0), "RAND_DRBG_reseed"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_RESTART, 0), "rand_drbg_restart"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_SET, 0), "RAND_DRBG_set"},
+ {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_UNINSTANTIATE, 0),
+ "RAND_DRBG_uninstantiate"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_LOAD_FILE, 0), "RAND_load_file"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD, 0), "RAND_POOL_add"},
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD_BEGIN, 0),
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NOT_A_REGULAR_FILE),
"Not a regular file"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NOT_INSTANTIATED), "not instantiated"},
+ {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED),
+ "no drbg implementation selected"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PERSONALISATION_STRING_TOO_LONG),
"personalisation string too long"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PRNG_NOT_SEEDED), "PRNG not seeded"},
} DRBG_STATUS;
+/* intantiate */
+typedef int (*RAND_DRBG_instantiate_fn)(RAND_DRBG *ctx,
+ const unsigned char *ent,
+ size_t entlen,
+ const unsigned char *nonce,
+ size_t noncelen,
+ const unsigned char *pers,
+ size_t perslen);
+/* reseed */
+typedef int (*RAND_DRBG_reseed_fn)(RAND_DRBG *ctx,
+ const unsigned char *ent,
+ size_t entlen,
+ const unsigned char *adin,
+ size_t adinlen);
+/* generat output */
+typedef int (*RAND_DRBG_generate_fn)(RAND_DRBG *ctx,
+ unsigned char *out,
+ size_t outlen,
+ const unsigned char *adin,
+ size_t adinlen);
+/* uninstantiate */
+typedef int (*RAND_DRBG_uninstantiate_fn)(RAND_DRBG *ctx);
+
+
+/*
+ * The DRBG methods
+ */
+
+typedef struct rand_drbg_method_st {
+ RAND_DRBG_instantiate_fn instantiate;
+ RAND_DRBG_reseed_fn reseed;
+ RAND_DRBG_generate_fn generate;
+ RAND_DRBG_uninstantiate_fn uninstantiate;
+} RAND_DRBG_METHOD;
+
+
/*
* The state of a DRBG AES-CTR.
*/
/*
* The following parameters are setup by the per-type "init" function.
*
- * Currently the only type is CTR_DRBG, its init function is ctr_init().
+ * Currently the only type is CTR_DRBG, its init function is drbg_ctr_init().
*
* The parameters are closely related to the ones described in
* section '10.2.1 CTR_DRBG' of [NIST SP 800-90Ar1], with one
/* Application data, mainly used in the KATs. */
CRYPTO_EX_DATA ex_data;
- /* Implementation specific structures; was a union, but inline for now */
- RAND_DRBG_CTR ctr;
+ /* Implementation specific data (currently only one implementation) */
+ union {
+ RAND_DRBG_CTR ctr;
+ } data;
+
+ /* Implementation specific methods */
+ RAND_DRBG_METHOD *meth;
/* Callback functions. See comments in rand_lib.c */
RAND_DRBG_get_entropy_fn get_entropy;
int rand_drbg_restart(RAND_DRBG *drbg,
const unsigned char *buffer, size_t len, size_t entropy);
-/* DRBG functions implementing AES-CTR */
-int ctr_init(RAND_DRBG *drbg);
-int ctr_uninstantiate(RAND_DRBG *drbg);
-int ctr_instantiate(RAND_DRBG *drbg,
- const unsigned char *entropy, size_t entropylen,
- const unsigned char *nonce, size_t noncelen,
- const unsigned char *pers, size_t perslen);
-int ctr_reseed(RAND_DRBG *drbg,
- const unsigned char *entropy, size_t entropylen,
- const unsigned char *adin, size_t adinlen);
-int ctr_generate(RAND_DRBG *drbg,
- unsigned char *out, size_t outlen,
- const unsigned char *adin, size_t adinlen);
+/* initializes the AES-CTR DRBG implementation */
+int drbg_ctr_init(RAND_DRBG *drbg);
#endif
# define RAND_F_RAND_DRBG_RESEED 110
# define RAND_F_RAND_DRBG_RESTART 102
# define RAND_F_RAND_DRBG_SET 104
+# define RAND_F_RAND_DRBG_UNINSTANTIATE 118
# define RAND_F_RAND_LOAD_FILE 111
# define RAND_F_RAND_POOL_ADD 103
# define RAND_F_RAND_POOL_ADD_BEGIN 113
# define RAND_R_IN_ERROR_STATE 114
# define RAND_R_NOT_A_REGULAR_FILE 122
# define RAND_R_NOT_INSTANTIATED 115
+# define RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED 128
# define RAND_R_PERSONALISATION_STRING_TOO_LONG 116
# define RAND_R_PRNG_NOT_SEEDED 100
# define RAND_R_RANDOM_POOL_OVERFLOW 125
goto err;
/* Standard says we have to check uninstantiate really zeroes */
- if (!TEST_mem_eq(zero, sizeof(drbg->ctr), &drbg->ctr, sizeof(drbg->ctr)))
+ if (!TEST_mem_eq(zero, sizeof(drbg->data), &drbg->data, sizeof(drbg->data)))
goto err;
ret = 1;