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
Improve FIPS RSA keygen performance - change BN_gcd() test #19578
Conversation
e87a547
to
3589be5
Compare
3589be5
to
84368aa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice optimization, Shane!
My primary concern is that
These points can be addressed easily enough but will cost some performance.
|
I would like to see even a theoretical attack on this BN_mod_inverse use in the RSA keygen. How would it work given the key is generated once so there is no real chance for the attacker to do repeated measurement to gather some statistics. But yeah, if making BN_mod_inverse consttime would not cost much, it would make sense. |
If this attack were only theoretical, why did we go to such lengths to be constant time in the BN mod function for keygen? I'm not saying it's exploitable, just that we need to be cautious. |
@t8m These seem to be very closely related:
|
If the attacker can probe the keygen process often enough (either through power side channel or through microarchitecutral means), they may be able to deduce exact code path taken That being said, this:
is calling BN_mod_inverse twice over the same arguments, so if inverse is leaky in an exploitable way, it's a problem already, and this change doesn't make the situation worse. The second change is much harder to say if it makes the code more vulnerable or not. |
Do you think it would be useful to have a public symbol BN_gcd_isone()? |
Not sure if anyone noticed the comment related to the default provider. i.e the multi prime keygen already uses the inverse instead of BN_gcd() - so this has been used like this for quite a long time. |
I think we should expose it as a |
What am I supposed to do with the tmp inv param? I was trying to avoid allocating it internally? (add it as an optional last param?) |
|
Needs rebase or putting the libcrypto.num entry at some more clever place 😁 |
FIPS 186-4 has 5 different algorithms for key generation, and all of them rely on testing GCD(a,n) == 1 many times. Cachegrind was showing that during a RSA keygen operation, the function BN_gcd() was taking a considerable percentage of the total cycles. The default provider uses multiprime keygen, which seemed to be much faster. This is because it uses BN_mod_inverse() instead. For a 4096 bit key, the entropy of a key that was taking a long time to generate was recorded and fed back into subsequent runs. Roughly 40% of the cycle time was BN_gcd() with most of the remainder in the prime testing. Changing to use the inverse resulted in the cycle count being 96% in the prime testing.
e523224
to
a245a89
Compare
This pull request is ready to merge |
@paulidale please reconfirm |
@@ -5481,3 +5481,4 @@ BIO_f_zstd ? 3_2_0 EXIST::FUNCTION:COMP | |||
d2i_PUBKEY_ex_fp ? 3_2_0 EXIST::FUNCTION:STDIO | |||
d2i_PUBKEY_ex_bio ? 3_2_0 EXIST::FUNCTION: | |||
COMP_zlib_oneshot ? 3_2_0 EXIST::FUNCTION:COMP | |||
BN_are_coprime ? 3_2_0 EXIST::FUNCTION: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So - 3_1_0 or 3_2_0 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3_1_0. I'll fix it when merging.
This pull request is ready to merge |
FIPS 186-4 has 5 different algorithms for key generation, and all of them rely on testing GCD(a,n) == 1 many times. Cachegrind was showing that during a RSA keygen operation, the function BN_gcd() was taking a considerable percentage of the total cycles. The default provider uses multiprime keygen, which seemed to be much faster. This is because it uses BN_mod_inverse() instead. For a 4096 bit key, the entropy of a key that was taking a long time to generate was recorded and fed back into subsequent runs. Roughly 40% of the cycle time was BN_gcd() with most of the remainder in the prime testing. Changing to use the inverse resulted in the cycle count being 96% in the prime testing. Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from #19578)
Merged to master and 3.1 branches (after fixing the version in libcrypto.num entry). Thank you. |
FIPS 186-4 has 5 different algorithms for key generation, and all of them rely on testing GCD(a,n) == 1 many times. Cachegrind was showing that during a RSA keygen operation, the function BN_gcd() was taking a considerable percentage of the total cycles. The default provider uses multiprime keygen, which seemed to be much faster. This is because it uses BN_mod_inverse() instead. For a 4096 bit key, the entropy of a key that was taking a long time to generate was recorded and fed back into subsequent runs. Roughly 40% of the cycle time was BN_gcd() with most of the remainder in the prime testing. Changing to use the inverse resulted in the cycle count being 96% in the prime testing. Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from #19578) (cherry picked from commit dd1d7bc)
FIPS 186-4 has 5 different algorithms for key generation, and all of them rely on testing GCD(a,n) == 1 many times. Cachegrind was showing that during a RSA keygen operation, the function BN_gcd() was taking a considerable percentage of the total cycles. The default provider uses multiprime keygen, which seemed to be much faster. This is because it uses BN_mod_inverse() instead. For a 4096 bit key, the entropy of a key that was taking a long time to generate was recorded and fed back into subsequent runs. Roughly 40% of the cycle time was BN_gcd() with most of the remainder in the prime testing. Changing to use the inverse resulted in the cycle count being 96% in the prime testing. Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from openssl#19578)
FIPS 186-4 has 5 different algorithms for key generation, and all of them rely on testing GCD(a,n) == 1 many times.
Cachegrind was showing that the function BN_gcd() was taking a considerable percentage of the total cycles, during a rsa keygen operation.
The default provider uses multiprime keygen, which seemed to be much faster. This is because it uses BN_mod_inverse() instead.
For a 4096 bit key, the entropy of a key that was taking a long time to generate was recorded and fed back into subsequent runs. Roughly 40% of the cycle time was BN_gcd() with most of the remainder in the prime testing. Changing to use the inverse resulted in the cyle count being 96% in the prime testing.
Checklist