Skip to content

Conversation

@paulidale
Copy link
Contributor

The fix in #24141 wasn't quite correct. The test case just happened to work on a freshly initialised context.

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

@paulidale paulidale added branch: master Applies to master branch approval: review pending This pull request needs review by a committer triaged: bug The issue/pr is/fixes a bug branch: 3.0 Applies to openssl-3.0 branch severity: regression The issue/pr is a regression from previous released version branch: 3.1 Applies to openssl-3.1 (EOL) tests: present The PR has suitable tests present branch: 3.2 Applies to openssl-3.2 (EOL) branch: 3.3 Applies to openssl-3.3 branch: 3.4 Applies to openssl-3.4 branch: 3.5 Applies to openssl-3.5 labels Apr 9, 2025
@paulidale paulidale self-assigned this Apr 9, 2025
@github-actions github-actions bot added the severity: fips change The pull request changes FIPS provider sources label Apr 9, 2025
if (!TEST_int_gt(EVP_PKEY_derive_init(pctx), 0)
|| !TEST_int_gt(EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()), 0)
|| !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_salt(pctx, fake,
sizeof(fake) - 1), 0)
Copy link
Member

Choose a reason for hiding this comment

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

not really overjoyed with how this does sizeof(salt) - 1 and sizeof(info)-1..
These are just 0 values.

Where is the test for setting salt to NULL?

Copy link
Contributor Author

@paulidale paulidale Apr 9, 2025

Choose a reason for hiding this comment

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

The line below sets a zero length salt (this was done by the existing test). This is needed because the default is a zero length salt and even though the set after this fails, it doesn't return an error so this test worked by fluke rather than design. Adding this set breaks the default and the next line has to work for the test to pass.

@t8m t8m removed the branch: 3.1 Applies to openssl-3.1 (EOL) label Apr 9, 2025
Comment on lines +311 to +313
ctx->salt = NULL;
if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0,
&ctx->salt_len))
Copy link
Member

Choose a reason for hiding this comment

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

Would this be more correct allowing for using NULL, 0 for the param?

Suggested change
ctx->salt = NULL;
if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0,
&ctx->salt_len))
ctx->salt = NULL;
ctx->salt_len = 0;
if (p->data_size != 0 && p->data != NULL
&& !OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0,
&ctx->salt_len))

Copy link
Contributor Author

@paulidale paulidale Apr 9, 2025

Choose a reason for hiding this comment

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

The length and NULL check were introduced by the earlier fix and they are broken in a subtle way. Subtle enough that both you and I missed the problem when reviewing the change 😢

I thought about leaving these checks in but the big issue for me is that we don't do it this way anywhere else. Consistency in our APIs is something we should be striving for.

We do not generally:

  • check for ->data_size != 0
  • check for ->data == NULL

If the param exists we just assume it has a valid pointer associated with it and that the length is trustworthy. It seemed reasonable to do the same here.

Copy link
Contributor

@tobiasbrunner tobiasbrunner Jul 10, 2025

Choose a reason for hiding this comment

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

I think @t8m is correct. Such a check is necessary because OSSL_PARAM_get_octet_string() fails if the param's data is NULL. This currently actually prevents setting the salt to NULL.

Choose a reason for hiding this comment

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

I think @t8m is correct. Such a check is necessary because OSSL_PARAM_get_octet_string() fails if the param's data is NULL. This currently actually prevents setting the salt to NULL.

Not sure if this was an intended change, but we found this statement to be true. We can no longer set the salt to NULL in openssl 3.5.1. We get the following error:

80476A18AA750000:error:078C0102:common libcrypto routines:get_string_internal:passed a null parameter

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You could never set the salt to NULL before 3.5.1. If you tried the salt remained unchanged and the call apparently suceeded. So if you ever set the salt to a non–empty value, you could not set it back to empty. What changed in 3.5.1 is that trying to set the salt to NULL raises an error. I think this is better than silently doing nothing and it's consistent with other parameter usage.

I see a few ways forward:

  1. if, as is likely, you never set the salt explicitly, there is no need to reset it;
  2. if you do set the salt explicitly, you're in a world of hurt because the previous salt will have been used without you knowing or
  3. set the salt to empty by passing "" and a length of zero instead of a NULL pointer.

In 3.4.0, line 310 means your attempt to set the parameter is silently ignored:

if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) {
if (p->data_size != 0 && p->data != NULL) {
OPENSSL_free(ctx->salt);
ctx->salt = NULL;
if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0,
&ctx->salt_len))
return 0;
}
}

In 3.5.1 this changed to:

if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) {
OPENSSL_free(ctx->salt);
ctx->salt = NULL;
if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0,
&ctx->salt_len))
return 0;
}

The call on line 313 raises an error if the parameter's data pointer is NULL.

: the reset call sets the salt to empty but also wipes everything else.

Copy link
Member

Choose a reason for hiding this comment

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

If you are having to set it and then reset it to NULL then something is also wrong. The RFC for HKDF says its optional, but it also says you should normally set it if possible because its more secure. The case where you dont set it should be if you just cant due to platform related restrictions. So you should probably always be setting it (if you can), or not setting it at all. In either of these cases setting it to NULL is not required.

@paulidale
Copy link
Contributor Author

Ping for reviews?

@paulidale paulidale requested review from a team and slontis April 17, 2025 02:38
@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 Apr 17, 2025
@openssl-machine openssl-machine removed the approval: done This pull request has the required number of approvals label Apr 18, 2025
@openssl-machine
Copy link
Collaborator

This pull request is ready to merge

