From nobody Sun Feb 13 07:29:49 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id F420B1941743; Sun, 13 Feb 2022 07:29:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4JxJs952nPz3qLg; Sun, 13 Feb 2022 07:29:49 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1644737389; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=tjYWNDicAr/Y8jRo6q1vC2uy80EN4l54uIz+6ReXBxE=; b=SRXHI5H0s1qf5jvljEhCTDvlp30W2QG9Y166MBYVx4jxU5bD7Zp4qk0yzHtYKRQRk6N+F2 0PL+sv+n1/d/mKw5QcaHlkOg7fokjC4YkHC3Jo4DT8MWc34KWdt1OzczHfT5mA7VlzPEV4 BoDHbHLX8tVbgqaI1BQq5defBcgEBFYP5VtzD3/PaRAh0OMVQsiuc5rmn9mvOuZ+Rspdg7 ytpVaOE8tT7GRXvHXW7FL2xB40zFgDhCEd/lbVjSO0tuqrgaOEldWUPULO70b4P6VeWO/a Y0N05bgW6SKQlUZaKfqpMOB48xqGx/XonHk2TbQRUCDZBKXhtpve+u3ndtGd4A== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 6457117413; Sun, 13 Feb 2022 07:29:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 21D7Tn7p018823; Sun, 13 Feb 2022 07:29:49 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 21D7Tnh0018822; Sun, 13 Feb 2022 07:29:49 GMT (envelope-from git) Date: Sun, 13 Feb 2022 07:29:49 GMT Message-Id: <202202130729.21D7Tnh0018822@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: "David E. O'Brien" Subject: git: 856230b94a54 - stable/12 - Fortuna: Fix false negatives in is_random_seeded() List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: obrien X-Git-Repository: src X-Git-Refname: refs/heads/stable/12 X-Git-Reftype: branch X-Git-Commit: 856230b94a544161dbb71406471bf15d48473cfd Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1644737389; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=tjYWNDicAr/Y8jRo6q1vC2uy80EN4l54uIz+6ReXBxE=; b=jts9lIT2vwowrxPnOPJCHtNG/AOdXiPG5woViikLVI6PR5KM5orh1c827GTQ8a9MUvCLw7 T44fbrXozfdjsFYfQigvxGdPaGpGEq/ghjG9woxAPQL0tdzywOgZXGwKzUx2GlIx/K7o/a kRTboEDus4J1lfc7l7HHcH/+iIIzoIJ71OqP4bZNI/fWQMSJO6K1dUvR29NuHM2Vk/V5me VxV2RwIf7HhZ6Dn3GUROF2QwttnqBerXVhVBGK4cfq5FqoPIECRPbLvacnoH459mFqEqO7 ar91aCZjL34qFqkXK3hDKhW96+qcxtPWDX5Iioqahbqcn+Dp9taTl2VH+pr5eg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1644737389; a=rsa-sha256; cv=none; b=MvstanmN/3UUCgZXbVJEzMVDl8H71KsnOz0u3bmMuqqceQ/C//cxQ3CbEUC9MUUeau3JKU 4TRyA9DLbJ/YT47URlzAM18PmKvK6aAUKQSY4X4o5bmxAnbV0GOrgJFK5smwGzXkSq6l3E OpmoQPtg9xdHo68iAA2vaRDTypy9dGwVQN7UJHSd6gwtB0DQarDlxAvoGjmf5ECZihl/3o //7maMG2dOCNAbaXAAddlshRpi8eRRvNN/sO835sLAGaRLGL0DHOLlFWKIRLYsA+8vVZDo S5QsHLwdeTterJrxpmikxzHTjD8yz6S2SvVsYHMeRrX6pmurlxsQThUnA6sHhA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/12 has been updated by obrien: URL: https://cgit.FreeBSD.org/src/commit/?id=856230b94a544161dbb71406471bf15d48473cfd commit 856230b94a544161dbb71406471bf15d48473cfd Author: Conrad Meyer AuthorDate: 2019-05-13 19:35:35 +0000 Commit: David E. O'Brien CommitDate: 2022-02-13 06:39:46 +0000 Fortuna: Fix false negatives in is_random_seeded() (1) We may have had sufficient entropy to consider Fortuna seeded, but the random_fortuna_seeded() function would produce a false negative if fs_counter was still zero. This condition could arise after random_harvestq_prime() processed the /boot/entropy file and before any read-type operation invoked "pre_read()." Fortuna's fs_counter variable is only incremented (if certain conditions are met) by reseeding, which is invoked by random_fortuna_pre_read(). is_random_seeded(9) was introduced in r346282, but the function was unused prior to r346358, which introduced this regression. The regression broke initial seeding of arc4random(9) and broke periodic reseeding[A], until something other than arc4random(9) invoked read_random(9) or read_random_uio(9) directly. (Such as userspace getrandom(2) or read(2) of /dev/random. By default, /etc/rc.d/random does this during multiuser start-up.) (2) The conditions under which Fortuna will reseed (including initial seeding) are: (a) sufficient "entropy" (by sheer byte count; default 64) is collected in the zeroth pool (of 32 pools), and (b) it has been at least 100ms since the last reseed (to prevent trivial DoS; part of FS&K design). Prior to this revision, initial seeding might have been prevented if the reseed function was invoked during the first 100ms of boot. This revision addresses both of these issues. If random_fortuna_seeded() observes a zero fs_counter, it invokes random_fortuna_pre_read() and checks again. This addresses the problem where entropy actually was sufficient, but nothing had attempted a read -> pre_read yet. The second change is to disable the 100ms reseed guard when Fortuna has never been seeded yet (fs_lasttime == 0). The guard is intended to prevent gratuitous subsequent reseeds, not initial seeding! Machines running CURRENT between r346358 and this revision are encouraged to refresh when possible. Keys generated by userspace with /dev/random or getrandom(9) during this timeframe are safe, but any long-term session keys generated by kernel arc4random consumers are potentially suspect. [A]: Broken in the sense that is_random_seeded(9) false negatives would cause arc4random(9) to (re-)seed with weak entropy (SHA256(cyclecount || FreeBSD_version)). (cherry picked from commit e8e1f0b4204dc766c4c5af5f259af11f9b0e0452) --- sys/dev/random/fortuna.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/sys/dev/random/fortuna.c b/sys/dev/random/fortuna.c index a6cfccaa3a1a..e0991d411df3 100644 --- a/sys/dev/random/fortuna.c +++ b/sys/dev/random/fortuna.c @@ -130,6 +130,7 @@ static uint8_t zero_region[RANDOM_ZERO_BLOCKSIZE]; static void random_fortuna_pre_read(void); static void random_fortuna_read(uint8_t *, u_int); static bool random_fortuna_seeded(void); +static bool random_fortuna_seeded_internal(void); static void random_fortuna_process_event(struct harvest_event *); static void random_fortuna_init_alg(void *); static void random_fortuna_deinit_alg(void *); @@ -277,7 +278,7 @@ random_fortuna_reseed_internal(uint32_t *entropy_data, u_int blockcount) RANDOM_RESEED_ASSERT_LOCK_OWNED(); - seeded = random_fortuna_seeded(); + seeded = random_fortuna_seeded_internal(); if (seeded) { randomdev_getkey(&fortuna_state.fs_key, &keymaterial, &keysz); KASSERT(keysz == RANDOM_KEYSIZE, ("%s: key size %zu not %u", @@ -377,8 +378,12 @@ random_fortuna_pre_read(void) if (fortuna_state.fs_pool[0].fsp_length < fortuna_state.fs_minpoolsize #ifdef _KERNEL - /* FS&K - Use 'getsbinuptime()' to prevent reseed-spamming. */ - || (now - fortuna_state.fs_lasttime <= SBT_1S/10) + /* + * FS&K - Use 'getsbinuptime()' to prevent reseed-spamming, but do + * not block initial seeding (fs_lasttime == 0). + */ + || (__predict_true(fortuna_state.fs_lasttime != 0) && + now - fortuna_state.fs_lasttime <= SBT_1S/10) #endif ) { RANDOM_RESEED_UNLOCK(); @@ -460,7 +465,13 @@ SYSCTL_BOOL(_kern_random, OID_AUTO, block_seeded_status, CTLFLAG_RWTUN, "unavailable."); #endif -bool +static bool +random_fortuna_seeded_internal(void) +{ + return (!uint128_is_zero(fortuna_state.fs_counter)); +} + +static bool random_fortuna_seeded(void) { @@ -469,5 +480,14 @@ random_fortuna_seeded(void) return (false); #endif - return (!uint128_is_zero(fortuna_state.fs_counter)); + if (__predict_true(random_fortuna_seeded_internal())) + return (true); + + /* + * Maybe we have enough entropy in the zeroth pool but just haven't + * kicked the initial seed step. Do so now. + */ + random_fortuna_pre_read(); + + return (random_fortuna_seeded_internal()); }