mirror of
https://github.com/openssl/openssl.git
synced 2024-12-14 20:43:46 +08:00
PBKDF2 updates to conform to SP800-132
The existing code used PKCS5 specifications. SP800-132 adds the following additional constraints for: - the range of the key length. - the minimum iteration count (1000 recommended). - salt length (at least 128 bits). These additional constraints may cause errors (in scrypt, and some PKCS5 related test vectors). To disable the new constraints use the new ctrl string "pkcs5". For backwards compatability, the checks are only enabled by default for fips mode. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/8868)
This commit is contained in:
parent
83b4a24384
commit
f0efeea29e
11
CHANGES
11
CHANGES
@ -9,6 +9,15 @@
|
||||
|
||||
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
|
||||
|
||||
*) Change PBKDF2 to conform to SP800-132 instead of the older PKCS5 RFC2898.
|
||||
This checks that the salt length is at least 128 bits, the derived key
|
||||
length is at least 112 bits, and that the iteration count is at least 1000.
|
||||
For backwards compatibility these checks are disabled by default in the
|
||||
default provider, but are enabled by default in the fips provider.
|
||||
To enable or disable these checks use the control
|
||||
EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE.
|
||||
[Shane Lontis]
|
||||
|
||||
*) Default cipher lists/suites are now avaialble via a function, the
|
||||
#defines are deprecated.
|
||||
[Todd Short]
|
||||
@ -30,7 +39,7 @@
|
||||
*) Added command 'openssl kdf' that uses the EVP_KDF API.
|
||||
[Shane Lontis]
|
||||
|
||||
*) Added command 'openssl mac' that uses the EVP_MAC API.
|
||||
*) Added command 'openssl mac' that uses the EVP_MAC API.
|
||||
[Shane Lontis]
|
||||
|
||||
*) Added OPENSSL_info() to get diverse built-in OpenSSL data, such
|
||||
|
@ -895,6 +895,7 @@ KDF_F_KDF_HKDF_DERIVE:113:kdf_hkdf_derive
|
||||
KDF_F_KDF_HKDF_NEW:114:kdf_hkdf_new
|
||||
KDF_F_KDF_HKDF_SIZE:115:kdf_hkdf_size
|
||||
KDF_F_KDF_MD2CTRL:116:kdf_md2ctrl
|
||||
KDF_F_KDF_PBKDF2_CTRL:140:kdf_pbkdf2_ctrl
|
||||
KDF_F_KDF_PBKDF2_CTRL_STR:117:kdf_pbkdf2_ctrl_str
|
||||
KDF_F_KDF_PBKDF2_DERIVE:118:kdf_pbkdf2_derive
|
||||
KDF_F_KDF_PBKDF2_NEW:119:kdf_pbkdf2_new
|
||||
@ -910,6 +911,7 @@ KDF_F_KDF_SSHKDF_NEW:133:kdf_sshkdf_new
|
||||
KDF_F_KDF_TLS1_PRF_CTRL_STR:125:kdf_tls1_prf_ctrl_str
|
||||
KDF_F_KDF_TLS1_PRF_DERIVE:126:kdf_tls1_prf_derive
|
||||
KDF_F_KDF_TLS1_PRF_NEW:127:kdf_tls1_prf_new
|
||||
KDF_F_PBKDF2_DERIVE:141:pbkdf2_derive
|
||||
KDF_F_PBKDF2_SET_MEMBUF:128:pbkdf2_set_membuf
|
||||
KDF_F_PKEY_HKDF_CTRL_STR:103:pkey_hkdf_ctrl_str
|
||||
KDF_F_PKEY_HKDF_DERIVE:102:pkey_hkdf_derive
|
||||
@ -2458,7 +2460,10 @@ EVP_R_WRONG_FINAL_BLOCK_LENGTH:109:wrong final block length
|
||||
EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE:191:xts data unit is too large
|
||||
EVP_R_XTS_DUPLICATED_KEYS:192:xts duplicated keys
|
||||
KDF_R_INVALID_DIGEST:100:invalid digest
|
||||
KDF_R_INVALID_ITERATION_COUNT:119:invalid iteration count
|
||||
KDF_R_INVALID_KEY_LEN:120:invalid key len
|
||||
KDF_R_INVALID_MAC_TYPE:116:invalid mac type
|
||||
KDF_R_INVALID_SALT_LEN:121:invalid salt len
|
||||
KDF_R_MISSING_ITERATION_COUNT:109:missing iteration count
|
||||
KDF_R_MISSING_KEY:104:missing key
|
||||
KDF_R_MISSING_MESSAGE_DIGEST:105:missing message digest
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1999-2019 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
|
||||
@ -40,6 +40,7 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
|
||||
if (kctx == NULL)
|
||||
return 0;
|
||||
if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, pass, (size_t)passlen) != 1
|
||||
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE, 1) != 1
|
||||
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT,
|
||||
salt, (size_t)saltlen) != 1
|
||||
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, iter) != 1
|
||||
|
@ -19,6 +19,7 @@ static const ERR_STRING_DATA KDF_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_NEW, 0), "kdf_hkdf_new"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_SIZE, 0), "kdf_hkdf_size"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_MD2CTRL, 0), "kdf_md2ctrl"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_CTRL, 0), "kdf_pbkdf2_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_CTRL_STR, 0),
|
||||
"kdf_pbkdf2_ctrl_str"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_DERIVE, 0), "kdf_pbkdf2_derive"},
|
||||
@ -41,6 +42,7 @@ static const ERR_STRING_DATA KDF_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_DERIVE, 0),
|
||||
"kdf_tls1_prf_derive"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_NEW, 0), "kdf_tls1_prf_new"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_PBKDF2_DERIVE, 0), "pbkdf2_derive"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_PBKDF2_SET_MEMBUF, 0), "pbkdf2_set_membuf"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_CTRL_STR, 0), "pkey_hkdf_ctrl_str"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_DERIVE, 0), "pkey_hkdf_derive"},
|
||||
@ -71,7 +73,11 @@ static const ERR_STRING_DATA KDF_str_functs[] = {
|
||||
|
||||
static const ERR_STRING_DATA KDF_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_DIGEST), "invalid digest"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_ITERATION_COUNT),
|
||||
"invalid iteration count"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_KEY_LEN), "invalid key len"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_MAC_TYPE), "invalid mac type"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_SALT_LEN), "invalid salt len"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_ITERATION_COUNT),
|
||||
"missing iteration count"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_KEY), "missing key"},
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2018-2019 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
|
||||
@ -17,12 +17,27 @@
|
||||
#include "internal/evp_int.h"
|
||||
#include "kdf_local.h"
|
||||
|
||||
/* Constants specified in SP800-132 */
|
||||
#define KDF_PBKDF2_MIN_KEY_LEN_BITS 112
|
||||
#define KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO 0xFFFFFFFF
|
||||
#define KDF_PBKDF2_MIN_ITERATIONS 1000
|
||||
#define KDF_PBKDF2_MIN_SALT_LEN (128 / 8)
|
||||
/*
|
||||
* For backwards compatibility reasons,
|
||||
* Extra checks are done by default in fips mode only.
|
||||
*/
|
||||
#ifdef FIPS_MODE
|
||||
# define KDF_PBKDF2_DEFAULT_CHECKS 1
|
||||
#else
|
||||
# define KDF_PBKDF2_DEFAULT_CHECKS 0
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
static void kdf_pbkdf2_reset(EVP_KDF_IMPL *impl);
|
||||
static void kdf_pbkdf2_init(EVP_KDF_IMPL *impl);
|
||||
static int pkcs5_pbkdf2_alg(const char *pass, size_t passlen,
|
||||
const unsigned char *salt, int saltlen, int iter,
|
||||
const EVP_MD *digest, unsigned char *key,
|
||||
size_t keylen);
|
||||
static int pbkdf2_derive(const char *pass, size_t passlen,
|
||||
const unsigned char *salt, int saltlen, int iter,
|
||||
const EVP_MD *digest, unsigned char *key,
|
||||
size_t keylen, int extra_checks);
|
||||
|
||||
struct evp_kdf_impl_st {
|
||||
unsigned char *pass;
|
||||
@ -31,6 +46,7 @@ struct evp_kdf_impl_st {
|
||||
size_t salt_len;
|
||||
int iter;
|
||||
const EVP_MD *md;
|
||||
int lower_bound_checks;
|
||||
};
|
||||
|
||||
static EVP_KDF_IMPL *kdf_pbkdf2_new(void)
|
||||
@ -64,6 +80,7 @@ static void kdf_pbkdf2_init(EVP_KDF_IMPL *impl)
|
||||
{
|
||||
impl->iter = PKCS5_DEFAULT_ITER;
|
||||
impl->md = EVP_sha1();
|
||||
impl->lower_bound_checks = KDF_PBKDF2_DEFAULT_CHECKS;
|
||||
}
|
||||
|
||||
static int pbkdf2_set_membuf(unsigned char **buffer, size_t *buflen,
|
||||
@ -91,12 +108,16 @@ static int pbkdf2_set_membuf(unsigned char **buffer, size_t *buflen,
|
||||
|
||||
static int kdf_pbkdf2_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
|
||||
{
|
||||
int iter;
|
||||
int iter, pkcs5, min_iter;
|
||||
const unsigned char *p;
|
||||
size_t len;
|
||||
const EVP_MD *md;
|
||||
|
||||
switch (cmd) {
|
||||
case EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE:
|
||||
pkcs5 = va_arg(args, int);
|
||||
impl->lower_bound_checks = (pkcs5 == 0) ? 1 : 0;
|
||||
return 1;
|
||||
case EVP_KDF_CTRL_SET_PASS:
|
||||
p = va_arg(args, const unsigned char *);
|
||||
len = va_arg(args, size_t);
|
||||
@ -105,20 +126,28 @@ static int kdf_pbkdf2_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
|
||||
case EVP_KDF_CTRL_SET_SALT:
|
||||
p = va_arg(args, const unsigned char *);
|
||||
len = va_arg(args, size_t);
|
||||
if (impl->lower_bound_checks != 0 && len < KDF_PBKDF2_MIN_SALT_LEN) {
|
||||
KDFerr(KDF_F_KDF_PBKDF2_CTRL, KDF_R_INVALID_SALT_LEN);
|
||||
return 0;
|
||||
}
|
||||
return pbkdf2_set_membuf(&impl->salt, &impl->salt_len, p, len);
|
||||
|
||||
case EVP_KDF_CTRL_SET_ITER:
|
||||
iter = va_arg(args, int);
|
||||
if (iter < 1)
|
||||
min_iter = impl->lower_bound_checks != 0 ? KDF_PBKDF2_MIN_ITERATIONS : 1;
|
||||
if (iter < min_iter) {
|
||||
KDFerr(KDF_F_KDF_PBKDF2_CTRL, KDF_R_INVALID_ITERATION_COUNT);
|
||||
return 0;
|
||||
|
||||
}
|
||||
impl->iter = iter;
|
||||
return 1;
|
||||
|
||||
case EVP_KDF_CTRL_SET_MD:
|
||||
md = va_arg(args, const EVP_MD *);
|
||||
if (md == NULL)
|
||||
if (md == NULL) {
|
||||
KDFerr(KDF_F_KDF_PBKDF2_CTRL, KDF_R_VALUE_MISSING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
impl->md = md;
|
||||
return 1;
|
||||
@ -159,6 +188,9 @@ static int kdf_pbkdf2_ctrl_str(EVP_KDF_IMPL *impl, const char *type,
|
||||
if (strcmp(type, "digest") == 0)
|
||||
return kdf_md2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_MD, value);
|
||||
|
||||
if (strcmp(type, "pkcs5") == 0)
|
||||
return kdf_str2ctrl(impl, kdf_pbkdf2_ctrl,
|
||||
EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE, value);
|
||||
return -2;
|
||||
}
|
||||
|
||||
@ -175,9 +207,9 @@ static int kdf_pbkdf2_derive(EVP_KDF_IMPL *impl, unsigned char *key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pkcs5_pbkdf2_alg((char *)impl->pass, impl->pass_len,
|
||||
impl->salt, impl->salt_len, impl->iter,
|
||||
impl->md, key, keylen);
|
||||
return pbkdf2_derive((char *)impl->pass, impl->pass_len,
|
||||
impl->salt, impl->salt_len, impl->iter,
|
||||
impl->md, key, keylen, impl->lower_bound_checks);
|
||||
}
|
||||
|
||||
const EVP_KDF pbkdf2_kdf_meth = {
|
||||
@ -195,12 +227,16 @@ const EVP_KDF pbkdf2_kdf_meth = {
|
||||
* This is an implementation of PKCS#5 v2.0 password based encryption key
|
||||
* derivation function PBKDF2. SHA1 version verified against test vectors
|
||||
* posted by Peter Gutmann to the PKCS-TNG mailing list.
|
||||
*
|
||||
* The constraints specified by SP800-132 have been added i.e.
|
||||
* - Check the range of the key length.
|
||||
* - Minimum iteration count of 1000.
|
||||
* - Randomly-generated portion of the salt shall be at least 128 bits.
|
||||
*/
|
||||
|
||||
static int pkcs5_pbkdf2_alg(const char *pass, size_t passlen,
|
||||
const unsigned char *salt, int saltlen, int iter,
|
||||
const EVP_MD *digest, unsigned char *key,
|
||||
size_t keylen)
|
||||
static int pbkdf2_derive(const char *pass, size_t passlen,
|
||||
const unsigned char *salt, int saltlen, int iter,
|
||||
const EVP_MD *digest, unsigned char *key,
|
||||
size_t keylen, int lower_bound_checks)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
|
||||
@ -209,9 +245,33 @@ static int pkcs5_pbkdf2_alg(const char *pass, size_t passlen,
|
||||
HMAC_CTX *hctx_tpl = NULL, *hctx = NULL;
|
||||
|
||||
mdlen = EVP_MD_size(digest);
|
||||
if (mdlen < 0)
|
||||
if (mdlen <= 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* This check should always be done because keylen / mdlen >= (2^32 - 1)
|
||||
* results in an overflow of the loop counter 'i'.
|
||||
*/
|
||||
if ((keylen / mdlen) >= KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO) {
|
||||
KDFerr(KDF_F_PBKDF2_DERIVE, KDF_R_INVALID_KEY_LEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lower_bound_checks) {
|
||||
if ((keylen * 8) < KDF_PBKDF2_MIN_KEY_LEN_BITS) {
|
||||
KDFerr(KDF_F_PBKDF2_DERIVE, KDF_R_INVALID_KEY_LEN);
|
||||
return 0;
|
||||
}
|
||||
if (saltlen < KDF_PBKDF2_MIN_SALT_LEN) {
|
||||
KDFerr(KDF_F_PBKDF2_DERIVE, KDF_R_INVALID_SALT_LEN);
|
||||
return 0;
|
||||
}
|
||||
if (iter < KDF_PBKDF2_MIN_ITERATIONS) {
|
||||
KDFerr(KDF_F_PBKDF2_DERIVE, KDF_R_INVALID_ITERATION_COUNT);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
hctx_tpl = HMAC_CTX_new();
|
||||
if (hctx_tpl == NULL)
|
||||
return 0;
|
||||
|
@ -10,7 +10,7 @@ Support for computing the B<PBKDF2> password-based KDF through the B<EVP_KDF>
|
||||
API.
|
||||
|
||||
The EVP_KDF_PBKDF2 algorithm implements the PBKDF2 password-based key
|
||||
derivation function, as described in RFC 2898; it derives a key from a password
|
||||
derivation function, as described in SP800-132; it derives a key from a password
|
||||
using a salt and iteration count.
|
||||
|
||||
=head2 Numeric identity
|
||||
@ -30,13 +30,38 @@ The supported controls are:
|
||||
|
||||
=item B<EVP_KDF_CTRL_SET_ITER>
|
||||
|
||||
This control has a default value of 2048.
|
||||
|
||||
=item B<EVP_KDF_CTRL_SET_MD>
|
||||
|
||||
These controls work as described in L<EVP_KDF_CTX(3)/CONTROLS>.
|
||||
|
||||
B<iter> is the iteration count and its value should be greater than or equal to
|
||||
1. RFC 2898 suggests an iteration count of at least 1000. The default value is
|
||||
2048. Any B<iter> less than 1 is treated as a single iteration.
|
||||
=item B<EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE>
|
||||
|
||||
This control expects one argument: C<int mode>
|
||||
|
||||
This control can be used to enable or disable SP800-132 compliance checks.
|
||||
|
||||
Setting the mode to 0 enables the compliance checks.
|
||||
|
||||
The checks performed are:
|
||||
|
||||
=over 4
|
||||
|
||||
=item - the iteration count is at least 1000.
|
||||
|
||||
=item - the salt length is at least 128 bits.
|
||||
|
||||
=item - the derived key length is at least 112 bits.
|
||||
|
||||
=back
|
||||
|
||||
The default provider uses a default mode of 1 for backwards compatibility,
|
||||
and the fips provider uses a default mode of 0.
|
||||
|
||||
EVP_KDF_ctrl_str() type string: "pkcs5"
|
||||
|
||||
The value string is expected to be a decimal number 0 or 1.
|
||||
|
||||
=back
|
||||
|
||||
@ -55,7 +80,7 @@ byte sequence.
|
||||
|
||||
=head1 CONFORMING TO
|
||||
|
||||
RFC 2898
|
||||
SP800-132
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
@ -66,9 +91,13 @@ L<EVP_KDF_ctrl(3)>,
|
||||
L<EVP_KDF_derive(3)>,
|
||||
L<EVP_KDF_CTX(3)/CONTROLS>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
This functionality was added to OpenSSL 3.0.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
Copyright 2018-2019 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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2016-2019 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
|
||||
@ -44,28 +44,29 @@ int EVP_KDF_nid(const EVP_KDF *kdf);
|
||||
# define EVP_KDF_name(o) OBJ_nid2sn(EVP_KDF_nid(o))
|
||||
const EVP_KDF *EVP_get_kdfbyname(const char *name);
|
||||
|
||||
# define EVP_KDF_CTRL_SET_PASS 0x01 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_SALT 0x02 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_ITER 0x03 /* int */
|
||||
# define EVP_KDF_CTRL_SET_MD 0x04 /* EVP_MD * */
|
||||
# define EVP_KDF_CTRL_SET_KEY 0x05 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_MAXMEM_BYTES 0x06 /* uint64_t */
|
||||
# define EVP_KDF_CTRL_SET_TLS_SECRET 0x07 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_RESET_TLS_SEED 0x08
|
||||
# define EVP_KDF_CTRL_ADD_TLS_SEED 0x09 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_RESET_HKDF_INFO 0x0a
|
||||
# define EVP_KDF_CTRL_ADD_HKDF_INFO 0x0b /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_HKDF_MODE 0x0c /* int */
|
||||
# define EVP_KDF_CTRL_SET_SCRYPT_N 0x0d /* uint64_t */
|
||||
# define EVP_KDF_CTRL_SET_SCRYPT_R 0x0e /* uint32_t */
|
||||
# define EVP_KDF_CTRL_SET_SCRYPT_P 0x0f /* uint32_t */
|
||||
# define EVP_KDF_CTRL_SET_SSHKDF_XCGHASH 0x10 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID 0x11 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_SSHKDF_TYPE 0x12 /* int */
|
||||
# define EVP_KDF_CTRL_SET_MAC 0x13 /* EVP_MAC * */
|
||||
# define EVP_KDF_CTRL_SET_MAC_SIZE 0x14 /* size_t */
|
||||
# define EVP_KDF_CTRL_SET_SSKDF_INFO 0x15 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_SHARED_INFO EVP_KDF_CTRL_SET_SSKDF_INFO
|
||||
# define EVP_KDF_CTRL_SET_PASS 0x01 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_SALT 0x02 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_ITER 0x03 /* int */
|
||||
# define EVP_KDF_CTRL_SET_MD 0x04 /* EVP_MD * */
|
||||
# define EVP_KDF_CTRL_SET_KEY 0x05 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_MAXMEM_BYTES 0x06 /* uint64_t */
|
||||
# define EVP_KDF_CTRL_SET_TLS_SECRET 0x07 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_RESET_TLS_SEED 0x08
|
||||
# define EVP_KDF_CTRL_ADD_TLS_SEED 0x09 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_RESET_HKDF_INFO 0x0a
|
||||
# define EVP_KDF_CTRL_ADD_HKDF_INFO 0x0b /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_HKDF_MODE 0x0c /* int */
|
||||
# define EVP_KDF_CTRL_SET_SCRYPT_N 0x0d /* uint64_t */
|
||||
# define EVP_KDF_CTRL_SET_SCRYPT_R 0x0e /* uint32_t */
|
||||
# define EVP_KDF_CTRL_SET_SCRYPT_P 0x0f /* uint32_t */
|
||||
# define EVP_KDF_CTRL_SET_SSHKDF_XCGHASH 0x10 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID 0x11 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_SSHKDF_TYPE 0x12 /* int */
|
||||
# define EVP_KDF_CTRL_SET_MAC 0x13 /* EVP_MAC * */
|
||||
# define EVP_KDF_CTRL_SET_MAC_SIZE 0x14 /* size_t */
|
||||
# define EVP_KDF_CTRL_SET_SSKDF_INFO 0x15 /* unsigned char *, size_t */
|
||||
# define EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE 0x16 /* int */
|
||||
# define EVP_KDF_CTRL_SET_SHARED_INFO EVP_KDF_CTRL_SET_SSKDF_INFO
|
||||
|
||||
# define EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND 0
|
||||
# define EVP_KDF_HKDF_MODE_EXTRACT_ONLY 1
|
||||
|
@ -28,6 +28,7 @@ int ERR_load_KDF_strings(void);
|
||||
# define KDF_F_KDF_HKDF_NEW 114
|
||||
# define KDF_F_KDF_HKDF_SIZE 115
|
||||
# define KDF_F_KDF_MD2CTRL 116
|
||||
# define KDF_F_KDF_PBKDF2_CTRL 140
|
||||
# define KDF_F_KDF_PBKDF2_CTRL_STR 117
|
||||
# define KDF_F_KDF_PBKDF2_DERIVE 118
|
||||
# define KDF_F_KDF_PBKDF2_NEW 119
|
||||
@ -43,6 +44,7 @@ int ERR_load_KDF_strings(void);
|
||||
# define KDF_F_KDF_TLS1_PRF_CTRL_STR 125
|
||||
# define KDF_F_KDF_TLS1_PRF_DERIVE 126
|
||||
# define KDF_F_KDF_TLS1_PRF_NEW 127
|
||||
# define KDF_F_PBKDF2_DERIVE 141
|
||||
# define KDF_F_PBKDF2_SET_MEMBUF 128
|
||||
# define KDF_F_PKEY_HKDF_CTRL_STR 103
|
||||
# define KDF_F_PKEY_HKDF_DERIVE 102
|
||||
@ -68,7 +70,10 @@ int ERR_load_KDF_strings(void);
|
||||
* KDF reason codes.
|
||||
*/
|
||||
# define KDF_R_INVALID_DIGEST 100
|
||||
# define KDF_R_INVALID_ITERATION_COUNT 119
|
||||
# define KDF_R_INVALID_KEY_LEN 120
|
||||
# define KDF_R_INVALID_MAC_TYPE 116
|
||||
# define KDF_R_INVALID_SALT_LEN 121
|
||||
# define KDF_R_MISSING_ITERATION_COUNT 109
|
||||
# define KDF_R_MISSING_KEY 104
|
||||
# define KDF_R_MISSING_MESSAGE_DIGEST 105
|
||||
|
@ -74,24 +74,57 @@ static int test_kdf_pbkdf2(void)
|
||||
{
|
||||
int ret;
|
||||
EVP_KDF_CTX *kctx;
|
||||
unsigned char out[32];
|
||||
static const unsigned char expected[sizeof(out)] = {
|
||||
0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3,
|
||||
0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0,
|
||||
0x2a, 0x30, 0x3f, 0x8e, 0xf3, 0xc2, 0x51, 0xdf,
|
||||
0xd6, 0xe2, 0xd8, 0x5a, 0x95, 0x47, 0x4c, 0x43
|
||||
unsigned char out[25];
|
||||
size_t len = 0;
|
||||
const unsigned char expected[sizeof(out)] = {
|
||||
0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f,
|
||||
0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf,
|
||||
0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18,
|
||||
0x1c
|
||||
};
|
||||
|
||||
ret =
|
||||
TEST_ptr(kctx = EVP_KDF_CTX_new_id(EVP_KDF_PBKDF2))
|
||||
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, "password",
|
||||
(size_t)8), 0)
|
||||
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "salt",
|
||||
(size_t)4), 0)
|
||||
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, 2), 0)
|
||||
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()), 0)
|
||||
&& TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0)
|
||||
&& TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
|
||||
if (sizeof(len) > 32)
|
||||
len = SIZE_MAX;
|
||||
|
||||
ret = TEST_ptr(kctx = EVP_KDF_CTX_new_id(EVP_KDF_PBKDF2))
|
||||
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS,
|
||||
"passwordPASSWORDpassword",
|
||||
(size_t)24), 0)
|
||||
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT,
|
||||
"saltSALTsaltSALTsaltSALTsaltSALTsalt",
|
||||
(size_t)36), 0)
|
||||
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, 4096), 0)
|
||||
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()),
|
||||
0)
|
||||
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE,
|
||||
0), 0)
|
||||
&& TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0)
|
||||
&& TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))
|
||||
/* A key length that is too small should fail */
|
||||
&& TEST_int_eq(EVP_KDF_derive(kctx, out, 112 / 8 - 1), 0)
|
||||
/* A key length that is too large should fail */
|
||||
&& (len == 0 || TEST_int_eq(EVP_KDF_derive(kctx, out, len), 0))
|
||||
/* Salt length less than 128 bits should fail */
|
||||
&& TEST_int_eq(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT,
|
||||
"123456781234567",
|
||||
(size_t)15), 0)
|
||||
/* A small iteration count should fail */
|
||||
&& TEST_int_eq(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, 1), 0)
|
||||
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE,
|
||||
1), 0)
|
||||
/* Small salts will pass if the "pkcs5" mode is enabled */
|
||||
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT,
|
||||
"123456781234567",
|
||||
(size_t)15), 0)
|
||||
/* A small iteration count will pass if "pkcs5" mode is enabled */
|
||||
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, 1), 0)
|
||||
/*
|
||||
* If the "pkcs5" mode is disabled then the small salt and iter will
|
||||
* fail when the derive gets called.
|
||||
*/
|
||||
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE,
|
||||
0), 0)
|
||||
&& TEST_int_eq(EVP_KDF_derive(kctx, out, sizeof(out)), 0);
|
||||
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
return ret;
|
||||
|
@ -25,8 +25,8 @@ my @kdf_tests = (
|
||||
{ cmd => [qw{openssl kdf -keylen 10 -kdfopt digest:SHA256 -kdfopt key:secret -kdfopt salt:salt -kdfopt info:label HKDF}],
|
||||
expected => '2a:c4:36:9f:52:59:96:f8:de:13',
|
||||
desc => 'HKDF SHA256' },
|
||||
{ cmd => [qw{openssl kdf -keylen 32 -kdfopt digest:SHA256 -kdfopt pass:password -kdfopt salt:salt -kdfopt iter:2 PBKDF2}],
|
||||
expected => 'ae:4d:0c:95:af:6b:46:d3:2d:0a:df:f9:28:f0:6d:d0:2a:30:3f:8e:f3:c2:51:df:d6:e2:d8:5a:95:47:4c:43',
|
||||
{ cmd => [qw{openssl kdf -keylen 25 -kdfopt digest:SHA256 -kdfopt pass:passwordPASSWORDpassword -kdfopt salt:saltSALTsaltSALTsaltSALTsaltSALTsalt -kdfopt iter:4096 PBKDF2}],
|
||||
expected => '34:8C:89:DB:CB:D3:2B:2F:32:D8:14:B8:11:6E:84:CF:2B:17:34:7E:BC:18:00:18:1C',
|
||||
desc => 'PBKDF2 SHA256'},
|
||||
{ cmd => [qw{openssl kdf -keylen 64 -kdfopt mac:KMAC128 -kdfopt maclen:20 -kdfopt hexkey:b74a149a161546f8c20b06ac4ed4 -kdfopt hexinfo:348a37a27ef1282f5f020dcc -kdfopt hexsalt:3638271ccd68a25dc24ecddd39ef3f89 SSKDF}],
|
||||
expected => 'e9:c1:84:53:a0:62:b5:3b:db:fc:bb:5a:34:bd:b8:e5:e7:07:ee:bb:5d:d1:34:42:43:d8:cf:c2:c2:e6:33:2f:91:bd:a5:86:f3:7d:e4:8a:65:d4:c5:14:fd:ef:aa:1e:67:54:f3:73:d2:38:e1:95:ae:15:7e:1d:e8:14:98:03',
|
||||
|
@ -306,6 +306,7 @@ Result = INTERNAL_ERROR
|
||||
Title = PBKDF2 tests
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.pass = pass:password
|
||||
Ctrl.salt = salt:salt
|
||||
Ctrl.iter = iter:1
|
||||
@ -313,6 +314,7 @@ Ctrl.digest = digest:sha1
|
||||
Output = 0c60c80f961f0e71f3a9b524af6012062fe037a6
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.pass = pass:password
|
||||
Ctrl.salt = salt:salt
|
||||
Ctrl.iter = iter:1
|
||||
@ -320,6 +322,7 @@ Ctrl.digest = digest:sha256
|
||||
Output = 120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.pass = pass:password
|
||||
Ctrl.salt = salt:salt
|
||||
Ctrl.iter = iter:1
|
||||
@ -327,6 +330,7 @@ Ctrl.digest = digest:sha512
|
||||
Output = 867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.pass = pass:password
|
||||
Ctrl.salt = salt:salt
|
||||
Ctrl.iter = iter:2
|
||||
@ -334,6 +338,7 @@ Ctrl.digest = digest:sha1
|
||||
Output = ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.pass = pass:password
|
||||
Ctrl.salt = salt:salt
|
||||
Ctrl.iter = iter:2
|
||||
@ -341,6 +346,7 @@ Ctrl.digest = digest:sha256
|
||||
Output = ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.pass = pass:password
|
||||
Ctrl.salt = salt:salt
|
||||
Ctrl.iter = iter:2
|
||||
@ -348,6 +354,7 @@ Ctrl.digest = digest:sha512
|
||||
Output = e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.pass = pass:password
|
||||
Ctrl.salt = salt:salt
|
||||
Ctrl.iter = iter:4096
|
||||
@ -355,6 +362,7 @@ Ctrl.digest = digest:sha1
|
||||
Output = 4b007901b765489abead49d926f721d065a429c1
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.pass = pass:password
|
||||
Ctrl.salt = salt:salt
|
||||
Ctrl.iter = iter:4096
|
||||
@ -362,6 +370,7 @@ Ctrl.digest = digest:sha256
|
||||
Output = c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.pass = pass:password
|
||||
Ctrl.salt = salt:salt
|
||||
Ctrl.iter = iter:4096
|
||||
@ -390,6 +399,7 @@ Ctrl.digest = digest:sha512
|
||||
Output = 8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.hexpass = hexpass:7061737300776f7264
|
||||
Ctrl.hexsalt = hexsalt:7361006c74
|
||||
Ctrl.iter = iter:4096
|
||||
@ -397,6 +407,7 @@ Ctrl.digest = digest:sha1
|
||||
Output = 56fa6aa75548099dcc37d7f03425e0c3
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.hexpass = hexpass:7061737300776f7264
|
||||
Ctrl.hexsalt = hexsalt:7361006c74
|
||||
Ctrl.iter = iter:4096
|
||||
@ -404,6 +415,7 @@ Ctrl.digest = digest:sha256
|
||||
Output = 89b69d0516f829893c696226650a8687
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.hexpass = hexpass:7061737300776f7264
|
||||
Ctrl.hexsalt = hexsalt:7361006c74
|
||||
Ctrl.iter = iter:4096
|
||||
@ -413,6 +425,7 @@ Output = 9d9e9c4cd21fe4be24d5b8244c759665
|
||||
Title = PBKDF2 tests for empty inputs
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.pass = pass:
|
||||
Ctrl.salt = salt:salt
|
||||
Ctrl.iter = iter:1
|
||||
@ -420,6 +433,7 @@ Ctrl.digest = digest:sha1
|
||||
Output = a33dddc30478185515311f8752895d36ea4363a2
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.pass = pass:
|
||||
Ctrl.salt = salt:salt
|
||||
Ctrl.iter = iter:1
|
||||
@ -427,6 +441,7 @@ Ctrl.digest = digest:sha256
|
||||
Output = f135c27993baf98773c5cdb40a5706ce6a345cde
|
||||
|
||||
KDF = PBKDF2
|
||||
Ctrl.pkcs5 = pkcs5:1
|
||||
Ctrl.pass = pass:
|
||||
Ctrl.salt = salt:salt
|
||||
Ctrl.iter = iter:1
|
||||
|
Loading…
Reference in New Issue
Block a user