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

Fix handling of NULL sig parameter in ECDSA_sign and similar #23529

Conversation

bernd-edlinger
Copy link
Member

The problem is, that it almost works to pass sig=NULL to the ECDSA_sign, ECDSA_sign_ex and DSA_sign, to compute the necessary space for the resulting signature.
But since the ECDSA signature is non-deterministic (except when ECDSA_sign_setup/ECDSA_sign_ex are used) the resulting length may be different when the API is called again. This can easily cause random memory corruption.
Several internal APIs had the same issue, but since they are never called with sig=NULL, it is better to make them return an error in that case, instead of making the code more complex.

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

The problem is, that it almost works to pass sig=NULL to the
ECDSA_sign, ECDSA_sign_ex and DSA_sign, to compute the necessary
space for the resulting signature.
But since the ECDSA signature is non-deterministic
(except when ECDSA_sign_setup/ECDSA_sign_ex are used)
the resulting length may be different when the API is called again.
This can easily cause random memory corruption.
Several internal APIs had the same issue, but since they are
never called with sig=NULL, it is better to make them return an
error in that case, instead of making the code more complex.
The handling of sig=NULL was broken in this function, but since it
is only used internally and was never called with sig=NULL, it is
better to return an error in that case.
@bernd-edlinger bernd-edlinger added branch: master Merge to master branch branch: 3.0 Merge to openssl-3.0 branch branch: 3.1 Merge to openssl-3.1 branch: 3.2 Merge to openssl-3.2 labels Feb 8, 2024
@bernd-edlinger bernd-edlinger force-pushed the fix_handling_of_null_sig_in_ecdsa_sign branch from 6a93305 to 747343a Compare February 8, 2024 21:58
@bernd-edlinger
Copy link
Member Author

I've split the PR in two commits, the first one will cherry-pick to all branches, and the second one is for 3.2+master only.

