Index: libgcrypt-1.9.4/random/rndlinux.c =================================================================== --- libgcrypt-1.9.4.orig/random/rndlinux.c +++ libgcrypt-1.9.4/random/rndlinux.c @@ -141,7 +141,7 @@ _gcry_rndlinux_gather_random (void (*add volatile pid_t apid; int fd; int n; - byte buffer[768]; + byte buffer[256]; size_t n_hw; size_t want = length; size_t last_so_far = 0; @@ -196,26 +196,43 @@ _gcry_rndlinux_gather_random (void (*add my_pid = apid; } + if (fips_mode()) + { + if (level >= GCRY_VERY_STRONG_RANDOM) + { + size_t n; - /* First read from a hardware source. Note that _gcry_rndhw_poll_slow lets - it account only for up to 50% (or 25% for RDRAND) of the requested - bytes. */ - n_hw = _gcry_rndhw_poll_slow (add, origin, length); - if (length > 1) - length -= n_hw; - - /* When using a blocking random generator try to get some entropy - * from the jitter based RNG. In this case we take up to 50% of the - * remaining requested bytes. */ - if (level >= GCRY_VERY_STRONG_RANDOM) - { - n_hw = _gcry_rndjent_poll (add, origin, length/2); - if (n_hw > length/2) - n_hw = length/2; + n = _gcry_rndjent_poll (add, origin, length); + if (n == 0) + log_fatal ("unexpected error from rndjent: %s\n", + strerror (errno)); + if (n > length) + n = length; + if (length > 1) + length -= n; + } + } + else + { + /* First read from a hardware source. Note that _gcry_rndhw_poll_slow lets + it account only for up to 50% (or 25% for RDRAND) of the requested + bytes. */ + n_hw = _gcry_rndhw_poll_slow (add, origin, length); if (length > 1) length -= n_hw; - } + /* When using a blocking random generator try to get some entropy + * from the jitter based RNG. In this case we take up to 50% of the + * remaining requested bytes. */ + if (level >= GCRY_VERY_STRONG_RANDOM) + { + n_hw = _gcry_rndjent_poll (add, origin, length/2); + if (n_hw > length/2) + n_hw = length/2; + if (length > 1) + length -= n_hw; + } + } /* Open the requested device. The first time a device is to be opened we fail with a fatal error if the device does not exists. @@ -283,8 +301,6 @@ _gcry_rndlinux_gather_random (void (*add do { nbytes = length < sizeof(buffer)? length : sizeof(buffer); - if (nbytes > 256) - nbytes = 256; _gcry_pre_syscall (); ret = getentropy (buffer, nbytes); _gcry_post_syscall (); Index: libgcrypt-1.9.4/random/rndjent.c =================================================================== --- libgcrypt-1.9.4.orig/random/rndjent.c +++ libgcrypt-1.9.4/random/rndjent.c @@ -279,13 +279,24 @@ _gcry_rndjent_poll (void (*add)(const vo if (!jent_rng_is_initialized) { /* Auto-initialize. */ - jent_rng_is_initialized = 1; jent_entropy_collector_free (jent_rng_collector); jent_rng_collector = NULL; if ( !(_gcry_random_read_conf () & RANDOM_CONF_DISABLE_JENT)) { - if (!jent_entropy_init ()) - jent_rng_collector = jent_entropy_collector_alloc (1, 0); + if (!jent_entropy_init_ex (1, 0)) + { + jent_rng_collector = jent_entropy_collector_alloc (1, 0); + jent_rng_is_initialized = 1; + } + } + } + + if (!jent_rng_collector) + { + if (!jent_entropy_init_ex (1, 0)) + { + jent_rng_collector = jent_entropy_collector_alloc (1, 0); + jent_rng_is_initialized = 1; } }