Added 'saltlen' option to the OpenSSL enc command line app.
This allows PBKDF2 to change the saltlen to something other than the new default value of 16. Previously this app hardwired the salt length to a maximum of 8 bytes. Non PBKDF2 mode uses EVP_BytesToKey() internally, which is documented to only allow 8 bytes. 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:
parent
9f679bdc71
commit
e3994583a1
@ -32,6 +32,9 @@ OpenSSL 3.2
|
||||
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.
|
||||
The additional commandline option 'saltlen' has been added to the
|
||||
OpenSSL command line applications for "pkcs8" and "enc" to allow the
|
||||
salt length to be set to a non default value.
|
||||
|
||||
*Shane Lontis*
|
||||
|
||||
|
28
apps/enc.c
28
apps/enc.c
@ -49,7 +49,7 @@ typedef enum OPTION_choice {
|
||||
OPT_NOPAD, OPT_SALT, OPT_NOSALT, OPT_DEBUG, OPT_UPPER_P, OPT_UPPER_A,
|
||||
OPT_A, OPT_Z, OPT_BUFSIZE, OPT_K, OPT_KFILE, OPT_UPPER_K, OPT_NONE,
|
||||
OPT_UPPER_S, OPT_IV, OPT_MD, OPT_ITER, OPT_PBKDF2, OPT_CIPHER,
|
||||
OPT_R_ENUM, OPT_PROV_ENUM
|
||||
OPT_SALTLEN, OPT_R_ENUM, OPT_PROV_ENUM
|
||||
} OPTION_CHOICE;
|
||||
|
||||
const OPTIONS enc_options[] = {
|
||||
@ -100,6 +100,8 @@ const OPTIONS enc_options[] = {
|
||||
{OPT_MORE_STR, 0, 0,
|
||||
"Use -iter to change the iteration count from " STR(PBKDF2_ITER_DEFAULT)},
|
||||
{"none", OPT_NONE, '-', "Don't encrypt"},
|
||||
{"saltlen", OPT_SALTLEN, 'p', "Specify the PBKDF2 salt length (in bytes)"},
|
||||
{OPT_MORE_STR, 0, 0, "Default: 16"},
|
||||
#ifndef OPENSSL_NO_ZLIB
|
||||
{"z", OPT_Z, '-', "Compress or decompress encrypted data using zlib"},
|
||||
#endif
|
||||
@ -132,7 +134,8 @@ int enc_main(int argc, char **argv)
|
||||
int base64 = 0, informat = FORMAT_BINARY, outformat = FORMAT_BINARY;
|
||||
int ret = 1, inl, nopad = 0;
|
||||
unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
|
||||
unsigned char *buff = NULL, salt[PKCS5_SALT_LEN];
|
||||
unsigned char *buff = NULL, salt[EVP_MAX_IV_LENGTH];
|
||||
int saltlen = 0;
|
||||
int pbkdf2 = 0;
|
||||
int iter = 0;
|
||||
long n;
|
||||
@ -293,6 +296,12 @@ int enc_main(int argc, char **argv)
|
||||
iter = opt_int_arg();
|
||||
pbkdf2 = 1;
|
||||
break;
|
||||
case OPT_SALTLEN:
|
||||
if (!opt_int(opt_arg(), &saltlen))
|
||||
goto opthelp;
|
||||
if (saltlen > (int)sizeof(salt))
|
||||
saltlen = (int)sizeof(salt);
|
||||
break;
|
||||
case OPT_PBKDF2:
|
||||
pbkdf2 = 1;
|
||||
if (iter == 0) /* do not overwrite a chosen value */
|
||||
@ -317,6 +326,8 @@ int enc_main(int argc, char **argv)
|
||||
goto opthelp;
|
||||
if (!app_RAND_load())
|
||||
goto end;
|
||||
if (saltlen == 0 || pbkdf2 == 0)
|
||||
saltlen = PKCS5_SALT_LEN;
|
||||
|
||||
/* Get the cipher name, either from progname (if set) or flag. */
|
||||
if (!opt_cipher(ciphername, &cipher))
|
||||
@ -496,13 +507,13 @@ int enc_main(int argc, char **argv)
|
||||
if (nosalt) {
|
||||
sptr = NULL;
|
||||
} else {
|
||||
if (hsalt != NULL && !set_hex(hsalt, salt, sizeof(salt))) {
|
||||
if (hsalt != NULL && !set_hex(hsalt, salt, saltlen)) {
|
||||
BIO_printf(bio_err, "invalid hex salt value\n");
|
||||
goto end;
|
||||
}
|
||||
if (enc) { /* encryption */
|
||||
if (hsalt == NULL) {
|
||||
if (RAND_bytes(salt, sizeof(salt)) <= 0) {
|
||||
if (RAND_bytes(salt, saltlen) <= 0) {
|
||||
BIO_printf(bio_err, "RAND_bytes failed\n");
|
||||
goto end;
|
||||
}
|
||||
@ -515,7 +526,7 @@ int enc_main(int argc, char **argv)
|
||||
sizeof(magic) - 1) != sizeof(magic) - 1
|
||||
|| BIO_write(wbio,
|
||||
(char *)salt,
|
||||
sizeof(salt)) != sizeof(salt))) {
|
||||
saltlen) != saltlen)) {
|
||||
BIO_printf(bio_err, "error writing output file\n");
|
||||
goto end;
|
||||
}
|
||||
@ -528,7 +539,7 @@ int enc_main(int argc, char **argv)
|
||||
}
|
||||
if (memcmp(mbuf, magic, sizeof(mbuf)) == 0) { /* file IS salted */
|
||||
if (BIO_read(rbio, salt,
|
||||
sizeof(salt)) != sizeof(salt)) {
|
||||
saltlen) != saltlen) {
|
||||
BIO_printf(bio_err, "error reading input file\n");
|
||||
goto end;
|
||||
}
|
||||
@ -550,7 +561,8 @@ int enc_main(int argc, char **argv)
|
||||
int iklen = EVP_CIPHER_get_key_length(cipher);
|
||||
int ivlen = EVP_CIPHER_get_iv_length(cipher);
|
||||
/* not needed if HASH_UPDATE() is fixed : */
|
||||
int islen = (sptr != NULL ? sizeof(salt) : 0);
|
||||
int islen = (sptr != NULL ? saltlen : 0);
|
||||
|
||||
if (!PKCS5_PBKDF2_HMAC(str, str_len, sptr, islen,
|
||||
iter, dgst, iklen+ivlen, tmpkeyiv)) {
|
||||
BIO_printf(bio_err, "PKCS5_PBKDF2_HMAC failed\n");
|
||||
@ -646,7 +658,7 @@ int enc_main(int argc, char **argv)
|
||||
if (printkey) {
|
||||
if (!nosalt) {
|
||||
printf("salt=");
|
||||
for (i = 0; i < (int)sizeof(salt); i++)
|
||||
for (i = 0; i < (int)saltlen; i++)
|
||||
printf("%02X", salt[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ B<openssl> B<enc>|I<cipher>
|
||||
[B<-md> I<digest>]
|
||||
[B<-iter> I<count>]
|
||||
[B<-pbkdf2>]
|
||||
[B<-saltlen> I<size>]
|
||||
[B<-p>]
|
||||
[B<-P>]
|
||||
[B<-bufsize> I<number>]
|
||||
@ -132,6 +133,15 @@ This option enables the use of PBKDF2 algorithm to derive the key.
|
||||
Use PBKDF2 algorithm with a default iteration count of 10000
|
||||
unless otherwise specified by the B<-iter> command line option.
|
||||
|
||||
=item B<-saltlen>
|
||||
|
||||
Set the salt length to use when using the B<-pbkdf2> option.
|
||||
For compatibility reasons, the default is 8 bytes.
|
||||
The maximum value is currently 16 bytes.
|
||||
If the B<-pbkdf2> option is not used, then this option is ignored
|
||||
and a fixed salt length of 8 is used. The salt length used when
|
||||
encrypting must also be used when decrypting.
|
||||
|
||||
=item B<-nosalt>
|
||||
|
||||
Don't use a salt in the key derivation routines. This option B<SHOULD NOT> be
|
||||
@ -147,7 +157,8 @@ encrypting, this is the default.
|
||||
|
||||
The actual salt to use: this must be represented as a string of hex digits.
|
||||
If this option is used while encrypting, the same exact value will be needed
|
||||
again during decryption.
|
||||
again during decryption. This salt may be truncated or zero padded to
|
||||
match the salt length (See B<-saltlen>).
|
||||
|
||||
=item B<-K> I<key>
|
||||
|
||||
@ -465,9 +476,11 @@ The B<-list> option was added in OpenSSL 1.1.1e.
|
||||
|
||||
The B<-ciphers> and B<-engine> options were deprecated in OpenSSL 3.0.
|
||||
|
||||
The B<-saltlen> option was added in OpenSSL 3.2.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
Copyright 2000-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
|
||||
|
@ -41,7 +41,7 @@ my @ciphers =
|
||||
|rc2|rc4|seed)/x} @ciphers
|
||||
if disabled("legacy");
|
||||
|
||||
plan tests => 2 + (scalar @ciphers)*2;
|
||||
plan tests => 5 + (scalar @ciphers)*2;
|
||||
|
||||
SKIP: {
|
||||
skip "Problems getting ciphers...", 1 + scalar(@ciphers)
|
||||
@ -72,4 +72,22 @@ plan tests => 2 + (scalar @ciphers)*2;
|
||||
&& compare_text($test,$clearfile) == 0, $t);
|
||||
}
|
||||
}
|
||||
ok(run(app([$cmd, "enc", "-in", $test, "-aes256", "-pbkdf2", "-out",
|
||||
"salted_default.cipher", "-pass", "pass:password"]))
|
||||
&& run(app([$cmd, "enc", "-d", "-in", "salted_default.cipher", "-aes256", "-pbkdf2",
|
||||
"-saltlen", "8", "-out", "salted_default.clear", "-pass", "pass:password"]))
|
||||
&& compare_text($test,"salted_default.clear") == 0,
|
||||
"Check that the default salt length of 8 bytes is used for PKDF2");
|
||||
|
||||
ok(!run(app([$cmd, "enc", "-d", "-in", "salted_default.cipher", "-aes256", "-pbkdf2",
|
||||
"-saltlen", "16", "-out", "salted_fail.clear", "-pass", "pass:password"])),
|
||||
"Check the decrypt fails if the saltlen is incorrect");
|
||||
|
||||
ok(run(app([$cmd, "enc", "-in", $test, "-aes256", "-pbkdf2", "-saltlen", "16",
|
||||
"-out", "salted.cipher", "-pass", "pass:password"]))
|
||||
&& run(app([$cmd, "enc", "-d", "-in", "salted.cipher", "-aes256", "-pbkdf2",
|
||||
"-saltlen", "16", "-out", "salted.clear", "-pass", "pass:password"]))
|
||||
&& compare_text($test,"salted.clear") == 0,
|
||||
"Check that we can still use a salt length of 16 bytes for PKDF2");
|
||||
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ SKIP: {
|
||||
'-in', 'pbe1.pem',
|
||||
'-offset', '19', '-length', '10']))),
|
||||
"Check the default size of the PBE PARAM 'salt length' = 8");
|
||||
|
||||
|
||||
ok(run(app(([ 'openssl', 'pkcs8', '-topk8',
|
||||
'-in', srctop_file('test', 'certs', 'pc5-key.pem'),
|
||||
'-v1', "PBE-MD5-DES",
|
||||
|
Loading…
x
Reference in New Issue
Block a user