-
Notifications
You must be signed in to change notification settings - Fork 132
Increase default salt from 8 to 16 bytes for PKCS#8 & PKCS#12 #2409
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #2409 +/- ##
==========================================
- Coverage 78.89% 78.87% -0.03%
==========================================
Files 621 621
Lines 108670 108670
Branches 15420 15419 -1
==========================================
- Hits 85738 85716 -22
- Misses 22262 22283 +21
- Partials 670 671 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This change appears to break our Ruby integration test:
|
it likely means that it is also broken against OpenSSL 3.6 master branch. Will poke it to fix their test suite. |
The code there is a bit incoherent. Salt can be of any length, 8 is suggested minimum, and raising the constant didn't change the testcase inputs. Will propose to fix up that unit test to not use such comparison. |
In the PKCS5 RFC salt length is specified of a default value of 8. But it can be longer or shorter. In OpenSSL PKCS5_SALT_LEN constant is specified, but it is a internal implementation detail, a fallback value, and a default suggestion. One can pick lower and higher salt values. Recently, many OpenSSL-like implementations are increasing this fallback default salt length from 8 bytes to 16 bytes. With such implementations ruby-openssl starts to fail (in error). Afterall the 8-byte salt is passed in, and is still acceptable to be used. Update the guard to keep 8-bytes as the lower value, without relying on the PKCS5_SALT_LEN which is going to be different based on a given system library implementation. References: - openssl/openssl@995e948 - https://marc.info/?l=openbsd-tech&m=174689919725477&w=2 - https://marc.info/?l=openbsd-tech&m=174690438827143&w=2 - aws/aws-lc#2409 - https://boringssl-review.googlesource.com/c/boringssl/+/79267 This was cought by aws-lc integration tests.
In the PKCS5 RFC salt length is specified of a default value of 8. But it can be longer or shorter. In OpenSSL PKCS5_SALT_LEN constant is specified, but it is a internal implementation detail, a fallback value, and a default suggestion. One can pick lower and higher salt values. Recently, many OpenSSL-like implementations are increasing this fallback default salt length from 8 bytes to 16 bytes. With such implementations ruby-openssl starts to fail (in error). Afterall the 8-byte salt is passed in, and is still acceptable to be used. Update the guard to keep 8-bytes as the lower value, without relying on the PKCS5_SALT_LEN which is going to be different based on a given system library implementation. References: - openssl/openssl@995e948 - https://marc.info/?l=openbsd-tech&m=174689919725477&w=2 - https://marc.info/?l=openbsd-tech&m=174690438827143&w=2 - aws/aws-lc#2409 - https://boringssl-review.googlesource.com/c/boringssl/+/79267 This was cought by aws-lc integration tests.
FYI OpenSSL's LibreSSL's man page for OpenSSL avoided changing I'm afraid there may be other examples in the wild that assume |
there are two types of PKCS5_SALT_LEN. And some implementations use this same define; in different headers/files; but are actually distinct - e.g. BoringSSL. Please carefully look at:
And observe that in all cases EVP_BytesToKey API remains using "salt[8]" input argument. Some are used for EVP_BytesToKey, others are used to create pkcs12 stores and what not. In boringssl, libressl and openssl the EVP_BytesToKey API remains the same, at 8 bytes. The PKCS12 one however is upgrading. I ensured to do these patches consistent. But yes, there are many places that use EVP_BytesToKey api that uses "salt[8]" input type. Note here, in this patch, I too keep EVP_BytesToKey to continue using salt[8], but change the pkcs12 one to 16. |
Possibly this define is used as a type-hint of the EVP_BytesToKeys() api (which has salt, but no salt length). And thus maybe alternative approach is needed of keeping this define as is; and stop using it altogether. |
I think it's the case, Just a data point, OpenSSL's man page for the legacy PEM encryption (which uses |
Ok, let me go back and figure out how to fix things - such that this public API remains in place, and is from now on the salt length for the Evo bytestokeys. And do something else for pkcs8/12 which can have arbitrary salt length to define a different private constant there. |
@rhenium @justsmth reimplemented the change that matters (ensuring that approved pkcs#8 and pkcs#12 use approved salt length) without changing in any way the legacy/deprecated EVP_BytesToKeys() api, which should be somehow deprecated across everywhere. Also left a comment such that nobody else attempts to bump that public constant which must remain frozen. |
Please retry https://github.com/aws/aws-lc/actions/runs/15020513928/job/42210011957?pr=2409 i attempted to edit the description correctly again (it didn't like newline separation) |
Ruby "main" integration is still failing, but it might be unrelated.
If you agree, would you update the PR description to contain the required text? Thanks! |
done & done sticking to 80 char column mode as i don't see any other comment or code go above it. And redid description without new line in the license statement. |
The equivalent change has now landed in the boringssl fork, and is being integrated throughout all the chromium trees and the rest of the mono repo. Is there anything outstanding from me needed to land this? Is my formatting still incorrect for lint / formatters? Do I need to grant maintainers edit access on this? Edit: I see there was a release, thus rebasing, hopefully that will make ABI diff pass |
Currently PKCS8_marshal_encrypted_private_key function uses salt length of 8 bytes / 64 bits when no salt length is specified. Increase this fallback default to 16 bytes / 128 bits, as recommended by NIST SP 800-132. Note this is for interoperability purposes. Some FIPS implementations enforce minimum salt length of 16 bytes. Examples of such FIPS implemenations are Bouncycastle FIPS Java API and Chainguard FIPS Provider for OpenSSL. Also future v3.6 release of OpenSSL will also increase the default salt length to 16 bytes. A similar change has also been submitted to BoringSSL and LibreSSL. Keep legacy EVP_BytesToKey and PKCS5_SALT_LEN defines at 8 bytes. Add a new internal only define PKCS12_SALT_LEN set to 16 bytes. Use PKCS12_SALT_LEN as the fallback salt length in PKCS#8 and PKCS#12 codepaths. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.
For reference: google/boringssl@6295694
I don't see any other blocking issues. We just need one more approval for a merge. I'll try to poke people for a review. |
@@ -81,6 +81,7 @@ int pkcs8_pbe_decrypt(uint8_t **out, size_t *out_len, CBS *algorithm, | |||
#define PKCS12_KEY_ID 1 | |||
#define PKCS12_IV_ID 2 | |||
#define PKCS12_MAC_ID 3 | |||
#define PKCS12_SALT_LEN 16 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering whether it's better to put this new constant in evp.h? Instead of just leaving there a deprecated constant we'd also have the one recommended by NIST
SP 800-132.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nebeid as a data point all other libraries have internalised such a constant without making it public, and only document the default salt length when otherwise not specified in their manpages and API docs. This is what boringssl, libressl, openssl have done.
Note that in openssl case it is also ifndef'ed such that one can override it to something else at compile time (to downgrade back to 8).
Hence my preference is for API users to explicitly set it themselves, or to read it back after encrypt has happened out of the data structure that encrypt has emitted.
## What's Changed * Increase default salt from 8 to 16 bytes for PKCS#8 & PKCS#12 by @xnox in #2409 * fix(nix): Make sure bssl is in the PATH; workaround nix build failure… by @dougch in #2431 * Fix path-has-spaces test by @justsmth in #2436 * Create pre-production stage for CI pipeline by @nhatnghiho in #2282 * Fix CI cross-mingw by @justsmth in #2437 * Display X509 fingerprint after hash by @justsmth in #2444 By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.
Currently PKCS8_marshal_encrypted_private_key function uses salt
length of 8 bytes / 64 bits when no salt length is specified. Increase
this fallback default to 16 bytes / 128 bits, as recommended by NIST
SP 800-132.
Note this is for interoperability purposes. Some FIPS implementations
enforce minimum salt length of 16 bytes. Examples of such FIPS
implementations are Bouncycastle FIPS Java API and Chainguard FIPS
Provider for OpenSSL. Also future v3.6 release of OpenSSL will also
increase the default salt length to 16 bytes. A similar change has
also been submitted to BoringSSL and LibreSSL.
Keep legacy EVP_BytesToKey and PKCS5_SALT_LEN defines at 8 bytes. Add
a new internal only define PKCS12_SALT_LEN set to 16 bytes. Use
PKCS12_SALT_LEN as the fallback salt length in PKCS#8 and PKCS#12
codepaths.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.