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