Skip to content

Commit 0f18367

Browse files
jon-oraclepaulidale
authored andcommitted
Add PBKDF1 to the legacy provider
Reviewed-by: Shane Lontis <shane.lontis@oracle.com> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from openssl#14326)
1 parent d136db2 commit 0f18367

14 files changed

Lines changed: 591 additions & 93 deletions

File tree

CHANGES.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,19 @@ breaking changes, and mappings for the large list of deprecated functions.
176176

177177
*Matt Caswell*
178178

179+
* PKCS#5 PBKDF1 key derivation has been moved from PKCS5_PBE_keyivgen() into
180+
the legacy crypto provider as an EVP_KDF. Applications requiring this KDF
181+
will need to load the legacy crypto provider. This includes these PBE
182+
algorithms which use this KDF:
183+
- NID_pbeWithMD2AndDES_CBC
184+
- NID_pbeWithMD5AndDES_CBC
185+
- NID_pbeWithSHA1AndRC2_CBC
186+
- NID_pbeWithMD2AndRC2_CBC
187+
- NID_pbeWithMD5AndRC2_CBC
188+
- NID_pbeWithSHA1AndDES_CBC
189+
190+
*Jon Spillett*
191+
179192
* Deprecated obsolete EVP_PKEY_CTX_get0_dh_kdf_ukm() and
180193
EVP_PKEY_CTX_get0_ecdh_kdf_ukm() functions.
181194

crypto/evp/p5_crpt.c

Lines changed: 34 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
#include "internal/cryptlib.h"
1313
#include <openssl/x509.h>
1414
#include <openssl/evp.h>
15+
#include <openssl/core_names.h>
16+
#include <openssl/kdf.h>
17+
18+
#define PKCS5_PBES1_OUTPUT_LENGTH 16
19+
#define PKCS5_PBES1_KEY_IV_LENGTH 8
1520

1621
/*
1722
* Doesn't do anything now: Builtin PBE algorithms in static table.
@@ -25,15 +30,16 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
2530
ASN1_TYPE *param, const EVP_CIPHER *cipher,
2631
const EVP_MD *md, int en_de)
2732
{
28-
EVP_MD_CTX *ctx;
29-
unsigned char md_tmp[EVP_MAX_MD_SIZE];
30-
unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
31-
int i, ivl, kl;
32-
PBEPARAM *pbe;
33+
unsigned char out[PKCS5_PBES1_OUTPUT_LENGTH];
34+
int ivl, kl;
35+
PBEPARAM *pbe = NULL;
3336
int saltlen, iter;
3437
unsigned char *salt;
35-
int mdsize;
3638
int rv = 0;
39+
EVP_KDF *kdf;
40+
EVP_KDF_CTX *kctx = NULL;
41+
OSSL_PARAM params[5], *p = params;
42+
const char *mdname = EVP_MD_name(md);
3743

3844
/* Extract useful info from parameter */
3945
if (param == NULL || param->type != V_ASN1_SEQUENCE ||
@@ -49,16 +55,14 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
4955
}
5056

5157
ivl = EVP_CIPHER_iv_length(cipher);
52-
if (ivl < 0 || ivl > 16) {
58+
if (ivl != PKCS5_PBES1_KEY_IV_LENGTH) {
5359
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH);
54-
PBEPARAM_free(pbe);
55-
return 0;
60+
goto err;
5661
}
5762
kl = EVP_CIPHER_key_length(cipher);
58-
if (kl < 0 || kl > (int)sizeof(md_tmp)) {
63+
if (kl != PKCS5_PBES1_KEY_IV_LENGTH) {
5964
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH);
60-
PBEPARAM_free(pbe);
61-
return 0;
65+
goto err;
6266
}
6367

6468
if (pbe->iter == NULL)
@@ -73,43 +77,29 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
7377
else if (passlen == -1)
7478
passlen = strlen(pass);
7579

76-
ctx = EVP_MD_CTX_new();
77-
if (ctx == NULL) {
78-
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
79-
goto err;
80-
}
81-
82-
if (!EVP_DigestInit_ex(ctx, md, NULL))
83-
goto err;
84-
if (!EVP_DigestUpdate(ctx, pass, passlen))
80+
kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_PBKDF1, NULL);
81+
kctx = EVP_KDF_CTX_new(kdf);
82+
EVP_KDF_free(kdf);
83+
if (kctx == NULL)
8584
goto err;
86-
if (!EVP_DigestUpdate(ctx, salt, saltlen))
87-
goto err;
88-
PBEPARAM_free(pbe);
89-
pbe = NULL;
90-
if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL))
85+
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
86+
(char *)pass, (size_t)passlen);
87+
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
88+
salt, saltlen);
89+
*p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter);
90+
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
91+
(char *)mdname, 0);
92+
*p = OSSL_PARAM_construct_end();
93+
if (EVP_KDF_derive(kctx, out, PKCS5_PBES1_OUTPUT_LENGTH, params) != 1)
9194
goto err;
92-
mdsize = EVP_MD_size(md);
93-
if (mdsize < 0)
94-
goto err;
95-
for (i = 1; i < iter; i++) {
96-
if (!EVP_DigestInit_ex(ctx, md, NULL))
97-
goto err;
98-
if (!EVP_DigestUpdate(ctx, md_tmp, mdsize))
99-
goto err;
100-
if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL))
101-
goto err;
102-
}
103-
memcpy(key, md_tmp, kl);
104-
memcpy(iv, md_tmp + (16 - ivl), ivl);
105-
if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de))
95+
96+
if (!EVP_CipherInit_ex(cctx, cipher, NULL, out,
97+
out + PKCS5_PBES1_KEY_IV_LENGTH, en_de))
10698
goto err;
107-
OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
108-
OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
109-
OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
99+
OPENSSL_cleanse(out, PKCS5_PBES1_OUTPUT_LENGTH);
110100
rv = 1;
111101
err:
102+
EVP_KDF_CTX_free(kctx);
112103
PBEPARAM_free(pbe);
113-
EVP_MD_CTX_free(ctx);
114104
return rv;
115105
}

