NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-amd64/58122: x86 cpu_rng health test has higher than intended false alarm rate



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



Home | Main Index | Thread Index | Old Index