xref: /freebsd-src/crypto/openssl/crypto/evp/mac_meth.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
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