Skip to content

Comments

Fix crash(es) in RSA_padding_add_PKCS1_PSS_mgf1#2699

Closed
guidovranken wants to merge 2 commits intoopenssl:masterfrom
guidovranken:RSA_padding_add_PKCS1_PSS_mgf1-fix
Closed

Fix crash(es) in RSA_padding_add_PKCS1_PSS_mgf1#2699
guidovranken wants to merge 2 commits intoopenssl:masterfrom
guidovranken:RSA_padding_add_PKCS1_PSS_mgf1-fix

Conversation

@guidovranken
Copy link
Contributor

Checklist
Description of change

This patch adds a number of checks that ought to ensure that there is not a single addition or subtraction operation in RSA_padding_add_PKCS1_PSS_mgf1 that results in unwanted behavior.

For example, before this fix

openssl dgst -sigopt rsa_padding_mode:pss -sign private.pem  ....

results in a crash if private.pem is a serialization of an RSA structure whose "N" parameter is "1".

…o integer addition or subtraction results in overflows or OOB memory access
@guidovranken
Copy link
Contributor Author

This affects both 1.0.2 and 1.1.0.

Copy link
Contributor

@richsalz richsalz left a comment

Choose a reason for hiding this comment

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

Looks okay to me, but ping @snhenson

@richsalz richsalz self-assigned this Feb 21, 2017
@richsalz richsalz added branch: 1.0.2 Applies to OpenSSL_1_0_2-stable branch (EOL) 1.1.0 branch: master Applies to master branch labels Feb 21, 2017
Copy link
Member

@levitte levitte left a comment

Choose a reason for hiding this comment

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

Other than the nit pick, looks fine to me

emLen < (hLen + sLen + 2)) {
RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
Copy link
Member

Choose a reason for hiding this comment

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

Nit pick: remove the extra indent

Copy link
Member

Choose a reason for hiding this comment

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

Doesn't now look the RSA_padding_add_PKCS1_PSS_mgf1 look completely different than
RSA_verify_PKCS1_PSS_mgf1 ?

if (RAND_bytes(salt, sLen) <= 0)
goto err;
}
if (hLen < 1 || hLen - 1 > emLen)
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand the condition. Can you explain what you want to test 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.

The next line is emLen - hLen - 1.

So let's say that hLen is 0. Subtracting 1 from it makes it negative. This has to be avoided. This explains the first condition.

As for the second condition, let's say hLen - 1 resolves to a value larger than emLen. Then the computation emLen - hLen - 1 yields a negative value. Perhaps I should change the > in the second condition to >=.

Note: I didn't check whether any of my checks can be true in any case. For example I didn't check if hLen can actually be 0 at this point. I implemented the checks so that there can be no doubt over over/underflows.

Copy link
Member

@bernd-edlinger bernd-edlinger Feb 27, 2017

Choose a reason for hiding this comment

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

so you want to predict if "emLen - hLen - 1" will be negative.
but algebraically this is transforms like follows:
emLen - hLen - 1 < 0
emLen < hLen + 1

IOW hLen + 1 > emLen

Copy link
Member

@bernd-edlinger bernd-edlinger Feb 27, 2017

Choose a reason for hiding this comment

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

But we not concerned about possible overflow here, I guess?
If that is the case all the algebra here wins nothing, and it would be
far more easy to test the condition directly on the result.

emLen--;
}
if (sLen == RSA_PSS_SALTLEN_MAX) {
if (hLen < 2 || hLen - 2 > emLen)
Copy link
Member

Choose a reason for hiding this comment

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

Here as well, maybe you meant hLen + 2 > emLen ?

goto err;
sLen = emLen - hLen - 2;
} else if (emLen < (hLen + sLen + 2)) {
} else if (sLen > INT_MAX - 2 - hLen ||
Copy link
Member

Choose a reason for hiding this comment

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

sLen needs to be much smaller, anything larger than emLen is obviously wrong.

goto err;
}

/* At this point, sLen is >= 0 */
Copy link
Member

Choose a reason for hiding this comment

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

Yes, that should be the case, but what happens if you try this:
openssl genrsa -out rsa.pem 512
openssl dgst -sign rsa.pem -sha512 -sigopt rsa_padding_mode:pss -hex < /dev/null

@richsalz
Copy link
Contributor

ping @levitte and @bernd-edlinger . status?

@bernd-edlinger
Copy link
Member

fixed on master by 108909d
fixed on 1.1.0 by e653b6c
fixed on 1.0.2 by 04cf392

@richsalz
Copy link
Contributor

Thanks for the info! Closing.

@richsalz richsalz closed this Jun 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

branch: master Applies to master branch branch: 1.0.2 Applies to OpenSSL_1_0_2-stable branch (EOL)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants