Hi,
I compile a custom kernel locally from the Fedora src.rpm. I notice that the most recent 4.13 kernel I compiled, 4.13.0-0.rc4.git3.1, has different behavior for the kernel entropy pool than it used to have.
The way it used to work was that when the kernel entropy pool was kept full, or fuller, it would bleed entropy across to the pseudo-random generator in order to reseed it. This makes the output sequence of the PRNG indeterminate, and thus more random, and harder to attack. It is no longer a pseudo random number generator, except in intervals.
I notice now that there is no bleed happening. When the kernel entropy pool gets full, if there are no calls to /dev/random, it stays full.
I don't have a hardware RNG, but I harvest entropy from a sound device, and from an rtl2832 receiver (atmospheric). They still work, if I do cat /dev/random | rngtest -b 10 they get fired up and run full out.
But if I do cat /dev/urandom | rngtest -b 20000 the entropy pool just sits there, and they don't run.
The entropy pool can be looked at, as root, with cat /proc/sys/kernel/random/entropy_avail I reset the write_wakeup_threshold there to 3840 from its default 1792, and lower the urandom_min_reseed_secs to 5 (I think the default is 60).
Can you explain why this was changed, or point me to a discussion of the rationale for the change? It seems like it has implications for system security, and on the surface seems to decrease security of the PRNG.
Thanks.
On Sat, Aug 12, 2017 at 06:32:37AM -0700, stan wrote:
Hi,
I compile a custom kernel locally from the Fedora src.rpm. I notice that the most recent 4.13 kernel I compiled, 4.13.0-0.rc4.git3.1, has different behavior for the kernel entropy pool than it used to have.
The way it used to work was that when the kernel entropy pool was kept full, or fuller, it would bleed entropy across to the pseudo-random generator in order to reseed it. This makes the output sequence of the PRNG indeterminate, and thus more random, and harder to attack. It is no longer a pseudo random number generator, except in intervals.
I notice now that there is no bleed happening. When the kernel entropy pool gets full, if there are no calls to /dev/random, it stays full.
I don't have a hardware RNG, but I harvest entropy from a sound device, and from an rtl2832 receiver (atmospheric). They still work, if I do cat /dev/random | rngtest -b 10 they get fired up and run full out.
But if I do cat /dev/urandom | rngtest -b 20000 the entropy pool just sits there, and they don't run.
The entropy pool can be looked at, as root, with cat /proc/sys/kernel/random/entropy_avail I reset the write_wakeup_threshold there to 3840 from its default 1792, and lower the urandom_min_reseed_secs to 5 (I think the default is 60).
Can you explain why this was changed, or point me to a discussion of the rationale for the change? It seems like it has implications for system security, and on the surface seems to decrease security of the PRNG.
Thanks. _______________________________________________ kernel mailing list -- kernel@lists.fedoraproject.org To unsubscribe send an email to kernel-leave@lists.fedoraproject.org
you might be looking at commit e297a783e41560b44e3c14f38e420cba518113b8. Normally urandom doesn't block, but you're description suggests it is now, and I think that commit introduced that. Neil
On Mon, 14 Aug 2017 08:26:34 -0400 Neil Horman nhorman@redhat.com wrote:
On Sat, Aug 12, 2017 at 06:32:37AM -0700, stan wrote:
Hi,
I compile a custom kernel locally from the Fedora src.rpm. I notice that the most recent 4.13 kernel I compiled, 4.13.0-0.rc4.git3.1, has different behavior for the kernel entropy pool than it used to have.
The way it used to work was that when the kernel entropy pool was kept full, or fuller, it would bleed entropy across to the pseudo-random generator in order to reseed it. This makes the output sequence of the PRNG indeterminate, and thus more random, and harder to attack. It is no longer a pseudo random number generator, except in intervals.
I notice now that there is no bleed happening. When the kernel entropy pool gets full, if there are no calls to /dev/random, it stays full.
I don't have a hardware RNG, but I harvest entropy from a sound device, and from an rtl2832 receiver (atmospheric). They still work, if I do cat /dev/random | rngtest -b 10 they get fired up and run full out.
But if I do cat /dev/urandom | rngtest -b 20000 the entropy pool just sits there, and they don't run.
The entropy pool can be looked at, as root, with cat /proc/sys/kernel/random/entropy_avail I reset the write_wakeup_threshold there to 3840 from its default 1792, and lower the urandom_min_reseed_secs to 5 (I think the default is 60).
Can you explain why this was changed, or point me to a discussion of the rationale for the change? It seems like it has implications for system security, and on the surface seems to decrease security of the PRNG.
Thanks.
you might be looking at commit e297a783e41560b44e3c14f38e420cba518113b8. Normally urandom doesn't block, but you're description suggests it is now, and I think that commit introduced that. Neil
I'm not sure that's correct. That commit seems to be for something else.
https://github.com/torvalds/linux/commit/e297a783e41560b44e3c14f38e420cba518...
It's creating a function to ensure any call to get random bytes blocks until there is enough entropy to ensure valid random data is returned. But that isn't what I'm seeing. There is no call to the blocking function, and both /dev/random and /dev/urandom yield results immediately. This is about the behind the scenes transfer of entropy from the kernel entropy pool to urandom in order to reseed the generator when the kernel entropy pool is full or nearly so. It used to do that, it no longer does.
I don't see how that can even be a side effect of this change. That transfer of entropy is a core relationship of the /dev/urandom PRNG with the /dev/random entropy pool.
On Mon, 14 Aug 2017 09:55:00 -0700 stan stanl-fedorauser@vfemail.net wrote:
On Mon, 14 Aug 2017 08:26:34 -0400 Neil Horman nhorman@redhat.com wrote:
On Sat, Aug 12, 2017 at 06:32:37AM -0700, stan wrote:
Hi,
I compile a custom kernel locally from the Fedora src.rpm. I notice that the most recent 4.13 kernel I compiled, 4.13.0-0.rc4.git3.1, has different behavior for the kernel entropy pool than it used to have.
The way it used to work was that when the kernel entropy pool was kept full, or fuller, it would bleed entropy across to the pseudo-random generator in order to reseed it. This makes the output sequence of the PRNG indeterminate, and thus more random, and harder to attack. It is no longer a pseudo random number generator, except in intervals.
I notice now that there is no bleed happening. When the kernel entropy pool gets full, if there are no calls to /dev/random, it stays full.
I don't have a hardware RNG, but I harvest entropy from a sound device, and from an rtl2832 receiver (atmospheric). They still work, if I do cat /dev/random | rngtest -b 10 they get fired up and run full out.
But if I do cat /dev/urandom | rngtest -b 20000 the entropy pool just sits there, and they don't run.
The entropy pool can be looked at, as root, with cat /proc/sys/kernel/random/entropy_avail I reset the write_wakeup_threshold there to 3840 from its default 1792, and lower the urandom_min_reseed_secs to 5 (I think the default is 60).
Can you explain why this was changed, or point me to a discussion of the rationale for the change? It seems like it has implications for system security, and on the surface seems to decrease security of the PRNG.
Thanks.
you might be looking at commit e297a783e41560b44e3c14f38e420cba518113b8. Normally urandom doesn't block, but you're description suggests it is now, and I think that commit introduced that. Neil
I'm not sure that's correct. That commit seems to be for something else.
https://github.com/torvalds/linux/commit/e297a783e41560b44e3c14f38e420cba518...
It's creating a function to ensure any call to get random bytes blocks until there is enough entropy to ensure valid random data is returned. But that isn't what I'm seeing. There is no call to the blocking function, and both /dev/random and /dev/urandom yield results immediately. This is about the behind the scenes transfer of entropy from the kernel entropy pool to urandom in order to reseed the generator when the kernel entropy pool is full or nearly so. It used to do that, it no longer does.
I don't see how that can even be a side effect of this change. That transfer of entropy is a core relationship of the /dev/urandom PRNG with the /dev/random entropy pool.
This is part of the functionality I'm talking about, from random.c:
if (crng_init < 2 && entropy_bits >= 128) { crng_reseed(&primary_crng, r); entropy_bits = r->entropy_count >> ENTROPY_SHIFT;
It was the most recent hit from a search of the commit site for crng_reseed.
On Mon, 14 Aug 2017 10:24:48 -0700 stan stanl-fedorauser@vfemail.net wrote:
On Mon, 14 Aug 2017 09:55:00 -0700 stan stanl-fedorauser@vfemail.net wrote:
On Mon, 14 Aug 2017 08:26:34 -0400 Neil Horman nhorman@redhat.com wrote:
On Sat, Aug 12, 2017 at 06:32:37AM -0700, stan wrote:
Hi,
I compile a custom kernel locally from the Fedora src.rpm. I notice that the most recent 4.13 kernel I compiled, 4.13.0-0.rc4.git3.1, has different behavior for the kernel entropy pool than it used to have.
The way it used to work was that when the kernel entropy pool was kept full, or fuller, it would bleed entropy across to the pseudo-random generator in order to reseed it. This makes the output sequence of the PRNG indeterminate, and thus more random, and harder to attack. It is no longer a pseudo random number generator, except in intervals.
I notice now that there is no bleed happening. When the kernel entropy pool gets full, if there are no calls to /dev/random, it stays full.
I don't have a hardware RNG, but I harvest entropy from a sound device, and from an rtl2832 receiver (atmospheric). They still work, if I do cat /dev/random | rngtest -b 10 they get fired up and run full out.
But if I do cat /dev/urandom | rngtest -b 20000 the entropy pool just sits there, and they don't run.
The entropy pool can be looked at, as root, with cat /proc/sys/kernel/random/entropy_avail I reset the write_wakeup_threshold there to 3840 from its default 1792, and lower the urandom_min_reseed_secs to 5 (I think the default is 60).
Can you explain why this was changed, or point me to a discussion of the rationale for the change? It seems like it has implications for system security, and on the surface seems to decrease security of the PRNG.
Thanks.
you might be looking at commit e297a783e41560b44e3c14f38e420cba518113b8. Normally urandom doesn't block, but you're description suggests it is now, and I think that commit introduced that. Neil
I'm not sure that's correct. That commit seems to be for something else.
https://github.com/torvalds/linux/commit/e297a783e41560b44e3c14f38e420cba518...
It's creating a function to ensure any call to get random bytes blocks until there is enough entropy to ensure valid random data is returned. But that isn't what I'm seeing. There is no call to the blocking function, and both /dev/random and /dev/urandom yield results immediately. This is about the behind the scenes transfer of entropy from the kernel entropy pool to urandom in order to reseed the generator when the kernel entropy pool is full or nearly so. It used to do that, it no longer does.
I don't see how that can even be a side effect of this change. That transfer of entropy is a core relationship of the /dev/urandom PRNG with the /dev/random entropy pool.
This is part of the functionality I'm talking about, from random.c:
if (crng_init < 2 && entropy_bits >= 128) { crng_reseed(&primary_crng, r); entropy_bits = r->entropy_count >> ENTROPY_SHIFT;
It was the most recent hit from a search of the commit site for crng_reseed.
Well, the behavior is deliberate, but I haven't found the reason for the change yet.
2017-01-18
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
The variable random_min_urandom_seed is not needed any more as it defined the reseeding behavior of the nonblocking pool. Though it is not needed any more, it is left in the code for user space interface compatibility.
Mystery solved.
Because there were concerns about entropy availability on many systems, particularly servers, a new method of seeding the PRNG was implemented. It is called chacha20, a variation of salsa20. https://en.wikipedia.org/wiki/Salsa20 Here is some discussion of the change: https://lwn.net/Articles/686033/ https://www.phoronix.com/scan.php?page=news_item&px=Linux-4.8-dev-random From comment in random.c + * Get a random word for internal kernel use only. The quality of the random + * number is either as good as RDRAND or as good as /dev/urandom, with the + * goal of being quite fast and not depleting entropy.
So, this is a compromise, which protects those systems without access to plentiful entropy, at the expense of those systems which do have such access.
I think they should have left this as a configuration option for the kernel, so those who had systems with plenty of entropy could continue using it to strengthen the output of the prng in the kernel. I suppose they thought that maintaining dual code was too problematic. But I think there would be very little maintenance of either of these code branches, barring drastic revelations about their security.
Forgot to thank Neil, who provided the thread which allowed me to unravel the issue. Thanks Neil.
On Mon, Aug 14, 2017 at 09:55:00AM -0700, stan wrote:
On Mon, 14 Aug 2017 08:26:34 -0400 Neil Horman nhorman@redhat.com wrote:
On Sat, Aug 12, 2017 at 06:32:37AM -0700, stan wrote:
Hi,
I compile a custom kernel locally from the Fedora src.rpm. I notice that the most recent 4.13 kernel I compiled, 4.13.0-0.rc4.git3.1, has different behavior for the kernel entropy pool than it used to have.
The way it used to work was that when the kernel entropy pool was kept full, or fuller, it would bleed entropy across to the pseudo-random generator in order to reseed it. This makes the output sequence of the PRNG indeterminate, and thus more random, and harder to attack. It is no longer a pseudo random number generator, except in intervals.
I notice now that there is no bleed happening. When the kernel entropy pool gets full, if there are no calls to /dev/random, it stays full.
I don't have a hardware RNG, but I harvest entropy from a sound device, and from an rtl2832 receiver (atmospheric). They still work, if I do cat /dev/random | rngtest -b 10 they get fired up and run full out.
But if I do cat /dev/urandom | rngtest -b 20000 the entropy pool just sits there, and they don't run.
The entropy pool can be looked at, as root, with cat /proc/sys/kernel/random/entropy_avail I reset the write_wakeup_threshold there to 3840 from its default 1792, and lower the urandom_min_reseed_secs to 5 (I think the default is 60).
Can you explain why this was changed, or point me to a discussion of the rationale for the change? It seems like it has implications for system security, and on the surface seems to decrease security of the PRNG.
Thanks.
you might be looking at commit e297a783e41560b44e3c14f38e420cba518113b8. Normally urandom doesn't block, but you're description suggests it is now, and I think that commit introduced that. Neil
I'm not sure that's correct. That commit seems to be for something else.
https://github.com/torvalds/linux/commit/e297a783e41560b44e3c14f38e420cba518...
my bad, I thought when you said,
the entropy pool just sits there, and they don't run.
You meant your process was blocking (which would be bad for urandom), and thats the first thing that caught my eye.
That said, what do you mean when you say "don't run". Do you mean to say the fips test exits on duplicate data, or that it runs, its just that the urandom crng doesn't seem to get refilled from the kernel entropy pool)
If the latter is what you are concerned about I'd look at commit f5b98461cb8167ba362ad9f74c41d126b7becea7. I don't know what the last kernel you used was back when it worked the way you thought it should, but that commit converted the urandom generator such that it uses a pseudo entropy pool made up of a chacha20 cipher block to extract entropy from during reseeds instead of the kernel entropy pool it seems.
Neil
It's creating a function to ensure any call to get random bytes blocks until there is enough entropy to ensure valid random data is returned. But that isn't what I'm seeing. There is no call to the blocking function, and both /dev/random and /dev/urandom yield results immediately. This is about the behind the scenes transfer of entropy from the kernel entropy pool to urandom in order to reseed the generator when the kernel entropy pool is full or nearly so. It used to do that, it no longer does.
I don't see how that can even be a side effect of this change. That transfer of entropy is a core relationship of the /dev/urandom PRNG with the /dev/random entropy pool. _______________________________________________ kernel mailing list -- kernel@lists.fedoraproject.org To unsubscribe send an email to kernel-leave@lists.fedoraproject.org
On Tue, 15 Aug 2017 10:07:27 -0400 Neil Horman nhorman@redhat.com wrote:
my bad, I thought when you said,
the entropy pool just sits there, and they don't run.
You meant your process was blocking (which would be bad for urandom), and thats the first thing that caught my eye.
That said, what do you mean when you say "don't run". Do you mean to say the fips test exits on duplicate data, or that it runs, its just that the urandom crng doesn't seem to get refilled from the kernel entropy pool)
The latter.
If the latter is what you are concerned about I'd look at commit f5b98461cb8167ba362ad9f74c41d126b7becea7. I don't know what the last kernel you used was back when it worked the way you thought it should, but that commit converted the urandom generator such that it uses a pseudo entropy pool made up of a chacha20 cipher block to extract entropy from during reseeds instead of the kernel entropy pool it seems.
Yeah, I eventually got there. My quick perusal of the chacha20 cipher leads me to the conclusion that it isn't really generating entropy, rather that now another PRNG is feeding the kernel PRNG with pretend entropy; bit fiddling doesn't generate entropy that isn't already there. But I'm not an SME, just an interested amateur, so that could be a false conclusion.
Using conservative settings, the rtl2832_entropyd daemon can extract ~90 kbits of entropy / second from atmospheric noise, and never runs out, so I have no shortage of entropy. Thus my preference for the way things used to work. The new way seems to be better for those without such a copious supply, but worse for me.
I'm not sure what the kernel was when I really looked at this last, it was probably in the 3 series kernels, or early 4s, before the 4.8 series. But I've noticed the entropy feeds being triggered by the kernel, and thought I was seeing the old behavior. I had a problem with the most recent alsa-lib interfering with the audio-entropyd daemon because the card I was using wasn't recognized properly, and so looked more closely again. I was probably seeing what I expected to see based on my previous experience until I did look more closely.
When I was looking at hardware RNGs, I looked at those listed on this page, https://en.wikipedia.org/wiki/Comparison_of_hardware_random_number_generator... My conclusion was that the bitbabbler was a good rng and good value; it seems to me that any one running a server farm who valued security could get it for < $50 US; 650 kbits/second can reseed a lot of PRNGs every 60 seconds. The rtl2382 is cheap and commodity, < $10 US on ebay, for personal use if someone didn't want to buy the bit babbler.
I'd patch for the old PRNG behavior, but that is prone to future error that might be worse than accepting the new behavior if I miss future security flaws. Conclusion? Live with the new behavior; it helps that /dev/random is used for critical security numbers, and still accepts local entropy.
On Tue, Aug 15, 2017 at 08:59:24AM -0700, stan wrote:
On Tue, 15 Aug 2017 10:07:27 -0400 Neil Horman nhorman@redhat.com wrote:
my bad, I thought when you said,
the entropy pool just sits there, and they don't run.
You meant your process was blocking (which would be bad for urandom), and thats the first thing that caught my eye.
That said, what do you mean when you say "don't run". Do you mean to say the fips test exits on duplicate data, or that it runs, its just that the urandom crng doesn't seem to get refilled from the kernel entropy pool)
The latter.
If the latter is what you are concerned about I'd look at commit f5b98461cb8167ba362ad9f74c41d126b7becea7. I don't know what the last kernel you used was back when it worked the way you thought it should, but that commit converted the urandom generator such that it uses a pseudo entropy pool made up of a chacha20 cipher block to extract entropy from during reseeds instead of the kernel entropy pool it seems.
Yeah, I eventually got there. My quick perusal of the chacha20 cipher leads me to the conclusion that it isn't really generating entropy, rather that now another PRNG is feeding the kernel PRNG with pretend entropy; bit fiddling doesn't generate entropy that isn't already there. But I'm not an SME, just an interested amateur, so that could be a false conclusion.
You're correct in your assertion, /dev/urandom isn't currently generating true entropy, but given that its designed to be non-blocking, its considered sufficient to generate bit sequences that are non-deterministic and sufficiently unpredictable for most use cases. If you need true entropy, then you need to use /dev/random or some other hwrng. We do the same thing with the crypto cprng, its frequently used to generate keypairs for ipsec tunnels.
Using conservative settings, the rtl2832_entropyd daemon can extract ~90 kbits of entropy / second from atmospheric noise, and never runs out, so I have no shortage of entropy. Thus my preference for the way things used to work. The new way seems to be better for those without such a copious supply, but worse for me.
That would be exactly the case, as most use cases are not like yours. Most people just need a source of non-deterministic bits, and to do so quickly (virt guests and the like).
I'm not sure what the kernel was when I really looked at this last, it was probably in the 3 series kernels, or early 4s, before the 4.8 series. But I've noticed the entropy feeds being triggered by the kernel, and thought I was seeing the old behavior. I had a problem with the most recent alsa-lib interfering with the audio-entropyd daemon because the card I was using wasn't recognized properly, and so looked more closely again. I was probably seeing what I expected to see based on my previous experience until I did look more closely.
That fits, the change to chacha20 was done around 4.10
When I was looking at hardware RNGs, I looked at those listed on this page, https://en.wikipedia.org/wiki/Comparison_of_hardware_random_number_generator... My conclusion was that the bitbabbler was a good rng and good value; it seems to me that any one running a server farm who valued security could get it for < $50 US; 650 kbits/second can reseed a lot of PRNGs every 60 seconds. The rtl2382 is cheap and commodity, < $10 US on ebay, for personal use if someone didn't want to buy the bit babbler.
I'd patch for the old PRNG behavior, but that is prone to future error that might be worse than accepting the new behavior if I miss future security flaws. Conclusion? Live with the new behavior; it helps that /dev/random is used for critical security numbers, and still accepts local entropy.
On Tue, 15 Aug 2017 13:50:49 -0400 Neil Horman nhorman@redhat.com wrote:
On Tue, Aug 15, 2017 at 08:59:24AM -0700, stan wrote:
On Tue, 15 Aug 2017 10:07:27 -0400
[snip]
You're correct in your assertion, /dev/urandom isn't currently generating true entropy, but given that its designed to be non-blocking, its considered sufficient to generate bit sequences that are non-deterministic and sufficiently unpredictable for most use cases. If you need true entropy, then you need to use /dev/random or some other hwrng. We do the same thing with the crypto cprng, its frequently used to generate keypairs for ipsec tunnels.
[snip]
I'd patch for the old PRNG behavior, but that is prone to future error that might be worse than accepting the new behavior if I miss future security flaws. Conclusion? Live with the new behavior; it helps that /dev/random is used for critical security numbers, and still accepts local entropy.
I decided to patch to use some of the entropy I have. I first refreshed my understanding of the random number generation in the kernel, the below is a good overview. https://pthree.org/2014/07/21/the-linux-random-number-generator/
Then I created a patch that uses the old urandom_min_reseed_secs variable to determine how often the crng in the kernel should be reseeded from entropy. And a new function to reseed that often, as long as there is enough entropy in the input pool (>= 4000 bits, out of a maximum size of 4096).
I then compiled the latest 4.13 kernel with that patch applied, and it seems to be working just fine. It puts a message into the journal every time it reseeds, and I eventually went back to the stock kernel default of 5 minutes. The default in the patch is 1 minute, and I was reseeding previously every 5 seconds. That worked but seems like overkill.
/usr/bin/echo 300 > /proc/sys/kernel/random/urandom_min_reseed_secs
I've attached the patch for anyone who has an external source of entropy feeding the kernel entropy input pool, and wants to reseed the crng in the kernel periodically.
If you decide to do this, you'll have to put this in the kernel.spec file:
# use entropy from input pool based on level and time to reseed crng Patch1000: 1000-use-input-entropy-to-reseed-crng-based-on-timer-and-.patch
Here's a page that explains how to generate a patch for a Fedora src.rpm from the git repository.
https://www.hiroom2.com/2016/06/25/fedora-24-rebuild-kernel-with-src-rpm/
These are the official pages for how to build a custom kernel in Fedora.
https://fedoraproject.org/wiki/Building_a_custom_kernel
https://fedoraproject.org/wiki/Building_a_custom_kernel/Source_RPM
Seems the attachment was stripped, probably an anti spam measure. So, I'll just put the text here.
From 8be9a727727b2a264e55abe8faefb0e5d29b6fd6 Mon Sep 17 00:00:00 2001 From: Fedora Kernel Team kernel-team@fedoraproject.org Date: Sun, 20 Aug 2017 12:16:14 -0700 Subject: [PATCH] use input entropy to reseed crng based on timer and input entropy pool level
--- drivers/char/random.c | 62 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 10 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c index 8ad9270..07da211 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -315,6 +315,13 @@ static int random_read_wakeup_bits = 64; static int random_write_wakeup_bits = 28 * OUTPUT_POOL_WORDS;
/* + * The minimum number of seconds between urandom pool reseeding. We + * do this to limit the amount of entropy that can be drained from the + * input pool even if there are heavy demands on /dev/urandom. + */ +static int random_min_urandom_seed = 60; + +/* * Originally, we used a primitive polynomial of degree .poolwords * over GF(2). The taps for various sizes are defined below. They * were chosen to be evenly spaced except for the last tap, which is 1 @@ -399,6 +406,8 @@ static struct poolinfo { #endif };
+#define CRNG_RESEED_INTERVAL (random_min_urandom_seed*HZ) + /* * Static global variables */ @@ -472,6 +481,7 @@ static ssize_t _extract_entropy(struct entropy_store *r, void *buf, size_t nbytes, int fips);
static void crng_reseed(struct crng_state *crng, struct entropy_store *r); +static void crng_entropy_reseed(struct crng_state *crng, struct entropy_store *r); static void push_to_pool(struct work_struct *work); static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy; static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy; @@ -702,13 +712,23 @@ static void credit_entropy_bits(struct entropy_store *r, int nbits) r->entropy_total, _RET_IP_);
if (r == &input_pool) { - int entropy_bits = entropy_count >> ENTROPY_SHIFT; - - if (crng_init < 2 && entropy_bits >= 128) { - crng_reseed(&primary_crng, r); - entropy_bits = r->entropy_count >> ENTROPY_SHIFT; + int entropy_bits; + if (crng_init < 2) + { entropy_bits = entropy_count >> ENTROPY_SHIFT; + if (entropy_bits >= 128) + { crng_reseed(&primary_crng, r); + entropy_bits = r->entropy_count >> ENTROPY_SHIFT; + } + } + else if (crng_init == 2) + { if (r->entropy_count >= 4000) + { struct crng_state *crng = &primary_crng; + if (time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)) + { crng_entropy_reseed(crng, r); + entropy_bits = r->entropy_count - 256; + } + } } - /* should we wake readers? */ if (entropy_bits >= random_read_wakeup_bits) { wake_up_interruptible(&random_read_wait); @@ -721,7 +741,6 @@ static void credit_entropy_bits(struct entropy_store *r, int nbits) r->initialized && r->entropy_total >= 2*random_read_wakeup_bits) { struct entropy_store *other = &blocking_pool; - if (other->entropy_count <= 3 * other->poolinfo->poolfracbits / 4) { schedule_work(&other->push_work); @@ -751,8 +770,6 @@ static int credit_entropy_bits_safe(struct entropy_store *r, int nbits) * *********************************************************************/
-#define CRNG_RESEED_INTERVAL (300*HZ) - static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
#ifdef CONFIG_NUMA @@ -851,6 +868,32 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) } }
+static void crng_entropy_reseed(struct crng_state *crng, struct entropy_store *r) +{ + unsigned long flags; + int i, num; + union { + __u8 block[CHACHA20_BLOCK_SIZE]; + __u32 key[8]; + } buf; + + if (r) { + num = extract_entropy(r, &buf, 32, 16, 0); + if (num == 0) + return; + } + spin_lock_irqsave(&primary_crng.lock, flags); + for (i = 0; i < 8; i++) { + crng->state[i+4] ^= buf.key[i]; + } + memzero_explicit(&buf, sizeof(buf)); + crng->init_time = jiffies; + spin_unlock_irqrestore(&primary_crng.lock, flags); + if (crng == &primary_crng && crng_init == 2) { + pr_notice("random: crng entropy reseed done\n"); + } +} + static void _extract_crng(struct crng_state *crng, __u8 out[CHACHA20_BLOCK_SIZE]) { @@ -1942,7 +1985,6 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, static int min_read_thresh = 8, min_write_thresh; static int max_read_thresh = OUTPUT_POOL_WORDS * 32; static int max_write_thresh = INPUT_POOL_WORDS * 32; -static int random_min_urandom_seed = 60; static char sysctl_bootid[16];
/*
kernel@lists.fedoraproject.org