It's even more absurd than the post draws it. From the paper:
The X9.31 random number generator [in FortiOS] is implemented within a kernel module that exports a Linux character device. At boot time, the init process loads the module and replaces /dev/urandom with a node corresponding to the X9.31 character device.
We reverse-engineered the kernel module providing the X9.31 implementation [...] and found the hard-coded AES key used for the RNG. The hard-coded key was f3b1666d13607242ed061cabb8d46202. The key used in both the firmware dump and virtual appliance was the same. Although the documentation stated that the key was “generated external to the module”, the key is the same one used for the NIST test vectors [14] and appears to have been hard-coded into the source code.
Random (no pun intended) thought after reading this: how much of the supposedly secure HTTPS/TLS traffic is terminated by hardware load balancers and such that aren't really open and might have similar vulnerabilities?
It's a huge chunk and it's an underappreciated problem.
Many appliance vendors have terrible self-made TLS stacks. There's a bunch of vendors whose names come up again and again when talking about stupid TLS bugs and vulnerabilities. Cisco, F5, Cavium, A10, Citrix, Fortinet are names that come to mind. And it's not only a problem for security, it's also a huge compatibility problem, as they tend to violate the protocol in ways that makes deploying new features and versions hard.
I will make the opposite bet to sibling comment and say not too much. It's too easy to just install nginx and let it terminate connections to bother with a hardware device that you have to buy, store, and maintain.
And many sites use CDNs or cloud services for connection termination. Cloudflare and Amazon are surely on top of these things.
This is true of small shops and cloud operations but every enterprise IT shop I’ve seen has a router geek who is convinced you need an appliance to terminate traffic, even if it’s a decelerator in practice.
It's weirdly impressive that you still find wide, systemic misuse of random number generators in professional products. But maybe un-use is a better term for not using one where appropriate. In a Def Con talk Dan Kaminsky described it in a slide as "a drop will do ya". Where even a half assed attempted at using a csprng will result in something that will resist all but very well resourced attackers. Also see OpenBSD who have been banging this drum for probably 10-15 years now.
This attack would have been avoided if the output of the RNG had been hashed before being used. The root of the problem here is that the function from the state to the output can be inverted, once the key is known; one of the properties of a cryptographic hash is that it cannot be inverted other than by brute force. In the same way, the function from the state to the next state should also not be invertible.
Given Dual-EC, one has to wonder whether this bad RNG design was by accident or on purpose, and how many other bad RNGs are out there. One also has to wonder whether we should all start hashing the outputs of every RNG before using them...
This attack would not have been avoided if the output of the RNG had been hashed, since the attack essentially brute-forces all entropy in the system (i.e. the timestamp jitter). No amount of deterministic post-processing can save you if you have no entropy to begin with.
You also don't build backdoors by building bad products.
Unless I'm missing something, I think hashing actually would make this attack much harder to pull off. The attack works by AES decrypting the generator output, which gives you V (the state) XOR T (the timestamp). If you can guess the timestamp, you have V and can now run the generator both forwards and backwards as long as you can keep guessing the timestamp for each output.
If the generator output was hashed after being encrypted, it would not be possible to perform the decryption step of the attack. You could still perform a brute force attack by encrypting and then hashing, but now you're brute forcing both the state and the timestamp together (i.e. you have to guess V XOR T, then encrypt, hash, and validate your guess), which will likely be much more difficult if the generator has been running for some amount of time. Without being able to invert the encryption step, an attacker has to basically guess ALL previous timestamps rather than just the one associated with the current output. If the attacker is able to see the first few outputs, the attack would still work, but it would be much harder to just start at an arbitrary point in time.
Edit: I still don't think the addition of a hashing step would make this a great generator design, but it would make it more resilient against this kind of attack.
You're right; but the conclusion would still be "this is horrifically broken". A passive attacker can get all random generated since boot, and any internal RNG calls are not secret (neither in theory, nor probably in practice.)
One abstraction level up, hashing the output of a RNG is a bad countermeasure against a possibly-bad RNG. Good countermeasures including mixing the outputs of multiple RNGs and using protocols that don't require entropy.
"hashing the output of a RNG is a bad countermeasure against a possibly-bad RNG"
Why? I would think it's a fair suggestion for defense in depth, especially if you need to expose the result as a nonce, and you don't want to leak anything else unwittingly. It's also a good idea if you're not sure whether the entropy is evenly distributed, which is where something like HKDF would also want to hash the entropy source.
does anybody else find the first comment on the original article to be lame enough? he apparently thought it was a click-bait or something and uses lame-ass arguments to prove his bullshit assumption
The X9.31 random number generator [in FortiOS] is implemented within a kernel module that exports a Linux character device. At boot time, the init process loads the module and replaces /dev/urandom with a node corresponding to the X9.31 character device.
We reverse-engineered the kernel module providing the X9.31 implementation [...] and found the hard-coded AES key used for the RNG. The hard-coded key was f3b1666d13607242ed061cabb8d46202. The key used in both the firmware dump and virtual appliance was the same. Although the documentation stated that the key was “generated external to the module”, the key is the same one used for the NIST test vectors [14] and appears to have been hard-coded into the source code.