2 * Copyright 1999-2021 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_pkcs12_new
;
27 static OSSL_FUNC_kdf_freectx_fn kdf_pkcs12_free
;
28 static OSSL_FUNC_kdf_reset_fn kdf_pkcs12_reset
;
29 static OSSL_FUNC_kdf_derive_fn kdf_pkcs12_derive
;
30 static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_pkcs12_settable_ctx_params
;
31 static OSSL_FUNC_kdf_set_ctx_params_fn kdf_pkcs12_set_ctx_params
;
32 static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_pkcs12_gettable_ctx_params
;
33 static OSSL_FUNC_kdf_get_ctx_params_fn kdf_pkcs12_get_ctx_params
;
46 /* PKCS12 compatible key/IV generation */
48 static int pkcs12kdf_derive(const unsigned char *pass
, size_t passlen
,
49 const unsigned char *salt
, size_t saltlen
,
50 int id
, uint64_t iter
, const EVP_MD
*md_type
,
51 unsigned char *out
, size_t n
)
53 unsigned char *B
= NULL
, *D
= NULL
, *I
= NULL
, *p
= NULL
, *Ai
= NULL
;
54 size_t Slen
, Plen
, Ilen
;
58 EVP_MD_CTX
*ctx
= NULL
;
60 ctx
= EVP_MD_CTX_new();
62 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
65 vi
= EVP_MD_block_size(md_type
);
66 ui
= EVP_MD_size(md_type
);
67 if (ui
< 0 || vi
<= 0) {
68 ERR_raise(ERR_LIB_PROV
, PROV_R_INVALID_DIGEST_SIZE
);
73 D
= OPENSSL_malloc(v
);
74 Ai
= OPENSSL_malloc(u
);
75 B
= OPENSSL_malloc(v
+ 1);
76 Slen
= v
* ((saltlen
+ v
- 1) / v
);
78 Plen
= v
* ((passlen
+ v
- 1) / v
);
82 I
= OPENSSL_malloc(Ilen
);
83 if (D
== NULL
|| Ai
== NULL
|| B
== NULL
|| I
== NULL
) {
84 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
87 for (i
= 0; i
< v
; i
++)
90 for (i
= 0; i
< Slen
; i
++)
91 *p
++ = salt
[i
% saltlen
];
92 for (i
= 0; i
< Plen
; i
++)
93 *p
++ = pass
[i
% passlen
];
95 if (!EVP_DigestInit_ex(ctx
, md_type
, NULL
)
96 || !EVP_DigestUpdate(ctx
, D
, v
)
97 || !EVP_DigestUpdate(ctx
, I
, Ilen
)
98 || !EVP_DigestFinal_ex(ctx
, Ai
, NULL
))
100 for (iter_cnt
= 1; iter_cnt
< iter
; iter_cnt
++) {
101 if (!EVP_DigestInit_ex(ctx
, md_type
, NULL
)
102 || !EVP_DigestUpdate(ctx
, Ai
, u
)
103 || !EVP_DigestFinal_ex(ctx
, Ai
, NULL
))
106 memcpy(out
, Ai
, n
< u
? n
: u
);
113 for (j
= 0; j
< v
; j
++)
115 for (j
= 0; j
< Ilen
; j
+= v
) {
116 unsigned char *Ij
= I
+ j
;
119 /* Work out Ij = Ij + B + 1 */
120 for (k
= v
; k
> 0;) {
123 Ij
[k
] = (unsigned char)c
;
134 EVP_MD_CTX_free(ctx
);
138 static void *kdf_pkcs12_new(void *provctx
)
142 if (!ossl_prov_is_running())
145 ctx
= OPENSSL_zalloc(sizeof(*ctx
));
147 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
150 ctx
->provctx
= provctx
;
154 static void kdf_pkcs12_cleanup(KDF_PKCS12
*ctx
)
156 ossl_prov_digest_reset(&ctx
->digest
);
157 OPENSSL_free(ctx
->salt
);
158 OPENSSL_clear_free(ctx
->pass
, ctx
->pass_len
);
159 memset(ctx
, 0, sizeof(*ctx
));
162 static void kdf_pkcs12_free(void *vctx
)
164 KDF_PKCS12
*ctx
= (KDF_PKCS12
*)vctx
;
167 kdf_pkcs12_cleanup(ctx
);
172 static void kdf_pkcs12_reset(void *vctx
)
174 KDF_PKCS12
*ctx
= (KDF_PKCS12
*)vctx
;
175 void *provctx
= ctx
->provctx
;
177 kdf_pkcs12_cleanup(ctx
);
178 ctx
->provctx
= provctx
;
181 static int pkcs12kdf_set_membuf(unsigned char **buffer
, size_t *buflen
,
184 OPENSSL_clear_free(*buffer
, *buflen
);
185 if (p
->data_size
== 0) {
186 if ((*buffer
= OPENSSL_malloc(1)) == NULL
) {
187 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
190 } else if (p
->data
!= NULL
) {
192 if (!OSSL_PARAM_get_octet_string(p
, (void **)buffer
, 0, buflen
))
198 static int kdf_pkcs12_derive(void *vctx
, unsigned char *key
, size_t keylen
,
199 const OSSL_PARAM params
[])
201 KDF_PKCS12
*ctx
= (KDF_PKCS12
*)vctx
;
204 if (!ossl_prov_is_running() || !kdf_pkcs12_set_ctx_params(ctx
, params
))
207 if (ctx
->pass
== NULL
) {
208 ERR_raise(ERR_LIB_PROV
, PROV_R_MISSING_PASS
);
212 if (ctx
->salt
== NULL
) {
213 ERR_raise(ERR_LIB_PROV
, PROV_R_MISSING_SALT
);
217 md
= ossl_prov_digest_md(&ctx
->digest
);
218 return pkcs12kdf_derive(ctx
->pass
, ctx
->pass_len
, ctx
->salt
, ctx
->salt_len
,
219 ctx
->id
, ctx
->iter
, md
, key
, keylen
);
222 static int kdf_pkcs12_set_ctx_params(void *vctx
, const OSSL_PARAM params
[])
225 KDF_PKCS12
*ctx
= vctx
;
226 OSSL_LIB_CTX
*provctx
= PROV_LIBCTX_OF(ctx
->provctx
);
231 if (!ossl_prov_digest_load_from_params(&ctx
->digest
, params
, provctx
))
234 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_PASSWORD
)) != NULL
)
235 if (!pkcs12kdf_set_membuf(&ctx
->pass
, &ctx
->pass_len
, p
))
238 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_SALT
)) != NULL
)
239 if (!pkcs12kdf_set_membuf(&ctx
->salt
, &ctx
->salt_len
,p
))
242 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_PKCS12_ID
)) != NULL
)
243 if (!OSSL_PARAM_get_int(p
, &ctx
->id
))
246 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_ITER
)) != NULL
)
247 if (!OSSL_PARAM_get_uint64(p
, &ctx
->iter
))
252 static const OSSL_PARAM
*kdf_pkcs12_settable_ctx_params(
253 ossl_unused
void *ctx
, ossl_unused
void *provctx
)
255 static const OSSL_PARAM known_settable_ctx_params
[] = {
256 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES
, NULL
, 0),
257 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST
, NULL
, 0),
258 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD
, NULL
, 0),
259 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT
, NULL
, 0),
260 OSSL_PARAM_uint64(OSSL_KDF_PARAM_ITER
, NULL
),
261 OSSL_PARAM_int(OSSL_KDF_PARAM_PKCS12_ID
, NULL
),
264 return known_settable_ctx_params
;
267 static int kdf_pkcs12_get_ctx_params(void *vctx
, OSSL_PARAM params
[])
271 if ((p
= OSSL_PARAM_locate(params
, OSSL_KDF_PARAM_SIZE
)) != NULL
)
272 return OSSL_PARAM_set_size_t(p
, SIZE_MAX
);
276 static const OSSL_PARAM
*kdf_pkcs12_gettable_ctx_params(
277 ossl_unused
void *ctx
, ossl_unused
void *provctx
)
279 static const OSSL_PARAM known_gettable_ctx_params
[] = {
280 OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE
, NULL
),
283 return known_gettable_ctx_params
;
286 const OSSL_DISPATCH ossl_kdf_pkcs12_functions
[] = {
287 { OSSL_FUNC_KDF_NEWCTX
, (void(*)(void))kdf_pkcs12_new
},
288 { OSSL_FUNC_KDF_FREECTX
, (void(*)(void))kdf_pkcs12_free
},
289 { OSSL_FUNC_KDF_RESET
, (void(*)(void))kdf_pkcs12_reset
},
290 { OSSL_FUNC_KDF_DERIVE
, (void(*)(void))kdf_pkcs12_derive
},
291 { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS
,
292 (void(*)(void))kdf_pkcs12_settable_ctx_params
},
293 { OSSL_FUNC_KDF_SET_CTX_PARAMS
, (void(*)(void))kdf_pkcs12_set_ctx_params
},
294 { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS
,
295 (void(*)(void))kdf_pkcs12_gettable_ctx_params
},
296 { OSSL_FUNC_KDF_GET_CTX_PARAMS
, (void(*)(void))kdf_pkcs12_get_ctx_params
},