uint8_t ntru_rand_default_init(NtruRandContext *rand_ctx, struct NtruRandGen *rand_gen) { uint8_t result = 1; result &= nist_ctr_initialize() == 0; rand_ctx->state = malloc(sizeof(NIST_CTR_DRBG)); if (!rand_ctx->state) return 0; uint8_t entropy[32]; result &= ntru_get_entropy(entropy, 32); uint16_t pers_string_size = strlen(NTRU_PERS_STRING) * sizeof(NTRU_PERS_STRING[0]); result &= nist_ctr_drbg_instantiate(rand_ctx->state, entropy, 10, NULL, 0, NTRU_PERS_STRING, pers_string_size) == 0; return result; }
struct cprng_strong * cprng_strong_create(const char *name, int ipl, int flags) { const uint32_t cc = cprng_counter(); struct cprng_strong *const cprng = kmem_alloc(sizeof(*cprng), KM_SLEEP); /* * rndsink_request takes a spin lock at IPL_VM, so we can be no * higher than that. */ KASSERT(ipl != IPL_SCHED && ipl != IPL_HIGH); /* Initialize the easy fields. */ (void)strlcpy(cprng->cs_name, name, sizeof(cprng->cs_name)); cprng->cs_flags = flags; mutex_init(&cprng->cs_lock, MUTEX_DEFAULT, ipl); cv_init(&cprng->cs_cv, cprng->cs_name); selinit(&cprng->cs_selq); cprng->cs_rndsink = rndsink_create(NIST_BLOCK_KEYLEN_BYTES, &cprng_strong_rndsink_callback, cprng); /* Get some initial entropy. Record whether it is full entropy. */ uint8_t seed[NIST_BLOCK_KEYLEN_BYTES]; mutex_enter(&cprng->cs_lock); cprng->cs_ready = rndsink_request(cprng->cs_rndsink, seed, sizeof(seed)); if (nist_ctr_drbg_instantiate(&cprng->cs_drbg, seed, sizeof(seed), &cc, sizeof(cc), cprng->cs_name, sizeof(cprng->cs_name))) /* XXX Fix nist_ctr_drbg API so this can't happen. */ panic("cprng %s: NIST CTR_DRBG instantiation failed", cprng->cs_name); explicit_memset(seed, 0, sizeof(seed)); if (ISSET(flags, CPRNG_HARD)) cprng->cs_remaining = NIST_BLOCK_KEYLEN_BYTES; else cprng->cs_remaining = 0; if (!cprng->cs_ready && !ISSET(flags, CPRNG_INIT_ANY)) printf("cprng %s: creating with partial entropy\n", cprng->cs_name); mutex_exit(&cprng->cs_lock); return cprng; }