Skip to content

Comments

Limit size of modulus for bn_mul_mont and BN_mod_exp_mont_consttime#19735

Closed
bernd-edlinger wants to merge 1 commit intoopenssl:OpenSSL_1_1_1-stablefrom
bernd-edlinger:limit_alloca_size_in_bn_mod_mul
Closed

Limit size of modulus for bn_mul_mont and BN_mod_exp_mont_consttime#19735
bernd-edlinger wants to merge 1 commit intoopenssl:OpenSSL_1_1_1-stablefrom
bernd-edlinger:limit_alloca_size_in_bn_mod_mul

Conversation

@bernd-edlinger
Copy link
Member

Otherwise the alloca can cause an exception.

Issue reported by Jiayi Lin.

Checklist
  • documentation is added or updated
  • tests are added or updated

@bernd-edlinger bernd-edlinger added the branch: 1.1.1 Applies to OpenSSL_1_1_1-stable branch (EOL) label Nov 22, 2022
@bernd-edlinger
Copy link
Member Author

The intention of this is limit the stack usage to ~4K
BN_SIZE_LIMIT is a soft limit equivalent to 2 * OPENSSL_RSA_MAX_MODULUS_BITS.
Beyond that size bn_mul_mont is no longer used, and the constant time
code is disabled, due to the blatant alloca and bn_mul_mont usage.

@t8m
Copy link
Member

t8m commented Nov 23, 2022

Could you please submit the patch against master branch also reverting the recent limit change in BN_mod_exp_mont_consttime there?

@t8m t8m added triaged: bug The issue/pr is/fixes a bug hold: wait for master The pull request must wait for approval of the equivalent change on master labels Nov 23, 2022
@bernd-edlinger
Copy link
Member Author

I think this needs a comment first.

/* #define BN_DEBUG */
/* #define BN_DEBUG_RAND */

#define BN_SIZE_LIMIT (4096 / BN_BYTES)
Copy link
Member

Choose a reason for hiding this comment

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

BN_CONSTTIME_SIZE_LIMIT or BN_MONT_CONSTTIME_SIZE_LIMIT?

Copy link
Member Author

Choose a reason for hiding this comment

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

BN_SIZE_LIMIT feels right, as @davidben pointed out also BN_mod_exp and BN_mod_exp_mont will eventually call
bn_mul_mont_fixed_top and thus bn_mul_mont, so it is neither specific to consttime nor montgomery at all.
Actutally the whole issue starts to look a lot less harmless than in the beginning.

Copy link
Member

Choose a reason for hiding this comment

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

Then BN_MONT_SIZE_LIMIT?

Copy link
Member

Choose a reason for hiding this comment

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

Unless this limit applies to all BN operations it should not be called BN_SIZE_LIMIT.

Copy link
Member Author

Choose a reason for hiding this comment

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

It is more the upper bound on the stack allocation of any BN operation we are willing to allow.
It also affects BN_mod_exp and BN_mod_sqrt.
Note: there are many call sites of the affected functions, especially of BN_mod_exp,
but not all of them seem to sanity check the input parameters.
If the modulus is a large enough odd number, a stack overflow will probably happen unexpectedly


