To give some easier explanation: This is an attack against faulty RSA implementations.
There is a common optimization in RSA signature implementations that splits up an expensive mathematical operation into two smaller operations. If one of these throws out a bad result then you can break the key.
Why does this happen? Multiple reasons. Implementations of big number math can and does contain bugs. (I used to hunt for those via fuzzing, which turned up an amazing number of them.) Hardware failures. Other bugs that corrupt numbers in memory.
The new thing this paper adds is applying this attack to SSH.
There is a countermeasure against this attack, and this is to verify the signature before revealing it. It works. As the paper says, openssh uses openssl's RSA implementation, and it has been doing that since forever (2001).
So in summary: Applying a well-known attack against RSA to its use in SSH. Only works if you have an RSA implementation that outputs results of flawed computations. Countermeasures exist, and RSA implementations should use them.
FWIW, RSA is well known to be difficult to get right because you have to select the primes very carefully, and must take explicit steps to avoid padding oracle attacks[1], and perhaps it's better to avoid it entirely.
FWIW I wrote one of the papers re RSA padding oracle attacks, and I disagree with quite a few bits in this blogpost.
Yeah, there are pitfalls in RSA, but so are there in elliptic curve algorithms. I'm not sure if I'd say RSA has more pitfalls than ECDSA. Ed25519 is better, but so is RSA-OAEP/PSS over PKCS #1.5, where many of the common RSA pitfalls are. Most of the RSA pitfalls are in RSA encryption, which is irrelevant if you only use signatures.
You don't have to select primes very carefully. You can select random numbers, check if they are of the right size and prime, and you're good. What some people tend to do is to select primes in a "smart" way, which this post rightfully points out is problematic (see ROCA). But they also reference the batchgcd issue, which is not really an RSA issue. It is ultimately a bad RNG issue, and the very same issue also caused ECDSA implementations to break (with the same catastrophic "you reveal your private key" result).
Ultimately, I think the big problem here is encryption. A footgun ECC constructions don't have is direct public key encryption; idiomatically, ECC "encryption" is a DH key establishment and then a block/bulk cipher doing the encryption, where RSA exposes a direct encryption transform that people idiomatically use.
It's just also the case that RSA in popular use is virtually never OAEP or PSS, and that this isn't a problem you have with ECC constructions, even if you're not using the most misuse-resistant of them.
It's also kind of a dead letter at this point. The ship has sailed: new designs all use curves, and have for something like a decade now.
(I didn't write a paper on this, but I do believe myself to be the proprietor of the Internet's single largest collection of Bleichenbacher padding oracle exploits, in every conceivable language, so there's my bona fides.)
I'd say encryption and PKCS#1v1.5. The latter is just hard enough to implement safely that it's quite likely to be vulnerable, but not so obviously bad as to be considered definitively broken & set for removal. PKCS#1v1.5 support might not be a deliberate backdoor, but allowing it in a new protocol today would be suspicious.
We went to curves largely due to the flaws of PKCS#1v1.5, not so much due to RSA itself being bad (though the false sense of simplicity it has is certainly dangerous). RSASSA-PSS verification is fast, so while the keys & signatures are big there's still some reason to use it for constrained devices.
Well, sure, but the alternatives are more complex and harder to get right. You can literally just pick two random numbers of the right magnitude, find the closest primes, and be good for RSA.
No, the alternatives are less complex, and easier to get right.
Further: the article you linked to describes the attack we are talking about right now on this thread, a fully remote fault attack that harvested keys off random SSH servers on the Internet, as "a completely theoretical hardware attack". (Narrator: it was not; further, this is that "completely theoretical" attack in its most difficult setting.)
This is still wrong! Leaving aside that hardware faults are themselves implementation pitfalls for RSA, the fundamental failure here is a software implementation flaw. You really need to understand these attacks before you supply guidance about them.
Upstream OpenSSH uses LibreSSL, which they've forked from OpenSSL precisely because they were concerned with code quality and correctness.
I don't know whether this problem affects LibreSSL, but one of their main goals was to be less afraid of breaking the OpenSSL API to fix usability problems that lead to incorrect (insecure) code.
IIUC, the original 2001 countermeasure for this is embedded in the modexp routine, and both OpenSSL (in rsa_ossl.c) and LibreSSL libcrypto (in rsa_eay.c) have substantially the same logic.
Look for the comment:
/*
* 'I' and 'vrfy' aren't congruent mod n. Don't leak
* miscalculated CRT output, just do a raw (slower)
* mod_exp and return that instead.
*/
Note that in the OpenSSL case at least, this check is in the default engine/plugin, not in generic code. If you load a different plugin, you only get protection if the engine/plugin implements a similar check internally.
(I expect that LibreSSL removed the plugin framework, but I haven't checked.)
RSA digital signatures can reveal a signer’s secret key if a computational or hardware fault occurs during signing with an unprotected
implementation using the Chinese Remainder Theorem and a deterministic padding scheme like PKCS#1 v1.5.[...] In this context, a passive adversary can quietly monitor legitimate connections without risking detection until they observe
a faulty signature that exposes the private key. The attacker can then actively and undetectably impersonate the compromised host to intercept sensitive data.
And they say crypto is hard, sheesh...
Seriously though, almost every time I hear about some new (to me) attack, I get amazed at the ingenuity of people.
I think GP's point is that one vulnerable hardware or software implementation in the entire network of implementations being passively observed by the attacker can reveal the private keys. So it's not just your implementations which must be perfect, but all your neighbors, and all theirs too.
I read it as "only" the signing machine needs faulty hardware. Still, bit errors occur, even with ECC, and this allows for a passive hence very unobtrusive attack.
My point was exactly that, it's bloody hard. Not only implementing it correctly, but all the non-obvious ways it can go wrong that'spartially out of your control due to non-ideal hardware (in the mathematical sense). Timing attacks, cache leaks, speculation leaks, this...
> We also carry out a retrospective analysis of historical SSH scan data collected over the course of seven years, and find that these invalid signatures and vulnerable devices are surprisingly common over time.
> Our combined dataset of around 5.2 billion SSH records contained more than 590,000 invalid RSA signatures.
Am I reading this right? This is about 1 in 10_000, this is way more common that what I would have imagined
Correct. You are almost certainly not at risk. OpenSSL isn't vulnerable to this attack; your stack needs to be seriously archaic to have a vulnerable RSA implementation.
Some OpenSSL deployments use RSA plugins that do not contain the check—it's not in generic OpenSSL or OpenSSH code, so every engine plugin needs to implement its own check.
Which plugins are you aware of that are used for RSA signatures and don't check signature validity? Just curious, from your comment it seemed like there might be specific ones.
* In (rare) vulnerable targets, this allows you to recover the host's key, and thus impersonate a host. You can't compromise client credentials with this attack, since client credentials are exchanged after the (active) secure channel is established. If you can impersonate a host, as this attack would allow you to do, you could capture client password credentials, and you can drive a forwarded agent.
* OpenSSH --- really, SSH servers on any Unix host you've been using in the last 20 years --- isn't vulnerable to this attack. The vulnerability is publishing a signature that is validly signed under RSA p and not under RSA q. Solution: just never do that; when you generate the signature, check it yourself before publishing. This is one of the better-known attacks on RSA, so this is a standard implementation countermeasure.
* The things that are vulnerable are crappy middleboxes from Zyxel, Mocana, apparently a rare subset of Cisco devices, and whatever "SSH-2.0-SSHD" is (the authors don't know either).
* This is a Nadia Heninger paper, and Heninger is, like, the modern master of the Coppersmith RSA attack, which transforms an RSA problem into a series of polynomials and then transforms those into a linear algebra problem set in a lattice (roughly: a vector space with exclusively integer components; really, when we say "lattice" we mean "some generated basis for that lattice"). You then use the LLL algorithm to reduce the basis, which gives you small vectors that, when reframed back into polynomials or whatever, can tractably solved for their roots. Get the intuition? Yeah, I mean, me neither. Lattice attacks on PQ crypto have a simpler intuition! But the lattices bases here are just R^3 matrices, so, that's pretty simple.
* You can get the intuition for the underlying vulnerability much more simply. From the paper: Boneh, DeMillo, and Lipton noted that if an attacker had a correct signature s and an incorrect signature s_hat of this form then the attacker could compute gcd(N, s_hat − s) = p. The complicated math comes from the fact that while we have the incorrect signature we're hoping for, we don't have the correct signature over the same message, or a fully known message.
* This attack is made possible by our old friend PKCSv1.5, this time in a signing setting. It works because a P1v1.5 RSA signature has regular format: 00 01 FF ... FF 00 aa .. aa hh .. hh, where aa are the (known) bits of the ASN.1 identifier of the hash, and hh are the (unknown) bits of the hash. Everything but the bit values of hh is known to the attacker.
* Amusing detail: the attack relies on a condition of the unknown bits being less than 1/4 of the RSA message (modulus) size, so the attack actually gets harder for RSA-1024 with better hashes, and is impossible for RSA-1024 with SHA2-512, which blows that budget.
* Another thing that uses PKCSv1.5-RSA signatures is DNSSEC. You could scan the Internet collecting DNSSEC signatures hoping to find some that don't validate (I think it's RIPE that periodically does surveys looking for invalid DNSSEC records, and routinely finding them?), and because all RSA DNSSEC is in viable parameters for this attack I guess recover keys from it? Or you could just not use DNSSEC. I guess maybe this is particularly problematic for "online-signers"; most DNSSEC signatures are computed offline, so you can't just repeatedly ask for new signatures waiting for a fault, but you could with an online signer.
Suppose you wanted to find a root of f(x) = x^3 - a mod N. If there is a root smaller than N^(1/3), this reduces to simply computing the integer cube root of a, since there is no wrap-around.
But imagine if the problem is slightly changed to f(x) = (x + padding)^3 - a mod N, for some large but known padding. Now you can't simply compute an integer cube root, and the above doesn't work anymore. But you can look for a product of f(x) by some other polynomial g(x): f(x)g(x) necessarily contains the roots of f(x), but may have smaller coefficients such that evaluating f(x)g(x) at the root you're looking for does not wrap around N.
Now look into what this multiplication looks like: f(x)g(x) = c_0 f(x) + c_1 x f(x) + c_2 x^2 f(x) + ..., where c_i are the unknown coefficients of g(x). This is a sum of integer multiples of known coefficient vectors and, to find the set of coefficients c_i such that this sum is a small as possible is exactly the same as finding a short vector in the lattice (f(x), xf(x), x^2f(x), ...), where the vectors are the coefficients of each (shifted) polynomial. You also have to weight the coefficients according to their exponent, to account for the fact that the coefficient of, say, x^3 needs to be smaller than x to avoid wrap-around.
Once lattice reduction gives you back an f(x)g(x) with small enough coefficients you compute its integer roots, which is doable very quickly, and check which of them work for f(x). That's the gist of it. The full-fledged method also includes powers of f(x) modulo powers of N instead of simply multiplying it by g(x), and that was the trick Coppersmith introduced, but if you understand the simple version the full version is straightforward.
I wonder if I can use this against Intel SGX/AMD SEV-SNP :)
These are hardware features where a private key is hardcoded in the chip and never supposed to be revealed. You can ask the chip to sign things for you. It has some anti-tampering measures, but it might be possible to induce faults without too much effort, if you apply heat, EM ("cosmic rays"), and play with voltage/frequency a little
I remember they fixed that one, but plundervolt is more finely targeted, like a traditional glitch attack. The fun thing with this attack is we just need a little bit of corruptions everywhere, and some broken signatures might make it through!
DVFS aside, there's plenty of ways to stress and CPU and cause random errors. I don't know whether their RSA implementation protects against this attack, though.
How about ELI precocious 10 year old? Cosmic rays and thermal effects cause random bit flips in memory very infrequently. If you sit on a network and listen to TLS handshakes for long enough, you'll find that any given server will issue the wrong signature occasionally, because of these bit flips. If you record the wrong signature(s) and use a fancy algorithm, you can recover the private key.
While at first it may seem an unlikely attack, it's probably more real than you'd think, given the number of times any single server does TLS negotiation using a given private key. The attack becomes even more likely when you realize that multiple servers will be using the private key.
In practice, this gives middle boxes more power, and raises their profile in the threat model significantly. This also opens up the possibility of simply collecting failed transient failed tls negotation data from a large number of (legitimate) clients to reconstruct a private key.
now put your tinfoil hat on and suppose you worked for a paramilitary organization that had infiltrated the top 2 semiconductor manufacturers. You persuade the silicon designers, when implementing hardware accelerated crypto (or "management engines") to not do their jobs quite perfectly, no just leave room for a tiny bit of....error. Could never happen, right?
It's akin to me having the secret number 17, giving you 221 (17*13) and then, during a solar flare, fucking it up once and giving you 187 (17*11). You know that the numbers are the product of a multiplication, and you know that a common factor is my private secret number. You figure out that the only way to get to 187 and 221 while keeping a common factor is if that factor is 17. That's just computing the GCD.
>An RSA public key consists of a public exponent 𝑒 and a modulus 𝑁 = 𝑝𝑞 that is the product of two primes. The private key consists of the private exponent 𝑑 = 𝑒 −1 mod 𝜙 (𝑁) and 𝑁 . A textbook RSA signature on a message 𝑚 is the value 𝑠 = 𝑚𝑑 mod 𝑁 . To verify the signature, a user checks if 𝑠𝑒 mod 𝑁 = 𝑚
> these attacks exploit the fact that if an error is made while computing modulo one prime, say 𝑞, then the resulting invalid signature ˆ𝑠 is equivalent to the correct signature modulo one prime factor 𝑝, but not 𝑞. 2.2.1 GCD attack on fully known messages. Boneh, DeMillo, and Lipton noted [11] that if an attacker had a correct signature 𝑠 and an incorrect signature ˆ𝑠 of this form then the attacker could compute gcd(𝑁, ˆ𝑠 − 𝑠) = 𝑝
Virtually never in practice (they are corrected) if you use ECC. A server that doesn't is weird. TBH any computer that doesn't is weird but the industry seems to consider it normal to have random computational unreliability because of that pretty much only unprotected component (Ram without ECC) in consumer hw.
> We also carry out a retrospective analysis of historical SSH scan data collected over the course of seven years, and find that these invalid signatures and vulnerable devices are surprisingly common over time.
> Our combined dataset of around 5.2 billion SSH records contained more than 590,000 invalid RSA signatures.
Seems like over long periods, it can occur a spoopy amount of time.
Why does this happen? Multiple reasons. Implementations of big number math can and does contain bugs. (I used to hunt for those via fuzzing, which turned up an amazing number of them.) Hardware failures. Other bugs that corrupt numbers in memory.
The basic attack is well known. Florian Weimer has demonstrated this against TLS in the wild: https://www.redhat.com/en/blog/factoring-rsa-keys-tls-perfec...
The new thing this paper adds is applying this attack to SSH.
There is a countermeasure against this attack, and this is to verify the signature before revealing it. It works. As the paper says, openssh uses openssl's RSA implementation, and it has been doing that since forever (2001).
So in summary: Applying a well-known attack against RSA to its use in SSH. Only works if you have an RSA implementation that outputs results of flawed computations. Countermeasures exist, and RSA implementations should use them.