From: Michael Tremer <michael.tremer@ipfire.org>
To: development@lists.ipfire.org
Subject: Re: [PATCH] kernel: backport "random: try to actively add entropy"
Date: Mon, 04 May 2020 15:36:37 +0100 [thread overview]
Message-ID: <705F5F6C-9E64-4111-A7E0-0512D166819D@ipfire.org> (raw)
In-Reply-To: <f1751fd55839600d630faf912fd7585b@ipfire.org>
[-- Attachment #1: Type: text/plain, Size: 9540 bytes --]
Perfect.
Do you want me to submit a patch that removes the script?
Best,
-Michael
> On 1 May 2020, at 19:25, Arne Fitzenreiter <arne_f(a)ipfire.org> wrote:
>
> Yes. I have tested this patch and the crng is much faster initialized.
> With current next and this patch the APU2 is not running in the loop that
> wait for the 128 bit entropy.
>
>
> Am 2020-05-01 10:33, schrieb Arne Fitzenreiter:
>> this backports
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/char/random.c?id=50ee7529ec4500c88f8664560770a7a1b65db72b
>> to gather enough entropy for initialise the crng faster.
>> Of some machines like the APU it will need forever if
>> the machine only wait for entropy without doing anything else.
>> Signed-off-by: Arne Fitzenreiter <arne_f(a)ipfire.org>
>> ---
>> lfs/linux | 4 +
>> ...inux-4.14.x-add_timer_setup_on_stack.patch | 18 +++
>> ...x-random_try_to_actively_add_entropy.patch | 146 ++++++++++++++++++
>> 3 files changed, 168 insertions(+)
>> create mode 100644
>> src/patches/linux/linux-4.14.x-add_timer_setup_on_stack.patch
>> create mode 100644
>> src/patches/linux/linux-random_try_to_actively_add_entropy.patch
>> diff --git a/lfs/linux b/lfs/linux
>> index 3651e120c..847abcbae 100644
>> --- a/lfs/linux
>> +++ b/lfs/linux
>> @@ -143,6 +143,10 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
>> # Fix uevent PHYSDEVDRIVER
>> cd $(DIR_APP) && patch -Np1 <
>> $(DIR_SRC)/src/patches/linux/linux-2.6.32.27_mcs7830-fix-driver-name.patch
>> + # Active try to add entropy if the kernel wait for it
>> + cd $(DIR_APP) && patch -Np1 <
>> $(DIR_SRC)/src/patches/linux/linux-random_try_to_actively_add_entropy.patch
>> + cd $(DIR_APP) && patch -Np1 <
>> $(DIR_SRC)/src/patches/linux/linux-4.14.x-add_timer_setup_on_stack.patch
>> +
>> ifeq "$(KCFG)" "-kirkwood"
>> cd $(DIR_APP) && patch -Np1 <
>> $(DIR_SRC)/src/patches/linux/linux-4.14.40-kirkwood-dtb.patch
>> endif
>> diff --git
>> a/src/patches/linux/linux-4.14.x-add_timer_setup_on_stack.patch
>> b/src/patches/linux/linux-4.14.x-add_timer_setup_on_stack.patch
>> new file mode 100644
>> index 000000000..744dbe570
>> --- /dev/null
>> +++ b/src/patches/linux/linux-4.14.x-add_timer_setup_on_stack.patch
>> @@ -0,0 +1,18 @@
>> +diff -Naur linux-4.14.173.org/include/linux/timer.h
>> linux-4.14.173/include/linux/timer.h
>> +--- linux-4.14.173.org/include/linux/timer.h 2020-03-11
>> 18:03:09.000000000 +0100
>> ++++ linux-4.14.173/include/linux/timer.h 2020-04-30 19:30:13.956596003 +0200
>> +@@ -180,6 +180,14 @@
>> + (TIMER_DATA_TYPE)timer, flags);
>> + }
>> +
>> ++static inline void timer_setup_on_stack(struct timer_list *timer,
>> ++ void (*callback)(struct timer_list *),
>> ++ unsigned int flags)
>> ++{
>> ++ __setup_timer_on_stack(timer, (TIMER_FUNC_TYPE)callback,
>> ++ (TIMER_DATA_TYPE)timer, flags);
>> ++}
>> ++
>> + #define from_timer(var, callback_timer, timer_fieldname) \
>> + container_of(callback_timer, typeof(*var), timer_fieldname)
>> +
>> diff --git
>> a/src/patches/linux/linux-random_try_to_actively_add_entropy.patch
>> b/src/patches/linux/linux-random_try_to_actively_add_entropy.patch
>> new file mode 100644
>> index 000000000..15d4319db
>> --- /dev/null
>> +++ b/src/patches/linux/linux-random_try_to_actively_add_entropy.patch
>> @@ -0,0 +1,146 @@
>> +From 50ee7529ec4500c88f8664560770a7a1b65db72b Mon Sep 17 00:00:00 2001
>> +From: Linus Torvalds <torvalds(a)linux-foundation.org>
>> +Date: Sat, 28 Sep 2019 16:53:52 -0700
>> +Subject: random: try to actively add entropy rather than passively wait for it
>> +
>> +For 5.3 we had to revert a nice ext4 IO pattern improvement, because it
>> +caused a bootup regression due to lack of entropy at bootup together
>> +with arguably broken user space that was asking for secure random
>> +numbers when it really didn't need to.
>> +
>> +See commit 72dbcf721566 (Revert "ext4: make __ext4_get_inode_loc plug").
>> +
>> +This aims to solve the issue by actively generating entropy noise using
>> +the CPU cycle counter when waiting for the random number generator to
>> +initialize. This only works when you have a high-frequency time stamp
>> +counter available, but that's the case on all modern x86 CPU's, and on
>> +most other modern CPU's too.
>> +
>> +What we do is to generate jitter entropy from the CPU cycle counter
>> +under a somewhat complex load: calling the scheduler while also
>> +guaranteeing a certain amount of timing noise by also triggering a
>> +timer.
>> +
>> +I'm sure we can tweak this, and that people will want to look at other
>> +alternatives, but there's been a number of papers written on jitter
>> +entropy, and this should really be fairly conservative by crediting one
>> +bit of entropy for every timer-induced jump in the cycle counter. Not
>> +because the timer itself would be all that unpredictable, but because
>> +the interaction between the timer and the loop is going to be.
>> +
>> +Even if (and perhaps particularly if) the timer actually happens on
>> +another CPU, the cacheline interaction between the loop that reads the
>> +cycle counter and the timer itself firing is going to add perturbations
>> +to the cycle counter values that get mixed into the entropy pool.
>> +
>> +As Thomas pointed out, with a modern out-of-order CPU, even quite simple
>> +loops show a fair amount of hard-to-predict timing variability even in
>> +the absense of external interrupts. But this tries to take that further
>> +by actually having a fairly complex interaction.
>> +
>> +This is not going to solve the entropy issue for architectures that have
>> +no CPU cycle counter, but it's not clear how (and if) that is solvable,
>> +and the hardware in question is largely starting to be irrelevant. And
>> +by doing this we can at least avoid some of the even more contentious
>> +approaches (like making the entropy waiting time out in order to avoid
>> +the possibly unbounded waiting).
>> +
>> +Cc: Ahmed Darwish <darwish.07(a)gmail.com>
>> +Cc: Thomas Gleixner <tglx(a)linutronix.de>
>> +Cc: Theodore Ts'o <tytso(a)mit.edu>
>> +Cc: Nicholas Mc Guire <hofrat(a)opentech.at>
>> +Cc: Andy Lutomirski <luto(a)kernel.org>
>> +Cc: Kees Cook <keescook(a)chromium.org>
>> +Cc: Willy Tarreau <w(a)1wt.eu>
>> +Cc: Alexander E. Patrakov <patrakov(a)gmail.com>
>> +Cc: Lennart Poettering <mzxreary(a)0pointer.de>
>> +Signed-off-by: Linus Torvalds <torvalds(a)linux-foundation.org>
>> +---
>> + drivers/char/random.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>> + 1 file changed, 61 insertions(+), 1 deletion(-)
>> +
>> +(limited to 'drivers/char/random.c')
>> +
>> +diff --git a/drivers/char/random.c b/drivers/char/random.c
>> +index 5d5ea4ce1442..2fda6166c1dd 100644
>> +--- a/drivers/char/random.c
>> ++++ b/drivers/char/random.c
>> +@@ -1731,6 +1731,56 @@ void get_random_bytes(void *buf, int nbytes)
>> + }
>> + EXPORT_SYMBOL(get_random_bytes);
>> +
>> ++
>> ++/*
>> ++ * Each time the timer fires, we expect that we got an unpredictable
>> ++ * jump in the cycle counter. Even if the timer is running on another
>> ++ * CPU, the timer activity will be touching the stack of the CPU that is
>> ++ * generating entropy..
>> ++ *
>> ++ * Note that we don't re-arm the timer in the timer itself - we are
>> ++ * happy to be scheduled away, since that just makes the load more
>> ++ * complex, but we do not want the timer to keep ticking unless the
>> ++ * entropy loop is running.
>> ++ *
>> ++ * So the re-arming always happens in the entropy loop itself.
>> ++ */
>> ++static void entropy_timer(struct timer_list *t)
>> ++{
>> ++ credit_entropy_bits(&input_pool, 1);
>> ++}
>> ++
>> ++/*
>> ++ * If we have an actual cycle counter, see if we can
>> ++ * generate enough entropy with timing noise
>> ++ */
>> ++static void try_to_generate_entropy(void)
>> ++{
>> ++ struct {
>> ++ unsigned long now;
>> ++ struct timer_list timer;
>> ++ } stack;
>> ++
>> ++ stack.now = random_get_entropy();
>> ++
>> ++ /* Slow counter - or none. Don't even bother */
>> ++ if (stack.now == random_get_entropy())
>> ++ return;
>> ++
>> ++ timer_setup_on_stack(&stack.timer, entropy_timer, 0);
>> ++ while (!crng_ready()) {
>> ++ if (!timer_pending(&stack.timer))
>> ++ mod_timer(&stack.timer, jiffies+1);
>> ++ mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
>> ++ schedule();
>> ++ stack.now = random_get_entropy();
>> ++ }
>> ++
>> ++ del_timer_sync(&stack.timer);
>> ++ destroy_timer_on_stack(&stack.timer);
>> ++ mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
>> ++}
>> ++
>> + /*
>> + * Wait for the urandom pool to be seeded and thus guaranteed to supply
>> + * cryptographically secure random numbers. This applies to: the /dev/urandom
>> +@@ -1745,7 +1795,17 @@ int wait_for_random_bytes(void)
>> + {
>> + if (likely(crng_ready()))
>> + return 0;
>> +- return wait_event_interruptible(crng_init_wait, crng_ready());
>> ++
>> ++ do {
>> ++ int ret;
>> ++ ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
>> ++ if (ret)
>> ++ return ret > 0 ? 0 : ret;
>> ++
>> ++ try_to_generate_entropy();
>> ++ } while (!crng_ready());
>> ++
>> ++ return 0;
>> + }
>> + EXPORT_SYMBOL(wait_for_random_bytes);
>> +
>> +--
>> +cgit 1.2-0.3.lf.el7
>> +
prev parent reply other threads:[~2020-05-04 14:36 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-01 8:33 Arne Fitzenreiter
2020-05-01 13:18 ` Michael Tremer
2020-05-01 18:25 ` Arne Fitzenreiter
2020-05-04 14:36 ` Michael Tremer [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=705F5F6C-9E64-4111-A7E0-0512D166819D@ipfire.org \
--to=michael.tremer@ipfire.org \
--cc=development@lists.ipfire.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox