![]() |
|
![]() |
|
I was going based off the commit link posted further down the thread (https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=c...). You're right that the PuTTY deterministic nonce generating code does appear to significantly predate the RFC, but it sounds like the developer made a conscious decision when 6979 came out not to switch from what PuTTY already had because they looked similar enough. The PuTTY release that introduced support for elliptic curve cryptography (and introduced this vulnerability) was 0.68, which came out in 2017, 4 years after the RFC. You're right that this was not an RNG security problem and instead was a problem with not understanding ECDSA nonce rules. However the notable fact for me was that the developer was apparently aware of the recommended way to deterministically generate nonces prior to the vulnerability being introduced and made a choice not to implement the RFC because what PuTTY was already doing seemed close enough, without fully understanding the implications of doing so. To put it another way, understanding ECDSA nonce rules would have avoided this vulnerability, but so too would implementing the RFC recommended way even if the developer did not fully understand why it was better than the existing implementation. |
![]() |
|
And then you find out about special soundness and that this is not only expected behaviour, but crucial to the security definitions and you realise that signatures are absolutely cursed.
|
![]() |
|
I don't think anybody consciously looked at 9 zero bits and thought this is fine, but it rather looks like unfortunate effect of plugging old code into new algorithms without proper verification.
|
![]() |
|
You could be right. If you look at the old code, dsa_gen_k(), that was removed during the commit (https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=c...), it does basically no bounds checking, presumably because at the time it was written it was assumed that all modulus values would be many fewer bits than the size of a SHA-512 output. So it would have been pretty easy to just reuse the function for a modulus value that was too big without encountering any errors. And the old code was written 15+ years before it was used for P-521, so it's entirely possible the developer forgot the limitations of the dsa_gen_k() function. So maybe there's another lesson here about bounds checking inputs and outputs even if they don't apply to anything you're currently doing. |
![]() |
|
Schnorr wouldn't have helped in this specific case, since Schnorr is equally vulnerable to biased nonces (https://ecc2017.cs.ru.nl/slides/ecc2017-tibouchi.pdf). EdDSA, which is essentially deterministic Schnorr, does solve the problem. Also, the use of P-521 didn't specifically cause the vulnerability, but the bad interaction between SHA512 and P-521 did play a role. It is unfortunate that nature conspired against us to make 2^511 - 1 a composite number. The fact that you have to go up to 521 bits to get a Mersenne prime whereas the natural target length for a hash output is 512 bits is the fatal interaction here. |
![]() |
|
Excellent points all around, and thank you for the pointer to the ECC slides :) (And indeed, nature could have been kinder to us and given us a Mersenne between 127 and 521...) |
![]() |
|
100% agreed. For me, the stakes are very low. It's my windows "gaming" machine, and has access to a few low-value hosts. Otherwise I'd invest the time to learn wtf is pageant ;D |
![]() |
|
If the hosts are under your control, and never connect to untrusted hosts, then you are ok. The user authentication is encrypted, so the signatures are not visible to a man in the middle.
|
![]() |
|
I am on a corporate desktop, so I cannot use the Microsoft variant of the ssh-agent:
Obviously, getting that changed globally (or even for myself) is impossible.PuTTY has a workaround, allowing PAGENT.EXE to be used in place of the forbidden/inaccessible Microsoft agent: https://tartarus.org/~simon/putty-snapshots/htmldoc/Chapter9... So PuTTY remains quite relevant because of the mechanisms that Microsoft has chosen. |
![]() |
|
And it’s why shadow IT exists and shadow IT is why companies don’t fall apart. It’s also why web apps are so popular and why the blackberry failed. |
![]() |
|
Really helpful. I found challenge in getting a Windows system (no admin) into a state where i can use it productively, and having a functional ssh-agent was one of the remaining pain points.
|
![]() |
|
It’s possible to lock this down, don’t misunderstand me. I’m saying it’s unlikely for a security team to make this decision on a system where pageant.exe is allowed to run.
|
![]() |
|
I may not need PuTTY, but I like me a nice GUI that I can point and click with ssh command is absolutely fine, but I much prefer a list of saved presets versus ~/.ssh/config file fuckery |
![]() |
|
If I'm understanding correctly, the difference is between knowing you have 60 and having to try (30000!/(60! * (30000 - 60)!) combinations and seeing if they worked, which is quite a few.
|
![]() |
|
I mean the write up indicates you'd need access to the server side, or the pageant with the private key loaded, which both seem to be like... umm... at that point don't we have bigger issues?
|
![]() |
|
Good catch! I wrote the title before I had dug into the matter and forgot to update it. Thanks for pointing that out. Any k generation and subsequent signature generation are going to be impacted. |
![]() |
|
It says the key may have been lost if it had ever been used with Putty. If you have keys of this type and have ever used Putty you should revoke them.
|
![]() |
|
You can look in the key file. From the OP: "has an id starting ecdsa-sha2-nistp521 in [...] the key file" He also mentions some other places the information shows up. |
![]() |
|
If you haven't already, this is probably a good time to switch to EdDSA keys. EdDSA signatures don't require RNG nor modular math unlike ECSDA signatures.
|
![]() |
|
There is no indication or mention that key exchange was compromised. SSH has forward secrecy, so compromising the authentication keys does not compromise the encryption keys.
|
![]() |
|
It appears that some of this was designed in the late 90s/early aughts, when Windows didn't have a cryptographically-secure random number generator. PuTTY carries its own formats from this time. |
![]() |
|
The problem is that 521 > 512, not that they used modulo. To get a sufficiently large nonce out of the hash, you need to think in terms of expanding the number of bits, not reducing it.
|
![]() |
|
Presumably because 512 of bits (a) seemed "random enough" and (b) was the nicest block size that fit comfortably in 521 bits of modulus. This is a common mistake.
|
![]() |
|
Caution here. If your modulus is too close to the maximum truncated value, there can be a bias in the upper bits, too. For example, if you reduce a number between 0 and 15 by the modulus 13, the values 0, 1 and 2 will be twice as likely as the values 3-12. This means that the highest bit will be 0 in 11 out of 16 cases. Even such a small bias might be exploitable (for example, sub 1 bit bias up to 160-bit ECDSA here: Gao, Wang, Hu, He https://eprint.iacr.org/2024/296.pdf)
|
![]() |
|
> Where did I imply that it is? You used 13 as an example in a response to my comment that was: Isn't modulo the same as truncation when dealing with powers of two? |
![]() |
|
> You used 13 as an example I don't see the number 13 in any of my comments on this thread (except this one, or where I quoted you). Perhaps you are confusing me with someone else? |
![]() |
|
We recommend against ECDSA for internal accounts. I know several of our partners use it though. Hard to not be cynical about this even though this issue seems mostly harmless.
|
![]() |
|
The benefit of EC is not speed, it is much smaller key sizes. Roughly speaking, an RSA key has to be 8 times as large as an EC key for the same security level. |
The problem here is the distinction between an n-bit random number and n-bit modulus. In DSA, if you're working with a 521-bit modulus, and you need a random k value for it, k needs to be random across all 521-bits.
Systems programming intuition tells you that a 512-bit random number is, to within mind-boggling tolerances, as unguessable as a 521-bit random number. But that's not the point. A 512 bit modulus leaves 9 zero bits, which are legible to cryptanalysis as bias. In the DSA/ECDSA equation, this reduces through linear algebra to the Hidden Number Problem, solvable over some number of sample signatures for the private key using CVP.
Later
Here you go, from Sean Devlin's Cryptopals Set 8:
https://cryptopals.com/sets/8/challenges/62.txt