Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp2951928pxk; Mon, 21 Sep 2020 01:02:44 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzc82i0BrZNIZEaefsvoZcLFKRXRkwx5XPhQuKaHpUoKRunEGSSlNbLdA1WOlsPgWuEQ/9J X-Received: by 2002:a50:d802:: with SMTP id o2mr52118378edj.152.1600675364626; Mon, 21 Sep 2020 01:02:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1600675364; cv=none; d=google.com; s=arc-20160816; b=p376Grw6eV+ZV8HeOJdEeB34g2NxIEszkcYZSITXWjwudRwC0+jRch1bUQ9SKk9qBA xEgEjSh90MXeqT7WQAg6PHMGOEVav3Mu2roF0o0DiTesZYARTvq3pr+gBghnb+fGNiE0 QEOwpBEgdF2t+nWj9tZn0cC3UMhpjnbMKXIG69hRu/bC2oR97m16wdcKPwpTqe4BLgWH JIdNsbcDpGXILE6345N/5/VteBLXbnaJ5FCP3bmj6svyGBy0fu3ecKxWQG2LLKKDfblO FN3GHGmeS4IOmr1XfhR9TTZQf45ZlMVZiLR21bKyCTjB6Qp9s6oBVs080UtKxxqOzlzj WPvw== 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 :references:in-reply-to:message-id:date:subject:cc:to:from; bh=mcre+dW2Hp62xM9tzKDYmyY4mjjJ1Ha3AkW0XbkpshY=; b=qSnEiBtuTF3uOIaqQCgdpTuoee/tZjxDG+Tv21lAmsifRXR0wIBDoCLKOn1Y55ENqg YwHfW6DpXcsZ18OHL7YuafbDurbgTBo8Urskv3zqfa2lsyP3jy5Ukq8lFa69dROivmfv CaFiSvzDm8A5xKIpi6jjdxTJOWgsg8Nn+dleMFkFUMw5RvesIErDRu0IteYc7cSbPiFT oGLoDQNVwYyu1soSgvyWIUT4jalxXcBCHdlIzCe5Na6bc1KuJBDCuL2IwiH+WwYsZI0m JZtakBGGu6HrmZCvv+xwGu69s1Zdv35HRuzX4fxnfD33u4GWJmMIUOVdkQXvNli10tE8 kc8A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y8si7760325edv.438.2020.09.21.01.02.19; Mon, 21 Sep 2020 01:02:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726577AbgIUIBI (ORCPT + 99 others); Mon, 21 Sep 2020 04:01:08 -0400 Received: from mx2.suse.de ([195.135.220.15]:56892 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726576AbgIUH7j (ORCPT ); Mon, 21 Sep 2020 03:59:39 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 3CEE4B532; Mon, 21 Sep 2020 08:00:11 +0000 (UTC) From: Nicolai Stange To: "Theodore Y. Ts'o" Cc: linux-crypto@vger.kernel.org, LKML , Arnd Bergmann , Greg Kroah-Hartman , "Eric W. Biederman" , "Alexander E. Patrakov" , "Ahmed S. Darwish" , Willy Tarreau , Matthew Garrett , Vito Caputo , Andreas Dilger , Jan Kara , Ray Strode , William Jon McCann , zhangjs , Andy Lutomirski , Florian Weimer , Lennart Poettering , Peter Matthias , Marcelo Henrique Cerri , Roman Drahtmueller , Neil Horman , Randy Dunlap , Julia Lawall , Dan Carpenter , Andy Lavr , Eric Biggers , "Jason A. Donenfeld" , =?UTF-8?q?Stephan=20M=C3=BCller?= , Torsten Duwe , Petr Tesarik , Nicolai Stange Subject: [RFC PATCH 38/41] random: enable NIST SP800-90B startup tests Date: Mon, 21 Sep 2020 09:58:54 +0200 Message-Id: <20200921075857.4424-39-nstange@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200921075857.4424-1-nstange@suse.de> References: <20200921075857.4424-1-nstange@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org NIST SP800-90B, section 4.3 requires an entropy source to inhibit output until the so-called "startup" tests have completed. These "startup" test shall process at least 1024 consecutive samples by means of the continuous health tests, i.e. the already implemented Repetition Count Test (RCT) and Adaptive Proportion Test (APT). Introduce a new field ->warmup to struct health_test. Initialize it to 1024 from health_test_reset(). Make health_test_process() decrement ->warmup once per event processed without test failure, but reset ->warmup to the intitial value upon failure. Prevent health_test_process() from returning health_dispatch as long as ->warmup hasn't dropped to zero. This will cause the caller, i.e. add_interrupt_randomness(), to not dispatch any entropy to the global balance until the startup tests have finished. Note that this change will delay the initial seeding of the primary_crng, especially for those values of the estimated per-IRQ min-entropy H where the mimimum of 1024 events from above is by several factors larger than 128/H, the number of events to be processed by a single APT run. That would only affect systems running with fips_enabled though and there's simply no way to avoid it without violating the specs. Signed-off-by: Nicolai Stange --- drivers/char/random.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 54ee082ca4a8..bd8c24e433d0 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -880,6 +880,7 @@ static void discard_queued_entropy(struct entropy_store *r, } struct health_test { + unsigned short warmup; unsigned short apt_event_count; union { u32 apt_presearch_bit_counters; @@ -1059,6 +1060,13 @@ health_test_apt(struct health_test *h, unsigned int event_entropy_shift, static void health_test_reset(struct health_test *h) { + /* + * Don't dispatch until at least 1024 events have been + * processed by the continuous health tests as required by + * NIST SP800-90B for the startup tests. + */ + h->warmup = 1024; + health_apt_reset(h); } @@ -1067,7 +1075,7 @@ health_test_process(struct health_test *h, unsigned int event_entropy_shift, u8 sample) { u8 sample_delta; - enum health_result rct; + enum health_result rct, apt; /* * The min-entropy estimate has been made for the lower eight @@ -1083,6 +1091,8 @@ health_test_process(struct health_test *h, unsigned int event_entropy_shift, * Something is really off, get_cycles() has become * (or always been) a constant. */ + if (h->warmup) + health_test_reset(h); return health_discard; } @@ -1091,7 +1101,18 @@ health_test_process(struct health_test *h, unsigned int event_entropy_shift, * don't care about whether the RCT needs to consume more * samples to complete. */ - return health_test_apt(h, event_entropy_shift, sample_delta); + apt = health_test_apt(h, event_entropy_shift, sample_delta); + if (unlikely(h->warmup) && --h->warmup) { + if (apt == health_discard) + health_test_reset(h); + /* + * Don't allow the caller to dispatch until warmup + * has completed. + */ + return apt == health_dispatch ? health_queue : apt; + } + + return apt; } struct fast_pool { -- 2.26.2