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;
}
Exemple #2
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
do_device_source (int init)
{
  static pid_t pid; /* detect fork() */
  int ret, reseed = 0;
  static int (*do_source) (int init) = NULL;
/* using static var here is ok since we are
 * always called with mutexes down 
 */

  if (init == 1)
    {
      pid = getpid();

      do_source = do_device_source_urandom;
      ret = do_source (init);
      if (ret < 0)
        {
          do_source = do_device_source_egd;
          ret = do_source (init);
        }

      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }

      return ret;
    }
  else
    {
      if (getpid() != pid) 
        { /* fork() detected */
          device_last_read = 0;
          pid = getpid();
          reseed = 1;
        }
    
      ret = do_source (init);
      
      if (reseed)
        yarrow256_slow_reseed (&yctx);
      
      return ret;
    }
}
Exemple #4
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;
}
Exemple #5
0
int
yarrow256_update(struct yarrow256_ctx *ctx,
		 unsigned source_index, unsigned entropy,
		 size_t length, const uint8_t *data)
{
  enum yarrow_pool_id current;
  struct yarrow_source *source;
  
  assert(source_index < ctx->nsources);

  if (!length)
    /* Nothing happens */
    return 0;

  source = &ctx->sources[source_index];
  
  if (!ctx->seeded)
    /* While seeding, use the slow pool */
    current = YARROW_SLOW;
  else
    {
      current = source->next;
      source->next = !source->next;
    }

  sha256_update(&ctx->pools[current], length, data);
 
  /* NOTE: We should be careful to avoid overflows in the estimates. */
  if (source->estimate[current] < YARROW_MAX_ENTROPY)
    {
      if (entropy > YARROW_MAX_ENTROPY)
	entropy = YARROW_MAX_ENTROPY;

      if ( (length < (YARROW_MAX_ENTROPY / YARROW_MULTIPLIER))
	   && (entropy > YARROW_MULTIPLIER * length) )
	entropy = YARROW_MULTIPLIER * length;

      entropy += source->estimate[current];
      if (entropy > YARROW_MAX_ENTROPY)
	entropy = YARROW_MAX_ENTROPY;

      source->estimate[current] = entropy;
    }

  /* Check for seed/reseed */
  switch(current)
    {
    case YARROW_FAST:
#if YARROW_DEBUG
      fprintf(stderr,
              "yarrow256_update: source_index = %d,\n"
              "            fast pool estimate = %d\n",
              source_index, source->estimate[YARROW_FAST]);
#endif
      if (source->estimate[YARROW_FAST] >= YARROW_FAST_THRESHOLD)
	{
	  yarrow256_fast_reseed(ctx);
	  return 1;
	}
      else
	return 0;

    case YARROW_SLOW:
      {
        if (!yarrow256_needed_sources(ctx))
	  {
	    yarrow256_slow_reseed(ctx);
	    return 1;
	  }
	else
	  return 0;
      }
    default:
      abort();
    }
}