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