]>
Commit | Line | Data |
---|---|---|
a94a3e0d | 1 | /* |
33388b44 | 2 | * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. |
a94a3e0d RL |
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> | |
23c48d94 | 11 | #include <openssl/core_dispatch.h> |
a94a3e0d RL |
12 | #include <openssl/evp.h> |
13 | #include <openssl/err.h> | |
14 | #include "internal/provider.h" | |
15 | #include "internal/refcount.h" | |
25f2138b | 16 | #include "crypto/evp.h" |
706457b7 | 17 | #include "evp_local.h" |
a94a3e0d | 18 | |
a94a3e0d RL |
19 | static void *keymgmt_new(void) |
20 | { | |
21 | EVP_KEYMGMT *keymgmt = NULL; | |
22 | ||
23 | if ((keymgmt = OPENSSL_zalloc(sizeof(*keymgmt))) == NULL | |
24 | || (keymgmt->lock = CRYPTO_THREAD_lock_new()) == NULL) { | |
25 | EVP_KEYMGMT_free(keymgmt); | |
6b9e3724 | 26 | EVPerr(0, ERR_R_MALLOC_FAILURE); |
a94a3e0d RL |
27 | return NULL; |
28 | } | |
29 | ||
30 | keymgmt->refcnt = 1; | |
31 | ||
32 | return keymgmt; | |
33 | } | |
34 | ||
f7c16d48 RL |
35 | static void *keymgmt_from_dispatch(int name_id, |
36 | const OSSL_DISPATCH *fns, | |
0ddf74bf | 37 | OSSL_PROVIDER *prov) |
a94a3e0d RL |
38 | { |
39 | EVP_KEYMGMT *keymgmt = NULL; | |
2b9add69 | 40 | int setparamfncnt = 0, getparamfncnt = 0; |
5e77b79a | 41 | int setgenparamfncnt = 0; |
1a5632e0 | 42 | int importfncnt = 0, exportfncnt = 0; |
a94a3e0d | 43 | |
f7c16d48 | 44 | if ((keymgmt = keymgmt_new()) == NULL) { |
6b9e3724 | 45 | EVP_KEYMGMT_free(keymgmt); |
a94a3e0d | 46 | return NULL; |
6b9e3724 | 47 | } |
f7c16d48 | 48 | keymgmt->name_id = name_id; |
a94a3e0d RL |
49 | |
50 | for (; fns->function_id != 0; fns++) { | |
51 | switch (fns->function_id) { | |
b305452f RL |
52 | case OSSL_FUNC_KEYMGMT_NEW: |
53 | if (keymgmt->new == NULL) | |
363b1e5d | 54 | keymgmt->new = OSSL_FUNC_keymgmt_new(fns); |
a94a3e0d | 55 | break; |
1a5632e0 RL |
56 | case OSSL_FUNC_KEYMGMT_GEN_INIT: |
57 | if (keymgmt->gen_init == NULL) | |
363b1e5d | 58 | keymgmt->gen_init = OSSL_FUNC_keymgmt_gen_init(fns); |
1a5632e0 RL |
59 | break; |
60 | case OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE: | |
61 | if (keymgmt->gen_set_template == NULL) | |
62 | keymgmt->gen_set_template = | |
363b1e5d | 63 | OSSL_FUNC_keymgmt_gen_set_template(fns); |
1a5632e0 RL |
64 | break; |
65 | case OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS: | |
66 | if (keymgmt->gen_set_params == NULL) { | |
67 | setgenparamfncnt++; | |
68 | keymgmt->gen_set_params = | |
363b1e5d | 69 | OSSL_FUNC_keymgmt_gen_set_params(fns); |
1a5632e0 RL |
70 | } |
71 | break; | |
72 | case OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS: | |
73 | if (keymgmt->gen_settable_params == NULL) { | |
74 | setgenparamfncnt++; | |
75 | keymgmt->gen_settable_params = | |
363b1e5d | 76 | OSSL_FUNC_keymgmt_gen_settable_params(fns); |
1a5632e0 RL |
77 | } |
78 | break; | |
79 | case OSSL_FUNC_KEYMGMT_GEN: | |
80 | if (keymgmt->gen == NULL) | |
363b1e5d | 81 | keymgmt->gen = OSSL_FUNC_keymgmt_gen(fns); |
1a5632e0 RL |
82 | break; |
83 | case OSSL_FUNC_KEYMGMT_GEN_CLEANUP: | |
84 | if (keymgmt->gen_cleanup == NULL) | |
363b1e5d | 85 | keymgmt->gen_cleanup = OSSL_FUNC_keymgmt_gen_cleanup(fns); |
1a5632e0 | 86 | break; |
b305452f RL |
87 | case OSSL_FUNC_KEYMGMT_FREE: |
88 | if (keymgmt->free == NULL) | |
363b1e5d | 89 | keymgmt->free = OSSL_FUNC_keymgmt_free(fns); |
a94a3e0d | 90 | break; |
5dacb38c RL |
91 | case OSSL_FUNC_KEYMGMT_LOAD: |
92 | if (keymgmt->load == NULL) | |
93 | keymgmt->load = OSSL_FUNC_keymgmt_load(fns); | |
94 | break; | |
b305452f | 95 | case OSSL_FUNC_KEYMGMT_GET_PARAMS: |
273a67e3 | 96 | if (keymgmt->get_params == NULL) { |
4fe54d67 | 97 | getparamfncnt++; |
363b1e5d | 98 | keymgmt->get_params = OSSL_FUNC_keymgmt_get_params(fns); |
273a67e3 | 99 | } |
a94a3e0d | 100 | break; |
b305452f | 101 | case OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS: |
273a67e3 | 102 | if (keymgmt->gettable_params == NULL) { |
4fe54d67 | 103 | getparamfncnt++; |
b305452f | 104 | keymgmt->gettable_params = |
363b1e5d | 105 | OSSL_FUNC_keymgmt_gettable_params(fns); |
273a67e3 | 106 | } |
a94a3e0d | 107 | break; |
4fe54d67 NT |
108 | case OSSL_FUNC_KEYMGMT_SET_PARAMS: |
109 | if (keymgmt->set_params == NULL) { | |
110 | setparamfncnt++; | |
363b1e5d | 111 | keymgmt->set_params = OSSL_FUNC_keymgmt_set_params(fns); |
4fe54d67 NT |
112 | } |
113 | break; | |
114 | case OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS: | |
115 | if (keymgmt->settable_params == NULL) { | |
116 | setparamfncnt++; | |
117 | keymgmt->settable_params = | |
363b1e5d | 118 | OSSL_FUNC_keymgmt_settable_params(fns); |
4fe54d67 NT |
119 | } |
120 | break; | |
b305452f RL |
121 | case OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME: |
122 | if (keymgmt->query_operation_name == NULL) | |
123 | keymgmt->query_operation_name = | |
363b1e5d | 124 | OSSL_FUNC_keymgmt_query_operation_name(fns); |
6508e858 | 125 | break; |
b305452f RL |
126 | case OSSL_FUNC_KEYMGMT_HAS: |
127 | if (keymgmt->has == NULL) | |
363b1e5d | 128 | keymgmt->has = OSSL_FUNC_keymgmt_has(fns); |
6508e858 | 129 | break; |
6136ecaa MC |
130 | case OSSL_FUNC_KEYMGMT_COPY: |
131 | if (keymgmt->copy == NULL) | |
363b1e5d | 132 | keymgmt->copy = OSSL_FUNC_keymgmt_copy(fns); |
6136ecaa | 133 | break; |
b305452f RL |
134 | case OSSL_FUNC_KEYMGMT_VALIDATE: |
135 | if (keymgmt->validate == NULL) | |
363b1e5d | 136 | keymgmt->validate = OSSL_FUNC_keymgmt_validate(fns); |
e62a45b6 | 137 | break; |
bee5d6cd RL |
138 | case OSSL_FUNC_KEYMGMT_MATCH: |
139 | if (keymgmt->match == NULL) | |
363b1e5d | 140 | keymgmt->match = OSSL_FUNC_keymgmt_match(fns); |
bee5d6cd | 141 | break; |
b305452f | 142 | case OSSL_FUNC_KEYMGMT_IMPORT: |
273a67e3 RL |
143 | if (keymgmt->import == NULL) { |
144 | importfncnt++; | |
363b1e5d | 145 | keymgmt->import = OSSL_FUNC_keymgmt_import(fns); |
273a67e3 | 146 | } |
12603de6 | 147 | break; |
b305452f | 148 | case OSSL_FUNC_KEYMGMT_IMPORT_TYPES: |
273a67e3 RL |
149 | if (keymgmt->import_types == NULL) { |
150 | importfncnt++; | |
363b1e5d | 151 | keymgmt->import_types = OSSL_FUNC_keymgmt_import_types(fns); |
273a67e3 | 152 | } |
12603de6 | 153 | break; |
b305452f | 154 | case OSSL_FUNC_KEYMGMT_EXPORT: |
273a67e3 RL |
155 | if (keymgmt->export == NULL) { |
156 | exportfncnt++; | |
363b1e5d | 157 | keymgmt->export = OSSL_FUNC_keymgmt_export(fns); |
273a67e3 | 158 | } |
12603de6 | 159 | break; |
b305452f | 160 | case OSSL_FUNC_KEYMGMT_EXPORT_TYPES: |
273a67e3 RL |
161 | if (keymgmt->export_types == NULL) { |
162 | exportfncnt++; | |
363b1e5d | 163 | keymgmt->export_types = OSSL_FUNC_keymgmt_export_types(fns); |
273a67e3 | 164 | } |
12603de6 | 165 | break; |
a94a3e0d RL |
166 | } |
167 | } | |
168 | /* | |
169 | * Try to check that the method is sensible. | |
b305452f RL |
170 | * At least one constructor and the destructor are MANDATORY |
171 | * The functions 'has' is MANDATORY | |
a94a3e0d RL |
172 | * It makes no sense being able to free stuff if you can't create it. |
173 | * It makes no sense providing OSSL_PARAM descriptors for import and | |
174 | * export if you can't import or export. | |
175 | */ | |
b305452f | 176 | if (keymgmt->free == NULL |
5dacb38c RL |
177 | || (keymgmt->new == NULL |
178 | && keymgmt->gen == NULL | |
179 | && keymgmt->load == NULL) | |
b305452f | 180 | || keymgmt->has == NULL |
4fe54d67 NT |
181 | || (getparamfncnt != 0 && getparamfncnt != 2) |
182 | || (setparamfncnt != 0 && setparamfncnt != 2) | |
1a5632e0 | 183 | || (setgenparamfncnt != 0 && setgenparamfncnt != 2) |
273a67e3 | 184 | || (importfncnt != 0 && importfncnt != 2) |
1a5632e0 RL |
185 | || (exportfncnt != 0 && exportfncnt != 2) |
186 | || (keymgmt->gen != NULL | |
187 | && (keymgmt->gen_init == NULL | |
188 | || keymgmt->gen_cleanup == NULL))) { | |
a94a3e0d RL |
189 | EVP_KEYMGMT_free(keymgmt); |
190 | EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS); | |
191 | return NULL; | |
192 | } | |
193 | keymgmt->prov = prov; | |
194 | if (prov != NULL) | |
195 | ossl_provider_up_ref(prov); | |
196 | ||
197 | return keymgmt; | |
198 | } | |
199 | ||
b4250010 | 200 | EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OSSL_LIB_CTX *ctx, int name_id, |
f7c16d48 RL |
201 | const char *properties) |
202 | { | |
203 | return evp_generic_fetch_by_number(ctx, | |
204 | OSSL_OP_KEYMGMT, name_id, properties, | |
0ddf74bf | 205 | keymgmt_from_dispatch, |
f7c16d48 RL |
206 | (int (*)(void *))EVP_KEYMGMT_up_ref, |
207 | (void (*)(void *))EVP_KEYMGMT_free); | |
208 | } | |
209 | ||
b4250010 | 210 | EVP_KEYMGMT *EVP_KEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, |
a94a3e0d RL |
211 | const char *properties) |
212 | { | |
f7c16d48 | 213 | return evp_generic_fetch(ctx, OSSL_OP_KEYMGMT, algorithm, properties, |
0ddf74bf | 214 | keymgmt_from_dispatch, |
f7c16d48 RL |
215 | (int (*)(void *))EVP_KEYMGMT_up_ref, |
216 | (void (*)(void *))EVP_KEYMGMT_free); | |
a94a3e0d RL |
217 | } |
218 | ||
219 | int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt) | |
220 | { | |
221 | int ref = 0; | |
222 | ||
223 | CRYPTO_UP_REF(&keymgmt->refcnt, &ref, keymgmt->lock); | |
224 | return 1; | |
225 | } | |
226 | ||
227 | void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt) | |
228 | { | |
229 | int ref = 0; | |
230 | ||
231 | if (keymgmt == NULL) | |
232 | return; | |
233 | ||
234 | CRYPTO_DOWN_REF(&keymgmt->refcnt, &ref, keymgmt->lock); | |
235 | if (ref > 0) | |
236 | return; | |
237 | ossl_provider_free(keymgmt->prov); | |
238 | CRYPTO_THREAD_lock_free(keymgmt->lock); | |
239 | OPENSSL_free(keymgmt); | |
240 | } | |
241 | ||
242 | const OSSL_PROVIDER *EVP_KEYMGMT_provider(const EVP_KEYMGMT *keymgmt) | |
243 | { | |
244 | return keymgmt->prov; | |
245 | } | |
246 | ||
506cb0f6 RL |
247 | int EVP_KEYMGMT_number(const EVP_KEYMGMT *keymgmt) |
248 | { | |
249 | return keymgmt->name_id; | |
250 | } | |
251 | ||
d8025f4a MC |
252 | const char *EVP_KEYMGMT_get0_first_name(const EVP_KEYMGMT *keymgmt) |
253 | { | |
254 | return evp_first_name(keymgmt->prov, keymgmt->name_id); | |
255 | } | |
256 | ||
251e610c RL |
257 | int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name) |
258 | { | |
e4a1d023 | 259 | return evp_is_a(keymgmt->prov, keymgmt->name_id, NULL, name); |
251e610c RL |
260 | } |
261 | ||
b4250010 | 262 | void EVP_KEYMGMT_do_all_provided(OSSL_LIB_CTX *libctx, |
251e610c RL |
263 | void (*fn)(EVP_KEYMGMT *keymgmt, void *arg), |
264 | void *arg) | |
265 | { | |
266 | evp_generic_do_all(libctx, OSSL_OP_KEYMGMT, | |
267 | (void (*)(void *, void *))fn, arg, | |
0ddf74bf | 268 | keymgmt_from_dispatch, |
251e610c RL |
269 | (void (*)(void *))EVP_KEYMGMT_free); |
270 | } | |
f651c727 RL |
271 | |
272 | void EVP_KEYMGMT_names_do_all(const EVP_KEYMGMT *keymgmt, | |
273 | void (*fn)(const char *name, void *data), | |
274 | void *data) | |
275 | { | |
276 | if (keymgmt->prov != NULL) | |
277 | evp_names_do_all(keymgmt->prov, keymgmt->name_id, fn, data); | |
278 | } | |
68552cde RL |
279 | |
280 | /* | |
281 | * Internal API that interfaces with the method function pointers | |
282 | */ | |
b305452f | 283 | void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt) |
68552cde RL |
284 | { |
285 | void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); | |
286 | ||
b305452f RL |
287 | /* |
288 | * TODO(3.0) 'new' is currently mandatory on its own, but when new | |
289 | * constructors appear, it won't be quite as mandatory, so we have | |
290 | * a check for future cases. | |
291 | */ | |
292 | if (keymgmt->new == NULL) | |
293 | return NULL; | |
294 | return keymgmt->new(provctx); | |
68552cde RL |
295 | } |
296 | ||
b305452f | 297 | void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keydata) |
68552cde | 298 | { |
b305452f RL |
299 | /* This is mandatory, no need to check for its presence */ |
300 | keymgmt->free(keydata); | |
68552cde RL |
301 | } |
302 | ||
1a5632e0 RL |
303 | void *evp_keymgmt_gen_init(const EVP_KEYMGMT *keymgmt, int selection) |
304 | { | |
305 | void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); | |
306 | ||
307 | if (keymgmt->gen_init == NULL) | |
308 | return NULL; | |
309 | return keymgmt->gen_init(provctx, selection); | |
310 | } | |
311 | ||
312 | int evp_keymgmt_gen_set_template(const EVP_KEYMGMT *keymgmt, void *genctx, | |
313 | void *template) | |
314 | { | |
d0ddf9b4 RL |
315 | /* |
316 | * It's arguable if we actually should return success in this case, as | |
317 | * it allows the caller to set a template key, which is then ignored. | |
318 | * However, this is how the legacy methods (EVP_PKEY_METHOD) operate, | |
319 | * so we do this in the interest of backward compatibility. | |
320 | * TODO(3.0) Investigate if we should change this behaviour. | |
321 | */ | |
1a5632e0 | 322 | if (keymgmt->gen_set_template == NULL) |
d0ddf9b4 | 323 | return 1; |
1a5632e0 RL |
324 | return keymgmt->gen_set_template(genctx, template); |
325 | } | |
326 | ||
327 | int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx, | |
328 | const OSSL_PARAM params[]) | |
329 | { | |
330 | if (keymgmt->gen_set_params == NULL) | |
331 | return 0; | |
332 | return keymgmt->gen_set_params(genctx, params); | |
333 | } | |
334 | ||
e3efe7a5 | 335 | const OSSL_PARAM *EVP_KEYMGMT_gen_settable_params(const EVP_KEYMGMT *keymgmt) |
1a5632e0 RL |
336 | { |
337 | void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); | |
338 | ||
339 | if (keymgmt->gen_settable_params == NULL) | |
340 | return NULL; | |
341 | return keymgmt->gen_settable_params(provctx); | |
342 | } | |
343 | ||
344 | void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx, | |
345 | OSSL_CALLBACK *cb, void *cbarg) | |
346 | { | |
347 | if (keymgmt->gen == NULL) | |
348 | return NULL; | |
349 | return keymgmt->gen(genctx, cb, cbarg); | |
350 | } | |
351 | ||
352 | void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx) | |
353 | { | |
354 | if (keymgmt->gen != NULL) | |
355 | keymgmt->gen_cleanup(genctx); | |
356 | } | |
357 | ||
5dacb38c RL |
358 | void *evp_keymgmt_load(const EVP_KEYMGMT *keymgmt, |
359 | const void *objref, size_t objref_sz) | |
360 | { | |
361 | if (keymgmt->load != NULL) | |
362 | return keymgmt->load(objref, objref_sz); | |
363 | return NULL; | |
364 | } | |
365 | ||
b305452f RL |
366 | int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, void *keydata, |
367 | OSSL_PARAM params[]) | |
68552cde | 368 | { |
b305452f | 369 | if (keymgmt->get_params == NULL) |
68552cde | 370 | return 1; |
b305452f | 371 | return keymgmt->get_params(keydata, params); |
68552cde RL |
372 | } |
373 | ||
e3efe7a5 | 374 | const OSSL_PARAM *EVP_KEYMGMT_gettable_params(const EVP_KEYMGMT *keymgmt) |
68552cde | 375 | { |
18ec26ba P |
376 | void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); |
377 | ||
b305452f | 378 | if (keymgmt->gettable_params == NULL) |
68552cde | 379 | return NULL; |
18ec26ba | 380 | return keymgmt->gettable_params(provctx); |
68552cde RL |
381 | } |
382 | ||
4fe54d67 NT |
383 | int evp_keymgmt_set_params(const EVP_KEYMGMT *keymgmt, void *keydata, |
384 | const OSSL_PARAM params[]) | |
385 | { | |
386 | if (keymgmt->set_params == NULL) | |
387 | return 1; | |
388 | return keymgmt->set_params(keydata, params); | |
389 | } | |
390 | ||
e3efe7a5 | 391 | const OSSL_PARAM *EVP_KEYMGMT_settable_params(const EVP_KEYMGMT *keymgmt) |
4fe54d67 | 392 | { |
18ec26ba P |
393 | void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); |
394 | ||
4fe54d67 NT |
395 | if (keymgmt->settable_params == NULL) |
396 | return NULL; | |
18ec26ba | 397 | return keymgmt->settable_params(provctx); |
4fe54d67 NT |
398 | } |
399 | ||
b305452f | 400 | int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keydata, int selection) |
68552cde | 401 | { |
b305452f RL |
402 | /* This is mandatory, no need to check for its presence */ |
403 | return keymgmt->has(keydata, selection); | |
68552cde RL |
404 | } |
405 | ||
b305452f RL |
406 | int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata, |
407 | int selection) | |
68552cde | 408 | { |
b305452f RL |
409 | /* We assume valid if the implementation doesn't have a function */ |
410 | if (keymgmt->validate == NULL) | |
68552cde | 411 | return 1; |
b305452f | 412 | return keymgmt->validate(keydata, selection); |
68552cde RL |
413 | } |
414 | ||
bee5d6cd RL |
415 | int evp_keymgmt_match(const EVP_KEYMGMT *keymgmt, |
416 | const void *keydata1, const void *keydata2, | |
417 | int selection) | |
418 | { | |
419 | /* We assume no match if the implementation doesn't have a function */ | |
420 | if (keymgmt->match == NULL) | |
421 | return 0; | |
422 | return keymgmt->match(keydata1, keydata2, selection); | |
423 | } | |
424 | ||
b305452f RL |
425 | int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata, |
426 | int selection, const OSSL_PARAM params[]) | |
68552cde | 427 | { |
b305452f RL |
428 | if (keymgmt->import == NULL) |
429 | return 0; | |
430 | return keymgmt->import(keydata, selection, params); | |
68552cde RL |
431 | } |
432 | ||
b305452f RL |
433 | const OSSL_PARAM *evp_keymgmt_import_types(const EVP_KEYMGMT *keymgmt, |
434 | int selection) | |
68552cde | 435 | { |
b305452f RL |
436 | if (keymgmt->import_types == NULL) |
437 | return NULL; | |
438 | return keymgmt->import_types(selection); | |
68552cde RL |
439 | } |
440 | ||
b305452f RL |
441 | int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata, |
442 | int selection, OSSL_CALLBACK *param_cb, void *cbarg) | |
68552cde | 443 | { |
b305452f RL |
444 | if (keymgmt->export == NULL) |
445 | return 0; | |
446 | return keymgmt->export(keydata, selection, param_cb, cbarg); | |
68552cde RL |
447 | } |
448 | ||
b305452f RL |
449 | const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt, |
450 | int selection) | |
68552cde | 451 | { |
b305452f RL |
452 | if (keymgmt->export_types == NULL) |
453 | return NULL; | |
454 | return keymgmt->export_types(selection); | |
68552cde | 455 | } |
13697f1c RL |
456 | |
457 | int evp_keymgmt_copy(const EVP_KEYMGMT *keymgmt, | |
458 | void *keydata_to, const void *keydata_from, | |
459 | int selection) | |
460 | { | |
461 | /* We assume no copy if the implementation doesn't have a function */ | |
462 | if (keymgmt->copy == NULL) | |
463 | return 0; | |
464 | return keymgmt->copy(keydata_to, keydata_from, selection); | |
465 | } |