@openssl-machine openssl-machine added the approval: ready to merge The 24 hour grace period has passed, ready to merge label Apr 18, 2025
openssl-machine pushed a commit that referenced this pull request Apr 18, 2025
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #27305)
openssl-machine pushed a commit that referenced this pull request Apr 18, 2025
Fixes #27302

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #27305)
openssl-machine pushed a commit that referenced this pull request Apr 18, 2025
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #27305)

(cherry picked from commit 12eb6c5)
openssl-machine pushed a commit that referenced this pull request Apr 18, 2025
Fixes #27302

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #27305)

(cherry picked from commit 7271179)
openssl-machine pushed a commit that referenced this pull request Apr 18, 2025
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #27305)

(cherry picked from commit 12eb6c5)
openssl-machine pushed a commit that referenced this pull request Apr 18, 2025
Fixes #27302

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #27305)

(cherry picked from commit 7271179)
openssl-machine pushed a commit that referenced this pull request Apr 18, 2025
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #27305)

(cherry picked from commit 12eb6c5)
openssl-machine pushed a commit that referenced this pull request Apr 18, 2025
Fixes #27302

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #27305)

(cherry picked from commit 7271179)
@mattcaswell
Copy link
Member

Pushed to master, 3.5, 3.4, 3.3, 3.2 and 3.0.

openssl-machine pushed a commit that referenced this pull request Apr 18, 2025
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #27305)

(cherry picked from commit 12eb6c5)
openssl-machine pushed a commit that referenced this pull request Apr 18, 2025
Fixes #27302

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #27305)

(cherry picked from commit 7271179)
Sashan pushed a commit to Sashan/openssl that referenced this pull request Apr 18, 2025
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from openssl#27305)
Sashan pushed a commit to Sashan/openssl that referenced this pull request Apr 18, 2025
Fixes openssl#27302

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from openssl#27305)
Sashan pushed a commit to Sashan/openssl that referenced this pull request Apr 22, 2025
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from openssl#27305)
Sashan pushed a commit to Sashan/openssl that referenced this pull request Apr 22, 2025
Fixes openssl#27302

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from openssl#27305)
simo5 pushed a commit to simo5/openssl that referenced this pull request Apr 25, 2025
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from openssl#27305)

(cherry picked from commit 12eb6c5)
@paulidale paulidale deleted the hkdf-0salt branch April 27, 2025 22:53
simo5 pushed a commit to simo5/openssl that referenced this pull request May 12, 2025
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from openssl#27305)

(cherry picked from commit 12eb6c5)
DDvO pushed a commit to siemens/openssl that referenced this pull request Jun 16, 2025
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from openssl#27305)
DDvO pushed a commit to siemens/openssl that referenced this pull request Jun 16, 2025
Fixes openssl#27302

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from openssl#27305)
MichaelA-Fireblocks pushed a commit to MichaelA-Fireblocks/openssl that referenced this pull request Jul 15, 2025
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from openssl#27305)
MichaelA-Fireblocks pushed a commit to MichaelA-Fireblocks/openssl that referenced this pull request Jul 15, 2025
Fixes openssl#27302

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from openssl#27305)
MichaelA-Fireblocks pushed a commit to MichaelA-Fireblocks/openssl that referenced this pull request Jul 15, 2025
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from openssl#27305)
MichaelA-Fireblocks pushed a commit to MichaelA-Fireblocks/openssl that referenced this pull request Jul 15, 2025
Fixes openssl#27302

Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from openssl#27305)
trflynn89 added a commit to trflynn89/ladybird that referenced this pull request Jul 16, 2025
This contains an API change that disallows setting the salt to a null
value. See:

openssl/openssl#27305

This seems to be the opposite of the intended effect of that change,
but this patch includes a workaround nonetheless.

Co-Authored-By: devgianlu <altomanigianluca@gmail.com>
@jwalch
Copy link
Contributor

jwalch commented Jul 28, 2025

The downstream impact of this seems to have not been particularly appropriate for a security patch release. For example, I cannot upgrade to 3.5.1 now without also updating strongswan to pull in fixes to adapt to the behavior change: https://github.com/strongswan/strongswan/commits/master/src/libstrongswan/plugins/openssl/openssl_kdf.c. I see that other consumers are referenced in recent notes here. I get the argument that what the consumers were counting on was wrong behavior anyway, but the point is that we generally do not expect for security patch releases to force code changes elsewhere...

@paulidale
Copy link
Contributor Author

We didn't classify this as a security problem, it's just a bug.

@jwalch
Copy link
Contributor

jwalch commented Jul 28, 2025

I understand that this wasn't a security issue and that's actually exactly why I'm a bit tweaked that the behavior change made its way into patch releases. Let's suppose the quarterly patch actually addressed something more critical than CVE-2025-4575. I have to update to the latest patch in whatever minor release I'm on (happens to be 3.5) to plug a security hole, but then that breaks something else (strongswan in my case). Now I'm stuck with either updating that too (presuming they changed their code) or living with the security issue. It's not exactly ideal. Like if I'm going 3.4 to 3.5, this is the kind of thing I expect to bump into... but from 3.5.0 to 3.5.1 it was a rather unpleasant surprise.

It seems to me that having cherry-picked this back into patch release demonstrates either a lack of understanding how widely the existing (albeit incorrect) behavior was actually being depended on by some consumers or else not viewing the use case of trying to update OpenSSL from patch-to-patch within a minor release without downstream impacts as being something that matters much to most of the community.

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 Applies to master branch branch: 3.0 Applies to openssl-3.0 branch branch: 3.2 Applies to openssl-3.2 (EOL) branch: 3.3 Applies to openssl-3.3 branch: 3.4 Applies to openssl-3.4 branch: 3.5 Applies to openssl-3.5 severity: fips change The pull request changes FIPS provider sources severity: regression The issue/pr is a regression from previous released version 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.

9 participants