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