Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't corrupt RSA private keys during loading. #1055

Merged
merged 2 commits into from
Sep 3, 2018

Conversation

agl
Copy link

@agl agl commented Aug 30, 2018

Fifteen years ago, Twisted landed a change 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, which is something to do with testing key serialisation round-tripping. 2003-era PyCrypto did something 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

Contributor Checklist:

Fifteen years ago, Twisted landed [a
change](twisted@3cf1ed6)
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](https://github.com/dlitz/pycrypto/blob/bb6a94896433587a7a819efde503337e4b9ab3a5/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
@alex
Copy link
Member

alex commented Aug 31, 2018

There are failing tests that look relevant; I suspect they need to be un-swapped

glyph
glyph previously requested changes Aug 31, 2018
Copy link
Member

@glyph glyph left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@glyph
Copy link
Member

glyph commented Aug 31, 2018

(Also it looks like you're using an email address that isn't associated with your github account here - is that intentional? If not maybe rebase...)

@codecov
Copy link

codecov bot commented Aug 31, 2018

Codecov Report

Merging #1055 into trunk will increase coverage by 0.35%.
The diff coverage is 100%.

@@            Coverage Diff             @@
##            trunk    #1055      +/-   ##
==========================================
+ Coverage   91.56%   91.91%   +0.35%     
==========================================
  Files         844      844              
  Lines      150840   150838       -2     
  Branches    13155    13154       -1     
==========================================
+ Hits       138117   138647     +530     
+ Misses      10609    10102     -507     
+ Partials     2114     2089      -25

@glyph glyph dismissed their stale review September 3, 2018 20:52

Tests seem to be passing.

@glyph glyph merged commit 2a18aba into twisted:trunk Sep 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants