NetBSD Problem Report #58122
From www@netbsd.org Sat Apr 6 20:29:48 2024
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 895D21A923B
for <gnats-bugs@gnats.NetBSD.org>; Sat, 6 Apr 2024 20:29:48 +0000 (UTC)
Message-Id: <20240406202916.CD88C1A923C@mollari.NetBSD.org>
Date: Sat, 6 Apr 2024 20:29:16 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: x86 cpu_rng health test has higher than intended false alarm rate
X-Send-Pr-Version: www-1.0
>Number: 58122
>Category: port-amd64
>Synopsis: x86 cpu_rng health test has higher than intended false alarm rate
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-amd64-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Apr 06 20:30:00 +0000 2024
>Originator: Taylor R Campbell
>Release: current, 10
>Organization:
The RdrandBSD Foundation
>Environment:
>Description:
The cpu_rng_get function -- which is used to implement the rdrand, rdseed, rdrand/rdseed, and via CPU hardware RNG sources -- has a simple repeated-output health test to detect cases such as the AMD RDRAND microcode bug (https://github.com/systemd/systemd/pull/12536, https://arstechnica.com/gadgets/2019/10/how-a-months-old-amd-microcode-bug-destroyed-my-weekend/).
This health test was intended to compare consecutive 256-bit outputs to see if they repeated. The intended test has a false alarm rate of 1/2^256, which is negligible. It also successfully detects the AMD RDRAND microcode bug with a statistical power of 100%.
Owing to a confusion of bits, bytes, and words, however, the health test that was actually implemented compares not-quite-consecutive 32-bit samples instead:
263 #define N howmany(256, 64)
264 uint64_t buf[2*N];
...
274 for (i = 0; i < __arraycount(buf); i++)
275 nbits += cpu_rng(cpu_rng_mode, &buf[i]);
276 if (consttime_memequal(buf, buf + N, N)) {
277 printf("cpu_rng %s: failed repetition test\n",
278 cpu_rng_name[cpu_rng_mode]);
279 nbits = 0;
https://nxr.netbsd.org/xref/src/sys/arch/x86/x86/cpu_rng.c?r=1.20#260
Line 276 compares 4-byte quantities (N=4), but was intended to compare 32-byte quantities.
Although this also successfully detects the AMD RDRAND microcode bug with a statistical power of 100%, it has a false alarm rate of 1/2^32, or about one in four billion, which, while small, is very much not negligible for an experiment that can be performed in a few hundred nanoseconds.
>How-To-Repeat:
code inspection
>Fix:
Compare 32 bytes, not 4 bytes, and tidy up the code to be clearer about bits/bytes/words.
(Contact us)
$NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2024
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.