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.

NetBSD Home
NetBSD PR Database Search

(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.