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
);
29 static void evp_kdf_free(void *vkdf
)
31 EVP_KDF
*kdf
= (EVP_KDF
*)vkdf
;
37 CRYPTO_DOWN_REF(&kdf
->refcnt
, &ref
);
40 OPENSSL_free(kdf
->type_name
);
41 ossl_provider_free(kdf
->prov
);
42 CRYPTO_FREE_REF(&kdf
->refcnt
);
46 static void *evp_kdf_new(void)
50 if ((kdf
= OPENSSL_zalloc(sizeof(*kdf
))) == NULL
51 || !CRYPTO_NEW_REF(&kdf
->refcnt
, 1)) {
58 static void *evp_kdf_from_algorithm(int name_id
,
59 const OSSL_ALGORITHM
*algodef
,
62 const OSSL_DISPATCH
*fns
= algodef
->implementation
;
64 int fnkdfcnt
= 0, fnctxcnt
= 0;
66 if ((kdf
= evp_kdf_new()) == NULL
) {
67 ERR_raise(ERR_LIB_EVP
, ERR_R_EVP_LIB
);
70 kdf
->name_id
= name_id
;
71 if ((kdf
->type_name
= ossl_algorithm_get1_first_name(algodef
)) == NULL
) {
75 kdf
->description
= algodef
->algorithm_description
;
77 for (; fns
->function_id
!= 0; fns
++) {
78 switch (fns
->function_id
) {
79 case OSSL_FUNC_KDF_NEWCTX
:
80 if (kdf
->newctx
!= NULL
)
82 kdf
->newctx
= OSSL_FUNC_kdf_newctx(fns
);
85 case OSSL_FUNC_KDF_DUPCTX
:
86 if (kdf
->dupctx
!= NULL
)
88 kdf
->dupctx
= OSSL_FUNC_kdf_dupctx(fns
);
90 case OSSL_FUNC_KDF_FREECTX
:
91 if (kdf
->freectx
!= NULL
)
93 kdf
->freectx
= OSSL_FUNC_kdf_freectx(fns
);
96 case OSSL_FUNC_KDF_RESET
:
97 if (kdf
->reset
!= NULL
)
99 kdf
->reset
= OSSL_FUNC_kdf_reset(fns
);
101 case OSSL_FUNC_KDF_DERIVE
:
102 if (kdf
->derive
!= NULL
)
104 kdf
->derive
= OSSL_FUNC_kdf_derive(fns
);
107 case OSSL_FUNC_KDF_GETTABLE_PARAMS
:
108 if (kdf
->gettable_params
!= NULL
)
110 kdf
->gettable_params
=
111 OSSL_FUNC_kdf_gettable_params(fns
);
113 case OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS
:
114 if (kdf
->gettable_ctx_params
!= NULL
)
116 kdf
->gettable_ctx_params
=
117 OSSL_FUNC_kdf_gettable_ctx_params(fns
);
119 case OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS
:
120 if (kdf
->settable_ctx_params
!= NULL
)
122 kdf
->settable_ctx_params
=
123 OSSL_FUNC_kdf_settable_ctx_params(fns
);
125 case OSSL_FUNC_KDF_GET_PARAMS
:
126 if (kdf
->get_params
!= NULL
)
128 kdf
->get_params
= OSSL_FUNC_kdf_get_params(fns
);
130 case OSSL_FUNC_KDF_GET_CTX_PARAMS
:
131 if (kdf
->get_ctx_params
!= NULL
)
133 kdf
->get_ctx_params
= OSSL_FUNC_kdf_get_ctx_params(fns
);
135 case OSSL_FUNC_KDF_SET_CTX_PARAMS
:
136 if (kdf
->set_ctx_params
!= NULL
)
138 kdf
->set_ctx_params
= OSSL_FUNC_kdf_set_ctx_params(fns
);
142 if (fnkdfcnt
!= 1 || fnctxcnt
!= 2) {
144 * In order to be a consistent set of functions we must have at least
145 * a derive function, and a complete set of context management
149 ERR_raise(ERR_LIB_EVP
, EVP_R_INVALID_PROVIDER_FUNCTIONS
);
154 ossl_provider_up_ref(prov
);
159 EVP_KDF
*EVP_KDF_fetch(OSSL_LIB_CTX
*libctx
, const char *algorithm
,
160 const char *properties
)
162 return evp_generic_fetch(libctx
, OSSL_OP_KDF
, algorithm
, properties
,
163 evp_kdf_from_algorithm
, evp_kdf_up_ref
,
167 int EVP_KDF_up_ref(EVP_KDF
*kdf
)
169 return evp_kdf_up_ref(kdf
);
172 void EVP_KDF_free(EVP_KDF
*kdf
)
177 const OSSL_PARAM
*EVP_KDF_gettable_params(const EVP_KDF
*kdf
)
179 if (kdf
->gettable_params
== NULL
)
181 return kdf
->gettable_params(ossl_provider_ctx(EVP_KDF_get0_provider(kdf
)));
184 const OSSL_PARAM
*EVP_KDF_gettable_ctx_params(const EVP_KDF
*kdf
)
188 if (kdf
->gettable_ctx_params
== NULL
)
190 alg
= ossl_provider_ctx(EVP_KDF_get0_provider(kdf
));
191 return kdf
->gettable_ctx_params(NULL
, alg
);
194 const OSSL_PARAM
*EVP_KDF_settable_ctx_params(const EVP_KDF
*kdf
)
198 if (kdf
->settable_ctx_params
== NULL
)
200 alg
= ossl_provider_ctx(EVP_KDF_get0_provider(kdf
));
201 return kdf
->settable_ctx_params(NULL
, alg
);
204 const OSSL_PARAM
*EVP_KDF_CTX_gettable_params(EVP_KDF_CTX
*ctx
)
208 if (ctx
->meth
->gettable_ctx_params
== NULL
)
210 alg
= ossl_provider_ctx(EVP_KDF_get0_provider(ctx
->meth
));
211 return ctx
->meth
->gettable_ctx_params(ctx
->algctx
, alg
);
214 const OSSL_PARAM
*EVP_KDF_CTX_settable_params(EVP_KDF_CTX
*ctx
)
218 if (ctx
->meth
->settable_ctx_params
== NULL
)
220 alg
= ossl_provider_ctx(EVP_KDF_get0_provider(ctx
->meth
));
221 return ctx
->meth
->settable_ctx_params(ctx
->algctx
, alg
);
224 void EVP_KDF_do_all_provided(OSSL_LIB_CTX
*libctx
,
225 void (*fn
)(EVP_KDF
*kdf
, void *arg
),
228 evp_generic_do_all(libctx
, OSSL_OP_KDF
,
229 (void (*)(void *, void *))fn
, arg
,
230 evp_kdf_from_algorithm
, evp_kdf_up_ref
, evp_kdf_free
);