aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crypto/err/openssl.txt2
-rw-r--r--crypto/rand/drbg_ctr.c43
-rw-r--r--crypto/rand/drbg_lib.c30
-rw-r--r--crypto/rand/rand_err.c4
-rw-r--r--crypto/rand/rand_lcl.h62
-rw-r--r--include/openssl/randerr.h2
-rw-r--r--test/drbgtest.c2
7 files changed, 104 insertions, 41 deletions
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 4357cfb..9ec0009 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -893,6 +893,7 @@ RAND_F_RAND_DRBG_NEW:109:RAND_DRBG_new
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
@@ -2258,6 +2259,7 @@ RAND_R_INTERNAL_ERROR:113:internal error
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
diff --git a/crypto/rand/drbg_ctr.c b/crypto/rand/drbg_ctr.c
index bb3acc8..3130e49 100644
--- a/crypto/rand/drbg_ctr.c
+++ b/crypto/rand/drbg_ctr.c
@@ -201,7 +201,7 @@ static void ctr_update(RAND_DRBG *drbg,
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);
@@ -236,12 +236,12 @@ static void ctr_update(RAND_DRBG *drbg,
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;
@@ -253,9 +253,9 @@ int ctr_instantiate(RAND_DRBG *drbg,
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;
@@ -263,11 +263,11 @@ int ctr_reseed(RAND_DRBG *drbg,
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);
@@ -299,15 +299,22 @@ int ctr_generate(RAND_DRBG *drbg,
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) {
@@ -325,6 +332,8 @@ int ctr_init(RAND_DRBG *drbg)
break;
}
+ drbg->meth = &drbg_ctr_meth;
+
ctr->keylen = keylen;
drbg->strength = keylen * 8;
drbg->seedlen = keylen + 16;
diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c
index e33877e..795b098 100644
--- a/crypto/rand/drbg_lib.c
+++ b/crypto/rand/drbg_lib.c
@@ -124,7 +124,7 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int nid, unsigned int flags)
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;
}
@@ -172,7 +172,8 @@ void RAND_DRBG_free(RAND_DRBG *drbg)
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));
}
@@ -196,6 +197,14 @@ int RAND_DRBG_instantiate(RAND_DRBG *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
@@ -223,7 +232,7 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
}
}
- 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;
@@ -267,11 +276,18 @@ 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);
}
@@ -314,7 +330,7 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
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;
@@ -420,7 +436,7 @@ int rand_drbg_restart(RAND_DRBG *drbg,
* 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);
@@ -507,7 +523,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
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;
diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c
index dc6140c..ac70b4a 100644
--- a/crypto/rand/rand_err.c
+++ b/crypto/rand/rand_err.c
@@ -27,6 +27,8 @@ static const ERR_STRING_DATA RAND_str_functs[] = {
{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),
@@ -76,6 +78,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = {
{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"},
diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h
index 9044981..1a09118 100644
--- a/crypto/rand/rand_lcl.h
+++ b/crypto/rand/rand_lcl.h
@@ -54,6 +54,42 @@ typedef enum drbg_status_e {
} 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.
*/
@@ -96,7 +132,7 @@ struct rand_drbg_st {
/*
* 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
@@ -148,8 +184,13 @@ struct rand_drbg_st {
/* 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;
@@ -179,18 +220,7 @@ void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
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
diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h
index b07ea23..b136ce8 100644
--- a/include/openssl/randerr.h
+++ b/include/openssl/randerr.h
@@ -33,6 +33,7 @@ int ERR_load_RAND_strings(void);
# 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
@@ -65,6 +66,7 @@ int ERR_load_RAND_strings(void);
# 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
diff --git a/test/drbgtest.c b/test/drbgtest.c
index 68c1697..fcb4b28 100644
--- a/test/drbgtest.c
+++ b/test/drbgtest.c
@@ -438,7 +438,7 @@ static int error_check(DRBG_SELFTEST_DATA *td)
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;