static int uninstantiate(RAND_DRBG *drbg) { int ret = drbg == NULL ? 1 : RAND_DRBG_uninstantiate(drbg); ERR_clear_error(); return ret; }
/* Cleans up the given global DRBG */ static void drbg_cleanup(RAND_DRBG *drbg) { if (drbg != NULL) { RAND_DRBG_uninstantiate(drbg); CRYPTO_THREAD_lock_free(drbg->lock); OPENSSL_secure_clear_free(drbg, sizeof(RAND_DRBG)); } }
static void free_drbg(RAND_DRBG *drbg) { CRYPTO_THREAD_lock_free(drbg->lock); if (drbg->secure) OPENSSL_secure_clear_free(drbg->randomness, drbg->size); else OPENSSL_clear_free(drbg->randomness, drbg->size); RAND_DRBG_uninstantiate(drbg); }
/* * Disable CRNG testing if it is enabled. * If the DRBG is ready or in an error state, this means an instantiate cycle * for which the default personalisation string is used. */ static int disable_crngt(RAND_DRBG *drbg) { static const char pers[] = DRBG_DEFAULT_PERS_STRING; const int instantiate = drbg->state != DRBG_UNINITIALISED; if (drbg->get_entropy != rand_crngt_get_entropy) return 1; if ((instantiate && !RAND_DRBG_uninstantiate(drbg)) || !TEST_true(RAND_DRBG_set_callbacks(drbg, &rand_drbg_get_entropy, &rand_drbg_cleanup_entropy, &rand_drbg_get_nonce, &rand_drbg_cleanup_nonce)) || (instantiate && !RAND_DRBG_instantiate(drbg, (const unsigned char *)pers, sizeof(pers) - 1))) return 0; return 1; }
/* * Restart |drbg|, using the specified entropy or additional input * * Tries its best to get the drbg instantiated by all means, * regardless of its current state. * * Optionally, a |buffer| of |len| random bytes can be passed, * which is assumed to contain at least |entropy| bits of entropy. * * If |entropy| > 0, the buffer content is used as entropy input. * * If |entropy| == 0, the buffer content is used as additional input * * Returns 1 on success, 0 on failure. * * This function is used internally only. */ int rand_drbg_restart(RAND_DRBG *drbg, const unsigned char *buffer, size_t len, size_t entropy) { int reseeded = 0; const unsigned char *adin = NULL; size_t adinlen = 0; if (drbg->pool != NULL) { RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR); rand_pool_free(drbg->pool); drbg->pool = NULL; } if (buffer != NULL) { if (entropy > 0) { if (drbg->max_entropylen < len) { RANDerr(RAND_F_RAND_DRBG_RESTART, RAND_R_ENTROPY_INPUT_TOO_LONG); return 0; } if (entropy > 8 * len) { RANDerr(RAND_F_RAND_DRBG_RESTART, RAND_R_ENTROPY_OUT_OF_RANGE); return 0; } /* will be picked up by the rand_drbg_get_entropy() callback */ drbg->pool = rand_pool_new(entropy, len, len); if (drbg->pool == NULL) return 0; rand_pool_add(drbg->pool, buffer, len, entropy); } else { if (drbg->max_adinlen < len) { RANDerr(RAND_F_RAND_DRBG_RESTART, RAND_R_ADDITIONAL_INPUT_TOO_LONG); return 0; } adin = buffer; adinlen = len; } } /* repair error state */ if (drbg->state == DRBG_ERROR) RAND_DRBG_uninstantiate(drbg); /* repair uninitialized state */ if (drbg->state == DRBG_UNINITIALISED) { /* reinstantiate drbg */ RAND_DRBG_instantiate(drbg, (const unsigned char *) ossl_pers_string, sizeof(ossl_pers_string) - 1); /* already reseeded. prevent second reseeding below */ reseeded = (drbg->state == DRBG_READY); } /* refresh current state if entropy or additional input has been provided */ if (drbg->state == DRBG_READY) { if (adin != NULL) { /* * mix in additional input without reseeding * * Similar to RAND_DRBG_reseed(), but the provided additional * data |adin| is mixed into the current state without pulling * entropy from the trusted entropy source using get_entropy(). * This is not a reseeding in the strict sense of NIST SP 800-90A. */ 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, 0); } } /* check whether a given entropy pool was cleared properly during reseed */ if (drbg->pool != NULL) { drbg->state = DRBG_ERROR; RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR); rand_pool_free(drbg->pool); drbg->pool = NULL; return 0; } return drbg->state == DRBG_READY; }
static void free_drbg(RAND_DRBG *drbg) { CRYPTO_THREAD_lock_free(drbg->lock); RAND_DRBG_uninstantiate(drbg); }