/src/openssl/crypto/evp/mac_meth.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2022-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/evp.h> |
11 | | #include <openssl/err.h> |
12 | | #include <openssl/core.h> |
13 | | #include <openssl/core_dispatch.h> |
14 | | #include "internal/provider.h" |
15 | | #include "internal/core.h" |
16 | | #include "crypto/evp.h" |
17 | | #include "evp_local.h" |
18 | | |
19 | | static int evp_mac_up_ref(void *vmac) |
20 | 0 | { |
21 | 0 | EVP_MAC *mac = vmac; |
22 | 0 | int ref = 0; |
23 | |
|
24 | 0 | CRYPTO_UP_REF(&mac->refcnt, &ref); |
25 | 0 | return 1; |
26 | 0 | } |
27 | | |
28 | | static void evp_mac_free(void *vmac) |
29 | 0 | { |
30 | 0 | EVP_MAC *mac = vmac; |
31 | 0 | int ref = 0; |
32 | |
|
33 | 0 | if (mac == NULL) |
34 | 0 | return; |
35 | | |
36 | 0 | CRYPTO_DOWN_REF(&mac->refcnt, &ref); |
37 | 0 | if (ref > 0) |
38 | 0 | return; |
39 | 0 | OPENSSL_free(mac->type_name); |
40 | 0 | ossl_provider_free(mac->prov); |
41 | 0 | CRYPTO_FREE_REF(&mac->refcnt); |
42 | 0 | OPENSSL_free(mac); |
43 | 0 | } |
44 | | |
45 | | static void *evp_mac_new(void) |
46 | 0 | { |
47 | 0 | EVP_MAC *mac = NULL; |
48 | |
|
49 | 0 | if ((mac = OPENSSL_zalloc(sizeof(*mac))) == NULL |
50 | 0 | || !CRYPTO_NEW_REF(&mac->refcnt, 1)) { |
51 | 0 | evp_mac_free(mac); |
52 | 0 | return NULL; |
53 | 0 | } |
54 | 0 | return mac; |
55 | 0 | } |
56 | | |
57 | | static void *evp_mac_from_algorithm(int name_id, |
58 | | const OSSL_ALGORITHM *algodef, |
59 | | OSSL_PROVIDER *prov) |
60 | 0 | { |
61 | 0 | const OSSL_DISPATCH *fns = algodef->implementation; |
62 | 0 | EVP_MAC *mac = NULL; |
63 | 0 | int fnmaccnt = 0, fnctxcnt = 0, mac_init_found = 0; |
64 | |
|
65 | 0 | if ((mac = evp_mac_new()) == NULL) { |
66 | 0 | ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); |
67 | 0 | goto err; |
68 | 0 | } |
69 | 0 | mac->name_id = name_id; |
70 | |
|
71 | 0 | if ((mac->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) |
72 | 0 | goto err; |
73 | | |
74 | 0 | mac->description = algodef->algorithm_description; |
75 | |
|
76 | 0 | for (; fns->function_id != 0; fns++) { |
77 | 0 | switch (fns->function_id) { |
78 | 0 | case OSSL_FUNC_MAC_NEWCTX: |
79 | 0 | if (mac->newctx != NULL) |
80 | 0 | break; |
81 | 0 | mac->newctx = OSSL_FUNC_mac_newctx(fns); |
82 | 0 | fnctxcnt++; |
83 | 0 | break; |
84 | 0 | case OSSL_FUNC_MAC_DUPCTX: |
85 | 0 | if (mac->dupctx != NULL) |
86 | 0 | break; |
87 | 0 | mac->dupctx = OSSL_FUNC_mac_dupctx(fns); |
88 | 0 | break; |
89 | 0 | case OSSL_FUNC_MAC_FREECTX: |
90 | 0 | if (mac->freectx != NULL) |
91 | 0 | break; |
92 | 0 | mac->freectx = OSSL_FUNC_mac_freectx(fns); |
93 | 0 | fnctxcnt++; |
94 | 0 | break; |
95 | 0 | case OSSL_FUNC_MAC_INIT: |
96 | 0 | if (mac->init != NULL) |
97 | 0 | break; |
98 | 0 | mac->init = OSSL_FUNC_mac_init(fns); |
99 | 0 | mac_init_found = 1; |
100 | 0 | break; |
101 | 0 | case OSSL_FUNC_MAC_UPDATE: |
102 | 0 | if (mac->update != NULL) |
103 | 0 | break; |
104 | 0 | mac->update = OSSL_FUNC_mac_update(fns); |
105 | 0 | fnmaccnt++; |
106 | 0 | break; |
107 | 0 | case OSSL_FUNC_MAC_FINAL: |
108 | 0 | if (mac->final != NULL) |
109 | 0 | break; |
110 | 0 | mac->final = OSSL_FUNC_mac_final(fns); |
111 | 0 | fnmaccnt++; |
112 | 0 | break; |
113 | 0 | case OSSL_FUNC_MAC_GETTABLE_PARAMS: |
114 | 0 | if (mac->gettable_params != NULL) |
115 | 0 | break; |
116 | 0 | mac->gettable_params = |
117 | 0 | OSSL_FUNC_mac_gettable_params(fns); |
118 | 0 | break; |
119 | 0 | case OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS: |
120 | 0 | if (mac->gettable_ctx_params != NULL) |
121 | 0 | break; |
122 | 0 | mac->gettable_ctx_params = |
123 | 0 | OSSL_FUNC_mac_gettable_ctx_params(fns); |
124 | 0 | break; |
125 | 0 | case OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS: |
126 | 0 | if (mac->settable_ctx_params != NULL) |
127 | 0 | break; |
128 | 0 | mac->settable_ctx_params = |
129 | 0 | OSSL_FUNC_mac_settable_ctx_params(fns); |
130 | 0 | break; |
131 | 0 | case OSSL_FUNC_MAC_GET_PARAMS: |
132 | 0 | if (mac->get_params != NULL) |
133 | 0 | break; |
134 | 0 | mac->get_params = OSSL_FUNC_mac_get_params(fns); |
135 | 0 | break; |
136 | 0 | case OSSL_FUNC_MAC_GET_CTX_PARAMS: |
137 | 0 | if (mac->get_ctx_params != NULL) |
138 | 0 | break; |
139 | 0 | mac->get_ctx_params = OSSL_FUNC_mac_get_ctx_params(fns); |
140 | 0 | break; |
141 | 0 | case OSSL_FUNC_MAC_SET_CTX_PARAMS: |
142 | 0 | if (mac->set_ctx_params != NULL) |
143 | 0 | break; |
144 | 0 | mac->set_ctx_params = OSSL_FUNC_mac_set_ctx_params(fns); |
145 | 0 | break; |
146 | 0 | case OSSL_FUNC_MAC_INIT_SKEY: |
147 | 0 | if (mac->init_skey != NULL) |
148 | 0 | break; |
149 | 0 | mac->init_skey = OSSL_FUNC_mac_init_skey(fns); |
150 | 0 | mac_init_found = 1; |
151 | 0 | break; |
152 | 0 | } |
153 | 0 | } |
154 | 0 | fnmaccnt += mac_init_found; |
155 | 0 | if (fnmaccnt != 3 |
156 | 0 | || fnctxcnt != 2) { |
157 | | /* |
158 | | * In order to be a consistent set of functions we must have at least |
159 | | * a complete set of "mac" functions, and a complete set of context |
160 | | * management functions, as well as the size function. |
161 | | */ |
162 | 0 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); |
163 | 0 | goto err; |
164 | 0 | } |
165 | | |
166 | 0 | if (prov != NULL && !ossl_provider_up_ref(prov)) |
167 | 0 | goto err; |
168 | | |
169 | 0 | mac->prov = prov; |
170 | |
|
171 | 0 | return mac; |
172 | | |
173 | 0 | err: |
174 | 0 | evp_mac_free(mac); |
175 | 0 | return NULL; |
176 | 0 | } |
177 | | |
178 | | EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, |
179 | | const char *properties) |
180 | 0 | { |
181 | 0 | return evp_generic_fetch(libctx, OSSL_OP_MAC, algorithm, properties, |
182 | 0 | evp_mac_from_algorithm, evp_mac_up_ref, |
183 | 0 | evp_mac_free); |
184 | 0 | } |
185 | | |
186 | | int EVP_MAC_up_ref(EVP_MAC *mac) |
187 | 0 | { |
188 | 0 | return evp_mac_up_ref(mac); |
189 | 0 | } |
190 | | |
191 | | void EVP_MAC_free(EVP_MAC *mac) |
192 | 0 | { |
193 | 0 | evp_mac_free(mac); |
194 | 0 | } |
195 | | |
196 | | const OSSL_PROVIDER *EVP_MAC_get0_provider(const EVP_MAC *mac) |
197 | 0 | { |
198 | 0 | return mac->prov; |
199 | 0 | } |
200 | | |
201 | | const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac) |
202 | 0 | { |
203 | 0 | if (mac->gettable_params == NULL) |
204 | 0 | return NULL; |
205 | 0 | return mac->gettable_params(ossl_provider_ctx(EVP_MAC_get0_provider(mac))); |
206 | 0 | } |
207 | | |
208 | | const OSSL_PARAM *EVP_MAC_gettable_ctx_params(const EVP_MAC *mac) |
209 | 0 | { |
210 | 0 | void *alg; |
211 | |
|
212 | 0 | if (mac->gettable_ctx_params == NULL) |
213 | 0 | return NULL; |
214 | 0 | alg = ossl_provider_ctx(EVP_MAC_get0_provider(mac)); |
215 | 0 | return mac->gettable_ctx_params(NULL, alg); |
216 | 0 | } |
217 | | |
218 | | const OSSL_PARAM *EVP_MAC_settable_ctx_params(const EVP_MAC *mac) |
219 | 0 | { |
220 | 0 | void *alg; |
221 | |
|
222 | 0 | if (mac->settable_ctx_params == NULL) |
223 | 0 | return NULL; |
224 | 0 | alg = ossl_provider_ctx(EVP_MAC_get0_provider(mac)); |
225 | 0 | return mac->settable_ctx_params(NULL, alg); |
226 | 0 | } |
227 | | |
228 | | const OSSL_PARAM *EVP_MAC_CTX_gettable_params(EVP_MAC_CTX *ctx) |
229 | 0 | { |
230 | 0 | void *alg; |
231 | |
|
232 | 0 | if (ctx->meth->gettable_ctx_params == NULL) |
233 | 0 | return NULL; |
234 | 0 | alg = ossl_provider_ctx(EVP_MAC_get0_provider(ctx->meth)); |
235 | 0 | return ctx->meth->gettable_ctx_params(ctx->algctx, alg); |
236 | 0 | } |
237 | | |
238 | | const OSSL_PARAM *EVP_MAC_CTX_settable_params(EVP_MAC_CTX *ctx) |
239 | 0 | { |
240 | 0 | void *alg; |
241 | |
|
242 | 0 | if (ctx->meth->settable_ctx_params == NULL) |
243 | 0 | return NULL; |
244 | 0 | alg = ossl_provider_ctx(EVP_MAC_get0_provider(ctx->meth)); |
245 | 0 | return ctx->meth->settable_ctx_params(ctx->algctx, alg); |
246 | 0 | } |
247 | | |
248 | | void EVP_MAC_do_all_provided(OSSL_LIB_CTX *libctx, |
249 | | void (*fn)(EVP_MAC *mac, void *arg), |
250 | | void *arg) |
251 | 0 | { |
252 | 0 | evp_generic_do_all(libctx, OSSL_OP_MAC, |
253 | 0 | (void (*)(void *, void *))fn, arg, |
254 | 0 | evp_mac_from_algorithm, evp_mac_up_ref, evp_mac_free); |
255 | 0 | } |
256 | | |
257 | | EVP_MAC *evp_mac_fetch_from_prov(OSSL_PROVIDER *prov, |
258 | | const char *algorithm, |
259 | | const char *properties) |
260 | 0 | { |
261 | 0 | return evp_generic_fetch_from_prov(prov, OSSL_OP_MAC, |
262 | 0 | algorithm, properties, |
263 | 0 | evp_mac_from_algorithm, |
264 | 0 | evp_mac_up_ref, |
265 | 0 | evp_mac_free); |
266 | 0 | } |