@github-actions github-actions bot added the severity: fips change The pull request changes FIPS provider sources label Feb 8, 2024
crypto/ec/ecdsa_ossl.c Show resolved Hide resolved
@t8m t8m added triaged: bug The issue/pr is/fixes a bug tests: present The PR has suitable tests present approval: review pending This pull request needs review by a committer approval: otc review pending This pull request needs review by an OTC member labels Feb 9, 2024
@t8m t8m removed the approval: otc review pending This pull request needs review by an OTC member label Feb 9, 2024
@@ -157,6 +157,11 @@ int ossl_dsa_sign_int(int type, const unsigned char *dgst, int dlen,
{
DSA_SIG *s;

if (sig == NULL) {
Copy link
Member

Choose a reason for hiding this comment

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

would it be safe to move this code down below the legacy case (line 165-174)?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, I don't think so. Which branch is taken depends on the dsa object,
that is passed to DSA_sign()
only thing that is sure that both possible ways will not create a deterministic
signature, thus the correct thing to do is return the max. possible length here.

Copy link
Member

Choose a reason for hiding this comment

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

What I am asking is, is there any way that line 172 should be run instead of the code you now run when sig is NULL

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 dont see why, the user is just asking for the memory size he needs to allocate,
and of course any error may happen when the call is repeated with sig != NULL.
This replicates the code pattern how EVP_DigestSign is to be used:

EVP_DigestSignInit(md_ctx, NULL, EVP_sha256(), NULL, dsa);
EVP_DigestSign(md_ctx, NULL, &sig_len, tbs, tbs_len);
sig = (unsigned char*) OPENSSL_malloc(sig_len);
EVP_DigestSign(md_ctx, sig, &sig_len, tbs, tbs_len);

just with DSA_sign like this:

DSA_sign(NID_sha256, dgst, dgst_len, NULL, &sig_len, dsa);
sig = (unsigned char*) OPENSSL_malloc(sig_len);
DSA_sign(NID_sha256, dgst, dgst_len, sig, &sig_len, dsa);

Copy link
Contributor

@shahsb shahsb left a comment

Choose a reason for hiding this comment

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

LGTM

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/committers but the last update was 30 days ago

Copy link
Member

@beldmit beldmit left a comment

Choose a reason for hiding this comment

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

LGTM

@beldmit beldmit added approval: done This pull request has the required number of approvals branch: 3.3 Merge to openssl-3.3 and removed approval: review pending This pull request needs review by a committer labels Mar 27, 2024
@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 Mar 28, 2024
@openssl-machine
Copy link
Collaborator

This pull request is ready to merge

openssl-machine pushed a commit that referenced this pull request Apr 2, 2024
The problem is, that it almost works to pass sig=NULL to the
ECDSA_sign, ECDSA_sign_ex and DSA_sign, to compute the necessary
space for the resulting signature.
But since the ECDSA signature is non-deterministic
(except when ECDSA_sign_setup/ECDSA_sign_ex are used)
the resulting length may be different when the API is called again.
This can easily cause random memory corruption.
Several internal APIs had the same issue, but since they are
never called with sig=NULL, it is better to make them return an
error in that case, instead of making the code more complex.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #23529)

(cherry picked from commit 1fa2bf9)
openssl-machine pushed a commit that referenced this pull request Apr 2, 2024
The handling of sig=NULL was broken in this function, but since it
is only used internally and was never called with sig=NULL, it is
better to return an error in that case.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #23529)

(cherry picked from commit 294782f)
openssl-machine pushed a commit that referenced this pull request Apr 2, 2024
The problem is, that it almost works to pass sig=NULL to the
ECDSA_sign, ECDSA_sign_ex and DSA_sign, to compute the necessary
space for the resulting signature.
But since the ECDSA signature is non-deterministic
(except when ECDSA_sign_setup/ECDSA_sign_ex are used)
the resulting length may be different when the API is called again.
This can easily cause random memory corruption.
Several internal APIs had the same issue, but since they are
never called with sig=NULL, it is better to make them return an
error in that case, instead of making the code more complex.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #23529)

(cherry picked from commit 1fa2bf9)
openssl-machine pushed a commit that referenced this pull request Apr 2, 2024
The handling of sig=NULL was broken in this function, but since it
is only used internally and was never called with sig=NULL, it is
better to return an error in that case.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #23529)

(cherry picked from commit 294782f)
openssl-machine pushed a commit that referenced this pull request Apr 2, 2024
The problem is, that it almost works to pass sig=NULL to the
ECDSA_sign, ECDSA_sign_ex and DSA_sign, to compute the necessary
space for the resulting signature.
But since the ECDSA signature is non-deterministic
(except when ECDSA_sign_setup/ECDSA_sign_ex are used)
the resulting length may be different when the API is called again.
This can easily cause random memory corruption.
Several internal APIs had the same issue, but since they are
never called with sig=NULL, it is better to make them return an
error in that case, instead of making the code more complex.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #23529)
openssl-machine pushed a commit that referenced this pull request Apr 2, 2024
The handling of sig=NULL was broken in this function, but since it
is only used internally and was never called with sig=NULL, it is
better to return an error in that case.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #23529)
openssl-machine pushed a commit that referenced this pull request Apr 2, 2024
The problem is, that it almost works to pass sig=NULL to the
ECDSA_sign, ECDSA_sign_ex and DSA_sign, to compute the necessary
space for the resulting signature.
But since the ECDSA signature is non-deterministic
(except when ECDSA_sign_setup/ECDSA_sign_ex are used)
the resulting length may be different when the API is called again.
This can easily cause random memory corruption.
Several internal APIs had the same issue, but since they are
never called with sig=NULL, it is better to make them return an
error in that case, instead of making the code more complex.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #23529)

(cherry picked from commit 1fa2bf9)
@t8m
Copy link
Member

t8m commented Apr 2, 2024

Merged to all the active branches. (The deterministic ecdsa fix only to branches where this is present.) Thank you for your contribution.

@t8m t8m closed this Apr 2, 2024
openssl-machine pushed a commit that referenced this pull request Apr 2, 2024
The problem is, that it almost works to pass sig=NULL to the
ECDSA_sign, ECDSA_sign_ex and DSA_sign, to compute the necessary
space for the resulting signature.
But since the ECDSA signature is non-deterministic
(except when ECDSA_sign_setup/ECDSA_sign_ex are used)
the resulting length may be different when the API is called again.
This can easily cause random memory corruption.
Several internal APIs had the same issue, but since they are
never called with sig=NULL, it is better to make them return an
error in that case, instead of making the code more complex.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #23529)

(cherry picked from commit 1fa2bf9)
bernd-edlinger added a commit to bernd-edlinger/openssl that referenced this pull request Apr 5, 2024
The problem is, that it almost works to pass sig=NULL to the
ECDSA_sign, ECDSA_sign_ex and DSA_sign, to compute the necessary
space for the resulting signature.
But since the ECDSA signature is non-deterministic
(except when ECDSA_sign_setup/ECDSA_sign_ex are used)
the resulting length may be different when the API is called again.
This can easily cause random memory corruption.
Several internal APIs had the same issue, but since they are
never called with sig=NULL, it is better to make them return an
error in that case, instead of making the code more complex.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from openssl#23529)

(cherry picked from commit 1fa2bf9)
bernd-edlinger added a commit to bernd-edlinger/openssl that referenced this pull request Apr 5, 2024
The problem is, that it almost works to pass sig=NULL to the
ECDSA_sign, ECDSA_sign_ex and DSA_sign, to compute the necessary
space for the resulting signature.
But since the ECDSA signature is non-deterministic
(except when ECDSA_sign_setup/ECDSA_sign_ex are used)
the resulting length may be different when the API is called again.
This can easily cause random memory corruption.
Several internal APIs had the same issue, but since they are
never called with sig=NULL, it is better to make them return an
error in that case, instead of making the code more complex.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from openssl#23529)

(cherry picked from commit 1fa2bf9)
jvdsn pushed a commit to jvdsn/openssl that referenced this pull request Jun 3, 2024
The problem is, that it almost works to pass sig=NULL to the
ECDSA_sign, ECDSA_sign_ex and DSA_sign, to compute the necessary
space for the resulting signature.
But since the ECDSA signature is non-deterministic
(except when ECDSA_sign_setup/ECDSA_sign_ex are used)
the resulting length may be different when the API is called again.
This can easily cause random memory corruption.
Several internal APIs had the same issue, but since they are
never called with sig=NULL, it is better to make them return an
error in that case, instead of making the code more complex.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from openssl#23529)
jvdsn pushed a commit to jvdsn/openssl that referenced this pull request Jun 3, 2024
The handling of sig=NULL was broken in this function, but since it
is only used internally and was never called with sig=NULL, it is
better to return an error in that case.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from openssl#23529)
eclipse-oniro-oh-bot pushed a commit to eclipse-oniro-mirrors/third_party_openssl that referenced this pull request Jul 5, 2024
The problem is, that it almost works to pass sig=NULL to the
ECDSA_sign, ECDSA_sign_ex and DSA_sign, to compute the necessary
space for the resulting signature.
But since the ECDSA signature is non-deterministic
(except when ECDSA_sign_setup/ECDSA_sign_ex are used)
the resulting length may be different when the API is called again.
This can easily cause random memory corruption.
Several internal APIs had the same issue, but since they are
never called with sig=NULL, it is better to make them return an
error in that case, instead of making the code more complex.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from openssl/openssl#23529)

(cherry picked from commit 1fa2bf9b1885d2e87524421fea5041d40149cffa)
Signed-off-by: hhhFun <fanghaojie@huawei.com>
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: master Merge to master branch branch: 3.0 Merge to openssl-3.0 branch branch: 3.1 Merge to openssl-3.1 branch: 3.2 Merge to openssl-3.2 branch: 3.3 Merge to openssl-3.3 severity: fips change The pull request changes FIPS provider sources tests: present The PR has suitable tests present triaged: bug The issue/pr is/fixes a bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants