-
Notifications
You must be signed in to change notification settings - Fork 111
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
RSA key check consolidation part 1a #1349
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #1349 /- ##
==========================================
- Coverage 76.89% 76.85% -0.04%
==========================================
Files 425 425
Lines 71527 71614 87
==========================================
Hits 55000 55040 40
- Misses 16527 16574 47 ☔ View full report in Codecov by Sentry. |
ca05c66
to
a9dfbc4
Compare
a9dfbc4
to
ad028da
Compare
// - 1 < log(e, 2) <= 33, | ||
// - n and e are odd, | ||
// - n > e. | ||
static int is_public_component_of_rsa_key_good(const RSA *key) { |
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.
why not keep rsa_check_public_key
?
https://github.com/aws/aws-lc/blob/main/crypto/fipsmodule/rsa/rsa_impl.c#L76
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.
I wanted to start with a clean slate so that we can clearly define the requirements, implement, and properly document them (I think part of the reason for the current mess is updating different functions over time without proper documentation and checking where and how they are used). Once the new key checking functions are done I intend to delete the old ones.
return 0; | ||
} | ||
|
||
if (!BN_is_odd(key->n)) { |
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.
Why not keep comments from rsa_check_public_key()
?
https://github.com/aws/aws-lc/blob/main/crypto/fipsmodule/rsa/rsa_impl.c#L76
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.
added a comment.
// the limit based on the recommendations in: | ||
// - https://www.imperialviolet.org/2012/03/16/rsae.html | ||
// - https://www.imperialviolet.org/2012/03/17/rsados.html | ||
if (e_bits < 2 || e_bits > 33) { |
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.
Why not keep kMaxExponentBits
instead of 33?
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.
don't see a reason for that, the comment states 33 explicitly and also justifies it.
return 0; | ||
} | ||
|
||
if (!BN_is_odd(key->e)) { |
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.
Can be combined with the check above as in the original code.
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.
I know, but I like it more this way. I was also able to add a comment explaining why is e
odd.
return 0; | ||
} | ||
|
||
if (BN_ucmp(key->n, key->e) <= 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.
Isn't the original check which compares if (n_bits <= kMaxExponentBits) then error
more economical?
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.
this is pointless optimization in my opinion and it only makes it harder to reason about the code.
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.
The way I see it is that we already calculated n_bits. I think the check on n_bits <= kMaxExponentBits is not hard to read, if we also keep that constant name. What do you think?
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.
We agreed to leave it as is.
// | ||
// Note: see the rsa_key_type_for_checking enum for details on types of keys | ||
// the function can work with. | ||
int wip_do_not_use_rsa_check_key(const RSA *key) { |
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.
There is a "multi-prime" check in the original function (which I didn't dive into); will we replace it here or in another 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.
not sure what you mean by multi-prime check?
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.
Sorry, I cannot find where I was looking, maybe an old version. multi-prime was removed from aws-lc (boringssl), I believe starting here 4a2cc28
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.
ah yeah, we don't support multi-prime RSA (OpenSSL does).
// (n, e, d, p, q, dmp1, dmq1, iqmp) | ||
if (key->d != NULL && key->p != NULL && key->q != NULL && | ||
key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { | ||
return RSA_KEY_TYPE_FOR_CHECKING_PRIVATE_CRT; |
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.
Do we want to handle the special case of returning RSA_R_INCONSISTENT_SET_OF_CRT_VALUES
as in
aws-lc/crypto/fipsmodule/rsa/rsa.c
Lines 872 to 877 in 023d157
int has_crt_values = key->dmp1 != NULL; | |
if (has_crt_values != (key->dmq1 != NULL) || | |
has_crt_values != (key->iqmp != NULL)) { | |
OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES); | |
goto out; | |
} |
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.
I was thinking about that but decided not to (OpenSSL doesn't have this error either, in fact, they'll allow inconsistent set of CRT values).
return 0; | ||
} | ||
|
||
if (BN_ucmp(key->n, key->e) <= 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.
We agreed to leave it as is.
// Keys that reach this point are either private keys (n, e, p, q, d), | ||
// or CRT keys with (dmp1, dmq1, iqmp) values precomputed. |
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.
Should we check that key_type
matches this assumption? It would be more for the unlikely event we were to add another key type to the enum but don't update any check logic.
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.
good idea, added
// - dmp1 == d mod (p - 1), | ||
// - dmq1 == d mod (q - 1), | ||
// - (iqmp * q) mod (p) == 1. |
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.
Do we actually use any of these CRT parameters in RSA key operations?
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.
yes, take a look here https://github.com/aws/aws-lc/blob/main/crypto/fipsmodule/rsa/rsa_impl.c#L792, the modular exponentiation function mod_exp
uses the CRT parameters. RSA private key operations are very slow if you don't use them.
Issues:
CryptoAlg-2280
Description of changes:
This is the first PR in a series of PRs that will attempt to
consolidate the RSA key checking in AWS-LC. The high level
plan is to do the following:
RSA_check_key|
that performs checks equivalent tothose in OpenSSL 1.x versions and 3.x non-FIPS versions of
RSA_check_key
with the exception of the primality tests, whileretaining the ability to process public keys.
RSA_check_fips
that performs SP 800-56b checksas OpenSSL 3.x
RSA_check_key
does when built in FIPS mode.RSA_check_key
function to callRSA_check_fips
when AWS-LC is built in FIPS mode,and deprecate
RSA_check_fips
.Two temporary functions will be introduced and used for development,
until the whole solution is done:
wip_do_not_use_rsa_check_key
,wip_do_not_use_rsa_check_key_fips
.After completing step 1 from above,
wip_do_not_use_rsa_check_key
should become
RSA_check_key
function.After completing step 2 from above,
wip_do_not_use_rsa_check_key_fips
should become
RSA_check_fips
function.After completing step 3 from above,
RSA_check_key
function shouldperform the
RSA_check_fips
checks when built in FIPS mode, andRSA_check_fips
could be deprecated.This change introduces the two temporary functions, implements a few
checks and adds tests alongside the existing tests for
RSA_check_key
.Call-outs:
Point out areas that need special attention or support during the review process. Discuss architecture or design changes.
Testing:
How is this change tested (unit tests, fuzz tests, etc.)? Are there any testing steps to be verified by the reviewer?
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.