/src/openssl/crypto/evp/skeymgmt_meth.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2025 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/crypto.h> |
11 | | #include <openssl/core_dispatch.h> |
12 | | #include <openssl/evp.h> |
13 | | #include <openssl/err.h> |
14 | | #include "internal/core.h" |
15 | | #include "internal/provider.h" |
16 | | #include "internal/refcount.h" |
17 | | #include "crypto/evp.h" |
18 | | #include "evp_local.h" |
19 | | |
20 | | void *evp_skeymgmt_generate(const EVP_SKEYMGMT *skeymgmt, const OSSL_PARAM params[]) |
21 | 0 | { |
22 | 0 | void *provctx = ossl_provider_ctx(EVP_SKEYMGMT_get0_provider(skeymgmt)); |
23 | |
|
24 | 0 | return (skeymgmt->generate != NULL) ? skeymgmt->generate(provctx, params) : NULL; |
25 | 0 | } |
26 | | |
27 | | void *evp_skeymgmt_import(const EVP_SKEYMGMT *skeymgmt, int selection, const OSSL_PARAM params[]) |
28 | 0 | { |
29 | 0 | void *provctx = ossl_provider_ctx(EVP_SKEYMGMT_get0_provider(skeymgmt)); |
30 | | |
31 | | /* This is mandatory, no need to check for its presence */ |
32 | 0 | return skeymgmt->import(provctx, selection, params); |
33 | 0 | } |
34 | | |
35 | | int evp_skeymgmt_export(const EVP_SKEYMGMT *skeymgmt, void *keydata, |
36 | | int selection, OSSL_CALLBACK *param_cb, void *cbarg) |
37 | 0 | { |
38 | | /* This is mandatory, no need to check for its presence */ |
39 | 0 | return skeymgmt->export(keydata, selection, param_cb, cbarg); |
40 | 0 | } |
41 | | |
42 | | void evp_skeymgmt_freedata(const EVP_SKEYMGMT *skeymgmt, void *keydata) |
43 | 0 | { |
44 | | /* This is mandatory, no need to check for its presence */ |
45 | 0 | skeymgmt->free(keydata); |
46 | 0 | } |
47 | | |
48 | | static void *skeymgmt_new(void) |
49 | 0 | { |
50 | 0 | EVP_SKEYMGMT *skeymgmt = NULL; |
51 | |
|
52 | 0 | if ((skeymgmt = OPENSSL_zalloc(sizeof(*skeymgmt))) == NULL) |
53 | 0 | return NULL; |
54 | 0 | if (!CRYPTO_NEW_REF(&skeymgmt->refcnt, 1)) { |
55 | 0 | EVP_SKEYMGMT_free(skeymgmt); |
56 | 0 | return NULL; |
57 | 0 | } |
58 | 0 | return skeymgmt; |
59 | 0 | } |
60 | | |
61 | | static void *skeymgmt_from_algorithm(int name_id, |
62 | | const OSSL_ALGORITHM *algodef, |
63 | | OSSL_PROVIDER *prov) |
64 | 0 | { |
65 | 0 | const OSSL_DISPATCH *fns = algodef->implementation; |
66 | 0 | EVP_SKEYMGMT *skeymgmt = NULL; |
67 | |
|
68 | 0 | if ((skeymgmt = skeymgmt_new()) == NULL) |
69 | 0 | return NULL; |
70 | | |
71 | 0 | skeymgmt->name_id = name_id; |
72 | 0 | if ((skeymgmt->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { |
73 | 0 | EVP_SKEYMGMT_free(skeymgmt); |
74 | 0 | return NULL; |
75 | 0 | } |
76 | 0 | skeymgmt->description = algodef->algorithm_description; |
77 | |
|
78 | 0 | for (; fns->function_id != 0; fns++) { |
79 | 0 | switch (fns->function_id) { |
80 | 0 | case OSSL_FUNC_SKEYMGMT_FREE: |
81 | 0 | if (skeymgmt->free == NULL) |
82 | 0 | skeymgmt->free = OSSL_FUNC_skeymgmt_free(fns); |
83 | 0 | break; |
84 | 0 | case OSSL_FUNC_SKEYMGMT_IMPORT: |
85 | 0 | if (skeymgmt->import == NULL) |
86 | 0 | skeymgmt->import = OSSL_FUNC_skeymgmt_import(fns); |
87 | 0 | break; |
88 | 0 | case OSSL_FUNC_SKEYMGMT_EXPORT: |
89 | 0 | if (skeymgmt->export == NULL) |
90 | 0 | skeymgmt->export = OSSL_FUNC_skeymgmt_export(fns); |
91 | 0 | break; |
92 | 0 | case OSSL_FUNC_SKEYMGMT_GENERATE: |
93 | 0 | if (skeymgmt->generate == NULL) |
94 | 0 | skeymgmt->generate = OSSL_FUNC_skeymgmt_generate(fns); |
95 | 0 | break; |
96 | 0 | case OSSL_FUNC_SKEYMGMT_GET_KEY_ID: |
97 | 0 | if (skeymgmt->get_key_id == NULL) |
98 | 0 | skeymgmt->get_key_id = OSSL_FUNC_skeymgmt_get_key_id(fns); |
99 | 0 | break; |
100 | 0 | case OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS: |
101 | 0 | if (skeymgmt->imp_params == NULL) |
102 | 0 | skeymgmt->imp_params = OSSL_FUNC_skeymgmt_imp_settable_params(fns); |
103 | 0 | break; |
104 | 0 | case OSSL_FUNC_SKEYMGMT_GEN_SETTABLE_PARAMS: |
105 | 0 | if (skeymgmt->gen_params == NULL) |
106 | 0 | skeymgmt->gen_params = OSSL_FUNC_skeymgmt_gen_settable_params(fns); |
107 | 0 | break; |
108 | 0 | } |
109 | 0 | } |
110 | | |
111 | | /* Check that the provider is sensible */ |
112 | 0 | if (skeymgmt->free == NULL |
113 | 0 | || skeymgmt->import == NULL |
114 | 0 | || skeymgmt->export == NULL) { |
115 | 0 | EVP_SKEYMGMT_free(skeymgmt); |
116 | 0 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); |
117 | 0 | return NULL; |
118 | 0 | } |
119 | | |
120 | 0 | if (!ossl_provider_up_ref(prov)) { |
121 | 0 | EVP_SKEYMGMT_free(skeymgmt); |
122 | 0 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
123 | 0 | return NULL; |
124 | 0 | } |
125 | 0 | skeymgmt->prov = prov; |
126 | |
|
127 | 0 | return skeymgmt; |
128 | 0 | } |
129 | | |
130 | | EVP_SKEYMGMT *evp_skeymgmt_fetch_from_prov(OSSL_PROVIDER *prov, |
131 | | const char *name, |
132 | | const char *properties) |
133 | 0 | { |
134 | 0 | return evp_generic_fetch_from_prov(prov, |
135 | 0 | OSSL_OP_SKEYMGMT, |
136 | 0 | name, properties, |
137 | 0 | skeymgmt_from_algorithm, |
138 | 0 | (int (*)(void *))EVP_SKEYMGMT_up_ref, |
139 | 0 | (void (*)(void *))EVP_SKEYMGMT_free); |
140 | 0 | } |
141 | | |
142 | | EVP_SKEYMGMT *EVP_SKEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, |
143 | | const char *properties) |
144 | 0 | { |
145 | 0 | return evp_generic_fetch(ctx, OSSL_OP_SKEYMGMT, algorithm, properties, |
146 | 0 | skeymgmt_from_algorithm, |
147 | 0 | (int (*)(void *))EVP_SKEYMGMT_up_ref, |
148 | 0 | (void (*)(void *))EVP_SKEYMGMT_free); |
149 | 0 | } |
150 | | |
151 | | int EVP_SKEYMGMT_up_ref(EVP_SKEYMGMT *skeymgmt) |
152 | 0 | { |
153 | 0 | int ref = 0; |
154 | |
|
155 | 0 | CRYPTO_UP_REF(&skeymgmt->refcnt, &ref); |
156 | 0 | return 1; |
157 | 0 | } |
158 | | |
159 | | void EVP_SKEYMGMT_free(EVP_SKEYMGMT *skeymgmt) |
160 | 0 | { |
161 | 0 | int ref = 0; |
162 | |
|
163 | 0 | if (skeymgmt == NULL) |
164 | 0 | return; |
165 | | |
166 | 0 | CRYPTO_DOWN_REF(&skeymgmt->refcnt, &ref); |
167 | 0 | if (ref > 0) |
168 | 0 | return; |
169 | 0 | OPENSSL_free(skeymgmt->type_name); |
170 | 0 | ossl_provider_free(skeymgmt->prov); |
171 | 0 | CRYPTO_FREE_REF(&skeymgmt->refcnt); |
172 | 0 | OPENSSL_free(skeymgmt); |
173 | 0 | } |
174 | | |
175 | | const OSSL_PROVIDER *EVP_SKEYMGMT_get0_provider(const EVP_SKEYMGMT *skeymgmt) |
176 | 0 | { |
177 | 0 | return (skeymgmt != NULL) ? skeymgmt->prov : NULL; |
178 | 0 | } |
179 | | |
180 | | const char *EVP_SKEYMGMT_get0_description(const EVP_SKEYMGMT *skeymgmt) |
181 | 0 | { |
182 | 0 | return (skeymgmt != NULL) ? skeymgmt->description : NULL; |
183 | 0 | } |
184 | | |
185 | | const char *EVP_SKEYMGMT_get0_name(const EVP_SKEYMGMT *skeymgmt) |
186 | 0 | { |
187 | 0 | return (skeymgmt != NULL) ? skeymgmt->type_name : NULL; |
188 | 0 | } |
189 | | |
190 | | int EVP_SKEYMGMT_is_a(const EVP_SKEYMGMT *skeymgmt, const char *name) |
191 | 0 | { |
192 | 0 | return skeymgmt != NULL |
193 | 0 | && evp_is_a(skeymgmt->prov, skeymgmt->name_id, NULL, name); |
194 | 0 | } |
195 | | |
196 | | void EVP_SKEYMGMT_do_all_provided(OSSL_LIB_CTX *libctx, |
197 | | void (*fn)(EVP_SKEYMGMT *skeymgmt, void *arg), |
198 | | void *arg) |
199 | 0 | { |
200 | 0 | evp_generic_do_all(libctx, OSSL_OP_KEYMGMT, |
201 | 0 | (void (*)(void *, void *))fn, arg, |
202 | 0 | skeymgmt_from_algorithm, |
203 | 0 | (int (*)(void *))EVP_SKEYMGMT_up_ref, |
204 | 0 | (void (*)(void *))EVP_SKEYMGMT_free); |
205 | 0 | } |
206 | | |
207 | | int EVP_SKEYMGMT_names_do_all(const EVP_SKEYMGMT *skeymgmt, |
208 | | void (*fn)(const char *name, void *data), |
209 | | void *data) |
210 | 0 | { |
211 | 0 | if (skeymgmt == NULL) |
212 | 0 | return 0; |
213 | | |
214 | 0 | if (skeymgmt->prov != NULL) |
215 | 0 | return evp_names_do_all(skeymgmt->prov, skeymgmt->name_id, fn, data); |
216 | | |
217 | 0 | return 1; |
218 | 0 | } |
219 | | |
220 | | const OSSL_PARAM *EVP_SKEYMGMT_get0_gen_settable_params(const EVP_SKEYMGMT *skeymgmt) |
221 | 0 | { |
222 | 0 | void *provctx = NULL; |
223 | |
|
224 | 0 | if (skeymgmt == NULL) |
225 | 0 | return 0; |
226 | | |
227 | 0 | provctx = ossl_provider_ctx(EVP_SKEYMGMT_get0_provider(skeymgmt)); |
228 | |
|
229 | 0 | return (skeymgmt->gen_params != NULL) ? skeymgmt->gen_params(provctx) : NULL; |
230 | 0 | } |
231 | | |
232 | | const OSSL_PARAM *EVP_SKEYMGMT_get0_imp_settable_params(const EVP_SKEYMGMT *skeymgmt) |
233 | 0 | { |
234 | 0 | void *provctx = NULL; |
235 | |
|
236 | 0 | if (skeymgmt == NULL) |
237 | 0 | return 0; |
238 | | |
239 | 0 | provctx = ossl_provider_ctx(EVP_SKEYMGMT_get0_provider(skeymgmt)); |
240 | |
|
241 | 0 | return (skeymgmt->imp_params != NULL) ? skeymgmt->imp_params(provctx) : NULL; |
242 | 0 | } |