Received: by 2002:a6b:fb09:0:0:0:0:0 with SMTP id h9csp6031620iog; Thu, 23 Jun 2022 09:56:48 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sQIIRke9LMdSz3gDsKaY5q+Ho9T0Su82LI4ed+hMSEjR/msnCjsRO+Nod/DB59oY0tkf90 X-Received: by 2002:a05:6402:448c:b0:435:9dcc:b8a5 with SMTP id er12-20020a056402448c00b004359dccb8a5mr11940082edb.287.1656003408583; Thu, 23 Jun 2022 09:56:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656003408; cv=none; d=google.com; s=arc-20160816; b=0VvQf2UEThyTB5USpWcpnN0kws151+PxmdF8Yh6LokoPGtkNn1OeA5kfUngqzW3fVS YmkTTZMMM3NMWXzJvxJpKjNfl/E8qspC2viFgm8pu/L1L4qL5IjmN7WFx6K+22HDX5aF TvFRViIW5iZgHopSU7K853pqj/dx3w4waCDnh/OP85NekUX1JJ9LFigL8t7jPLOeEGCg WRhsVC1t8aN7kn1m0505ZaCxSvGZP6JEutjnFlkmNYqcKDLQ9pTd9ZBy2RLzgpuWST8g AOMhg/BOlTbDhRUQNBX3fqWS6biEgawIGC8AW+CM3YvZWljfL2PBLCuIqklDLgffXOcL C7ZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=+w8A3SUtnlnry9vpcg79E6C2yNrCIhi3jUBmvhAvySI=; b=VwGFReBU49wu8N88NSkjWcnjqG91UpZEETw9381CW30ndXsDv+qPOFD+FXBUJHgbcB hKV4mjF6JEAWAalLhegEb5mM0VtMhhaZBkEBTsg3vXn01rkhvWKek9vh4WJ90rF+r4d4 uZL3GLrvrglu2eJdL2rLjwcWg1a57MZp2Ph3HM8HhjQH2nLxlnRTyDmyzexLaPgS+nS5 GYuBjGI9XBK60PMiy78E4Pa0ebrLYJ6jMIuJWNlys8CpbBCqy+4y92KE+25dz3PDGjEG U+eCh3VtUc5T2uV8wCuWbQe5x87x6vbw9lKLkgWYNI7ORvoShiv80SETYsOz4SmMBleQ Pq/g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=iZGVzrDW; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id w16-20020a056402269000b004359b77f70csi149325edd.16.2022.06.23.09.56.18; Thu, 23 Jun 2022 09:56:48 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=iZGVzrDW; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233358AbiFWQyd (ORCPT + 99 others); Thu, 23 Jun 2022 12:54:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49138 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233828AbiFWQvm (ORCPT ); Thu, 23 Jun 2022 12:51:42 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8E608286; Thu, 23 Jun 2022 09:50:07 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 22B7C61FBF; Thu, 23 Jun 2022 16:50:07 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B975EC3411B; Thu, 23 Jun 2022 16:50:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1656003006; bh=veAEAwIenDtLv4KEbl6EfcTrELtYPqBLwzi1IGMjgUY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iZGVzrDW3hiMMgpWyICZPlcs1x8smykACDjFcTHm6NuCDAU1KMVAbKHqD8mgg3YBa de8JEKzmx0zeO9U4Ocy5OSiLP3oAE3QMq5+lUBwe6VjvkQmEiP20+QJtO2gj8bwJZr cHXMT+MMIXjNjMuCwq95HRp2jnlBTQWBxjoeWIIg= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ahmed Darwish , Thomas Gleixner , Theodore Tso , Nicholas Mc Guire , Andy Lutomirski , Kees Cook , Willy Tarreau , "Alexander E. Patrakov" , Lennart Poettering , Noah Meyerhans , Linus Torvalds Subject: [PATCH 4.9 099/264] random: try to actively add entropy rather than passively wait for it Date: Thu, 23 Jun 2022 18:41:32 +0200 Message-Id: <20220623164346.872243127@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220623164344.053938039@linuxfoundation.org> References: <20220623164344.053938039@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Linus Torvalds commit 50ee7529ec4500c88f8664560770a7a1b65db72b upstream. 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 Cc: Thomas Gleixner Cc: Theodore Ts'o Cc: Nicholas Mc Guire Cc: Andy Lutomirski Cc: Kees Cook Cc: Willy Tarreau Cc: Alexander E. Patrakov Cc: Lennart Poettering Cc: Noah Meyerhans Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/char/random.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1573,6 +1573,56 @@ void get_random_bytes(void *buf, int nby } 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(unsigned long data) +{ + 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; + + __setup_timer_on_stack(&stack.timer, entropy_timer, 0, 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 @@ -1587,7 +1637,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);