/* * Generate some output and apply a statistical RNG test to it. */ static void cprng_strong_rngtest(struct cprng_strong *cprng) { KASSERT(mutex_owned(&cprng->cs_lock)); /* XXX Switch to a pool cache instead? */ rngtest_t *const rt = kmem_intr_alloc(sizeof(*rt), KM_NOSLEEP); if (rt == NULL) /* XXX Warn? */ return; (void)strlcpy(rt->rt_name, cprng->cs_name, sizeof(rt->rt_name)); if (nist_ctr_drbg_generate(&cprng->cs_drbg, rt->rt_b, sizeof(rt->rt_b), NULL, 0)) panic("cprng %s: NIST CTR_DRBG failed after reseed", cprng->cs_name); if (rngtest(rt)) { printf("cprng %s: failed statistical RNG test\n", cprng->cs_name); /* XXX Not clear that this does any good... */ cprng->cs_ready = false; rndsink_schedule(cprng->cs_rndsink); } explicit_memset(rt, 0, sizeof(*rt)); /* paranoia */ kmem_intr_free(rt, sizeof(*rt)); }
/* * Generate some data from the underlying generator. */ static void cprng_strong_generate(struct cprng_strong *cprng, void *buffer, size_t bytes) { const uint32_t cc = cprng_counter(); KASSERT(bytes <= CPRNG_MAX_LEN); KASSERT(mutex_owned(&cprng->cs_lock)); /* * Generate some data from the NIST CTR_DRBG. Caller * guarantees reseed if we're not ready, and if we exhaust the * generator, we mark ourselves not ready. Consequently, this * call to the CTR_DRBG should not fail. */ if (__predict_false(nist_ctr_drbg_generate(&cprng->cs_drbg, buffer, bytes, &cc, sizeof(cc)))) panic("cprng %s: NIST CTR_DRBG failed", cprng->cs_name); /* * If we've been seeing a lot of use, ask for some fresh * entropy soon. */ if (__predict_false(nist_ctr_drbg_reseed_advised_p(&cprng->cs_drbg))) rndsink_schedule(cprng->cs_rndsink); /* * If we just exhausted the generator, inform the next user * that we need a reseed. */ if (__predict_false(nist_ctr_drbg_reseed_needed_p(&cprng->cs_drbg))) { cprng->cs_ready = false; rndsink_schedule(cprng->cs_rndsink); /* paranoia */ } }
uint8_t ntru_rand_default_generate(uint8_t rand_data[], uint16_t len, NtruRandContext *rand_ctx) { nist_ctr_drbg_generate(rand_ctx->state, rand_data, len, NULL, 0); return 1; }