}
+static int drbg_ctr_uninstantiate(DRBG_CTX *dctx)
+ {
+ OPENSSL_cleanse(&dctx->d.ctr, sizeof(DRBG_CTR_CTX));
+ return 1;
+ }
+
int fips_drbg_ctr_init(DRBG_CTX *dctx)
{
DRBG_CTR_CTX *cctx = &dctx->d.ctr;
dctx->instantiate = drbg_ctr_instantiate;
dctx->reseed = drbg_ctr_reseed;
dctx->generate = drbg_ctr_generate;
+ dctx->uninstantiate = drbg_ctr_uninstantiate;
cctx->keylen = keylen;
return 1;
}
+static int drbg_hash_uninstantiate(DRBG_CTX *dctx)
+ {
+ EVP_MD_CTX_cleanup(&dctx->d.hash.mctx);
+ OPENSSL_cleanse(&dctx->d.hash, sizeof(DRBG_HASH_CTX));
+ return 1;
+ }
+
int fips_drbg_hash_init(DRBG_CTX *dctx)
{
const EVP_MD *md;
dctx->instantiate = drbg_hash_instantiate;
dctx->reseed = drbg_hash_reseed;
dctx->generate = drbg_hash_generate;
+ dctx->uninstantiate = drbg_hash_uninstantiate;
dctx->d.hash.md = md;
EVP_MD_CTX_init(&hctx->mctx);
/* Support framework for SP800-90 DRBGs */
-DRBG_CTX *FIPS_drbg_new(int type, unsigned int flags)
+static int fips_drbg_init(DRBG_CTX *dctx, int type, unsigned int flags)
{
int rv;
- DRBG_CTX *dctx;
- dctx = OPENSSL_malloc(sizeof(DRBG_CTX));
memset(dctx, 0, sizeof(DRBG_CTX));
dctx->status = DRBG_STATUS_UNINITIALISED;
dctx->flags = flags;
dctx->type = type;
+
rv = fips_drbg_hash_init(dctx);
+
if (rv == -2)
rv = fips_drbg_ctr_init(dctx);
- if (rv <= 0)
+
+ return rv;
+ }
+
+DRBG_CTX *FIPS_drbg_new(int type, unsigned int flags)
+ {
+ DRBG_CTX *dctx;
+ dctx = OPENSSL_malloc(sizeof(DRBG_CTX));
+ if (!dctx)
+ return NULL;
+ if (fips_drbg_init(dctx, type, flags) <= 0)
{
- /* Fatal: cannot initialiase DRBG */
- goto err;
+ OPENSSL_free(dctx);
+ return NULL;
}
-
return dctx;
+ }
- err:
- if (dctx)
- OPENSSL_free(dctx);
- return NULL;
+void FIPS_drbg_free(DRBG_CTX *dctx)
+ {
+ dctx->uninstantiate(dctx);
+ OPENSSL_cleanse(dctx, sizeof(DRBG_CTX));
+ OPENSSL_free(dctx);
}
int FIPS_drbg_instantiate(DRBG_CTX *dctx,
return 1;
}
+int FIPS_drbg_uninstantiate(DRBG_CTX *dctx)
+ {
+ int save_type, save_flags, rv;
+ save_type = dctx->type;
+ save_flags = dctx->flags;
+ rv = dctx->uninstantiate(dctx);
+ OPENSSL_cleanse(dctx, sizeof(DRBG_CTX));
+ /* If method has problems uninstantiating, return error */
+ if (rv <= 0)
+ return rv;
+ return fips_drbg_init(dctx, save_type, save_flags);
+ }
int FIPS_drbg_set_test_mode(DRBG_CTX *dctx,
size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char *out,
int prediction_resistance,
const unsigned char *adin, size_t adinlen);
+int FIPS_drbg_uninstantiate(DRBG_CTX *dctx);
+void FIPS_drbg_free(DRBG_CTX *dctx);
+
int FIPS_drbg_set_test_mode(DRBG_CTX *dctx,
size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char *out,
int entropy, size_t min_len, size_t max_len),