From nobody Thu Apr 2 15:04:08 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F32E3C6FA82 for ; Thu, 22 Sep 2022 14:02:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231584AbiIVOCH (ORCPT ); Thu, 22 Sep 2022 10:02:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229901AbiIVOB5 (ORCPT ); Thu, 22 Sep 2022 10:01:57 -0400 Received: from isilmar-4.linta.de (isilmar-4.linta.de [136.243.71.142]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 624B352464; Thu, 22 Sep 2022 07:01:55 -0700 (PDT) X-isilmar-external: YES X-isilmar-external: YES X-isilmar-external: YES X-isilmar-external: YES Received: from owl.dominikbrodowski.net (owl.brodo.linta [10.2.0.111]) by isilmar-4.linta.de (Postfix) with ESMTPSA id 40AC0201349; Thu, 22 Sep 2022 14:01:53 +0000 (UTC) Received: by owl.dominikbrodowski.net (Postfix, from userid 1000) id DF826806F2; Thu, 22 Sep 2022 15:59:31 +0200 (CEST) Date: Thu, 22 Sep 2022 15:59:31 +0200 From: Dominik Brodowski To: "Jason A. Donenfeld" , Herbert Xu , linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org Subject: [PATCH v3] hw_random: core: start hwrng kthread also for untrusted sources Message-ID: References: <20220920142159.2789273-1-Jason@zx2c4.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20220920142159.2789273-1-Jason@zx2c4.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Start the hwrng kthread even if the hwrng source has a quality setting of zero. Then, every crng reseed interval, one batch of data from this zero-quality hwrng source will be mixed into the CRNG pool. This patch is based on the assumption that data from a hwrng source will not actively harm the CRNG state. Instead, many hwrng sources (such as TPM devices), even though they are assigend a quality level of zero, actually provide some entropy, which is good enough to mix into the CRNG pool every once in a while. Cc: Herbert Xu Cc: Jason A. Donenfeld Signed-off-by: Dominik Brodowski --- Thanks to Jason for splitting my v1 into two parts, as per Herbert's request. In comparison to v2, I've updated (and shortened) the commit message. diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 16f227b995e8..edb86c0cccda 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -52,7 +52,7 @@ MODULE_PARM_DESC(default_quality, =20 static void drop_current_rng(void); static int hwrng_init(struct hwrng *rng); -static void hwrng_manage_rngd(struct hwrng *rng); +static int hwrng_fillfn(void *unused); =20 static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size, int wait); @@ -96,6 +96,15 @@ static int set_current_rng(struct hwrng *rng) drop_current_rng(); current_rng =3D rng; =20 + /* if necessary, start hwrng thread */ + if (!hwrng_fill) { + hwrng_fill =3D kthread_run(hwrng_fillfn, NULL, "hwrng"); + if (IS_ERR(hwrng_fill)) { + pr_err("hwrng_fill thread creation failed\n"); + hwrng_fill =3D NULL; + } + } + return 0; } =20 @@ -167,8 +176,6 @@ static int hwrng_init(struct hwrng *rng) rng->quality =3D 1024; current_quality =3D rng->quality; /* obsolete */ =20 - hwrng_manage_rngd(rng); - return 0; } =20 @@ -454,10 +461,6 @@ static ssize_t rng_quality_store(struct device *dev, /* the best available RNG may have changed */ ret =3D enable_best_rng(); =20 - /* start/stop rngd if necessary */ - if (current_rng) - hwrng_manage_rngd(current_rng); - out: mutex_unlock(&rng_mutex); return ret ? ret : len; @@ -509,9 +512,6 @@ static int hwrng_fillfn(void *unused) mutex_unlock(&reading_mutex); put_rng(rng); =20 - if (!quality) - break; - if (rc <=3D 0) { pr_warn("hwrng: no data available\n"); msleep_interruptible(10000); @@ -533,22 +533,6 @@ static int hwrng_fillfn(void *unused) return 0; } =20 -static void hwrng_manage_rngd(struct hwrng *rng) -{ - if (WARN_ON(!mutex_is_locked(&rng_mutex))) - return; - - if (rng->quality =3D=3D 0 && hwrng_fill) - kthread_stop(hwrng_fill); - if (rng->quality > 0 && !hwrng_fill) { - hwrng_fill =3D kthread_run(hwrng_fillfn, NULL, "hwrng"); - if (IS_ERR(hwrng_fill)) { - pr_err("hwrng_fill thread creation failed\n"); - hwrng_fill =3D NULL; - } - } -} - int hwrng_register(struct hwrng *rng) { int err =3D -EINVAL;