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

Alternative fix for CVE-2022-4304 (3.1) #20282

Conversation

bernd-edlinger
Copy link
Member

This makes bn_correct_top use constant time code
if BN_FLG_CONSTTIME is set. Together with the
fact, that BN_bn2binpad is already constant time,
if this flag is set, this should eliminate the
timing oracle completely.

Use that to make BN_BLINDING_invert_ex not reveal
the leading zero limbs in the result.

@bernd-edlinger bernd-edlinger added the branch: 3.1 Merge to openssl-3.1 label Feb 14, 2023
@github-actions github-actions bot added the severity: fips change The pull request changes FIPS provider sources label Feb 14, 2023
@tomato42
Copy link
Contributor

blocked on #20281: we first need to verify that it's fixed on at least one branch before backporting it

This is about a timing leak in the topmost limb
of the internal result of RSA_private_decrypt,
before the padding check.

There are in fact at least three bugs together that
caused the timing leak:

First and probably most important is the fact that
the blinding did not use the constant time code path
at all when the RSA object was used for a private
decrypt, due to the fact that the Montgomery context
rsa->_method_mod_n was not set up early enough in
rsa_ossl_private_decrypt, when BN_BLINDING_create_param
needed it, and that was persisted as blinding->m_ctx,
although the RSA object creates the Montgomery context
just a bit later.

Then the infamous bn_correct_top was used on the
secret value right after the blinding was removed.

And finally the function BN_bn2binpad did not use
the constant-time code path since the BN_FLG_CONSTTIME
was not set on the secret value.

In order to address the first problem, this patch
makes sure that the rsa->_method_mod_n is initialized
right before the blinding context.

And to fix the second problem, we add a new utility
function bn_correct_top_consttime, a const-time
variant of bn_correct_top.

Together with the fact, that BN_bn2binpad is already
constant time if the flag BN_FLG_CONSTTIME is set,
this should eliminate the timing oracle completely.

In addition the no-asm variant may also have
branches that depend on secret values, because the last
invocation of bn_sub_words in bn_from_montgomery_word
had branches when the function is compiled by certain
gcc compiler versions, due to the clumsy coding style.

So additionally this patch stream-lined the no-asm
C-code in order to avoid branches where possible and
improve the resulting code quality.
@paulidale paulidale added the approval: review pending This pull request needs review by a committer label Apr 3, 2023
@t8m t8m added approval: review pending This pull request needs review by a committer triaged: bug The issue/pr is/fixes a bug triaged: refactor The issue/pr requests/implements refactoring tests: exempted The PR is exempt from requirements for testing hold: need otc decision The OTC needs to make a decision and removed approval: review pending This pull request needs review by a committer labels Apr 3, 2023
@t8m t8m added approval: done This pull request has the required number of approvals and removed approval: review pending This pull request needs review by a committer labels Apr 3, 2023
@t8m
Copy link
Member

t8m commented Apr 3, 2023

OTC question: Is this a bug fix? Should it be merged to released branches?

@t8m t8m removed the hold: need otc decision The OTC needs to make a decision label Apr 4, 2023
@t8m
Copy link
Member

t8m commented Apr 4, 2023

OTC: It is ok to merge this to 3.1.

@openssl-machine
Copy link
Collaborator

24 hours has passed since 'approval: done' was set, but as this PR has been updated in that time the label 'approval: ready to merge' is not being automatically set. Please review the updates and set the label manually.

@t8m
Copy link
Member

t8m commented Apr 4, 2023

Merged to 3.1 branch. Thank you for your contribution.

@t8m t8m closed this Apr 4, 2023
openssl-machine pushed a commit that referenced this pull request Apr 4, 2023
This reverts commit 8022a47.

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #20282)
openssl-machine pushed a commit that referenced this pull request Apr 4, 2023
This is about a timing leak in the topmost limb
of the internal result of RSA_private_decrypt,
before the padding check.

There are in fact at least three bugs together that
caused the timing leak:

First and probably most important is the fact that
the blinding did not use the constant time code path
at all when the RSA object was used for a private
decrypt, due to the fact that the Montgomery context
rsa->_method_mod_n was not set up early enough in
rsa_ossl_private_decrypt, when BN_BLINDING_create_param
needed it, and that was persisted as blinding->m_ctx,
although the RSA object creates the Montgomery context
just a bit later.

Then the infamous bn_correct_top was used on the
secret value right after the blinding was removed.

And finally the function BN_bn2binpad did not use
the constant-time code path since the BN_FLG_CONSTTIME
was not set on the secret value.

In order to address the first problem, this patch
makes sure that the rsa->_method_mod_n is initialized
right before the blinding context.

And to fix the second problem, we add a new utility
function bn_correct_top_consttime, a const-time
variant of bn_correct_top.

Together with the fact, that BN_bn2binpad is already
constant time if the flag BN_FLG_CONSTTIME is set,
this should eliminate the timing oracle completely.

In addition the no-asm variant may also have
branches that depend on secret values, because the last
invocation of bn_sub_words in bn_from_montgomery_word
had branches when the function is compiled by certain
gcc compiler versions, due to the clumsy coding style.

So additionally this patch stream-lined the no-asm
C-code in order to avoid branches where possible and
improve the resulting code quality.

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #20282)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approval: done This pull request has the required number of approvals branch: 3.1 Merge to openssl-3.1 severity: fips change The pull request changes FIPS provider sources tests: exempted The PR is exempt from requirements for testing triaged: bug The issue/pr is/fixes a bug triaged: refactor The issue/pr requests/implements refactoring
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants