Tongsuo-Project / Tongsuo

铜锁/Tongsuo is a Modern Cryptographic Primitives and Protocols Library
https://www.tongsuo.net
Apache License 2.0
1.16k stars 186 forks source link

Alternative fix for CVE-2022-4304 #668

Open dongbeiouba opened 3 weeks ago

dongbeiouba commented 3 weeks ago

Revert "Fix Timing Oracle in RSA decryption"

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.

Checklist