]>
Commit | Line | Data |
---|---|---|
fb9e6dd6 | 1 | /* |
8020d79b | 2 | * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. |
fb9e6dd6 P |
3 | * |
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 | |
8 | */ | |
9 | ||
10 | #include <openssl/evp.h> | |
11 | #include <openssl/err.h> | |
12 | #include <openssl/core.h> | |
23c48d94 | 13 | #include <openssl/core_dispatch.h> |
fb9e6dd6 | 14 | #include <openssl/kdf.h> |
fb9e6dd6 | 15 | #include "internal/provider.h" |
6c9bc258 TM |
16 | #include "internal/core.h" |
17 | #include "crypto/evp.h" | |
706457b7 | 18 | #include "evp_local.h" |
fb9e6dd6 P |
19 | |
20 | static int evp_kdf_up_ref(void *vkdf) | |
21 | { | |
22 | EVP_KDF *kdf = (EVP_KDF *)vkdf; | |
23 | int ref = 0; | |
24 | ||
25 | CRYPTO_UP_REF(&kdf->refcnt, &ref, kdf->lock); | |
26 | return 1; | |
27 | } | |
28 | ||
543e740b RS |
29 | static void evp_kdf_free(void *vkdf) |
30 | { | |
fb9e6dd6 P |
31 | EVP_KDF *kdf = (EVP_KDF *)vkdf; |
32 | int ref = 0; | |
33 | ||
543e740b RS |
34 | if (kdf == NULL) |
35 | return; | |
36 | ||
37 | CRYPTO_DOWN_REF(&kdf->refcnt, &ref, kdf->lock); | |
38 | if (ref > 0) | |
39 | return; | |
6c9bc258 | 40 | OPENSSL_free(kdf->type_name); |
543e740b RS |
41 | ossl_provider_free(kdf->prov); |
42 | CRYPTO_THREAD_lock_free(kdf->lock); | |
43 | OPENSSL_free(kdf); | |
fb9e6dd6 P |
44 | } |
45 | ||
46 | static void *evp_kdf_new(void) | |
47 | { | |
48 | EVP_KDF *kdf = NULL; | |
49 | ||
50 | if ((kdf = OPENSSL_zalloc(sizeof(*kdf))) == NULL | |
51 | || (kdf->lock = CRYPTO_THREAD_lock_new()) == NULL) { | |
52 | OPENSSL_free(kdf); | |
53 | return NULL; | |
54 | } | |
55 | kdf->refcnt = 1; | |
56 | return kdf; | |
57 | } | |
58 | ||
309a78aa RL |
59 | static void *evp_kdf_from_algorithm(int name_id, |
60 | const OSSL_ALGORITHM *algodef, | |
61 | OSSL_PROVIDER *prov) | |
fb9e6dd6 | 62 | { |
309a78aa | 63 | const OSSL_DISPATCH *fns = algodef->implementation; |
fb9e6dd6 P |
64 | EVP_KDF *kdf = NULL; |
65 | int fnkdfcnt = 0, fnctxcnt = 0; | |
66 | ||
f7c16d48 | 67 | if ((kdf = evp_kdf_new()) == NULL) { |
9311d0c4 | 68 | ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); |
fb9e6dd6 P |
69 | return NULL; |
70 | } | |
f7c16d48 | 71 | kdf->name_id = name_id; |
6c9bc258 TM |
72 | if ((kdf->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { |
73 | evp_kdf_free(kdf); | |
74 | return NULL; | |
75 | } | |
309a78aa | 76 | kdf->description = algodef->algorithm_description; |
fb9e6dd6 P |
77 | |
78 | for (; fns->function_id != 0; fns++) { | |
79 | switch (fns->function_id) { | |
80 | case OSSL_FUNC_KDF_NEWCTX: | |
81 | if (kdf->newctx != NULL) | |
82 | break; | |
363b1e5d | 83 | kdf->newctx = OSSL_FUNC_kdf_newctx(fns); |
fb9e6dd6 P |
84 | fnctxcnt++; |
85 | break; | |
86 | case OSSL_FUNC_KDF_DUPCTX: | |
87 | if (kdf->dupctx != NULL) | |
88 | break; | |
363b1e5d | 89 | kdf->dupctx = OSSL_FUNC_kdf_dupctx(fns); |
fb9e6dd6 P |
90 | break; |
91 | case OSSL_FUNC_KDF_FREECTX: | |
92 | if (kdf->freectx != NULL) | |
93 | break; | |
363b1e5d | 94 | kdf->freectx = OSSL_FUNC_kdf_freectx(fns); |
fb9e6dd6 P |
95 | fnctxcnt++; |
96 | break; | |
6d1c3154 RL |
97 | case OSSL_FUNC_KDF_RESET: |
98 | if (kdf->reset != NULL) | |
99 | break; | |
363b1e5d | 100 | kdf->reset = OSSL_FUNC_kdf_reset(fns); |
6d1c3154 | 101 | break; |
fb9e6dd6 P |
102 | case OSSL_FUNC_KDF_DERIVE: |
103 | if (kdf->derive != NULL) | |
104 | break; | |
363b1e5d | 105 | kdf->derive = OSSL_FUNC_kdf_derive(fns); |
fb9e6dd6 P |
106 | fnkdfcnt++; |
107 | break; | |
108 | case OSSL_FUNC_KDF_GETTABLE_PARAMS: | |
109 | if (kdf->gettable_params != NULL) | |
110 | break; | |
111 | kdf->gettable_params = | |
363b1e5d | 112 | OSSL_FUNC_kdf_gettable_params(fns); |
fb9e6dd6 P |
113 | break; |
114 | case OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS: | |
115 | if (kdf->gettable_ctx_params != NULL) | |
116 | break; | |
117 | kdf->gettable_ctx_params = | |
363b1e5d | 118 | OSSL_FUNC_kdf_gettable_ctx_params(fns); |
fb9e6dd6 P |
119 | break; |
120 | case OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS: | |
121 | if (kdf->settable_ctx_params != NULL) | |
122 | break; | |
123 | kdf->settable_ctx_params = | |
363b1e5d | 124 | OSSL_FUNC_kdf_settable_ctx_params(fns); |
fb9e6dd6 P |
125 | break; |
126 | case OSSL_FUNC_KDF_GET_PARAMS: | |
127 | if (kdf->get_params != NULL) | |
128 | break; | |
363b1e5d | 129 | kdf->get_params = OSSL_FUNC_kdf_get_params(fns); |
fb9e6dd6 P |
130 | break; |
131 | case OSSL_FUNC_KDF_GET_CTX_PARAMS: | |
132 | if (kdf->get_ctx_params != NULL) | |
133 | break; | |
363b1e5d | 134 | kdf->get_ctx_params = OSSL_FUNC_kdf_get_ctx_params(fns); |
fb9e6dd6 P |
135 | break; |
136 | case OSSL_FUNC_KDF_SET_CTX_PARAMS: | |
137 | if (kdf->set_ctx_params != NULL) | |
138 | break; | |
363b1e5d | 139 | kdf->set_ctx_params = OSSL_FUNC_kdf_set_ctx_params(fns); |
fb9e6dd6 P |
140 | break; |
141 | } | |
142 | } | |
143 | if (fnkdfcnt != 1 || fnctxcnt != 2) { | |
144 | /* | |
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 | |
147 | * functions. | |
148 | */ | |
149 | evp_kdf_free(kdf); | |
150 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); | |
151 | return NULL; | |
152 | } | |
153 | kdf->prov = prov; | |
154 | if (prov != NULL) | |
155 | ossl_provider_up_ref(prov); | |
156 | ||
157 | return kdf; | |
158 | } | |
159 | ||
b4250010 | 160 | EVP_KDF *EVP_KDF_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, |
fb9e6dd6 P |
161 | const char *properties) |
162 | { | |
163 | return evp_generic_fetch(libctx, OSSL_OP_KDF, algorithm, properties, | |
309a78aa | 164 | evp_kdf_from_algorithm, evp_kdf_up_ref, |
fb9e6dd6 P |
165 | evp_kdf_free); |
166 | } | |
167 | ||
168 | int EVP_KDF_up_ref(EVP_KDF *kdf) | |
169 | { | |
170 | return evp_kdf_up_ref(kdf); | |
171 | } | |
172 | ||
173 | void EVP_KDF_free(EVP_KDF *kdf) | |
174 | { | |
175 | evp_kdf_free(kdf); | |
176 | } | |
177 | ||
178 | const OSSL_PARAM *EVP_KDF_gettable_params(const EVP_KDF *kdf) | |
179 | { | |
180 | if (kdf->gettable_params == NULL) | |
181 | return NULL; | |
ed576acd | 182 | return kdf->gettable_params(ossl_provider_ctx(EVP_KDF_get0_provider(kdf))); |
fb9e6dd6 P |
183 | } |
184 | ||
41f7ecf3 | 185 | const OSSL_PARAM *EVP_KDF_gettable_ctx_params(const EVP_KDF *kdf) |
fb9e6dd6 | 186 | { |
a5120afd P |
187 | void *alg; |
188 | ||
fb9e6dd6 P |
189 | if (kdf->gettable_ctx_params == NULL) |
190 | return NULL; | |
ed576acd | 191 | alg = ossl_provider_ctx(EVP_KDF_get0_provider(kdf)); |
a5120afd | 192 | return kdf->gettable_ctx_params(NULL, alg); |
fb9e6dd6 P |
193 | } |
194 | ||
41f7ecf3 | 195 | const OSSL_PARAM *EVP_KDF_settable_ctx_params(const EVP_KDF *kdf) |
fb9e6dd6 | 196 | { |
a5120afd P |
197 | void *alg; |
198 | ||
fb9e6dd6 P |
199 | if (kdf->settable_ctx_params == NULL) |
200 | return NULL; | |
ed576acd | 201 | alg = ossl_provider_ctx(EVP_KDF_get0_provider(kdf)); |
a5120afd P |
202 | return kdf->settable_ctx_params(NULL, alg); |
203 | } | |
204 | ||
205 | const OSSL_PARAM *EVP_KDF_CTX_gettable_params(EVP_KDF_CTX *ctx) | |
206 | { | |
207 | void *alg; | |
208 | ||
209 | if (ctx->meth->gettable_ctx_params == NULL) | |
210 | return NULL; | |
ed576acd | 211 | alg = ossl_provider_ctx(EVP_KDF_get0_provider(ctx->meth)); |
7c14d0c1 | 212 | return ctx->meth->gettable_ctx_params(ctx->algctx, alg); |
a5120afd P |
213 | } |
214 | ||
215 | const OSSL_PARAM *EVP_KDF_CTX_settable_params(EVP_KDF_CTX *ctx) | |
216 | { | |
217 | void *alg; | |
218 | ||
219 | if (ctx->meth->settable_ctx_params == NULL) | |
220 | return NULL; | |
ed576acd | 221 | alg = ossl_provider_ctx(EVP_KDF_get0_provider(ctx->meth)); |
7c14d0c1 | 222 | return ctx->meth->settable_ctx_params(ctx->algctx, alg); |
fb9e6dd6 P |
223 | } |
224 | ||
b4250010 | 225 | void EVP_KDF_do_all_provided(OSSL_LIB_CTX *libctx, |
251e610c RL |
226 | void (*fn)(EVP_KDF *kdf, void *arg), |
227 | void *arg) | |
fb9e6dd6 P |
228 | { |
229 | evp_generic_do_all(libctx, OSSL_OP_KDF, | |
230 | (void (*)(void *, void *))fn, arg, | |
cd770738 | 231 | evp_kdf_from_algorithm, evp_kdf_up_ref, evp_kdf_free); |
fb9e6dd6 | 232 | } |