static int wrap_nettle_rnd (void *_ctx, int level, void *data, size_t datasize) { int ret; RND_LOCK; ret = do_trivia_source (0); if (ret < 0) { RND_UNLOCK; gnutls_assert (); return ret; } ret = do_device_source (0); if (ret < 0) { RND_UNLOCK; gnutls_assert (); return ret; } yarrow256_random (&yctx, datasize, data); RND_UNLOCK; return 0; }
static int wrap_nettle_rnd_init (void **ctx) { int ret; ret = gnutls_mutex_init (&rnd_mutex); if (ret < 0) { gnutls_assert (); return ret; } yarrow256_init (&yctx, SOURCES, ysources); ret = do_device_source (1); if (ret < 0) { gnutls_assert (); return ret; } ret = do_trivia_source (1); if (ret < 0) { gnutls_assert (); return ret; } yarrow256_slow_reseed (&yctx); return 0; }
static int wrap_nettle_rnd_init(void **ctx) { int ret; struct event_st event; uint8_t nonce_key[NONCE_KEY_SIZE]; memset(&rnd_ctx, 0, sizeof(rnd_ctx)); ret = gnutls_mutex_init(&nonce_ctx.mutex); if (ret < 0) { gnutls_assert(); return ret; } ret = gnutls_mutex_init(&rnd_ctx.mutex); if (ret < 0) { gnutls_assert(); return ret; } /* initialize the main RNG */ yarrow256_init(&rnd_ctx.yctx, SOURCES, rnd_ctx.ysources); _rnd_get_event(&event); rnd_ctx.forkid = _gnutls_get_forkid(); ret = do_device_source(&rnd_ctx, 1, &event); if (ret < 0) { gnutls_assert(); return ret; } ret = do_trivia_source(&rnd_ctx, 1, &event); if (ret < 0) { gnutls_assert(); return ret; } yarrow256_slow_reseed(&rnd_ctx.yctx); /* initialize the nonce RNG */ ret = _rnd_get_system_entropy(nonce_key, sizeof(nonce_key)); if (ret < 0) return gnutls_assert_val(ret); ret = nonce_rng_init(&nonce_ctx, nonce_key, sizeof(nonce_key), 1); if (ret < 0) return gnutls_assert_val(ret); return 0; }
static int wrap_nettle_rnd(void *_ctx, int level, void *data, size_t datasize) { int ret, reseed = 0; struct event_st event; if (level == GNUTLS_RND_NONCE) return wrap_nettle_rnd_nonce(_ctx, data, datasize); _rnd_get_event(&event); RND_LOCK(&rnd_ctx); if (_gnutls_detect_fork(rnd_ctx.forkid)) { /* fork() detected */ memset(&rnd_ctx.device_last_read, 0, sizeof(rnd_ctx.device_last_read)); reseed = 1; } /* reseed main */ ret = do_trivia_source(&rnd_ctx, 0, &event); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = do_device_source(&rnd_ctx, 0, &event); if (ret < 0) { gnutls_assert(); goto cleanup; } if (reseed != 0) { yarrow256_slow_reseed(&rnd_ctx.yctx); rnd_ctx.forkid = _gnutls_get_forkid(); } yarrow256_random(&rnd_ctx.yctx, datasize, data); ret = 0; cleanup: RND_UNLOCK(&rnd_ctx); return ret; }