xref: /freebsd-src/sys/contrib/openzfs/module/icp/api/kcf_mac.c (revision eda14cbc264d6969b02f2b1994cef11148e914f1)
1*eda14cbcSMatt Macy /*
2*eda14cbcSMatt Macy  * CDDL HEADER START
3*eda14cbcSMatt Macy  *
4*eda14cbcSMatt Macy  * The contents of this file are subject to the terms of the
5*eda14cbcSMatt Macy  * Common Development and Distribution License (the "License").
6*eda14cbcSMatt Macy  * You may not use this file except in compliance with the License.
7*eda14cbcSMatt Macy  *
8*eda14cbcSMatt Macy  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*eda14cbcSMatt Macy  * or http://www.opensolaris.org/os/licensing.
10*eda14cbcSMatt Macy  * See the License for the specific language governing permissions
11*eda14cbcSMatt Macy  * and limitations under the License.
12*eda14cbcSMatt Macy  *
13*eda14cbcSMatt Macy  * When distributing Covered Code, include this CDDL HEADER in each
14*eda14cbcSMatt Macy  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*eda14cbcSMatt Macy  * If applicable, add the following below this CDDL HEADER, with the
16*eda14cbcSMatt Macy  * fields enclosed by brackets "[]" replaced with your own identifying
17*eda14cbcSMatt Macy  * information: Portions Copyright [yyyy] [name of copyright owner]
18*eda14cbcSMatt Macy  *
19*eda14cbcSMatt Macy  * CDDL HEADER END
20*eda14cbcSMatt Macy  */
21*eda14cbcSMatt Macy /*
22*eda14cbcSMatt Macy  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*eda14cbcSMatt Macy  * Use is subject to license terms.
24*eda14cbcSMatt Macy  */
25*eda14cbcSMatt Macy 
26*eda14cbcSMatt Macy #include <sys/zfs_context.h>
27*eda14cbcSMatt Macy #include <sys/crypto/common.h>
28*eda14cbcSMatt Macy #include <sys/crypto/impl.h>
29*eda14cbcSMatt Macy #include <sys/crypto/api.h>
30*eda14cbcSMatt Macy #include <sys/crypto/spi.h>
31*eda14cbcSMatt Macy #include <sys/crypto/sched_impl.h>
32*eda14cbcSMatt Macy 
33*eda14cbcSMatt Macy /*
34*eda14cbcSMatt Macy  * Message authentication codes routines.
35*eda14cbcSMatt Macy  */
36*eda14cbcSMatt Macy 
37*eda14cbcSMatt Macy /*
38*eda14cbcSMatt Macy  * The following are the possible returned values common to all the routines
39*eda14cbcSMatt Macy  * below. The applicability of some of these return values depends on the
40*eda14cbcSMatt Macy  * presence of the arguments.
41*eda14cbcSMatt Macy  *
42*eda14cbcSMatt Macy  *	CRYPTO_SUCCESS:	The operation completed successfully.
43*eda14cbcSMatt Macy  *	CRYPTO_QUEUED:	A request was submitted successfully. The callback
44*eda14cbcSMatt Macy  *			routine will be called when the operation is done.
45*eda14cbcSMatt Macy  *	CRYPTO_INVALID_MECH_NUMBER, CRYPTO_INVALID_MECH_PARAM, or
46*eda14cbcSMatt Macy  *	CRYPTO_INVALID_MECH for problems with the 'mech'.
47*eda14cbcSMatt Macy  *	CRYPTO_INVALID_DATA for bogus 'data'
48*eda14cbcSMatt Macy  *	CRYPTO_HOST_MEMORY for failure to allocate memory to handle this work.
49*eda14cbcSMatt Macy  *	CRYPTO_INVALID_CONTEXT: Not a valid context.
50*eda14cbcSMatt Macy  *	CRYPTO_BUSY:	Cannot process the request now. Schedule a
51*eda14cbcSMatt Macy  *			crypto_bufcall(), or try later.
52*eda14cbcSMatt Macy  *	CRYPTO_NOT_SUPPORTED and CRYPTO_MECH_NOT_SUPPORTED: No provider is
53*eda14cbcSMatt Macy  *			capable of a function or a mechanism.
54*eda14cbcSMatt Macy  *	CRYPTO_INVALID_KEY: bogus 'key' argument.
55*eda14cbcSMatt Macy  *	CRYPTO_INVALID_MAC: bogus 'mac' argument.
56*eda14cbcSMatt Macy  */
57*eda14cbcSMatt Macy 
58*eda14cbcSMatt Macy /*
59*eda14cbcSMatt Macy  * crypto_mac_prov()
60*eda14cbcSMatt Macy  *
61*eda14cbcSMatt Macy  * Arguments:
62*eda14cbcSMatt Macy  *	mech:	crypto_mechanism_t pointer.
63*eda14cbcSMatt Macy  *		mech_type is a valid value previously returned by
64*eda14cbcSMatt Macy  *		crypto_mech2id();
65*eda14cbcSMatt Macy  *		When the mech's parameter is not NULL, its definition depends
66*eda14cbcSMatt Macy  *		on the standard definition of the mechanism.
67*eda14cbcSMatt Macy  *	key:	pointer to a crypto_key_t structure.
68*eda14cbcSMatt Macy  *	data:	The message to compute the MAC for.
69*eda14cbcSMatt Macy  *	mac: Storage for the MAC. The length needed depends on the mechanism.
70*eda14cbcSMatt Macy  *	tmpl:	a crypto_ctx_template_t, opaque template of a context of a
71*eda14cbcSMatt Macy  *		MAC with the 'mech' using 'key'. 'tmpl' is created by
72*eda14cbcSMatt Macy  *		a previous call to crypto_create_ctx_template().
73*eda14cbcSMatt Macy  *	cr:	crypto_call_req_t calling conditions and call back info.
74*eda14cbcSMatt Macy  *
75*eda14cbcSMatt Macy  * Description:
76*eda14cbcSMatt Macy  *	Asynchronously submits a request for, or synchronously performs a
77*eda14cbcSMatt Macy  *	single-part message authentication of 'data' with the mechanism
78*eda14cbcSMatt Macy  *	'mech', using *	the key 'key', on the specified provider with
79*eda14cbcSMatt Macy  *	the specified session id.
80*eda14cbcSMatt Macy  *	When complete and successful, 'mac' will contain the message
81*eda14cbcSMatt Macy  *	authentication code.
82*eda14cbcSMatt Macy  *
83*eda14cbcSMatt Macy  * Context:
84*eda14cbcSMatt Macy  *	Process or interrupt, according to the semantics dictated by the 'crq'.
85*eda14cbcSMatt Macy  *
86*eda14cbcSMatt Macy  * Returns:
87*eda14cbcSMatt Macy  *	See comment in the beginning of the file.
88*eda14cbcSMatt Macy  */
89*eda14cbcSMatt Macy int
90*eda14cbcSMatt Macy crypto_mac_prov(crypto_provider_t provider, crypto_session_id_t sid,
91*eda14cbcSMatt Macy     crypto_mechanism_t *mech, crypto_data_t *data, crypto_key_t *key,
92*eda14cbcSMatt Macy     crypto_ctx_template_t tmpl, crypto_data_t *mac, crypto_call_req_t *crq)
93*eda14cbcSMatt Macy {
94*eda14cbcSMatt Macy 	kcf_req_params_t params;
95*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd = provider;
96*eda14cbcSMatt Macy 	kcf_provider_desc_t *real_provider = pd;
97*eda14cbcSMatt Macy 	int rv;
98*eda14cbcSMatt Macy 
99*eda14cbcSMatt Macy 	ASSERT(KCF_PROV_REFHELD(pd));
100*eda14cbcSMatt Macy 
101*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
102*eda14cbcSMatt Macy 		rv = kcf_get_hardware_provider(mech->cm_type,
103*eda14cbcSMatt Macy 		    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
104*eda14cbcSMatt Macy 		    &real_provider, CRYPTO_FG_MAC_ATOMIC);
105*eda14cbcSMatt Macy 
106*eda14cbcSMatt Macy 		if (rv != CRYPTO_SUCCESS)
107*eda14cbcSMatt Macy 			return (rv);
108*eda14cbcSMatt Macy 	}
109*eda14cbcSMatt Macy 
110*eda14cbcSMatt Macy 	KCF_WRAP_MAC_OPS_PARAMS(&params, KCF_OP_ATOMIC, sid, mech, key,
111*eda14cbcSMatt Macy 	    data, mac, tmpl);
112*eda14cbcSMatt Macy 	rv = kcf_submit_request(real_provider, NULL, crq, &params, B_FALSE);
113*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
114*eda14cbcSMatt Macy 		KCF_PROV_REFRELE(real_provider);
115*eda14cbcSMatt Macy 
116*eda14cbcSMatt Macy 	return (rv);
117*eda14cbcSMatt Macy }
118*eda14cbcSMatt Macy 
119*eda14cbcSMatt Macy /*
120*eda14cbcSMatt Macy  * Same as crypto_mac_prov(), but relies on the KCF scheduler to choose
121*eda14cbcSMatt Macy  * a provider. See crypto_mac() comments for more information.
122*eda14cbcSMatt Macy  */
123*eda14cbcSMatt Macy int
124*eda14cbcSMatt Macy crypto_mac(crypto_mechanism_t *mech, crypto_data_t *data,
125*eda14cbcSMatt Macy     crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *mac,
126*eda14cbcSMatt Macy     crypto_call_req_t *crq)
127*eda14cbcSMatt Macy {
128*eda14cbcSMatt Macy 	int error;
129*eda14cbcSMatt Macy 	kcf_mech_entry_t *me;
130*eda14cbcSMatt Macy 	kcf_req_params_t params;
131*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
132*eda14cbcSMatt Macy 	kcf_ctx_template_t *ctx_tmpl;
133*eda14cbcSMatt Macy 	crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
134*eda14cbcSMatt Macy 	kcf_prov_tried_t *list = NULL;
135*eda14cbcSMatt Macy 
136*eda14cbcSMatt Macy retry:
137*eda14cbcSMatt Macy 	/* The pd is returned held */
138*eda14cbcSMatt Macy 	if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
139*eda14cbcSMatt Macy 	    list, CRYPTO_FG_MAC_ATOMIC, CHECK_RESTRICT(crq),
140*eda14cbcSMatt Macy 	    data->cd_length)) == NULL) {
141*eda14cbcSMatt Macy 		if (list != NULL)
142*eda14cbcSMatt Macy 			kcf_free_triedlist(list);
143*eda14cbcSMatt Macy 		return (error);
144*eda14cbcSMatt Macy 	}
145*eda14cbcSMatt Macy 
146*eda14cbcSMatt Macy 	/*
147*eda14cbcSMatt Macy 	 * For SW providers, check the validity of the context template
148*eda14cbcSMatt Macy 	 * It is very rare that the generation number mis-matches, so
149*eda14cbcSMatt Macy 	 * is acceptable to fail here, and let the consumer recover by
150*eda14cbcSMatt Macy 	 * freeing this tmpl and create a new one for the key and new SW
151*eda14cbcSMatt Macy 	 * provider
152*eda14cbcSMatt Macy 	 */
153*eda14cbcSMatt Macy 	if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
154*eda14cbcSMatt Macy 	    ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
155*eda14cbcSMatt Macy 		if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
156*eda14cbcSMatt Macy 			if (list != NULL)
157*eda14cbcSMatt Macy 				kcf_free_triedlist(list);
158*eda14cbcSMatt Macy 			KCF_PROV_REFRELE(pd);
159*eda14cbcSMatt Macy 			return (CRYPTO_OLD_CTX_TEMPLATE);
160*eda14cbcSMatt Macy 		} else {
161*eda14cbcSMatt Macy 			spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
162*eda14cbcSMatt Macy 		}
163*eda14cbcSMatt Macy 	}
164*eda14cbcSMatt Macy 
165*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
166*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(crq, pd)) {
167*eda14cbcSMatt Macy 		crypto_mechanism_t lmech;
168*eda14cbcSMatt Macy 
169*eda14cbcSMatt Macy 		lmech = *mech;
170*eda14cbcSMatt Macy 		KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech);
171*eda14cbcSMatt Macy 
172*eda14cbcSMatt Macy 		error = KCF_PROV_MAC_ATOMIC(pd, pd->pd_sid, &lmech, key, data,
173*eda14cbcSMatt Macy 		    mac, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq));
174*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, error);
175*eda14cbcSMatt Macy 	} else {
176*eda14cbcSMatt Macy 		if (pd->pd_prov_type == CRYPTO_HW_PROVIDER &&
177*eda14cbcSMatt Macy 		    (pd->pd_flags & CRYPTO_HASH_NO_UPDATE) &&
178*eda14cbcSMatt Macy 		    (data->cd_length > pd->pd_hash_limit)) {
179*eda14cbcSMatt Macy 			/*
180*eda14cbcSMatt Macy 			 * XXX - We need a check to see if this is indeed
181*eda14cbcSMatt Macy 			 * a HMAC. So far, all kernel clients use
182*eda14cbcSMatt Macy 			 * this interface only for HMAC. So, this is fine
183*eda14cbcSMatt Macy 			 * for now.
184*eda14cbcSMatt Macy 			 */
185*eda14cbcSMatt Macy 			error = CRYPTO_BUFFER_TOO_BIG;
186*eda14cbcSMatt Macy 		} else {
187*eda14cbcSMatt Macy 			KCF_WRAP_MAC_OPS_PARAMS(&params, KCF_OP_ATOMIC,
188*eda14cbcSMatt Macy 			    pd->pd_sid, mech, key, data, mac, spi_ctx_tmpl);
189*eda14cbcSMatt Macy 
190*eda14cbcSMatt Macy 			error = kcf_submit_request(pd, NULL, crq, &params,
191*eda14cbcSMatt Macy 			    KCF_ISDUALREQ(crq));
192*eda14cbcSMatt Macy 		}
193*eda14cbcSMatt Macy 	}
194*eda14cbcSMatt Macy 
195*eda14cbcSMatt Macy 	if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
196*eda14cbcSMatt Macy 	    IS_RECOVERABLE(error)) {
197*eda14cbcSMatt Macy 		/* Add pd to the linked list of providers tried. */
198*eda14cbcSMatt Macy 		if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
199*eda14cbcSMatt Macy 			goto retry;
200*eda14cbcSMatt Macy 	}
201*eda14cbcSMatt Macy 
202*eda14cbcSMatt Macy 	if (list != NULL)
203*eda14cbcSMatt Macy 		kcf_free_triedlist(list);
204*eda14cbcSMatt Macy 
205*eda14cbcSMatt Macy 	KCF_PROV_REFRELE(pd);
206*eda14cbcSMatt Macy 	return (error);
207*eda14cbcSMatt Macy }
208*eda14cbcSMatt Macy 
209*eda14cbcSMatt Macy /*
210*eda14cbcSMatt Macy  * Single part operation to compute the MAC corresponding to the specified
211*eda14cbcSMatt Macy  * 'data' and to verify that it matches the MAC specified by 'mac'.
212*eda14cbcSMatt Macy  * The other arguments are the same as the function crypto_mac_prov().
213*eda14cbcSMatt Macy  */
214*eda14cbcSMatt Macy int
215*eda14cbcSMatt Macy crypto_mac_verify_prov(crypto_provider_t provider, crypto_session_id_t sid,
216*eda14cbcSMatt Macy     crypto_mechanism_t *mech, crypto_data_t *data, crypto_key_t *key,
217*eda14cbcSMatt Macy     crypto_ctx_template_t tmpl, crypto_data_t *mac, crypto_call_req_t *crq)
218*eda14cbcSMatt Macy {
219*eda14cbcSMatt Macy 	kcf_req_params_t params;
220*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd = provider;
221*eda14cbcSMatt Macy 	kcf_provider_desc_t *real_provider = pd;
222*eda14cbcSMatt Macy 	int rv;
223*eda14cbcSMatt Macy 
224*eda14cbcSMatt Macy 	ASSERT(KCF_PROV_REFHELD(pd));
225*eda14cbcSMatt Macy 
226*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
227*eda14cbcSMatt Macy 		rv = kcf_get_hardware_provider(mech->cm_type,
228*eda14cbcSMatt Macy 		    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
229*eda14cbcSMatt Macy 		    &real_provider, CRYPTO_FG_MAC_ATOMIC);
230*eda14cbcSMatt Macy 
231*eda14cbcSMatt Macy 		if (rv != CRYPTO_SUCCESS)
232*eda14cbcSMatt Macy 			return (rv);
233*eda14cbcSMatt Macy 	}
234*eda14cbcSMatt Macy 
235*eda14cbcSMatt Macy 	KCF_WRAP_MAC_OPS_PARAMS(&params, KCF_OP_MAC_VERIFY_ATOMIC, sid, mech,
236*eda14cbcSMatt Macy 	    key, data, mac, tmpl);
237*eda14cbcSMatt Macy 	rv = kcf_submit_request(real_provider, NULL, crq, &params, B_FALSE);
238*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
239*eda14cbcSMatt Macy 		KCF_PROV_REFRELE(real_provider);
240*eda14cbcSMatt Macy 
241*eda14cbcSMatt Macy 	return (rv);
242*eda14cbcSMatt Macy }
243*eda14cbcSMatt Macy 
244*eda14cbcSMatt Macy /*
245*eda14cbcSMatt Macy  * Same as crypto_mac_verify_prov(), but relies on the KCF scheduler to choose
246*eda14cbcSMatt Macy  * a provider. See crypto_mac_verify_prov() comments for more information.
247*eda14cbcSMatt Macy  */
248*eda14cbcSMatt Macy int
249*eda14cbcSMatt Macy crypto_mac_verify(crypto_mechanism_t *mech, crypto_data_t *data,
250*eda14cbcSMatt Macy     crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *mac,
251*eda14cbcSMatt Macy     crypto_call_req_t *crq)
252*eda14cbcSMatt Macy {
253*eda14cbcSMatt Macy 	int error;
254*eda14cbcSMatt Macy 	kcf_mech_entry_t *me;
255*eda14cbcSMatt Macy 	kcf_req_params_t params;
256*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
257*eda14cbcSMatt Macy 	kcf_ctx_template_t *ctx_tmpl;
258*eda14cbcSMatt Macy 	crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
259*eda14cbcSMatt Macy 	kcf_prov_tried_t *list = NULL;
260*eda14cbcSMatt Macy 
261*eda14cbcSMatt Macy retry:
262*eda14cbcSMatt Macy 	/* The pd is returned held */
263*eda14cbcSMatt Macy 	if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
264*eda14cbcSMatt Macy 	    list, CRYPTO_FG_MAC_ATOMIC, CHECK_RESTRICT(crq),
265*eda14cbcSMatt Macy 	    data->cd_length)) == NULL) {
266*eda14cbcSMatt Macy 		if (list != NULL)
267*eda14cbcSMatt Macy 			kcf_free_triedlist(list);
268*eda14cbcSMatt Macy 		return (error);
269*eda14cbcSMatt Macy 	}
270*eda14cbcSMatt Macy 
271*eda14cbcSMatt Macy 	/*
272*eda14cbcSMatt Macy 	 * For SW providers, check the validity of the context template
273*eda14cbcSMatt Macy 	 * It is very rare that the generation number mis-matches, so
274*eda14cbcSMatt Macy 	 * is acceptable to fail here, and let the consumer recover by
275*eda14cbcSMatt Macy 	 * freeing this tmpl and create a new one for the key and new SW
276*eda14cbcSMatt Macy 	 * provider
277*eda14cbcSMatt Macy 	 */
278*eda14cbcSMatt Macy 	if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
279*eda14cbcSMatt Macy 	    ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
280*eda14cbcSMatt Macy 		if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
281*eda14cbcSMatt Macy 			if (list != NULL)
282*eda14cbcSMatt Macy 				kcf_free_triedlist(list);
283*eda14cbcSMatt Macy 			KCF_PROV_REFRELE(pd);
284*eda14cbcSMatt Macy 			return (CRYPTO_OLD_CTX_TEMPLATE);
285*eda14cbcSMatt Macy 		} else {
286*eda14cbcSMatt Macy 			spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
287*eda14cbcSMatt Macy 		}
288*eda14cbcSMatt Macy 	}
289*eda14cbcSMatt Macy 
290*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
291*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(crq, pd)) {
292*eda14cbcSMatt Macy 		crypto_mechanism_t lmech;
293*eda14cbcSMatt Macy 
294*eda14cbcSMatt Macy 		lmech = *mech;
295*eda14cbcSMatt Macy 		KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech);
296*eda14cbcSMatt Macy 
297*eda14cbcSMatt Macy 		error = KCF_PROV_MAC_VERIFY_ATOMIC(pd, pd->pd_sid, &lmech, key,
298*eda14cbcSMatt Macy 		    data, mac, spi_ctx_tmpl, KCF_SWFP_RHNDL(crq));
299*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, error);
300*eda14cbcSMatt Macy 	} else {
301*eda14cbcSMatt Macy 		if (pd->pd_prov_type == CRYPTO_HW_PROVIDER &&
302*eda14cbcSMatt Macy 		    (pd->pd_flags & CRYPTO_HASH_NO_UPDATE) &&
303*eda14cbcSMatt Macy 		    (data->cd_length > pd->pd_hash_limit)) {
304*eda14cbcSMatt Macy 			/* see comments in crypto_mac() */
305*eda14cbcSMatt Macy 			error = CRYPTO_BUFFER_TOO_BIG;
306*eda14cbcSMatt Macy 		} else {
307*eda14cbcSMatt Macy 			KCF_WRAP_MAC_OPS_PARAMS(&params,
308*eda14cbcSMatt Macy 			    KCF_OP_MAC_VERIFY_ATOMIC, pd->pd_sid, mech,
309*eda14cbcSMatt Macy 			    key, data, mac, spi_ctx_tmpl);
310*eda14cbcSMatt Macy 
311*eda14cbcSMatt Macy 			error = kcf_submit_request(pd, NULL, crq, &params,
312*eda14cbcSMatt Macy 			    KCF_ISDUALREQ(crq));
313*eda14cbcSMatt Macy 		}
314*eda14cbcSMatt Macy 	}
315*eda14cbcSMatt Macy 
316*eda14cbcSMatt Macy 	if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
317*eda14cbcSMatt Macy 	    IS_RECOVERABLE(error)) {
318*eda14cbcSMatt Macy 		/* Add pd to the linked list of providers tried. */
319*eda14cbcSMatt Macy 		if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
320*eda14cbcSMatt Macy 			goto retry;
321*eda14cbcSMatt Macy 	}
322*eda14cbcSMatt Macy 
323*eda14cbcSMatt Macy 	if (list != NULL)
324*eda14cbcSMatt Macy 		kcf_free_triedlist(list);
325*eda14cbcSMatt Macy 
326*eda14cbcSMatt Macy 	KCF_PROV_REFRELE(pd);
327*eda14cbcSMatt Macy 	return (error);
328*eda14cbcSMatt Macy }
329*eda14cbcSMatt Macy 
330*eda14cbcSMatt Macy /*
331*eda14cbcSMatt Macy  * crypto_mac_init_prov()
332*eda14cbcSMatt Macy  *
333*eda14cbcSMatt Macy  * Arguments:
334*eda14cbcSMatt Macy  *	pd:	pointer to the descriptor of the provider to use for this
335*eda14cbcSMatt Macy  *		operation.
336*eda14cbcSMatt Macy  *	sid:	provider session id.
337*eda14cbcSMatt Macy  *	mech:	crypto_mechanism_t pointer.
338*eda14cbcSMatt Macy  *		mech_type is a valid value previously returned by
339*eda14cbcSMatt Macy  *		crypto_mech2id();
340*eda14cbcSMatt Macy  *		When the mech's parameter is not NULL, its definition depends
341*eda14cbcSMatt Macy  *		on the standard definition of the mechanism.
342*eda14cbcSMatt Macy  *	key:	pointer to a crypto_key_t structure.
343*eda14cbcSMatt Macy  *	tmpl:	a crypto_ctx_template_t, opaque template of a context of a
344*eda14cbcSMatt Macy  *		MAC with the 'mech' using 'key'. 'tmpl' is created by
345*eda14cbcSMatt Macy  *		a previous call to crypto_create_ctx_template().
346*eda14cbcSMatt Macy  *	ctxp:	Pointer to a crypto_context_t.
347*eda14cbcSMatt Macy  *	cr:	crypto_call_req_t calling conditions and call back info.
348*eda14cbcSMatt Macy  *
349*eda14cbcSMatt Macy  * Description:
350*eda14cbcSMatt Macy  *	Asynchronously submits a request for, or synchronously performs the
351*eda14cbcSMatt Macy  *	initialization of a MAC operation on the specified provider with
352*eda14cbcSMatt Macy  *	the specified session.
353*eda14cbcSMatt Macy  *	When possible and applicable, will internally use the pre-computed MAC
354*eda14cbcSMatt Macy  *	context from the context template, tmpl.
355*eda14cbcSMatt Macy  *	When complete and successful, 'ctxp' will contain a crypto_context_t
356*eda14cbcSMatt Macy  *	valid for later calls to mac_update() and mac_final().
357*eda14cbcSMatt Macy  *	The caller should hold a reference on the specified provider
358*eda14cbcSMatt Macy  *	descriptor before calling this function.
359*eda14cbcSMatt Macy  *
360*eda14cbcSMatt Macy  * Context:
361*eda14cbcSMatt Macy  *	Process or interrupt, according to the semantics dictated by the 'cr'.
362*eda14cbcSMatt Macy  *
363*eda14cbcSMatt Macy  * Returns:
364*eda14cbcSMatt Macy  *	See comment in the beginning of the file.
365*eda14cbcSMatt Macy  */
366*eda14cbcSMatt Macy int
367*eda14cbcSMatt Macy crypto_mac_init_prov(crypto_provider_t provider, crypto_session_id_t sid,
368*eda14cbcSMatt Macy     crypto_mechanism_t *mech, crypto_key_t *key, crypto_spi_ctx_template_t tmpl,
369*eda14cbcSMatt Macy     crypto_context_t *ctxp, crypto_call_req_t *crq)
370*eda14cbcSMatt Macy {
371*eda14cbcSMatt Macy 	int rv;
372*eda14cbcSMatt Macy 	crypto_ctx_t *ctx;
373*eda14cbcSMatt Macy 	kcf_req_params_t params;
374*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd = provider;
375*eda14cbcSMatt Macy 	kcf_provider_desc_t *real_provider = pd;
376*eda14cbcSMatt Macy 
377*eda14cbcSMatt Macy 	ASSERT(KCF_PROV_REFHELD(pd));
378*eda14cbcSMatt Macy 
379*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
380*eda14cbcSMatt Macy 		rv = kcf_get_hardware_provider(mech->cm_type,
381*eda14cbcSMatt Macy 		    CRYPTO_MECH_INVALID, CHECK_RESTRICT(crq), pd,
382*eda14cbcSMatt Macy 		    &real_provider, CRYPTO_FG_MAC);
383*eda14cbcSMatt Macy 
384*eda14cbcSMatt Macy 		if (rv != CRYPTO_SUCCESS)
385*eda14cbcSMatt Macy 			return (rv);
386*eda14cbcSMatt Macy 	}
387*eda14cbcSMatt Macy 
388*eda14cbcSMatt Macy 	/* Allocate and initialize the canonical context */
389*eda14cbcSMatt Macy 	if ((ctx = kcf_new_ctx(crq, real_provider, sid)) == NULL) {
390*eda14cbcSMatt Macy 		if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
391*eda14cbcSMatt Macy 			KCF_PROV_REFRELE(real_provider);
392*eda14cbcSMatt Macy 		return (CRYPTO_HOST_MEMORY);
393*eda14cbcSMatt Macy 	}
394*eda14cbcSMatt Macy 
395*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
396*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(crq, pd)) {
397*eda14cbcSMatt Macy 		crypto_mechanism_t lmech;
398*eda14cbcSMatt Macy 
399*eda14cbcSMatt Macy 		lmech = *mech;
400*eda14cbcSMatt Macy 		KCF_SET_PROVIDER_MECHNUM(mech->cm_type, real_provider, &lmech);
401*eda14cbcSMatt Macy 		rv = KCF_PROV_MAC_INIT(real_provider, ctx, &lmech, key, tmpl,
402*eda14cbcSMatt Macy 		    KCF_SWFP_RHNDL(crq));
403*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, rv);
404*eda14cbcSMatt Macy 	} else {
405*eda14cbcSMatt Macy 		KCF_WRAP_MAC_OPS_PARAMS(&params, KCF_OP_INIT, sid, mech, key,
406*eda14cbcSMatt Macy 		    NULL, NULL, tmpl);
407*eda14cbcSMatt Macy 		rv = kcf_submit_request(real_provider, ctx, crq, &params,
408*eda14cbcSMatt Macy 		    B_FALSE);
409*eda14cbcSMatt Macy 	}
410*eda14cbcSMatt Macy 
411*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER)
412*eda14cbcSMatt Macy 		KCF_PROV_REFRELE(real_provider);
413*eda14cbcSMatt Macy 
414*eda14cbcSMatt Macy 	if ((rv == CRYPTO_SUCCESS) || (rv == CRYPTO_QUEUED))
415*eda14cbcSMatt Macy 		*ctxp = (crypto_context_t)ctx;
416*eda14cbcSMatt Macy 	else {
417*eda14cbcSMatt Macy 		/* Release the hold done in kcf_new_ctx(). */
418*eda14cbcSMatt Macy 		KCF_CONTEXT_REFRELE((kcf_context_t *)ctx->cc_framework_private);
419*eda14cbcSMatt Macy 	}
420*eda14cbcSMatt Macy 
421*eda14cbcSMatt Macy 	return (rv);
422*eda14cbcSMatt Macy }
423*eda14cbcSMatt Macy 
424*eda14cbcSMatt Macy /*
425*eda14cbcSMatt Macy  * Same as crypto_mac_init_prov(), but relies on the KCF scheduler to
426*eda14cbcSMatt Macy  * choose a provider. See crypto_mac_init_prov() comments for more
427*eda14cbcSMatt Macy  * information.
428*eda14cbcSMatt Macy  */
429*eda14cbcSMatt Macy int
430*eda14cbcSMatt Macy crypto_mac_init(crypto_mechanism_t *mech, crypto_key_t *key,
431*eda14cbcSMatt Macy     crypto_ctx_template_t tmpl, crypto_context_t *ctxp,
432*eda14cbcSMatt Macy     crypto_call_req_t  *crq)
433*eda14cbcSMatt Macy {
434*eda14cbcSMatt Macy 	int error;
435*eda14cbcSMatt Macy 	kcf_mech_entry_t *me;
436*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
437*eda14cbcSMatt Macy 	kcf_ctx_template_t *ctx_tmpl;
438*eda14cbcSMatt Macy 	crypto_spi_ctx_template_t spi_ctx_tmpl = NULL;
439*eda14cbcSMatt Macy 	kcf_prov_tried_t *list = NULL;
440*eda14cbcSMatt Macy 
441*eda14cbcSMatt Macy retry:
442*eda14cbcSMatt Macy 	/* The pd is returned held */
443*eda14cbcSMatt Macy 	if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error,
444*eda14cbcSMatt Macy 	    list, CRYPTO_FG_MAC, CHECK_RESTRICT(crq), 0)) == NULL) {
445*eda14cbcSMatt Macy 		if (list != NULL)
446*eda14cbcSMatt Macy 			kcf_free_triedlist(list);
447*eda14cbcSMatt Macy 		return (error);
448*eda14cbcSMatt Macy 	}
449*eda14cbcSMatt Macy 
450*eda14cbcSMatt Macy 	/*
451*eda14cbcSMatt Macy 	 * For SW providers, check the validity of the context template
452*eda14cbcSMatt Macy 	 * It is very rare that the generation number mis-matches, so
453*eda14cbcSMatt Macy 	 * is acceptable to fail here, and let the consumer recover by
454*eda14cbcSMatt Macy 	 * freeing this tmpl and create a new one for the key and new SW
455*eda14cbcSMatt Macy 	 * provider
456*eda14cbcSMatt Macy 	 */
457*eda14cbcSMatt Macy 
458*eda14cbcSMatt Macy 	if ((pd->pd_prov_type == CRYPTO_SW_PROVIDER) &&
459*eda14cbcSMatt Macy 	    ((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) {
460*eda14cbcSMatt Macy 		if (ctx_tmpl->ct_generation != me->me_gen_swprov) {
461*eda14cbcSMatt Macy 			if (list != NULL)
462*eda14cbcSMatt Macy 				kcf_free_triedlist(list);
463*eda14cbcSMatt Macy 			KCF_PROV_REFRELE(pd);
464*eda14cbcSMatt Macy 			return (CRYPTO_OLD_CTX_TEMPLATE);
465*eda14cbcSMatt Macy 		} else {
466*eda14cbcSMatt Macy 			spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl;
467*eda14cbcSMatt Macy 		}
468*eda14cbcSMatt Macy 	}
469*eda14cbcSMatt Macy 
470*eda14cbcSMatt Macy 	if (pd->pd_prov_type == CRYPTO_HW_PROVIDER &&
471*eda14cbcSMatt Macy 	    (pd->pd_flags & CRYPTO_HASH_NO_UPDATE)) {
472*eda14cbcSMatt Macy 		/*
473*eda14cbcSMatt Macy 		 * The hardware provider has limited HMAC support.
474*eda14cbcSMatt Macy 		 * So, we fallback early here to using a software provider.
475*eda14cbcSMatt Macy 		 *
476*eda14cbcSMatt Macy 		 * XXX - need to enhance to do the fallback later in
477*eda14cbcSMatt Macy 		 * crypto_mac_update() if the size of accumulated input data
478*eda14cbcSMatt Macy 		 * exceeds the maximum size digestable by hardware provider.
479*eda14cbcSMatt Macy 		 */
480*eda14cbcSMatt Macy 		error = CRYPTO_BUFFER_TOO_BIG;
481*eda14cbcSMatt Macy 	} else {
482*eda14cbcSMatt Macy 		error = crypto_mac_init_prov(pd, pd->pd_sid, mech, key,
483*eda14cbcSMatt Macy 		    spi_ctx_tmpl, ctxp, crq);
484*eda14cbcSMatt Macy 	}
485*eda14cbcSMatt Macy 	if (error != CRYPTO_SUCCESS && error != CRYPTO_QUEUED &&
486*eda14cbcSMatt Macy 	    IS_RECOVERABLE(error)) {
487*eda14cbcSMatt Macy 		/* Add pd to the linked list of providers tried. */
488*eda14cbcSMatt Macy 		if (kcf_insert_triedlist(&list, pd, KCF_KMFLAG(crq)) != NULL)
489*eda14cbcSMatt Macy 			goto retry;
490*eda14cbcSMatt Macy 	}
491*eda14cbcSMatt Macy 
492*eda14cbcSMatt Macy 	if (list != NULL)
493*eda14cbcSMatt Macy 		kcf_free_triedlist(list);
494*eda14cbcSMatt Macy 
495*eda14cbcSMatt Macy 	KCF_PROV_REFRELE(pd);
496*eda14cbcSMatt Macy 	return (error);
497*eda14cbcSMatt Macy }
498*eda14cbcSMatt Macy 
499*eda14cbcSMatt Macy /*
500*eda14cbcSMatt Macy  * crypto_mac_update()
501*eda14cbcSMatt Macy  *
502*eda14cbcSMatt Macy  * Arguments:
503*eda14cbcSMatt Macy  *	context: A crypto_context_t initialized by mac_init().
504*eda14cbcSMatt Macy  *	data: The message part to be MAC'ed
505*eda14cbcSMatt Macy  *	cr:	crypto_call_req_t calling conditions and call back info.
506*eda14cbcSMatt Macy  *
507*eda14cbcSMatt Macy  * Description:
508*eda14cbcSMatt Macy  *	Asynchronously submits a request for, or synchronously performs a
509*eda14cbcSMatt Macy  *	part of a MAC operation.
510*eda14cbcSMatt Macy  *
511*eda14cbcSMatt Macy  * Context:
512*eda14cbcSMatt Macy  *	Process or interrupt, according to the semantics dictated by the 'cr'.
513*eda14cbcSMatt Macy  *
514*eda14cbcSMatt Macy  * Returns:
515*eda14cbcSMatt Macy  *	See comment in the beginning of the file.
516*eda14cbcSMatt Macy  */
517*eda14cbcSMatt Macy int
518*eda14cbcSMatt Macy crypto_mac_update(crypto_context_t context, crypto_data_t *data,
519*eda14cbcSMatt Macy     crypto_call_req_t *cr)
520*eda14cbcSMatt Macy {
521*eda14cbcSMatt Macy 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
522*eda14cbcSMatt Macy 	kcf_context_t *kcf_ctx;
523*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
524*eda14cbcSMatt Macy 	kcf_req_params_t params;
525*eda14cbcSMatt Macy 	int rv;
526*eda14cbcSMatt Macy 
527*eda14cbcSMatt Macy 	if ((ctx == NULL) ||
528*eda14cbcSMatt Macy 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
529*eda14cbcSMatt Macy 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
530*eda14cbcSMatt Macy 		return (CRYPTO_INVALID_CONTEXT);
531*eda14cbcSMatt Macy 	}
532*eda14cbcSMatt Macy 
533*eda14cbcSMatt Macy 	ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
534*eda14cbcSMatt Macy 
535*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
536*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(cr, pd)) {
537*eda14cbcSMatt Macy 		rv = KCF_PROV_MAC_UPDATE(pd, ctx, data, NULL);
538*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, rv);
539*eda14cbcSMatt Macy 	} else {
540*eda14cbcSMatt Macy 		KCF_WRAP_MAC_OPS_PARAMS(&params, KCF_OP_UPDATE,
541*eda14cbcSMatt Macy 		    ctx->cc_session, NULL, NULL, data, NULL, NULL);
542*eda14cbcSMatt Macy 		rv = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
543*eda14cbcSMatt Macy 	}
544*eda14cbcSMatt Macy 
545*eda14cbcSMatt Macy 	return (rv);
546*eda14cbcSMatt Macy }
547*eda14cbcSMatt Macy 
548*eda14cbcSMatt Macy /*
549*eda14cbcSMatt Macy  * crypto_mac_final()
550*eda14cbcSMatt Macy  *
551*eda14cbcSMatt Macy  * Arguments:
552*eda14cbcSMatt Macy  *	context: A crypto_context_t initialized by mac_init().
553*eda14cbcSMatt Macy  *	mac: Storage for the message authentication code.
554*eda14cbcSMatt Macy  *	cr:	crypto_call_req_t calling conditions and call back info.
555*eda14cbcSMatt Macy  *
556*eda14cbcSMatt Macy  * Description:
557*eda14cbcSMatt Macy  *	Asynchronously submits a request for, or synchronously performs a
558*eda14cbcSMatt Macy  *	part of a message authentication operation.
559*eda14cbcSMatt Macy  *
560*eda14cbcSMatt Macy  * Context:
561*eda14cbcSMatt Macy  *	Process or interrupt, according to the semantics dictated by the 'cr'.
562*eda14cbcSMatt Macy  *
563*eda14cbcSMatt Macy  * Returns:
564*eda14cbcSMatt Macy  *	See comment in the beginning of the file.
565*eda14cbcSMatt Macy  */
566*eda14cbcSMatt Macy int
567*eda14cbcSMatt Macy crypto_mac_final(crypto_context_t context, crypto_data_t *mac,
568*eda14cbcSMatt Macy     crypto_call_req_t *cr)
569*eda14cbcSMatt Macy {
570*eda14cbcSMatt Macy 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
571*eda14cbcSMatt Macy 	kcf_context_t *kcf_ctx;
572*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
573*eda14cbcSMatt Macy 	kcf_req_params_t params;
574*eda14cbcSMatt Macy 	int rv;
575*eda14cbcSMatt Macy 
576*eda14cbcSMatt Macy 	if ((ctx == NULL) ||
577*eda14cbcSMatt Macy 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
578*eda14cbcSMatt Macy 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
579*eda14cbcSMatt Macy 		return (CRYPTO_INVALID_CONTEXT);
580*eda14cbcSMatt Macy 	}
581*eda14cbcSMatt Macy 
582*eda14cbcSMatt Macy 	ASSERT(pd->pd_prov_type != CRYPTO_LOGICAL_PROVIDER);
583*eda14cbcSMatt Macy 
584*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
585*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(cr, pd)) {
586*eda14cbcSMatt Macy 		rv = KCF_PROV_MAC_FINAL(pd, ctx, mac, NULL);
587*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, rv);
588*eda14cbcSMatt Macy 	} else {
589*eda14cbcSMatt Macy 		KCF_WRAP_MAC_OPS_PARAMS(&params, KCF_OP_FINAL,
590*eda14cbcSMatt Macy 		    ctx->cc_session, NULL, NULL, NULL, mac, NULL);
591*eda14cbcSMatt Macy 		rv = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
592*eda14cbcSMatt Macy 	}
593*eda14cbcSMatt Macy 
594*eda14cbcSMatt Macy 	/* Release the hold done in kcf_new_ctx() during init step. */
595*eda14cbcSMatt Macy 	KCF_CONTEXT_COND_RELEASE(rv, kcf_ctx);
596*eda14cbcSMatt Macy 	return (rv);
597*eda14cbcSMatt Macy }
598*eda14cbcSMatt Macy 
599*eda14cbcSMatt Macy /*
600*eda14cbcSMatt Macy  * See comments for crypto_mac_update() and crypto_mac_final().
601*eda14cbcSMatt Macy  */
602*eda14cbcSMatt Macy int
603*eda14cbcSMatt Macy crypto_mac_single(crypto_context_t context, crypto_data_t *data,
604*eda14cbcSMatt Macy     crypto_data_t *mac, crypto_call_req_t *cr)
605*eda14cbcSMatt Macy {
606*eda14cbcSMatt Macy 	crypto_ctx_t *ctx = (crypto_ctx_t *)context;
607*eda14cbcSMatt Macy 	kcf_context_t *kcf_ctx;
608*eda14cbcSMatt Macy 	kcf_provider_desc_t *pd;
609*eda14cbcSMatt Macy 	int error;
610*eda14cbcSMatt Macy 	kcf_req_params_t params;
611*eda14cbcSMatt Macy 
612*eda14cbcSMatt Macy 
613*eda14cbcSMatt Macy 	if ((ctx == NULL) ||
614*eda14cbcSMatt Macy 	    ((kcf_ctx = (kcf_context_t *)ctx->cc_framework_private) == NULL) ||
615*eda14cbcSMatt Macy 	    ((pd = kcf_ctx->kc_prov_desc) == NULL)) {
616*eda14cbcSMatt Macy 		return (CRYPTO_INVALID_CONTEXT);
617*eda14cbcSMatt Macy 	}
618*eda14cbcSMatt Macy 
619*eda14cbcSMatt Macy 
620*eda14cbcSMatt Macy 	/* The fast path for SW providers. */
621*eda14cbcSMatt Macy 	if (CHECK_FASTPATH(cr, pd)) {
622*eda14cbcSMatt Macy 		error = KCF_PROV_MAC(pd, ctx, data, mac, NULL);
623*eda14cbcSMatt Macy 		KCF_PROV_INCRSTATS(pd, error);
624*eda14cbcSMatt Macy 	} else {
625*eda14cbcSMatt Macy 		KCF_WRAP_MAC_OPS_PARAMS(&params, KCF_OP_SINGLE, pd->pd_sid,
626*eda14cbcSMatt Macy 		    NULL, NULL, data, mac, NULL);
627*eda14cbcSMatt Macy 		error = kcf_submit_request(pd, ctx, cr, &params, B_FALSE);
628*eda14cbcSMatt Macy 	}
629*eda14cbcSMatt Macy 
630*eda14cbcSMatt Macy 	/* Release the hold done in kcf_new_ctx() during init step. */
631*eda14cbcSMatt Macy 	KCF_CONTEXT_COND_RELEASE(error, kcf_ctx);
632*eda14cbcSMatt Macy 	return (error);
633*eda14cbcSMatt Macy }
634*eda14cbcSMatt Macy 
635*eda14cbcSMatt Macy #if defined(_KERNEL)
636*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_prov);
637*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac);
638*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_verify_prov);
639*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_verify);
640*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_init_prov);
641*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_init);
642*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_update);
643*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_final);
644*eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_mac_single);
645*eda14cbcSMatt Macy #endif
646