2 * Copyright 1999-2024 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 if (n
> (size_t)mdsize
) {
76 ERR_raise(ERR_LIB_PROV
, PROV_R_LENGTH_TOO_LARGE
);
80 for (i
= 1; i
< iter
; i
++) {
81 if (!EVP_DigestInit_ex(ctx
, md_type
, NULL
))
83 if (!EVP_DigestUpdate(ctx
, md_tmp
, mdsize
))
85 if (!EVP_DigestFinal_ex(ctx
, md_tmp
, NULL
))
89 memcpy(out
, md_tmp
, n
);
92 OPENSSL_cleanse(md_tmp
, EVP_MAX_MD_SIZE
);
97 static void *kdf_pbkdf1_new(void *provctx
)
101 if (!ossl_prov_is_running())
104 ctx
= OPENSSL_zalloc(sizeof(*ctx
));
107 ctx
->provctx
= provctx
;
111 static void kdf_pbkdf1_cleanup(KDF_PBKDF1
*ctx
)
113 ossl_prov_digest_reset(&ctx
->digest
);
114 OPENSSL_free(ctx
->salt
);
115 OPENSSL_clear_free(ctx
->pass
, ctx
->pass_len
);
116 memset(ctx
, 0, sizeof(*ctx
));
119 static void kdf_pbkdf1_free(void *vctx
)
121 KDF_PBKDF1
*ctx
= (KDF_PBKDF1
*)vctx
;
124 kdf_pbkdf1_cleanup(ctx
);
129 static void kdf_pbkdf1_reset(void *vctx
)
131 KDF_PBKDF1
*ctx
= (KDF_PBKDF1
*)vctx
;
132 void *provctx
= ctx
->provctx
;
134 kdf_pbkdf1_cleanup(ctx
);
135 ctx
->provctx
= provctx
;
138 static void *kdf_pbkdf1_dup(void *vctx
)
140 const KDF_PBKDF1
*src
= (const KDF_PBKDF1
*)vctx
;
143 dest
= kdf_pbkdf1_new(src
->provctx
);
145 if (!ossl_prov_memdup(src
->salt
, src
->salt_len
,
146 &dest
->salt
, &dest
->salt_len
)
147 || !ossl_prov_memdup(src
->pass
, src
->pass_len
,
148 &dest
->pass
, &dest
->pass_len
)
149 || !ossl_prov_digest_copy(&dest
->digest
, &src
->digest
))
151 dest
->iter
= src
->iter
;
156 kdf_pbkdf1_free(dest
);
160 static int kdf_pbkdf1_set_membuf(unsigned char **buffer
, size_t *buflen
,
163 OPENSSL_clear_free(*buffer
, *buflen
);
167 if (p
->data_size
== 0) {
168 if ((*buffer
= OPENSSL_malloc(1)) == NULL
)
170 } else if (p
->data
!= NULL
) {
171 if (!OSSL_PARAM_get_octet_string(p
, (void **)buffer
, 0, buflen
))
177 static int kdf_pbkdf1_derive(void *vctx
, unsigned char *key
, size_t keylen
,
178 const OSSL_PARAM params
[])
180 KDF_PBKDF1
*ctx
= (KDF_PBKDF1
*)vctx
;
183 if (!ossl_prov_is_running() || !kdf_pbkdf1_set_ctx_params(ctx
, params
))
186 if (ctx
->pass
== NULL
) {
187 ERR_raise(ERR_LIB_PROV
, PROV_R_MISSING_PASS
);
191 if (ctx
->salt
== NULL
) {
192 ERR_raise(ERR_LIB_PROV
, PROV_R_MISSING_SALT
);
196 md
= ossl_prov_digest_md(&ctx
->digest
);
197 return kdf_pbkdf1_do_derive(ctx
->pass
, ctx
->pass_len
, ctx
->salt
, ctx
->salt_len
,
198 ctx
->iter
, md
, key
, keylen
);
201 static int kdf_pbkdf1_set_ctx_params(void *vctx
, const OSSL_PARAM params
[])
204 KDF_PBKDF1
*ctx
= vctx
;
205 OSSL_LIB_CTX
*libctx
= PROV_LIBCTX_OF(ctx
->provctx
);
207 if (!ossl_prov_digest_load_from_params(&ctx
->digest
, params
, libctx
))
210 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_PASSWORD
)) != NULL
)
211 if (!kdf_pbkdf1_set_membuf(&ctx
->pass
, &ctx
->pass_len
, p
))
214 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_SALT
)) != NULL
)
215 if (!kdf_pbkdf1_set_membuf(&ctx
->salt
, &ctx
->salt_len
, p
))
218 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_ITER
)) != NULL
)
219 if (!OSSL_PARAM_get_uint64(p
, &ctx
->iter
))
224 static const OSSL_PARAM
*kdf_pbkdf1_settable_ctx_params(ossl_unused
void *ctx
,
225 ossl_unused
void *p_ctx
)
227 static const OSSL_PARAM known_settable_ctx_params
[] = {
228 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES
, NULL
, 0),
229 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST
, NULL
, 0),
230 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD
, NULL
, 0),
231 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT
, NULL
, 0),
232 OSSL_PARAM_uint64(OSSL_KDF_PARAM_ITER
, NULL
),
235 return known_settable_ctx_params
;
238 static int kdf_pbkdf1_get_ctx_params(void *vctx
, OSSL_PARAM params
[])
242 if ((p
= OSSL_PARAM_locate(params
, OSSL_KDF_PARAM_SIZE
)) != NULL
)
243 return OSSL_PARAM_set_size_t(p
, SIZE_MAX
);
247 static const OSSL_PARAM
*kdf_pbkdf1_gettable_ctx_params(ossl_unused
void *ctx
,
248 ossl_unused
void *p_ctx
)
250 static const OSSL_PARAM known_gettable_ctx_params
[] = {
251 OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE
, NULL
),
254 return known_gettable_ctx_params
;
257 const OSSL_DISPATCH ossl_kdf_pbkdf1_functions
[] = {
258 { OSSL_FUNC_KDF_NEWCTX
, (void(*)(void))kdf_pbkdf1_new
},
259 { OSSL_FUNC_KDF_DUPCTX
, (void(*)(void))kdf_pbkdf1_dup
},
260 { OSSL_FUNC_KDF_FREECTX
, (void(*)(void))kdf_pbkdf1_free
},
261 { OSSL_FUNC_KDF_RESET
, (void(*)(void))kdf_pbkdf1_reset
},
262 { OSSL_FUNC_KDF_DERIVE
, (void(*)(void))kdf_pbkdf1_derive
},
263 { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS
,
264 (void(*)(void))kdf_pbkdf1_settable_ctx_params
},
265 { OSSL_FUNC_KDF_SET_CTX_PARAMS
, (void(*)(void))kdf_pbkdf1_set_ctx_params
},
266 { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS
,
267 (void(*)(void))kdf_pbkdf1_gettable_ctx_params
},
268 { OSSL_FUNC_KDF_GET_CTX_PARAMS
, (void(*)(void))kdf_pbkdf1_get_ctx_params
},