if (top > BN_SIZE_LIMIT) {
/* Prevent overflowing the powerbufLen computation below */
return BN_mod_exp_mont(rr, a, p, m, ctx, in_mont);
Copy link
Contributor

Choose a reason for hiding this comment

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

Having a function that's explicitly about treating the exponent as secret then fallback to a function which doesn't seems poor. It seems better to just make the operation fail at this point.

Additionally, both these operations actually have comparable memory requirements anyway, because they're both windowed exponentiations. It's just that this one happens to allocate the memory contiguously, while BN_mod_exp_mont happens to just make a bunch of BIGNUMs. (Well, slightly less memory usage because, by using a sliding window, the public exponent variant is able to halve the table size, since you only need odd powers.)

The fallback from bn_mul_mont is more defensible, though I'd personally still just declare this is the limit for Montgomery reduction so there aren't extra codepaths to test and such.

Copy link
Member Author

Choose a reason for hiding this comment

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

The rationale is this:
I dont think there is any valid cryptographic reason for doing computations with such large moduli,
RSA is limited 16384 bits, DH and DSA is limited to 10000 bits for a good reason.
It is much more likely that someone was tricked into calling this function with some bogus values
because doing this is likely to cause a stack overflow.
However, it is a clear ABI break to return an error when previously this function might have succeeded.
On the other hand, it is easy to configure with ./config -DBN_SIZE_LIMIT=1000000 if you are fine
with a stack allocation of 1MB or more.

Copy link
Member Author

Choose a reason for hiding this comment

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

Having a function that's explicitly about treating the exponent as secret

by the way, the number of bits in the exponent is not a secret at all.
I kind of assumed that the while loop down below uses the number of bits in the modulus,
but now i see it takes a short cut if the exponent is much smaller than the modulus.

Copy link
Member Author

@bernd-edlinger bernd-edlinger Nov 29, 2022

Choose a reason for hiding this comment

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

I dont think there is any valid cryptographic reason for doing computations with such large moduli,

Well, one exception came just into my mind: I think I remember having read once a paper where researchers
did multiply the moduli of lots of publically available RSA certificates, forming huge composite numbers, and
doing GCD to find common divisors between them, And in deed that did result in some common primes
that were the result of poor random number generators.

However I doubt that they did consider using openssl for such computations, sinve there are better suited
math programs for math with such huge numbers. And moreover I doubt that I would call such use a
legitimate cryptographic use.

And doing this kind of math is not safe either, since currently all openssl versions might crash unexpectedly
with such computations, or will just be not optimized for use with such numbers if this PR gets merged.
But I wouldn't rule out the possibility that a future openssl version will turn this soft limit into a hard limit.

@bernd-edlinger
Copy link
Member Author

I've addressed the review comments.
There is now a BN_SIZE_LIMIT which only limits the stack usage,
in constant time and non-constant time code,
and a new BN_CONSTTIME_SIZE_LIMIT which has the same value
as the limit in #19647:
values larger than this limit do not get computed in constant time.

Comment on lines 38 to 56
/*
* This should limit the stack usage due to alloca to about 4K.
* BN_SIZE_LIMIT is a soft limit equivalent to 2*OPENSSL_RSA_MAX_MODULUS_BITS.
* Beyond that size bn_mul_mont is no longer used, and the constant time
* assembler code is disabled, due to the blatant alloca and bn_mul_mont usage.
* Note that bn_mul_mont does an alloca that is hidden away in assembly.
*/
# ifndef BN_SIZE_LIMIT
# define BN_SIZE_LIMIT (4096 / BN_BYTES)
# endif
Copy link
Member

Choose a reason for hiding this comment

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

As this is not hard size limit I'd still like to see a different name. BN_STACK_SIZE_LIMIT?

Copy link
Member Author

Choose a reason for hiding this comment

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

I have extended the comment:
It is not recommended to do computations with numbers exceeding this limit,
since the result will be highly version dependent:
While the current OpenSSL version will use non-optimized, but safe code,
previous versions will use optimized code, that may crash due to unexpected
stack overflow, and future versions may very well turn this into a hard
limit.
Note however, that it is possible to override the size limit using
"./config -DBN_SITE_LIMIT=" if necessary, and the O/S specific
stack limit is known and taken into consideration.

Copy link
Member

Choose a reason for hiding this comment

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

I'd still like to see a different name for the macro. The current one is totally misleading.

Copy link
Member Author

Choose a reason for hiding this comment

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

Could we agree on BN_SOFT_LIMIT ?

Copy link
Member

Choose a reason for hiding this comment

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

That would be fine with me.

@bernd-edlinger bernd-edlinger force-pushed the limit_alloca_size_in_bn_mod_mul branch from 26267e3 to 6643ed9 Compare December 2, 2022 13:31
@bernd-edlinger bernd-edlinger force-pushed the limit_alloca_size_in_bn_mod_mul branch 2 times, most recently from d71a9e1 to da371a4 Compare December 21, 2022 16:43
@bernd-edlinger bernd-edlinger force-pushed the limit_alloca_size_in_bn_mod_mul branch from da371a4 to c7f93ef Compare January 2, 2023 08:38
Otherwise the alloca can cause an exception.

Issue reported by Jiayi Lin.
@bernd-edlinger bernd-edlinger force-pushed the limit_alloca_size_in_bn_mod_mul branch from c7f93ef to 4f68d0d Compare January 6, 2023 18:37
@t8m t8m added the approval: review pending This pull request needs review by a committer label Jan 9, 2023
@paulidale paulidale added approval: done This pull request has the required number of approvals and removed approval: review pending This pull request needs review by a committer labels Jan 10, 2023
@openssl-machine openssl-machine added approval: ready to merge The 24 hour grace period has passed, ready to merge and removed approval: done This pull request has the required number of approvals labels Jan 11, 2023
@openssl-machine
Copy link
Collaborator

This pull request is ready to merge

@bernd-edlinger bernd-edlinger removed the hold: wait for master The pull request must wait for approval of the equivalent change on master label Jan 14, 2023
@bernd-edlinger
Copy link
Member Author

Removing the hold, since #20005 has been merged.

openssl-machine pushed a commit that referenced this pull request Jan 14, 2023
Otherwise the alloca can cause an exception.

Issue reported by Jiayi Lin.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from #19735)
@bernd-edlinger
Copy link
Member Author

Merged to 1.1.1 as 5bbd921.
Thanks everybody for all the helpful review comments!

bernd-edlinger added a commit to bernd-edlinger/openssl that referenced this pull request Jan 27, 2023
Otherwise the alloca can cause an exception.

Issue reported by Jiayi Lin.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl#19735)

(cherry picked from commit 5bbd921)
bernd-edlinger added a commit to bernd-edlinger/openssl that referenced this pull request Jan 27, 2023
Otherwise the alloca can cause an exception.

Issue reported by Jiayi Lin.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl#19735)

(cherry picked from commit 5bbd921)
bernd-edlinger added a commit to bernd-edlinger/openssl that referenced this pull request Jan 27, 2023
Otherwise the alloca can cause an exception.

Issue reported by Jiayi Lin.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl#19735)

(cherry picked from commit 5bbd921)
a-kromm-rogii pushed a commit to a-kromm-rogii/openssl that referenced this pull request Mar 14, 2025
Otherwise the alloca can cause an exception.

Issue reported by Jiayi Lin.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl#19735)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval: ready to merge The 24 hour grace period has passed, ready to merge branch: 1.1.1 Applies to OpenSSL_1_1_1-stable branch (EOL) triaged: bug The issue/pr is/fixes a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants