Back to News
Advertisement
Advertisement

⚡ Community Insights

Discussion Sentiment

17% Positive

Analyzed from 1375 words in the discussion.

Trending Topics

#code#rng#random#number#problem#xof#never#numbers#dev#always

Discussion (54 Comments)Read Original on HackerNews

jstanley•about 2 hours ago
This is not the first RNG bug on Zen 2, I recall after I first got mine that some application or other would quit immediately at startup because rdrand always returned -1, i.e. all 1s. It was fixed with a microcode update.

Do we now learn that they fixed "always generate all 1s" with "never generate all 0s"??

EDIT: I've been unable to reproduce the problem on my CPU, FWIW. It's a Ryzen 5 3600.

EDIT2: OK, update, I can reproduce it with rdrand16, rdrand32 is fine but rdrand16 can never generate all 0s. So my CPU does have this problem!

yk•about 2 hours ago

    return 4 # Determined by fair dice roll.
Gander5739•about 2 hours ago
https://xkcd.com/221/ for those not in the know
strenholme•about 1 hour ago
This is why I use, in security critical contents of my software (where the numbers have to be computationally infeasible to produce), a type of random number generator called an XOF (extendable-output function).

It takes entropy from multiple different sources, makes it all input to the XOF, then the XOF uses cryptography to output a stream that has as much entropy as the combined entropy of all of its sources of randomness. So if an XOF, for example, takes 100 runs of rdrand16, along with the system time in microseconds and the number of milliseconds between receiving 100 packets over the network, the XOF will output a completely random stream without artifacts like never returning 0x0000, even if rdrand16 never outputs 0x0000.

stingraycharles•about 1 hour ago
Isn’t this effectively what systems like /dev/(u)rand do? Pool multiple random sources together to hedge against these things?

I fail to see why one should either rely on a single random source nor roll their own.

strenholme•36 minutes ago
Yes, /dev/(u)random is supposed to do that, but what if there’s a bug in the kernel which causes /dev/(u)ramdom to be less than secure? There’s also issues where, for example, it may no longer be possible to read /dev/(u)random after putting the process in a chroot() sandbox (chroot() isn’t defined in POSIX so its behavior is not guaranteed to be consistent across multiple operating systems).

getrandom() is often times suggested, but alas isn’t a standardized function, i.e. it’s not part of the POSIX specification. Considering how the C23 changes to the C specification caused a lot of perfectly good C code to no longer compile, I’m very anal about sticking to specs; I use '-std=C99' for my code these days (even though it can compile as C23 code) and stick to POSIX functions (except chroot() and setgroups(), but both of those predate POSIX, and even here I have a compile-time option to compile my code without those non-POSIX syscalls).

The code using a secure XOF (the algorithm was developed by the same team which later on made SHA-3, and includes people who helped make AES) has been around for nearly two decades (the code where I roll my own RNG to make secure random numbers has been around for over 25 years, but used AES before XOFs existed) and not one security problem has found with the RNG code has ever been found. [1] “Don’t roll your own RNG” is a suggestion, but it is possible to do so securely if one knows what they are doing (i.e. they have read Applied Cryptography and keep current with cryptographic developments).

For anything vibe coded (my code is 100% human written, for the record), rolling one’s own RNG is a really bad idea.

[1] There was a theoretical issue with cache timing attacks over two decades ago, so I put mitigations in place, and then chose to use an XOF for newer code.

[2] There was an issue where a separate implementation I made of this XOF would generate incorrect test vectors in clang, but only at some optimization levels. I now test the XOF in both GCC and clang at multiple optimization levels to make sure it acts correctly.

boltzmann64•4 minutes ago
i remember some linux kernel dev got ousted by the community because he/she wanted to not implement a backdoor that would compromise the results of /dev/urandom.
sltkr•3 minutes ago
> getrandom() is often times suggested, but alas isn’t a standardized function

The POSIX standard function is getentropy(), which internally calls getrandom() on Linux.

> what if there’s a bug in the kernel which causes /dev/(u)ramdom to be less than secure?

It's often the other way around: the Linux kernel contains thousands of workarounds for buggy hardware, while the buggy hardware itself doesn't always get patched. Linux developers take this stuff very seriously. As a result it's often safer to rely on kernel APIs than to access the hardware directly.

The kernel code involving random number generation receives an exceptionally high amount of scrutiny because of its security implications, so I'd trust it to do the right thing over a naked call to RDRAND which nobody knows how exactly it's implemented in proprietary hardware or a handrolled solution to mix the RDRAND output with other entropy sources.

Remember the Debian openssl disaster from 2008? That happened exactly because someone had handrolled their entropy mixing solution, then someone else broke it.

NooneAtAll3•14 minutes ago
> but what if there’s a bug in the kernel which causes /dev/(u)ramdom to be less than secure?

so instead you suggest trusting your own untested unlooked at implementation more?

peri-cl•about 1 hour ago
The OP says they discovered this on a Zen 2, which is not covered by that bulletin (?)
ciupicri•about 1 hour ago
CodesInChaos•about 2 hours ago
Embarrassing, but probably little practical impact, since these hardware random numbers are typically not used directly and instead seed a CSPRNG.
rbanffy•about 1 hour ago
I have a couple questions:

