Change PBES2 KDF default salt length to 16 bytes.

The PKCS5 (RFC 8018) standard uses a 64 bit salt length for PBE, and
recommends a minimum of 64 bits for PBES2. For FIPS compliance PBKDF2
requires a salt length of 128 bits.
This affects OpenSSL command line applications such as "genrsa" and "pkcs8"
and API's such as PEM_write_bio_PrivateKey() that are reliant on the
default salt length.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21858)
This commit is contained in:
slontis 2023-08-28 12:47:51 +10:00 committed by Pauli
parent 61cfc22b60
commit 3859a02725
8 changed files with 95 additions and 6 deletions

View File

@ -25,6 +25,16 @@ OpenSSL 3.2
### Changes between 3.1 and 3.2 [xx XXX xxxx]
* Changed the default salt length used by PBES2 KDF's (PBKDF2 and scrypt)
from 8 bytes to 16 bytes.
The PKCS5 (RFC 8018) standard uses a 64 bit salt length for PBE, and
recommends a minimum of 64 bits for PBES2. For FIPS compliance PBKDF2
requires a salt length of 128 bits. This affects OpenSSL command line
applications such as "genrsa" and "pkcs8" and API's such as
PEM_write_bio_PrivateKey() that are reliant on the default value.
*Shane Lontis*
* Changed the default value of the `ess_cert_id_alg` configuration
option which is used to calculate the TSA's public key certificate
identifier. The default algorithm is updated to be sha256 instead

View File

@ -12,6 +12,7 @@
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/rand.h>
#include "crypto/evp.h"
/* PKCS#5 password based encryption structure */
@ -45,7 +46,7 @@ int PKCS5_pbe_set0_algor_ex(X509_ALGOR *algor, int alg, int iter,
goto err;
}
if (!saltlen)
saltlen = PKCS5_SALT_LEN;
saltlen = PKCS5_DEFAULT_PBE1_SALT_LEN;
if (saltlen < 0)
goto err;

View File

@ -10,6 +10,7 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include "crypto/asn1.h"
#include "crypto/evp.h"
#include <openssl/asn1t.h>
#include <openssl/core.h>
#include <openssl/core_names.h>
@ -196,7 +197,7 @@ X509_ALGOR *PKCS5_pbkdf2_set_ex(int iter, unsigned char *salt, int saltlen,
goto err;
}
if (saltlen == 0)
saltlen = PKCS5_SALT_LEN;
saltlen = PKCS5_DEFAULT_PBE2_SALT_LEN;
if ((osalt->data = OPENSSL_malloc(saltlen)) == NULL)
goto err;

View File

