]>
Commit | Line | Data |
---|---|---|
fb9e6dd6 P |
1 | /* |
2 | * Copyright 2019 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_numbers.h> | |
14 | #include <openssl/kdf.h> | |
15 | #include "internal/evp_int.h" | |
16 | #include "internal/provider.h" | |
17 | #include "evp_locl.h" | |
18 | ||
19 | static int evp_kdf_up_ref(void *vkdf) | |
20 | { | |
21 | EVP_KDF *kdf = (EVP_KDF *)vkdf; | |
22 | int ref = 0; | |
23 | ||
24 | CRYPTO_UP_REF(&kdf->refcnt, &ref, kdf->lock); | |
25 | return 1; | |
26 | } | |
27 | ||
28 | static void evp_kdf_free(void *vkdf){ | |
29 | EVP_KDF *kdf = (EVP_KDF *)vkdf; | |
30 | int ref = 0; | |
31 | ||
32 | if (kdf != NULL) { | |
33 | CRYPTO_DOWN_REF(&kdf->refcnt, &ref, kdf->lock); | |
34 | if (ref <= 0) { | |
35 | ossl_provider_free(kdf->prov); | |
36 | OPENSSL_free(kdf->name); | |
37 | CRYPTO_THREAD_lock_free(kdf->lock); | |
38 | OPENSSL_free(kdf); | |
39 | } | |
40 | } | |
41 | } | |
42 | ||
43 | static void *evp_kdf_new(void) | |
44 | { | |
45 | EVP_KDF *kdf = NULL; | |
46 | ||
47 | if ((kdf = OPENSSL_zalloc(sizeof(*kdf))) == NULL | |
48 | || (kdf->lock = CRYPTO_THREAD_lock_new()) == NULL) { | |
49 | OPENSSL_free(kdf); | |
50 | return NULL; | |
51 | } | |
52 | kdf->refcnt = 1; | |
53 | return kdf; | |
54 | } | |
55 | ||
56 | static void *evp_kdf_from_dispatch(const char *name, const OSSL_DISPATCH *fns, | |
57 | OSSL_PROVIDER *prov, void *method_data) | |
58 | { | |
59 | EVP_KDF *kdf = NULL; | |
60 | int fnkdfcnt = 0, fnctxcnt = 0; | |
61 | ||
62 | if ((kdf = evp_kdf_new()) == NULL | |
63 | || (kdf->name = OPENSSL_strdup(name)) == NULL) { | |
64 | evp_kdf_free(kdf); | |
65 | EVPerr(0, ERR_R_MALLOC_FAILURE); | |
66 | return NULL; | |
67 | } | |
68 | ||
69 | for (; fns->function_id != 0; fns++) { | |
70 | switch (fns->function_id) { | |
71 | case OSSL_FUNC_KDF_NEWCTX: | |
72 | if (kdf->newctx != NULL) | |
73 | break; | |
74 | kdf->newctx = OSSL_get_OP_kdf_newctx(fns); | |
75 | fnctxcnt++; | |
76 | break; | |
77 | case OSSL_FUNC_KDF_DUPCTX: | |
78 | if (kdf->dupctx != NULL) | |
79 | break; | |
80 | kdf->dupctx = OSSL_get_OP_kdf_dupctx(fns); | |
81 | break; | |
82 | case OSSL_FUNC_KDF_FREECTX: | |
83 | if (kdf->freectx != NULL) | |
84 | break; | |
85 | kdf->freectx = OSSL_get_OP_kdf_freectx(fns); | |
86 | fnctxcnt++; | |
87 | break; | |
88 | case OSSL_FUNC_KDF_DERIVE: | |
89 | if (kdf->derive != NULL) | |
90 | break; | |
91 | kdf->derive = OSSL_get_OP_kdf_derive(fns); | |
92 | fnkdfcnt++; | |
93 | break; | |
94 | case OSSL_FUNC_KDF_GETTABLE_PARAMS: | |
95 | if (kdf->gettable_params != NULL) | |
96 | break; | |
97 | kdf->gettable_params = | |
98 | OSSL_get_OP_kdf_gettable_params(fns); | |
99 | break; | |
100 | case OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS: | |
101 | if (kdf->gettable_ctx_params != NULL) | |
102 | break; | |
103 | kdf->gettable_ctx_params = | |
104 | OSSL_get_OP_kdf_gettable_ctx_params(fns); | |
105 | break; | |
106 | case OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS: | |
107 | if (kdf->settable_ctx_params != NULL) | |
108 | break; | |
109 | kdf->settable_ctx_params = | |
110 | OSSL_get_OP_kdf_settable_ctx_params(fns); | |
111 | break; | |
112 | case OSSL_FUNC_KDF_GET_PARAMS: | |
113 | if (kdf->get_params != NULL) | |
114 | break; | |
115 | kdf->get_params = OSSL_get_OP_kdf_get_params(fns); | |
116 | break; | |
117 | case OSSL_FUNC_KDF_GET_CTX_PARAMS: | |
118 | if (kdf->get_ctx_params != NULL) | |
119 | break; | |
120 | kdf->get_ctx_params = OSSL_get_OP_kdf_get_ctx_params(fns); | |
121 | break; | |
122 | case OSSL_FUNC_KDF_SET_CTX_PARAMS: | |
123 | if (kdf->set_ctx_params != NULL) | |
124 | break; | |
125 | kdf->set_ctx_params = OSSL_get_OP_kdf_set_ctx_params(fns); | |
126 | break; | |
127 | } | |
128 | } | |
129 | if (fnkdfcnt != 1 || fnctxcnt != 2) { | |
130 | /* | |
131 | * In order to be a consistent set of functions we must have at least | |
132 | * a derive function, and a complete set of context management | |
133 | * functions. | |
134 | */ | |
135 | evp_kdf_free(kdf); | |
136 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); | |
137 | return NULL; | |
138 | } | |
139 | kdf->prov = prov; | |
140 | if (prov != NULL) | |
141 | ossl_provider_up_ref(prov); | |
142 | ||
143 | return kdf; | |
144 | } | |
145 | ||
146 | EVP_KDF *EVP_KDF_fetch(OPENSSL_CTX *libctx, const char *algorithm, | |
147 | const char *properties) | |
148 | { | |
149 | return evp_generic_fetch(libctx, OSSL_OP_KDF, algorithm, properties, | |
150 | evp_kdf_from_dispatch, NULL, evp_kdf_up_ref, | |
151 | evp_kdf_free); | |
152 | } | |
153 | ||
154 | int EVP_KDF_up_ref(EVP_KDF *kdf) | |
155 | { | |
156 | return evp_kdf_up_ref(kdf); | |
157 | } | |
158 | ||
159 | void EVP_KDF_free(EVP_KDF *kdf) | |
160 | { | |
161 | evp_kdf_free(kdf); | |
162 | } | |
163 | ||
164 | const OSSL_PARAM *EVP_KDF_gettable_params(const EVP_KDF *kdf) | |
165 | { | |
166 | if (kdf->gettable_params == NULL) | |
167 | return NULL; | |
168 | return kdf->gettable_params(); | |
169 | } | |
170 | ||
171 | const OSSL_PARAM *EVP_KDF_CTX_gettable_params(const EVP_KDF *kdf) | |
172 | { | |
173 | if (kdf->gettable_ctx_params == NULL) | |
174 | return NULL; | |
175 | return kdf->gettable_ctx_params(); | |
176 | } | |
177 | ||
178 | const OSSL_PARAM *EVP_KDF_CTX_settable_params(const EVP_KDF *kdf) | |
179 | { | |
180 | if (kdf->settable_ctx_params == NULL) | |
181 | return NULL; | |
182 | return kdf->settable_ctx_params(); | |
183 | } | |
184 | ||
185 | void EVP_KDF_do_all_ex(OPENSSL_CTX *libctx, | |
186 | void (*fn)(EVP_KDF *kdf, void *arg), | |
187 | void *arg) | |
188 | { | |
189 | evp_generic_do_all(libctx, OSSL_OP_KDF, | |
190 | (void (*)(void *, void *))fn, arg, | |
191 | evp_kdf_from_dispatch, NULL, evp_kdf_free); | |
192 | } |