2 * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
10 #include <openssl/trace.h>
14 #include <openssl/evp.h>
15 #include <openssl/kdf.h>
16 #include <openssl/core_names.h>
17 #include <openssl/proverr.h>
18 #include "internal/cryptlib.h"
19 #include "internal/numbers.h"
20 #include "crypto/evp.h"
21 #include "prov/provider_ctx.h"
22 #include "prov/providercommon.h"
23 #include "prov/implementations.h"
24 #include "prov/provider_util.h"
26 static OSSL_FUNC_kdf_newctx_fn kdf_pbkdf1_new
;
27 static OSSL_FUNC_kdf_dupctx_fn kdf_pbkdf1_dup
;
28 static OSSL_FUNC_kdf_freectx_fn kdf_pbkdf1_free
;
29 static OSSL_FUNC_kdf_reset_fn kdf_pbkdf1_reset
;
30 static OSSL_FUNC_kdf_derive_fn kdf_pbkdf1_derive
;
31 static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_pbkdf1_settable_ctx_params
;
32 static OSSL_FUNC_kdf_set_ctx_params_fn kdf_pbkdf1_set_ctx_params
;
33 static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_pbkdf1_gettable_ctx_params
;
34 static OSSL_FUNC_kdf_get_ctx_params_fn kdf_pbkdf1_get_ctx_params
;
47 * PKCS5 PBKDF1 compatible key/IV generation as specified in:
48 * https://tools.ietf.org/html/rfc8018#page-10
51 static int kdf_pbkdf1_do_derive(const unsigned char *pass
, size_t passlen
,
52 const unsigned char *salt
, size_t saltlen
,
53 uint64_t iter
, const EVP_MD
*md_type
,
54 unsigned char *out
, size_t n
)
58 unsigned char md_tmp
[EVP_MAX_MD_SIZE
];
59 EVP_MD_CTX
*ctx
= NULL
;
61 ctx
= EVP_MD_CTX_new();
63 ERR_raise(ERR_LIB_PROV
, ERR_R_EVP_LIB
);
67 if (!EVP_DigestInit_ex(ctx
, md_type
, NULL
)
68 || !EVP_DigestUpdate(ctx
, pass
, passlen
)
69 || !EVP_DigestUpdate(ctx
, salt
, saltlen
)
70 || !EVP_DigestFinal_ex(ctx
, md_tmp
, NULL
))
72 mdsize
= EVP_MD_size(md_type
);
75 for (i
= 1; i
< iter
; i
++) {
76 if (!EVP_DigestInit_ex(ctx
, md_type
, NULL
))
78 if (!EVP_DigestUpdate(ctx
, md_tmp
, mdsize
))
80 if (!EVP_DigestFinal_ex(ctx
, md_tmp
, NULL
))
84 memcpy(out
, md_tmp
, n
);
91 static void *kdf_pbkdf1_new(void *provctx
)
95 if (!ossl_prov_is_running())
98 ctx
= OPENSSL_zalloc(sizeof(*ctx
));
101 ctx
->provctx
= provctx
;
105 static void kdf_pbkdf1_cleanup(KDF_PBKDF1
*ctx
)
107 ossl_prov_digest_reset(&ctx
->digest
);
108 OPENSSL_free(ctx
->salt
);
109 OPENSSL_clear_free(ctx
->pass
, ctx
->pass_len
);
110 memset(ctx
, 0, sizeof(*ctx
));
113 static void kdf_pbkdf1_free(void *vctx
)
115 KDF_PBKDF1
*ctx
= (KDF_PBKDF1
*)vctx
;
118 kdf_pbkdf1_cleanup(ctx
);
123 static void kdf_pbkdf1_reset(void *vctx
)
125 KDF_PBKDF1
*ctx
= (KDF_PBKDF1
*)vctx
;
126 void *provctx
= ctx
->provctx
;
128 kdf_pbkdf1_cleanup(ctx
);
129 ctx
->provctx
= provctx
;
132 static void *kdf_pbkdf1_dup(void *vctx
)
134 const KDF_PBKDF1
*src
= (const KDF_PBKDF1
*)vctx
;
137 dest
= kdf_pbkdf1_new(src
->provctx
);
139 if (!ossl_prov_memdup(src
->salt
, src
->salt_len
,
140 &dest
->salt
, &dest
->salt_len
)
141 || !ossl_prov_memdup(src
->pass
, src
->pass_len
,
142 &dest
->pass
, &dest
->pass_len
)
143 || !ossl_prov_digest_copy(&dest
->digest
, &src
->digest
))
145 dest
->iter
= src
->iter
;
150 kdf_pbkdf1_free(dest
);
154 static int kdf_pbkdf1_set_membuf(unsigned char **buffer
, size_t *buflen
,
157 OPENSSL_clear_free(*buffer
, *buflen
);
161 if (p
->data_size
== 0) {
162 if ((*buffer
= OPENSSL_malloc(1)) == NULL
)
164 } else if (p
->data
!= NULL
) {
165 if (!OSSL_PARAM_get_octet_string(p
, (void **)buffer
, 0, buflen
))
171 static int kdf_pbkdf1_derive(void *vctx
, unsigned char *key
, size_t keylen
,
172 const OSSL_PARAM params
[])
174 KDF_PBKDF1
*ctx
= (KDF_PBKDF1
*)vctx
;
177 if (!ossl_prov_is_running() || !kdf_pbkdf1_set_ctx_params(ctx
, params
))
180 if (ctx
->pass
== NULL
) {
181 ERR_raise(ERR_LIB_PROV
, PROV_R_MISSING_PASS
);
185 if (ctx
->salt
== NULL
) {
186 ERR_raise(ERR_LIB_PROV
, PROV_R_MISSING_SALT
);
190 md
= ossl_prov_digest_md(&ctx
->digest
);
191 return kdf_pbkdf1_do_derive(ctx
->pass
, ctx
->pass_len
, ctx
->salt
, ctx
->salt_len
,
192 ctx
->iter
, md
, key
, keylen
);
195 static int kdf_pbkdf1_set_ctx_params(void *vctx
, const OSSL_PARAM params
[])
198 KDF_PBKDF1
*ctx
= vctx
;
199 OSSL_LIB_CTX
*libctx
= PROV_LIBCTX_OF(ctx
->provctx
);
201 if (!ossl_prov_digest_load_from_params(&ctx
->digest
, params
, libctx
))
204 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_PASSWORD
)) != NULL
)
205 if (!kdf_pbkdf1_set_membuf(&ctx
->pass
, &ctx
->pass_len
, p
))
208 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_SALT
)) != NULL
)
209 if (!kdf_pbkdf1_set_membuf(&ctx
->salt
, &ctx
->salt_len
, p
))
212 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_ITER
)) != NULL
)
213 if (!OSSL_PARAM_get_uint64(p
, &ctx
->iter
))
218 static const OSSL_PARAM
*kdf_pbkdf1_settable_ctx_params(ossl_unused
void *ctx
,
219 ossl_unused
void *p_ctx
)
221 static const OSSL_PARAM known_settable_ctx_params
[] = {
222 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES
, NULL
, 0),
223 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST
, NULL
, 0),
224 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD
, NULL
, 0),
225 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT
, NULL
, 0),
226 OSSL_PARAM_uint64(OSSL_KDF_PARAM_ITER
, NULL
),
229 return known_settable_ctx_params
;
232 static int kdf_pbkdf1_get_ctx_params(void *vctx
, OSSL_PARAM params
[])
236 if ((p
= OSSL_PARAM_locate(params
, OSSL_KDF_PARAM_SIZE
)) != NULL
)
237 return OSSL_PARAM_set_size_t(p
, SIZE_MAX
);
241 static const OSSL_PARAM
*kdf_pbkdf1_gettable_ctx_params(ossl_unused
void *ctx
,
242 ossl_unused
void *p_ctx
)
244 static const OSSL_PARAM known_gettable_ctx_params
[] = {
245 OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE
, NULL
),
248 return known_gettable_ctx_params
;
251 const OSSL_DISPATCH ossl_kdf_pbkdf1_functions
[] = {
252 { OSSL_FUNC_KDF_NEWCTX
, (void(*)(void))kdf_pbkdf1_new
},
253 { OSSL_FUNC_KDF_DUPCTX
, (void(*)(void))kdf_pbkdf1_dup
},
254 { OSSL_FUNC_KDF_FREECTX
, (void(*)(void))kdf_pbkdf1_free
},
255 { OSSL_FUNC_KDF_RESET
, (void(*)(void))kdf_pbkdf1_reset
},
256 { OSSL_FUNC_KDF_DERIVE
, (void(*)(void))kdf_pbkdf1_derive
},
257 { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS
,
258 (void(*)(void))kdf_pbkdf1_settable_ctx_params
},
259 { OSSL_FUNC_KDF_SET_CTX_PARAMS
, (void(*)(void))kdf_pbkdf1_set_ctx_params
},
260 { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS
,
261 (void(*)(void))kdf_pbkdf1_gettable_ctx_params
},
262 { OSSL_FUNC_KDF_GET_CTX_PARAMS
, (void(*)(void))kdf_pbkdf1_get_ctx_params
},