@ -166,7 +166,7 @@ static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen,
}
if (!saltlen)
saltlen = PKCS5_SALT_LEN;
saltlen = PKCS5_DEFAULT_PBE2_SALT_LEN;
/* This will either copy salt or grow the buffer */
if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0) {

View File

@ -127,6 +127,12 @@ associated parameters for the PBKDF2 algorithm.
PKCS5_pbe_set0_algor() and PKCS5_pbe_set0_algor_ex() set the PBE algorithm OID and
parameters into the supplied B<X509_ALGOR>.
If I<salt> is NULL, then I<saltlen> specifies the size in bytes of the random salt to
generate. If I<saltlen> is 0 then a default size is used.
For PBE related functions such as PKCS5_pbe_set_ex() the default salt length is 8 bytes.
For PBE2 related functions that use PBKDF2 such as PKCS5_pbkdf2_set(),
PKCS5_pbe2_set_scrypt() and PKCS5_pbe2_set() the default salt length is 16 bytes.
=head1 NOTES
The *_keyivgen() functions are typically used in PKCS#12 to encrypt objects.
@ -165,9 +171,13 @@ PKCS5_pbkdf2_set_ex() were added in OpenSSL 3.0.
From OpenSSL 3.0 the PBKDF1 algorithm used in PKCS5_PBE_keyivgen() and
PKCS5_PBE_keyivgen_ex() has been moved to the legacy provider as an EVP_KDF.
In OpenSSL 3.2 the default salt length changed from 8 bytes to 16 bytes for PBE2
related functions such as PKCS5_pbe2_set().
This is required for PBKDF2 FIPS compliance.
=head1 COPYRIGHT
Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy

View File

@ -16,6 +16,15 @@
# include "internal/refcount.h"
# include "crypto/ecx.h"
/*
* Default PKCS5 PBE KDF salt lengths
* In RFC 8018, PBE1 uses 8 bytes (64 bits) for its salt length.
* It also specifies to use at least 8 bytes for PBES2.
* The NIST requirement for PBKDF2 is 128 bits so we use this as the
* default for PBE2 (scrypt and HKDF2)
*/
# define PKCS5_DEFAULT_PBE1_SALT_LEN PKCS5_SALT_LEN
# define PKCS5_DEFAULT_PBE2_SALT_LEN 16
/*
* Don't free up md_ctx->pctx in EVP_MD_CTX_reset, use the reserved flag
* values in evp.h

View File

@ -25,7 +25,7 @@ my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
plan tests =>
($no_fips ? 0 : 5) # Extra FIPS related tests
+ 15;
+ 16;
# We want to know that an absurdly small number of bits isn't support
is(run(app([ 'openssl', 'genpkey', '-out', 'genrsatest.pem',
@ -106,6 +106,13 @@ ok(run(app([ 'openssl', 'rsa', '-check', '-in', 'genrsatest.pem', '-noout' ])),
ok(run(app([ 'openssl', 'rsa', '-in', 'genrsatest.pem', '-out', 'genrsatest-enc.pem',
'-aes256', '-passout', 'pass:x' ])),
"rsa encrypt");
# Check the default salt length for PBKDF2 is 16 bytes
# We expect the output to be of the form "0:d=0 hl=2 l= 16 prim: OCTET STRING [HEX DUMP]:FAC7F37508E6B7A805BF4B13861B3687"
# i.e. 2 byte header + 16 byte salt.
ok(run(app(([ 'openssl', 'asn1parse',
'-in', 'genrsatest-enc.pem',
'-offset', '34', '-length', '18']))),
"Check the default size of the PBKDF2 PARAM 'salt length' is 16");
ok(run(app([ 'openssl', 'rsa', '-in', 'genrsatest-enc.pem', '-passin', 'pass:x' ])),
"rsa decrypt");

View File

@ -15,7 +15,58 @@ use OpenSSL::Test qw/:DEFAULT srctop_file ok_nofips is_nofips/;
setup("test_pkcs8");
plan tests => 3;
plan tests => 9;
ok(run(app(([ 'openssl', 'pkcs8', '-topk8',
'-in', srctop_file('test', 'certs', 'pc5-key.pem'),
'-out', 'pbkdf2_default_saltlen.pem',
'-passout', 'pass:password']))),
"Convert a private key to PKCS5 v2.0 format using PBKDF2 with the default saltlen");
# We expect the output to be of the form "0:d=0 hl=2 l= 16 prim: OCTET STRING [HEX DUMP]:FAC7F37508E6B7A805BF4B13861B3687"
# i.e. 2 byte header + 16 byte salt.
ok(run(app(([ 'openssl', 'asn1parse',
'-in', 'pbkdf2_default_saltlen.pem',
'-offset', '34', '-length', '18']))),
"Check the default size of the PBKDF2 PARAM 'salt length' is 16");
SKIP: {
skip "scrypt is not supported by this OpenSSL build", 2
if disabled("scrypt");
ok(run(app(([ 'openssl', 'pkcs8', '-topk8',
'-in', srctop_file('test', 'certs', 'pc5-key.pem'),
'-scrypt',
'-out', 'scrypt_default_saltlen.pem',
'-passout', 'pass:password']))),
"Convert a private key to PKCS5 v2.0 format using scrypt with the default saltlen");
# We expect the output to be of the form "0:d=0 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:FAC7F37508E6B7A805BF4B13861B3687"
# i.e. 2 byte header + 16 byte salt.
ok(run(app(([ 'openssl', 'asn1parse',
'-in', 'scrypt_default_saltlen.pem',
'-offset', '34', '-length', '18']))),
"Check the default size of the SCRYPT PARAM 'salt length' = 16");
}
SKIP: {
skip "legacy provider is not supported by this OpenSSL build", 2
if disabled('legacy') || disabled("des");
ok(run(app(([ 'openssl', 'pkcs8', '-topk8',
'-in', srctop_file('test', 'certs', 'pc5-key.pem'),
'-v1', "PBE-MD5-DES",
'-provider', 'legacy',
'-provider', 'default',
'-out', 'pbe1.pem',
'-passout', 'pass:password']))),
"Convert a private key to PKCS5 v1.5 format using pbeWithMD5AndDES-CBC with the default saltlen");
ok(run(app(([ 'openssl', 'asn1parse',
'-in', 'pbe1.pem',
'-offset', '19', '-length', '10']))),
"Check the default size of the PBE PARAM 'salt length' = 8");
};
SKIP: {
skip "SM2, SM3 or SM4 is not supported by this OpenSSL build", 3