doc/man3/PKCS5_PBE_keyivgen.pod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ PKCS5_v2_PBE_keyivgen_ex(), EVP_PBE_scrypt_ex(), PKCS5_v2_scrypt_keyivgen_ex(),
158158
PKCS5_pbe_set0_algor_ex(), PKCS5_pbe_set_ex(), PKCS5_pbe2_set_iv_ex() and
159159
PKCS5_pbkdf2_set_ex() were added in OpenSSL 3.0.
160160

161+
From OpenSSL 3.0 the PBKDF1 algorithm used in PKCS5_PBE_keyivgen() and
162+
PKCS5_PBE_keyivgen_ex() has been moved to the legacy provider as an EVP_KDF.
163+
161164
=head1 COPYRIGHT
162165

163166
Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.

doc/man7/OSSL_PROVIDER-legacy.pod

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ Disabled by default. Use I<enable-rc5> config option to enable.
7979

8080
=back
8181

82+
=head2 Key Derivation Function (KDF)
83+
84+
=over 4
85+
86+
=item PBKDF1
87+
88+
=back
89+
8290
=begin comment
8391

8492
When algorithms for other operations start appearing, the

include/openssl/core_names.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ extern "C" {
220220

221221
/* Known KDF names */
222222
#define OSSL_KDF_NAME_HKDF "HKDF"
223+
#define OSSL_KDF_NAME_PBKDF1 "PBKDF1"
223224
#define OSSL_KDF_NAME_PBKDF2 "PBKDF2"
224225
#define OSSL_KDF_NAME_SCRYPT "SCRYPT"
225226
#define OSSL_KDF_NAME_SSHKDF "SSHKDF"

providers/common/build.info

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@ SOURCE[../libcommon.a]=provider_err.c provider_ctx.c
44
$FIPSCOMMON=provider_util.c capabilities.c bio_prov.c digest_to_nid.c\
55
securitycheck.c provider_seeding.c
66
SOURCE[../libdefault.a]=$FIPSCOMMON securitycheck_default.c
7+
IF[{- !$disabled{module} && !$disabled{shared} -}]
8+
SOURCE[../liblegacy.a]=provider_util.c
9+
ENDIF
710
SOURCE[../libfips.a]=$FIPSCOMMON securitycheck_fips.c

providers/implementations/include/prov/implementations.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ extern const OSSL_DISPATCH ossl_siphash_functions[];
249249
extern const OSSL_DISPATCH ossl_poly1305_functions[];
250250

251251
/* KDFs / PRFs */
252+
extern const OSSL_DISPATCH ossl_kdf_pbkdf1_functions[];
252253
extern const OSSL_DISPATCH ossl_kdf_pbkdf2_functions[];
253254
extern const OSSL_DISPATCH ossl_kdf_pkcs12_functions[];
254255
#ifndef OPENSSL_NO_SCRYPT

providers/implementations/kdfs/build.info

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ $TLS1_PRF_GOAL=../../libdefault.a ../../libfips.a
55
$HKDF_GOAL=../../libdefault.a ../../libfips.a
66
$KBKDF_GOAL=../../libdefault.a ../../libfips.a
77
$KRB5KDF_GOAL=../../libdefault.a
8+
$PBKDF1_GOAL=../../liblegacy.a
89
$PBKDF2_GOAL=../../libdefault.a ../../libfips.a
910
$PKCS12KDF_GOAL=../../libdefault.a
1011
$SSKDF_GOAL=../../libdefault.a ../../libfips.a
@@ -20,6 +21,8 @@ SOURCE[$KBKDF_GOAL]=kbkdf.c
2021

2122
SOURCE[$KRB5KDF_GOAL]=krb5kdf.c
2223

24+
SOURCE[$PBKDF1_GOAL]=pbkdf1.c
25+
2326
SOURCE[$PBKDF2_GOAL]=pbkdf2.c
2427
# Extra code to satisfy the FIPS and non-FIPS separation.
2528
# When the PBKDF2 moves to legacy, this can be removed.

0 commit comments

Comments
 (0)