Looks like they tried 16-bit numbers. Does the odd behavior happen also on 32 and 64 (might take a long time to check - I'd start scratching my head after a couple hundred years of no zeroes) ones? Is the zero masking as some other fixed number, increasing its output count? Is RDRAND implemented as multiple reads of an internal state so that a larger random number takes longer?

matja•about 2 hours ago
I'm getting 16-bit zeros on my Zen 3 chip (+1:3821, 0:3893, -1:3895), I will wait to get some statistically significant samples for the 32-bit values and update the forum thread. Maybe it was fixed after Zen 2?
20k•about 2 hours ago
I always wonder how hardware bugs like this happen with the sheer amount of hardware validation that's done. It'd be fascinating to know how it slipped through the cracks, though I know almost nothing about this side of the industry sadly
hnacobsxph•about 1 hour ago
Chased a similar bug in a KDF once and only caught it by histogramming the 16 bit draws, statistical suites never flagged it.
deadbabe•27 minutes ago
I would be very concerned if an RNG simply produced a natural 0.
flippingheck•3 minutes ago
I would be very concerned if an RNG simply produced a natural 1.
dark-star•about 2 hours ago
Usually you do "rdrand % <some-number>" anyways, and in that case you will still get zeroes. True, your result might be skewed by 1/(maxint/some-number) but I guess that's not a big problem in practice
throwawayffffas•about 2 hours ago
So what? The point is to be non predictable not to pick all the numbers in the range with exactly the same probability. Would it be a problem if it never generated 16542?
gnfargbl•about 1 hour ago
Consider an 8-bit RNG.

By your argument, it would not be a problem if the RNG never generated 0. So, it must follow that it would also not be a problem if it never generated {1, 2, 3, ..., 253}.

That means that our RNG now only generates the values 254 and 255. Which of the values is generated is unpredictable on any given call. However, 7 of the 8 output bits are now always fixed and so completely predictable. Can you imagine how an attacker could exploit that?

Failing to generate only the number 0 is a weaker version of the same class of flaw.

brookst•about 1 hour ago
This is the “what’s the big deal if I lost $100k in a casino, it’s really the same thing as if I had lost $5” argument.

I don’t think you can rebut “you only lose one of many values” with “it’s the same as only having one left”.

gnfargbl•34 minutes ago
We're talking about whether a modification of the expected probabilities changes the dynamics of the game. The example I gave was deliberately extreme, because that makes it easier to reason about.

If you want a casino example, then consider a roulette wheel that always lands on 36 but still pays out as usual. I think you'd want to play on it. Now consider one that always lands somewhere between 30 and 36. Still worth it, right? With careful bets and a good starting float you're still coming away from the table up (with a very high probability).

In fact for a roulette wheel you only need two dead pockets for the player to get an edge. Bias is exploitable.

throwawayffffas•about 1 hour ago
The value space goes from 2^16, 2^32, 2^64 to 2^16 - 1, 2^32 - 1, and 2^64 - 1 respectively.

The bug has zero practical impact.

gnfargbl•39 minutes ago
It is absolutely untrue that a biased RNG has "zero practical impact." Modern cryptography has plenty of examples of relatively small biases leading to breaks. Check out Bleichenbacher's attack, for instance.

You could be correct that the very small bias here is not enough to be exploitable. But, given the history around this, it would be wrong to handwave it away as trivial.

antiloper•about 1 hour ago
What are you talking about? The point is in fact to pick all the numbers in the range with exactly the same probability.

See section 7.3.17 of the Intel SDM, and how NIST SP800-90A (which the SDM refers to) defines "random number".

swader999•about 1 hour ago
Betty from accounting will have words.
throwawayffffas•about 1 hour ago
What does Betty from accounting care about RNGs?
Hugsbox•about 1 hour ago
That may well be a problem, yes.
Advertisement
ExoticPearTree•about 2 hours ago
The probability of generating a zero is incredibly low if you use the normal distribution curve.

So it is not necessarily that it doesn't generate zero, they did not run enough times to increase the probability of actually generating a zero.

blensor•about 2 hours ago
From what I can see they were trying to generate 16bit integers, so the probability is 1 in 65536 and they were running the test for 11 hours.

You definitely would expect a roughly equal number of 0s as any other of those numbers since it's uniformly distributed. And definitely not 0

zygentoma•about 2 hours ago
This also seems to happen for 16 and 32 bit numbers, so you should be able to see zeros easily.

They also write:

> Running the same programs on an Intel processor, and the 0's are there with no problem.

matja•about 2 hours ago
Why would it be a normal distribution?
throawayonthe•about 2 hours ago
should be a discrete uniform distribution right?
m_antis89•about 1 hour ago
0 is not a number, it's undefined
HackerThemAll•5 minutes ago
the what?
ZiiS•about 2 hours ago
It is just possible they decided crypto code that uses it was safer to skip zeros. (Whist mathematically it should be no more likely; it is vastly more likely someone will actually try that key).

It is also possible that their code was generating too many zeros and the easiest fix was to discard them all.

dark-star•about 2 hours ago
this is not how crypto works