diff --git a/CHANGES.md b/CHANGES.md index 78e74c41fa..8f1e757f8c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -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 diff --git a/crypto/asn1/p5_pbe.c b/crypto/asn1/p5_pbe.c index 13b3f19bae..c595973fe5 100644 --- a/crypto/asn1/p5_pbe.c +++ b/crypto/asn1/p5_pbe.c @@ -12,6 +12,7 @@ #include #include #include +#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; diff --git a/crypto/asn1/p5_pbev2.c b/crypto/asn1/p5_pbev2.c index e710cf3c35..c188a08a6e 100644 --- a/crypto/asn1/p5_pbev2.c +++ b/crypto/asn1/p5_pbev2.c @@ -10,6 +10,7 @@ #include #include "internal/cryptlib.h" #include "crypto/asn1.h" +#include "crypto/evp.h" #include #include #include @@ -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; diff --git a/crypto/asn1/p5_scrypt.c b/crypto/asn1/p5_scrypt.c index 94b77fd3ab..d6ec2445fa 100644 --- a/crypto/asn1/p5_scrypt.c +++ b/crypto/asn1/p5_scrypt.c @@ -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) { diff --git a/doc/man3/PKCS5_PBE_keyivgen.pod b/doc/man3/PKCS5_PBE_keyivgen.pod index 72de3153b9..f697628db1 100644 --- a/doc/man3/PKCS5_PBE_keyivgen.pod +++ b/doc/man3/PKCS5_PBE_keyivgen.pod @@ -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. +If I is NULL, then I specifies the size in bytes of the random salt to +generate. If I 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 diff --git a/include/crypto/evp.h b/include/crypto/evp.h index 566b7889db..9605c9daa5 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -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 diff --git a/test/recipes/15-test_genrsa.t b/test/recipes/15-test_genrsa.t index fe99f33694..5632efe5fc 100644 --- a/test/recipes/15-test_genrsa.t +++ b/test/recipes/15-test_genrsa.t @@ -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"); diff --git a/test/recipes/25-test_pkcs8.t b/test/recipes/25-test_pkcs8.t index 299a56b852..7a06be19e4 100644 --- a/test/recipes/25-test_pkcs8.t +++ b/test/recipes/25-test_pkcs8.t @@ -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