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

Require matching hashlen in RSA functions: implementation #4707

Conversation

gilles-peskine-arm
Copy link
Contributor

@gilles-peskine-arm gilles-peskine-arm commented Jun 22, 2021

RSA and PK signature function that take both a hash parameter and a hashlen or hash_len parameter now require the length parameter to be the length of the input. If there is additional information about the hash algorithm and the length does not match, the functions return an error instead of silently ignoring the length parameter.

Continuation of #4665 and #4702, will need to be rebased when #4665 is merged.

yanesca and others added 9 commits June 21, 2021 10:39
Hashes used in RSA-PSS encoding (EMSA-PSS-ENCODE, see §9.1.1 in RFC
8017):

- H1: Hashing the message (step 2)
- H2: Hashing in the salt (step 6)
- H3: Mask generation function (step 9)

According to the standard:

- H1 and H2 MUST be done by the same hash function
- H3 is RECOMMENDED to be the same as the hash used for H1 and H2.

According to the implementation:

- H1 happens outside of the function call. It might or might not happen
and the implementation might or might not be aware of the hash used.
- H2 happens inside the function call, consistency with H1 is not
enforced and might not even be possible to detect.
- H3 is done with the same hash as H2 (with the exception of
mbedtls_rsassa_pss_verify_ext(), which takes a dedicated parameter for
the hash used in the MGF).

Issues with the documentation:

- The comments weren't always clear about the three hashes involved and
often only mentioned two of them (which two varied from function to
function).
- The documentation was giving the impression that the standard
recommends aligning H2 and H1 (which is not a recommendation but a
must).

Signed-off-by: Janos Follath <janos.follath@arm.com>
PSA Crypto always passed MBEDTLS_MD_NONE to Mbed TLS, which worked well
as Mbed TLS does not use this parameter for anything beyond determining
the input lengths.

Some alternative implementations however check the consistency of the
algorithm used for pre-hash and for other uses in verification (verify
operation and mask generation) and fail if they don't match. This makes
all such verifications fail.

Furthermore, the PSA Crypto API mandates that the pre-hash and internal
uses are aligned as well.

Fixes Mbed-TLS#3990.

Signed-off-by: Janos Follath <janos.follath@arm.com>
The psa_verify_hash() is the pre-hashed version of the API and supposed
to work on hashes generated by the user. There were tests passing that
were getting "hashes" of sizes different from the expected.

Transform these into properly failing tests.

Signed-off-by: Janos Follath <janos.follath@arm.com>
Hash and sign algorithms require the alignment of the input length with
the hash length at verification as well not just when signing.

Signed-off-by: Janos Follath <janos.follath@arm.com>
Signed-off-by: Janos Follath <janos.follath@arm.com>
Remove a case that cannot be triggered as PSA_ALG_SIGN_GET_HASH always
returns 0 for raw algorithms.

Signed-off-by: Janos Follath <janos.follath@arm.com>
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Where hashlen was previously ignored when the hash length could be
inferred from an md_alg parameter, the two must now match.

Adapt the existing tests accordingly. Adapt the sample programs accordingly.

This commit does not add any negative testing.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
@gilles-peskine-arm gilles-peskine-arm added enhancement component-crypto Crypto primitives and low-level interfaces needs-ci Needs to pass CI tests mbedtls-3 size-s Estimated task size: small (~2d) labels Jun 22, 2021
@gilles-peskine-arm gilles-peskine-arm added needs-preceding-pr Requires another PR to be merged first needs-review Every commit must be reviewed by at least two team members, needs-reviewer This PR needs someone to pick it up for review and removed needs-ci Needs to pass CI tests labels Jun 22, 2021
Copy link
Contributor

@mpg mpg left a comment

Choose a reason for hiding this comment

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

This looks good to me.

I'm closing #4702 in favour of this PR in order to avoid diluting or review effort and having dependency chains, as this PR is no more risky than #4702 considering it passed CI.

I'm not closing #4665 now because it has an associated 2.x backport.

