Don't corrupt RSA private keys during loading.

Fifteen years ago, Twisted landed [a
change](3cf1ed6058)
which enforced that the RSA primes were ordered p <= q, but then
serialised them backwards, so that actually p >= q, and it always
recreated the CRT values. This was because of [this
bug](https://twistedmatrix.com/trac/ticket/259), which is something to
do with testing key serialisation round-tripping. 2003-era PyCrypto [did
something](bb6a948964/PublicKey/RSA.py (L74))
very similar, so they were probably copying that in order to avoid
PyCrypto changing their keys and triggering round-trip failures.

As time has gone by, much of the Twisted code has changed, but the
initial condition to swap p & q if p > q has remained. However, the CRT
values are no longer recomputed, so this just corrupts the key. (For
example, `dmp1` stands for "d mod p-1" so clearly if p & q are swapped,
that value has to be updated in order to be correct. The values `dmq1`
and `iqmp` (inverse of q mod p) are likewise.)

OpenSSL has anti-glitch checking in its RSA implementation that is
designed to stop power-glitching attacks. (An arithmetic error during
CRT computation has a high chance of leaking the private key.) That
anti-glitch code detects the error caused by swapping p and q and
triggers a slow-path re-computation of signatures without the CRT. Thus
OpenSSL is silently correcting this, but spending much more CPU to do
so.

https://twistedmatrix.com/trac/ticket/9518
This commit is contained in:
Adam Langley 2018-08-30 16:49:56 -07:00
parent 1928146558
commit 737db21084
2 changed files with 1 additions and 2 deletions

View File

@ -0,0 +1 @@
RSA private keys are no longer corrupted during loading, allowing OpenSSL's fast-path to operate for RSA signing.

View File

@ -416,8 +416,6 @@ class Key(object):
n, e, d, p, q, dmp1, dmq1, iqmp = [
long(value) for value in decodedKey[1:9]
]
if p > q: # Make p smaller than q
p, q = q, p
return cls(
rsa.RSAPrivateNumbers(
p=p,