Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6d4947b authored by Theodore Ts'o's avatar Theodore Ts'o
Browse files

random: use the arch-specific rng in xfer_secondary_pool



If the CPU supports a hardware random number generator, use it in
xfer_secondary_pool(), where it will significantly improve things and
where we can afford it.

Also, remove the use of the arch-specific rng in
add_timer_randomness(), since the call is significantly slower than
get_cycles(), and we're much better off using it in
xfer_secondary_pool() anyway.

Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
Cc: stable@vger.kernel.org
parent 7bf23575
Loading
Loading
Loading
Loading
+16 −9
Original line number Diff line number Diff line
@@ -254,6 +254,7 @@
#include <linux/cryptohash.h>
#include <linux/fips.h>
#include <linux/ptrace.h>
#include <linux/kmemcheck.h>

#ifdef CONFIG_GENERIC_HARDIRQS
# include <linux/irq.h>
@@ -702,11 +703,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
		goto out;

	sample.jiffies = jiffies;

	/* Use arch random value, fall back to cycles */
	if (!arch_get_random_int(&sample.cycles))
	sample.cycles = get_cycles();

	sample.num = num;
	mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL);

@@ -838,7 +835,11 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
 */
static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
{
	union {
		__u32	tmp[OUTPUT_POOL_WORDS];
		long	hwrand[4];
	} u;
	int	i;

	if (r->pull && r->entropy_count < nbytes * 8 &&
	    r->entropy_count < r->poolinfo->POOLBITS) {
@@ -849,17 +850,23 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
		/* pull at least as many as BYTES as wakeup BITS */
		bytes = max_t(int, bytes, random_read_wakeup_thresh / 8);
		/* but never more than the buffer size */
		bytes = min_t(int, bytes, sizeof(tmp));
		bytes = min_t(int, bytes, sizeof(u.tmp));

		DEBUG_ENT("going to reseed %s with %d bits "
			  "(%d of %d requested)\n",
			  r->name, bytes * 8, nbytes * 8, r->entropy_count);

		bytes = extract_entropy(r->pull, tmp, bytes,
		bytes = extract_entropy(r->pull, u.tmp, bytes,
					random_read_wakeup_thresh / 8, rsvd);
		mix_pool_bytes(r, tmp, bytes, NULL);
		mix_pool_bytes(r, u.tmp, bytes, NULL);
		credit_entropy_bits(r, bytes*8);
	}
	kmemcheck_mark_initialized(&u.hwrand, sizeof(u.hwrand));
	for (i = 0; i < 4; i++)
		if (arch_get_random_long(&u.hwrand[i]))
			break;
	if (i)
		mix_pool_bytes(r, &u.hwrand, sizeof(u.hwrand), 0);
}

/*