We should probably also close #4561 as the changes in this PR are a superset what it does, but someone should probably still backport the relevant parts of #4561 to 2.x and 2.16. In the interest of speed, I suggest you do it rather than the original contributor. If you agree, please close #4561 and let its author know what's going on.

@@ -2031,6 +2032,8 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg,
* TAG-NULL + LEN [ NULL ] ]
* TAG-OCTET + LEN [ HASH ] ]
*/
if( 0x08 + oid_size + hashlen >= 0x80 )
Copy link
Contributor

Choose a reason for hiding this comment

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

Note: I'm not sure how that is related to the hashlen work. I this is an independent hardening, we should probably backport it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now that the functions have a clearly defined input length, I wanted to make the code robust to changes that could result in accepting different input lengths (for example, one day this code might run on a long SHAKE output). That meant checking that hashlen fits, regardless of any assumption we might make on hashes being small enough.

Indeed I think this change should be backported.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The backports don't need to hold up the upcoming release. Filed as a Q3 tech debt item in #4722

Copy link
Contributor

@davidhorstmann-arm davidhorstmann-arm Jul 8, 2021

Choose a reason for hiding this comment

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

Hmm
Should this check be backported?
If md_alg == MBEDTLS_MD_NONE then we never reach it because we've already returned (in 2019), and if md_alg != MBEDTLS_MD_NONE then we have already performed this check in 1974, and neither hashlen nor oid_size have changed since.
Have I missed something here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I (and the reviewers of this PR) missed that the check was already done earlier. So instead of backporting it, please make a PR on development to remove the redundant check!

Copy link
Contributor

Choose a reason for hiding this comment

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

As a matter of fact, I noticed the check was already done earlier but noticed it was inside a conditional, and didn't go to the next step and failed to notice that this path was always taken if we ever get to the point where the new check was added. Should probably have said something, though. Thanks @davidhorstmann-arm for noticing.

@@ -611,7 +612,8 @@ void pk_sign_verify( int type, int parameter, int sign_ret, int verify_ret )
{
mbedtls_pk_context pk;
size_t sig_len;
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
unsigned char hash[32]; // Hard-coded for SHA256
Copy link
Contributor

Choose a reason for hiding this comment

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

Note: this is very similar to the second commit of #4561 - so perhaps we can close #4561 in favour of this one ? (But probably still backport the relevant parts of #4561, see my comments there.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't look at #4561 while writing this, I'll take a look after #4665 is merged and I've rebased this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Since #4561 is a community PR and this PR (#4707) needs rebasing anyway, I think we could merge #4561 quickly and wait with rebasing #4707 until then. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

#4561 is a behavior change where #4707 changes the behavior again, plus some testing improvements. I think it would be easier to put #4707 first and then make a version of #4561 with just the testing improvements, and perhaps some implementation improvements in pk.c, but no behavior change.

@gilles-peskine-arm gilles-peskine-arm added this to the 3.0 milestone Jun 23, 2021
@tom-daubney-arm tom-daubney-arm self-requested a review June 23, 2021 10:41
@tom-daubney-arm tom-daubney-arm removed the needs-reviewer This PR needs someone to pick it up for review label Jun 23, 2021
Copy link
Contributor

@tom-daubney-arm tom-daubney-arm left a comment

Choose a reason for hiding this comment

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

No issues. This all LGTM. Thanks.

davidhorstmann-arm added a commit to davidhorstmann-arm/mbedtls that referenced this pull request Jul 8, 2021
Remove a check in rsa_rsassa_pkcs1_v15_encode() that
is not needed because the same check is performed
earlier. This check was added in Mbed-TLS#4707.

Signed-off-by: David Horstmann <david.horstmann@arm.com>
@bensze01 bensze01 modified the milestones: 3.0, Mbed TLS 4.0 Jul 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component-crypto Crypto primitives and low-level interfaces enhancement needs-preceding-pr Requires another PR to be merged first needs-review Every commit must be reviewed by at least two team members, size-s Estimated task size: small (~2d)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants