2 * Copyright 2019-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/evp.h>
11 #include <openssl/err.h>
12 #include <openssl/core.h>
13 #include <openssl/core_dispatch.h>
14 #include <openssl/kdf.h>
15 #include "internal/provider.h"
16 #include "internal/core.h"
17 #include "crypto/evp.h"
18 #include "evp_local.h"
20 static int evp_kdf_up_ref(void *vkdf
)
22 EVP_KDF
*kdf
= (EVP_KDF
*)vkdf
;
25 CRYPTO_UP_REF(&kdf
->refcnt
, &ref
, kdf
->lock
);
29 static void evp_kdf_free(void *vkdf
)
31 EVP_KDF
*kdf
= (EVP_KDF
*)vkdf
;
37 CRYPTO_DOWN_REF(&kdf
->refcnt
, &ref
, kdf
->lock
);
40 OPENSSL_free(kdf
->type_name
);
41 ossl_provider_free(kdf
->prov
);
42 CRYPTO_THREAD_lock_free(kdf
->lock
);
46 static void *evp_kdf_new(void)
50 if ((kdf
= OPENSSL_zalloc(sizeof(*kdf
))) == NULL
51 || (kdf
->lock
= CRYPTO_THREAD_lock_new()) == NULL
) {
59 static void *evp_kdf_from_algorithm(int name_id
,
60 const OSSL_ALGORITHM
*algodef
,
63 const OSSL_DISPATCH
*fns
= algodef
->implementation
;
65 int fnkdfcnt
= 0, fnctxcnt
= 0;
67 if ((kdf
= evp_kdf_new()) == NULL
) {
68 ERR_raise(ERR_LIB_EVP
, ERR_R_MALLOC_FAILURE
);
71 kdf
->name_id
= name_id
;
72 if ((kdf
->type_name
= ossl_algorithm_get1_first_name(algodef
)) == NULL
) {
76 kdf
->description
= algodef
->algorithm_description
;
78 for (; fns
->function_id
!= 0; fns
++) {
79 switch (fns
->function_id
) {
80 case OSSL_FUNC_KDF_NEWCTX
:
81 if (kdf
->newctx
!= NULL
)
83 kdf
->newctx
= OSSL_FUNC_kdf_newctx(fns
);
86 case OSSL_FUNC_KDF_DUPCTX
:
87 if (kdf
->dupctx
!= NULL
)
89 kdf
->dupctx
= OSSL_FUNC_kdf_dupctx(fns
);
91 case OSSL_FUNC_KDF_FREECTX
:
92 if (kdf
->freectx
!= NULL
)
94 kdf
->freectx
= OSSL_FUNC_kdf_freectx(fns
);
97 case OSSL_FUNC_KDF_RESET
:
98 if (kdf
->reset
!= NULL
)
100 kdf
->reset
= OSSL_FUNC_kdf_reset(fns
);
102 case OSSL_FUNC_KDF_DERIVE
:
103 if (kdf
->derive
!= NULL
)
105 kdf
->derive
= OSSL_FUNC_kdf_derive(fns
);
108 case OSSL_FUNC_KDF_GETTABLE_PARAMS
:
109 if (kdf
->gettable_params
!= NULL
)
111 kdf
->gettable_params
=
112 OSSL_FUNC_kdf_gettable_params(fns
);
114 case OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS
:
115 if (kdf
->gettable_ctx_params
!= NULL
)
117 kdf
->gettable_ctx_params
=
118 OSSL_FUNC_kdf_gettable_ctx_params(fns
);
120 case OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS
:
121 if (kdf
->settable_ctx_params
!= NULL
)
123 kdf
->settable_ctx_params
=
124 OSSL_FUNC_kdf_settable_ctx_params(fns
);
126 case OSSL_FUNC_KDF_GET_PARAMS
:
127 if (kdf
->get_params
!= NULL
)
129 kdf
->get_params
= OSSL_FUNC_kdf_get_params(fns
);
131 case OSSL_FUNC_KDF_GET_CTX_PARAMS
:
132 if (kdf
->get_ctx_params
!= NULL
)
134 kdf
->get_ctx_params
= OSSL_FUNC_kdf_get_ctx_params(fns
);
136 case OSSL_FUNC_KDF_SET_CTX_PARAMS
:
137 if (kdf
->set_ctx_params
!= NULL
)
139 kdf
->set_ctx_params
= OSSL_FUNC_kdf_set_ctx_params(fns
);
143 if (fnkdfcnt
!= 1 || fnctxcnt
!= 2) {
145 * In order to be a consistent set of functions we must have at least
146 * a derive function, and a complete set of context management
150 ERR_raise(ERR_LIB_EVP
, EVP_R_INVALID_PROVIDER_FUNCTIONS
);
155 ossl_provider_up_ref(prov
);
160 EVP_KDF
*EVP_KDF_fetch(OSSL_LIB_CTX
*libctx
, const char *algorithm
,
161 const char *properties
)
163 return evp_generic_fetch(libctx
, OSSL_OP_KDF
, algorithm
, properties
,
164 evp_kdf_from_algorithm
, evp_kdf_up_ref
,
168 int EVP_KDF_up_ref(EVP_KDF
*kdf
)
170 return evp_kdf_up_ref(kdf
);
173 void EVP_KDF_free(EVP_KDF
*kdf
)
178 const OSSL_PARAM
*EVP_KDF_gettable_params(const EVP_KDF
*kdf
)
180 if (kdf
->gettable_params
== NULL
)
182 return kdf
->gettable_params(ossl_provider_ctx(EVP_KDF_provider(kdf
)));
185 const OSSL_PARAM
*EVP_KDF_gettable_ctx_params(const EVP_KDF
*kdf
)
189 if (kdf
->gettable_ctx_params
== NULL
)
191 alg
= ossl_provider_ctx(EVP_KDF_provider(kdf
));
192 return kdf
->gettable_ctx_params(NULL
, alg
);
195 const OSSL_PARAM
*EVP_KDF_settable_ctx_params(const EVP_KDF
*kdf
)
199 if (kdf
->settable_ctx_params
== NULL
)
201 alg
= ossl_provider_ctx(EVP_KDF_provider(kdf
));
202 return kdf
->settable_ctx_params(NULL
, alg
);
205 const OSSL_PARAM
*EVP_KDF_CTX_gettable_params(EVP_KDF_CTX
*ctx
)
209 if (ctx
->meth
->gettable_ctx_params
== NULL
)
211 alg
= ossl_provider_ctx(EVP_KDF_provider(ctx
->meth
));
212 return ctx
->meth
->gettable_ctx_params(ctx
->algctx
, alg
);
215 const OSSL_PARAM
*EVP_KDF_CTX_settable_params(EVP_KDF_CTX
*ctx
)
219 if (ctx
->meth
->settable_ctx_params
== NULL
)
221 alg
= ossl_provider_ctx(EVP_KDF_provider(ctx
->meth
));
222 return ctx
->meth
->settable_ctx_params(ctx
->algctx
, alg
);
225 void EVP_KDF_do_all_provided(OSSL_LIB_CTX
*libctx
,
226 void (*fn
)(EVP_KDF
*kdf
, void *arg
),
229 evp_generic_do_all(libctx
, OSSL_OP_KDF
,
230 (void (*)(void *, void *))fn
, arg
,
231 evp_kdf_from_algorithm
, evp_kdf_free
);