f35c2d157e3e26a5401cc8e89a3e238614a5ad0c
[openssl.git] / crypto / evp / mac_meth.c
1 #include <openssl/evp.h>
2 #include <openssl/err.h>
3 #include <openssl/core.h>
4 #include <openssl/core_numbers.h>
5 #include "crypto/evp.h"
6 #include "internal/provider.h"
7 #include "evp_local.h"
8
9 static int evp_mac_up_ref(void *vmac)
10 {
11     EVP_MAC *mac = vmac;
12     int ref = 0;
13
14     CRYPTO_UP_REF(&mac->refcnt, &ref, mac->lock);
15     return 1;
16 }
17
18 static void evp_mac_free(void *vmac)
19 {
20     EVP_MAC *mac = vmac;
21     int ref = 0;
22
23     if (mac == NULL)
24         return;
25
26     CRYPTO_DOWN_REF(&mac->refcnt, &ref, mac->lock);
27     if (ref > 0)
28         return;
29     ossl_provider_free(mac->prov);
30     CRYPTO_THREAD_lock_free(mac->lock);
31     OPENSSL_free(mac);
32 }
33
34 static void *evp_mac_new(void)
35 {
36     EVP_MAC *mac = NULL;
37
38     if ((mac = OPENSSL_zalloc(sizeof(*mac))) == NULL
39         || (mac->lock = CRYPTO_THREAD_lock_new()) == NULL) {
40         evp_mac_free(mac);
41         return NULL;
42     }
43
44     mac->refcnt = 1;
45
46     return mac;
47 }
48
49 static void *evp_mac_from_dispatch(int name_id,
50                                    const OSSL_DISPATCH *fns,
51                                    OSSL_PROVIDER *prov,
52                                    void *unused)
53 {
54     EVP_MAC *mac = NULL;
55     int fnmaccnt = 0, fnctxcnt = 0;
56
57     if ((mac = evp_mac_new()) == NULL) {
58         EVPerr(0, ERR_R_MALLOC_FAILURE);
59         return NULL;
60     }
61     mac->name_id = name_id;
62
63     for (; fns->function_id != 0; fns++) {
64         switch (fns->function_id) {
65         case OSSL_FUNC_MAC_NEWCTX:
66             if (mac->newctx != NULL)
67                 break;
68             mac->newctx = OSSL_get_OP_mac_newctx(fns);
69             fnctxcnt++;
70             break;
71         case OSSL_FUNC_MAC_DUPCTX:
72             if (mac->dupctx != NULL)
73                 break;
74             mac->dupctx = OSSL_get_OP_mac_dupctx(fns);
75             break;
76         case OSSL_FUNC_MAC_FREECTX:
77             if (mac->freectx != NULL)
78                 break;
79             mac->freectx = OSSL_get_OP_mac_freectx(fns);
80             fnctxcnt++;
81             break;
82         case OSSL_FUNC_MAC_INIT:
83             if (mac->init != NULL)
84                 break;
85             mac->init = OSSL_get_OP_mac_init(fns);
86             fnmaccnt++;
87             break;
88         case OSSL_FUNC_MAC_UPDATE:
89             if (mac->update != NULL)
90                 break;
91             mac->update = OSSL_get_OP_mac_update(fns);
92             fnmaccnt++;
93             break;
94         case OSSL_FUNC_MAC_FINAL:
95             if (mac->final != NULL)
96                 break;
97             mac->final = OSSL_get_OP_mac_final(fns);
98             fnmaccnt++;
99             break;
100         case OSSL_FUNC_MAC_GETTABLE_PARAMS:
101             if (mac->gettable_params != NULL)
102                 break;
103             mac->gettable_params =
104                 OSSL_get_OP_mac_gettable_params(fns);
105             break;
106         case OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS:
107             if (mac->gettable_ctx_params != NULL)
108                 break;
109             mac->gettable_ctx_params =
110                 OSSL_get_OP_mac_gettable_ctx_params(fns);
111             break;
112         case OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS:
113             if (mac->settable_ctx_params != NULL)
114                 break;
115             mac->settable_ctx_params =
116                 OSSL_get_OP_mac_settable_ctx_params(fns);
117             break;
118         case OSSL_FUNC_MAC_GET_PARAMS:
119             if (mac->get_params != NULL)
120                 break;
121             mac->get_params = OSSL_get_OP_mac_get_params(fns);
122             break;
123         case OSSL_FUNC_MAC_GET_CTX_PARAMS:
124             if (mac->get_ctx_params != NULL)
125                 break;
126             mac->get_ctx_params = OSSL_get_OP_mac_get_ctx_params(fns);
127             break;
128         case OSSL_FUNC_MAC_SET_CTX_PARAMS:
129             if (mac->set_ctx_params != NULL)
130                 break;
131             mac->set_ctx_params = OSSL_get_OP_mac_set_ctx_params(fns);
132             break;
133         }
134     }
135     if (fnmaccnt != 3
136         || fnctxcnt != 2) {
137         /*
138          * In order to be a consistent set of functions we must have at least
139          * a complete set of "mac" functions, and a complete set of context
140          * management functions, as well as the size function.
141          */
142         evp_mac_free(mac);
143         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
144         return NULL;
145     }
146     mac->prov = prov;
147     if (prov != NULL)
148         ossl_provider_up_ref(prov);
149
150     return mac;
151 }
152
153 EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm,
154                        const char *properties)
155 {
156     return evp_generic_fetch(libctx, OSSL_OP_MAC, algorithm, properties,
157                              evp_mac_from_dispatch, NULL, evp_mac_up_ref,
158                              evp_mac_free);
159 }
160
161 int EVP_MAC_up_ref(EVP_MAC *mac)
162 {
163     return evp_mac_up_ref(mac);
164 }
165
166 void EVP_MAC_free(EVP_MAC *mac)
167 {
168     evp_mac_free(mac);
169 }
170
171 int EVP_MAC_is_a(const EVP_MAC *mac, const char *name)
172 {
173     return evp_is_a(mac->prov, mac->name_id, name);
174 }
175
176 const char *EVP_MAC_name(const EVP_MAC *mac)
177 {
178     return evp_first_name(mac->prov, mac->name_id);
179 }
180
181 const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac)
182 {
183     return mac->prov;
184 }
185
186 const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac)
187 {
188     if (mac->gettable_params == NULL)
189         return NULL;
190     return mac->gettable_params();
191 }
192
193 const OSSL_PARAM *EVP_MAC_gettable_ctx_params(const EVP_MAC *mac)
194 {
195     if (mac->gettable_ctx_params == NULL)
196         return NULL;
197     return mac->gettable_ctx_params();
198 }
199
200 const OSSL_PARAM *EVP_MAC_settable_ctx_params(const EVP_MAC *mac)
201 {
202     if (mac->settable_ctx_params == NULL)
203         return NULL;
204     return mac->settable_ctx_params();
205 }
206
207 void EVP_MAC_do_all_ex(OPENSSL_CTX *libctx,
208                        void (*fn)(EVP_MAC *mac, void *arg),
209                        void *arg)
210 {
211     evp_generic_do_all(libctx, OSSL_OP_MAC,
212                        (void (*)(void *, void *))fn, arg,
213                        evp_mac_from_dispatch, NULL, evp_mac_free);
214 }