1*a1157835SDaniel Fojt /*
2*a1157835SDaniel Fojt  * Crypto wrapper for Linux kernel AF_ALG
3*a1157835SDaniel Fojt  * Copyright (c) 2017, Jouni Malinen <j@w1.fi>
4*a1157835SDaniel Fojt  *
5*a1157835SDaniel Fojt  * This software may be distributed under the terms of the BSD license.
6*a1157835SDaniel Fojt  * See README for more details.
7*a1157835SDaniel Fojt  */
8*a1157835SDaniel Fojt 
9*a1157835SDaniel Fojt #include "includes.h"
10*a1157835SDaniel Fojt #include <linux/if_alg.h>
11*a1157835SDaniel Fojt 
12*a1157835SDaniel Fojt #include "common.h"
13*a1157835SDaniel Fojt #include "crypto.h"
14*a1157835SDaniel Fojt #include "md5.h"
15*a1157835SDaniel Fojt #include "sha1.h"
16*a1157835SDaniel Fojt #include "sha256.h"
17*a1157835SDaniel Fojt #include "sha384.h"
18*a1157835SDaniel Fojt #include "aes.h"
19*a1157835SDaniel Fojt 
20*a1157835SDaniel Fojt 
21*a1157835SDaniel Fojt #ifndef SOL_ALG
22*a1157835SDaniel Fojt #define SOL_ALG 279
23*a1157835SDaniel Fojt #endif /* SOL_ALG */
24*a1157835SDaniel Fojt 
25*a1157835SDaniel Fojt 
linux_af_alg_socket(const char * type,const char * name)26*a1157835SDaniel Fojt static int linux_af_alg_socket(const char *type, const char *name)
27*a1157835SDaniel Fojt {
28*a1157835SDaniel Fojt 	struct sockaddr_alg sa;
29*a1157835SDaniel Fojt 	int s;
30*a1157835SDaniel Fojt 
31*a1157835SDaniel Fojt 	if (TEST_FAIL())
32*a1157835SDaniel Fojt 		return -1;
33*a1157835SDaniel Fojt 
34*a1157835SDaniel Fojt 	s = socket(AF_ALG, SOCK_SEQPACKET, 0);
35*a1157835SDaniel Fojt 	if (s < 0) {
36*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: Failed to open AF_ALG socket: %s",
37*a1157835SDaniel Fojt 			   __func__, strerror(errno));
38*a1157835SDaniel Fojt 		return -1;
39*a1157835SDaniel Fojt 	}
40*a1157835SDaniel Fojt 
41*a1157835SDaniel Fojt 	os_memset(&sa, 0, sizeof(sa));
42*a1157835SDaniel Fojt 	sa.salg_family = AF_ALG;
43*a1157835SDaniel Fojt 	os_strlcpy((char *) sa.salg_type, type, sizeof(sa.salg_type));
44*a1157835SDaniel Fojt 	os_strlcpy((char *) sa.salg_name, name, sizeof(sa.salg_type));
45*a1157835SDaniel Fojt 	if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
46*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
47*a1157835SDaniel Fojt 			   "%s: Failed to bind AF_ALG socket(%s,%s): %s",
48*a1157835SDaniel Fojt 			   __func__, type, name, strerror(errno));
49*a1157835SDaniel Fojt 		close(s);
50*a1157835SDaniel Fojt 		return -1;
51*a1157835SDaniel Fojt 	}
52*a1157835SDaniel Fojt 
53*a1157835SDaniel Fojt 	return s;
54*a1157835SDaniel Fojt }
55*a1157835SDaniel Fojt 
56*a1157835SDaniel Fojt 
linux_af_alg_hash_vector(const char * alg,const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac,size_t mac_len)57*a1157835SDaniel Fojt static int linux_af_alg_hash_vector(const char *alg, const u8 *key,
58*a1157835SDaniel Fojt 				    size_t key_len, size_t num_elem,
59*a1157835SDaniel Fojt 				    const u8 *addr[], const size_t *len,
60*a1157835SDaniel Fojt 				    u8 *mac, size_t mac_len)
61*a1157835SDaniel Fojt {
62*a1157835SDaniel Fojt 	int s, t;
63*a1157835SDaniel Fojt 	size_t i;
64*a1157835SDaniel Fojt 	ssize_t res;
65*a1157835SDaniel Fojt 	int ret = -1;
66*a1157835SDaniel Fojt 
67*a1157835SDaniel Fojt 	s = linux_af_alg_socket("hash", alg);
68*a1157835SDaniel Fojt 	if (s < 0)
69*a1157835SDaniel Fojt 		return -1;
70*a1157835SDaniel Fojt 
71*a1157835SDaniel Fojt 	if (key && setsockopt(s, SOL_ALG, ALG_SET_KEY, key, key_len) < 0) {
72*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: setsockopt(ALG_SET_KEY) failed: %s",
73*a1157835SDaniel Fojt 			   __func__, strerror(errno));
74*a1157835SDaniel Fojt 		close(s);
75*a1157835SDaniel Fojt 		return -1;
76*a1157835SDaniel Fojt 	}
77*a1157835SDaniel Fojt 
78*a1157835SDaniel Fojt 	t = accept(s, NULL, NULL);
79*a1157835SDaniel Fojt 	if (t < 0) {
80*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: accept on AF_ALG socket failed: %s",
81*a1157835SDaniel Fojt 			   __func__, strerror(errno));
82*a1157835SDaniel Fojt 		close(s);
83*a1157835SDaniel Fojt 		return -1;
84*a1157835SDaniel Fojt 	}
85*a1157835SDaniel Fojt 
86*a1157835SDaniel Fojt 	for (i = 0; i < num_elem; i++) {
87*a1157835SDaniel Fojt 		res = send(t, addr[i], len[i], i + 1 < num_elem ? MSG_MORE : 0);
88*a1157835SDaniel Fojt 		if (res < 0) {
89*a1157835SDaniel Fojt 			wpa_printf(MSG_ERROR,
90*a1157835SDaniel Fojt 				   "%s: send on AF_ALG socket failed: %s",
91*a1157835SDaniel Fojt 				   __func__, strerror(errno));
92*a1157835SDaniel Fojt 			goto fail;
93*a1157835SDaniel Fojt 		}
94*a1157835SDaniel Fojt 		if ((size_t) res < len[i]) {
95*a1157835SDaniel Fojt 			wpa_printf(MSG_ERROR,
96*a1157835SDaniel Fojt 				   "%s: send on AF_ALG socket did not accept full buffer (%d/%d)",
97*a1157835SDaniel Fojt 				   __func__, (int) res, (int) len[i]);
98*a1157835SDaniel Fojt 			goto fail;
99*a1157835SDaniel Fojt 		}
100*a1157835SDaniel Fojt 	}
101*a1157835SDaniel Fojt 
102*a1157835SDaniel Fojt 	res = recv(t, mac, mac_len, 0);
103*a1157835SDaniel Fojt 	if (res < 0) {
104*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
105*a1157835SDaniel Fojt 			   "%s: recv on AF_ALG socket failed: %s",
106*a1157835SDaniel Fojt 			   __func__, strerror(errno));
107*a1157835SDaniel Fojt 		goto fail;
108*a1157835SDaniel Fojt 	}
109*a1157835SDaniel Fojt 	if ((size_t) res < mac_len) {
110*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
111*a1157835SDaniel Fojt 			   "%s: recv on AF_ALG socket did not return full buffer (%d/%d)",
112*a1157835SDaniel Fojt 			   __func__, (int) res, (int) mac_len);
113*a1157835SDaniel Fojt 		goto fail;
114*a1157835SDaniel Fojt 	}
115*a1157835SDaniel Fojt 
116*a1157835SDaniel Fojt 	ret = 0;
117*a1157835SDaniel Fojt fail:
118*a1157835SDaniel Fojt 	close(t);
119*a1157835SDaniel Fojt 	close(s);
120*a1157835SDaniel Fojt 
121*a1157835SDaniel Fojt 	return ret;
122*a1157835SDaniel Fojt }
123*a1157835SDaniel Fojt 
124*a1157835SDaniel Fojt 
md4_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)125*a1157835SDaniel Fojt int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
126*a1157835SDaniel Fojt {
127*a1157835SDaniel Fojt 	return linux_af_alg_hash_vector("md4", NULL, 0, num_elem, addr, len,
128*a1157835SDaniel Fojt 					mac, 16);
129*a1157835SDaniel Fojt }
130*a1157835SDaniel Fojt 
131*a1157835SDaniel Fojt 
md5_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)132*a1157835SDaniel Fojt int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
133*a1157835SDaniel Fojt {
134*a1157835SDaniel Fojt 	return linux_af_alg_hash_vector("md5", NULL, 0, num_elem, addr, len,
135*a1157835SDaniel Fojt 					mac, MD5_MAC_LEN);
136*a1157835SDaniel Fojt }
137*a1157835SDaniel Fojt 
138*a1157835SDaniel Fojt 
sha1_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)139*a1157835SDaniel Fojt int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
140*a1157835SDaniel Fojt 		u8 *mac)
141*a1157835SDaniel Fojt {
142*a1157835SDaniel Fojt 	return linux_af_alg_hash_vector("sha1", NULL, 0, num_elem, addr, len,
143*a1157835SDaniel Fojt 					mac, SHA1_MAC_LEN);
144*a1157835SDaniel Fojt }
145*a1157835SDaniel Fojt 
146*a1157835SDaniel Fojt 
sha256_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)147*a1157835SDaniel Fojt int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
148*a1157835SDaniel Fojt 		  u8 *mac)
149*a1157835SDaniel Fojt {
150*a1157835SDaniel Fojt 	return linux_af_alg_hash_vector("sha256", NULL, 0, num_elem, addr, len,
151*a1157835SDaniel Fojt 					mac, SHA256_MAC_LEN);
152*a1157835SDaniel Fojt }
153*a1157835SDaniel Fojt 
154*a1157835SDaniel Fojt 
sha384_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)155*a1157835SDaniel Fojt int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
156*a1157835SDaniel Fojt 		  u8 *mac)
157*a1157835SDaniel Fojt {
158*a1157835SDaniel Fojt 	return linux_af_alg_hash_vector("sha384", NULL, 0, num_elem, addr, len,
159*a1157835SDaniel Fojt 					mac, SHA384_MAC_LEN);
160*a1157835SDaniel Fojt }
161*a1157835SDaniel Fojt 
162*a1157835SDaniel Fojt 
sha512_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)163*a1157835SDaniel Fojt int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len,
164*a1157835SDaniel Fojt 		  u8 *mac)
165*a1157835SDaniel Fojt {
166*a1157835SDaniel Fojt 	return linux_af_alg_hash_vector("sha512", NULL, 0, num_elem, addr, len,
167*a1157835SDaniel Fojt 					mac, 64);
168*a1157835SDaniel Fojt }
169*a1157835SDaniel Fojt 
170*a1157835SDaniel Fojt 
hmac_md5_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)171*a1157835SDaniel Fojt int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
172*a1157835SDaniel Fojt 		    const u8 *addr[], const size_t *len, u8 *mac)
173*a1157835SDaniel Fojt {
174*a1157835SDaniel Fojt 	return linux_af_alg_hash_vector("hmac(md5)", key, key_len, num_elem,
175*a1157835SDaniel Fojt 					addr, len, mac, 16);
176*a1157835SDaniel Fojt }
177*a1157835SDaniel Fojt 
178*a1157835SDaniel Fojt 
hmac_md5(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)179*a1157835SDaniel Fojt int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
180*a1157835SDaniel Fojt 	     u8 *mac)
181*a1157835SDaniel Fojt {
182*a1157835SDaniel Fojt 	return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
183*a1157835SDaniel Fojt }
184*a1157835SDaniel Fojt 
185*a1157835SDaniel Fojt 
hmac_sha1_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)186*a1157835SDaniel Fojt int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
187*a1157835SDaniel Fojt 		     const u8 *addr[], const size_t *len, u8 *mac)
188*a1157835SDaniel Fojt {
189*a1157835SDaniel Fojt 	return linux_af_alg_hash_vector("hmac(sha1)", key, key_len, num_elem,
190*a1157835SDaniel Fojt 					addr, len, mac, SHA1_MAC_LEN);
191*a1157835SDaniel Fojt }
192*a1157835SDaniel Fojt 
193*a1157835SDaniel Fojt 
hmac_sha1(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)194*a1157835SDaniel Fojt int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
195*a1157835SDaniel Fojt 	      u8 *mac)
196*a1157835SDaniel Fojt {
197*a1157835SDaniel Fojt 	return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
198*a1157835SDaniel Fojt }
199*a1157835SDaniel Fojt 
200*a1157835SDaniel Fojt 
hmac_sha256_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)201*a1157835SDaniel Fojt int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
202*a1157835SDaniel Fojt 		       const u8 *addr[], const size_t *len, u8 *mac)
203*a1157835SDaniel Fojt {
204*a1157835SDaniel Fojt 	return linux_af_alg_hash_vector("hmac(sha256)", key, key_len, num_elem,
205*a1157835SDaniel Fojt 					addr, len, mac, SHA256_MAC_LEN);
206*a1157835SDaniel Fojt }
207*a1157835SDaniel Fojt 
208*a1157835SDaniel Fojt 
hmac_sha256(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)209*a1157835SDaniel Fojt int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
210*a1157835SDaniel Fojt 		size_t data_len, u8 *mac)
211*a1157835SDaniel Fojt {
212*a1157835SDaniel Fojt 	return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
213*a1157835SDaniel Fojt }
214*a1157835SDaniel Fojt 
215*a1157835SDaniel Fojt 
hmac_sha384_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)216*a1157835SDaniel Fojt int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
217*a1157835SDaniel Fojt 		       const u8 *addr[], const size_t *len, u8 *mac)
218*a1157835SDaniel Fojt {
219*a1157835SDaniel Fojt 	return linux_af_alg_hash_vector("hmac(sha384)", key, key_len, num_elem,
220*a1157835SDaniel Fojt 					addr, len, mac, SHA384_MAC_LEN);
221*a1157835SDaniel Fojt }
222*a1157835SDaniel Fojt 
223*a1157835SDaniel Fojt 
hmac_sha384(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)224*a1157835SDaniel Fojt int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
225*a1157835SDaniel Fojt 		size_t data_len, u8 *mac)
226*a1157835SDaniel Fojt {
227*a1157835SDaniel Fojt 	return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
228*a1157835SDaniel Fojt }
229*a1157835SDaniel Fojt 
230*a1157835SDaniel Fojt 
231*a1157835SDaniel Fojt struct crypto_hash {
232*a1157835SDaniel Fojt 	int s;
233*a1157835SDaniel Fojt 	int t;
234*a1157835SDaniel Fojt 	size_t mac_len;
235*a1157835SDaniel Fojt 	int failed;
236*a1157835SDaniel Fojt };
237*a1157835SDaniel Fojt 
238*a1157835SDaniel Fojt 
crypto_hash_init(enum crypto_hash_alg alg,const u8 * key,size_t key_len)239*a1157835SDaniel Fojt struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
240*a1157835SDaniel Fojt 				      size_t key_len)
241*a1157835SDaniel Fojt {
242*a1157835SDaniel Fojt 	struct crypto_hash *ctx;
243*a1157835SDaniel Fojt 	const char *name;
244*a1157835SDaniel Fojt 
245*a1157835SDaniel Fojt 	ctx = os_zalloc(sizeof(*ctx));
246*a1157835SDaniel Fojt 	if (!ctx)
247*a1157835SDaniel Fojt 		return NULL;
248*a1157835SDaniel Fojt 
249*a1157835SDaniel Fojt 	switch (alg) {
250*a1157835SDaniel Fojt 	case CRYPTO_HASH_ALG_MD5:
251*a1157835SDaniel Fojt 		name = "md5";
252*a1157835SDaniel Fojt 		ctx->mac_len = MD5_MAC_LEN;
253*a1157835SDaniel Fojt 		break;
254*a1157835SDaniel Fojt 	case CRYPTO_HASH_ALG_SHA1:
255*a1157835SDaniel Fojt 		name = "sha1";
256*a1157835SDaniel Fojt 		ctx->mac_len = SHA1_MAC_LEN;
257*a1157835SDaniel Fojt 		break;
258*a1157835SDaniel Fojt 	case CRYPTO_HASH_ALG_HMAC_MD5:
259*a1157835SDaniel Fojt 		name = "hmac(md5)";
260*a1157835SDaniel Fojt 		ctx->mac_len = MD5_MAC_LEN;
261*a1157835SDaniel Fojt 		break;
262*a1157835SDaniel Fojt 	case CRYPTO_HASH_ALG_HMAC_SHA1:
263*a1157835SDaniel Fojt 		name = "hmac(sha1)";
264*a1157835SDaniel Fojt 		ctx->mac_len = SHA1_MAC_LEN;
265*a1157835SDaniel Fojt 		break;
266*a1157835SDaniel Fojt 	case CRYPTO_HASH_ALG_SHA256:
267*a1157835SDaniel Fojt 		name = "sha256";
268*a1157835SDaniel Fojt 		ctx->mac_len = SHA256_MAC_LEN;
269*a1157835SDaniel Fojt 		break;
270*a1157835SDaniel Fojt 	case CRYPTO_HASH_ALG_HMAC_SHA256:
271*a1157835SDaniel Fojt 		name = "hmac(sha256)";
272*a1157835SDaniel Fojt 		ctx->mac_len = SHA256_MAC_LEN;
273*a1157835SDaniel Fojt 		break;
274*a1157835SDaniel Fojt 	case CRYPTO_HASH_ALG_SHA384:
275*a1157835SDaniel Fojt 		name = "sha384";
276*a1157835SDaniel Fojt 		ctx->mac_len = SHA384_MAC_LEN;
277*a1157835SDaniel Fojt 		break;
278*a1157835SDaniel Fojt 	case CRYPTO_HASH_ALG_SHA512:
279*a1157835SDaniel Fojt 		name = "sha512";
280*a1157835SDaniel Fojt 		ctx->mac_len = 64;
281*a1157835SDaniel Fojt 		break;
282*a1157835SDaniel Fojt 	default:
283*a1157835SDaniel Fojt 		os_free(ctx);
284*a1157835SDaniel Fojt 		return NULL;
285*a1157835SDaniel Fojt 	}
286*a1157835SDaniel Fojt 
287*a1157835SDaniel Fojt 	ctx->s = linux_af_alg_socket("hash", name);
288*a1157835SDaniel Fojt 	if (ctx->s < 0) {
289*a1157835SDaniel Fojt 		os_free(ctx);
290*a1157835SDaniel Fojt 		return NULL;
291*a1157835SDaniel Fojt 	}
292*a1157835SDaniel Fojt 
293*a1157835SDaniel Fojt 	if (key && key_len &&
294*a1157835SDaniel Fojt 	    setsockopt(ctx->s, SOL_ALG, ALG_SET_KEY, key, key_len) < 0) {
295*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: setsockopt(ALG_SET_KEY) failed: %s",
296*a1157835SDaniel Fojt 			   __func__, strerror(errno));
297*a1157835SDaniel Fojt 		close(ctx->s);
298*a1157835SDaniel Fojt 		os_free(ctx);
299*a1157835SDaniel Fojt 		return NULL;
300*a1157835SDaniel Fojt 	}
301*a1157835SDaniel Fojt 
302*a1157835SDaniel Fojt 	ctx->t = accept(ctx->s, NULL, NULL);
303*a1157835SDaniel Fojt 	if (ctx->t < 0) {
304*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: accept on AF_ALG socket failed: %s",
305*a1157835SDaniel Fojt 			   __func__, strerror(errno));
306*a1157835SDaniel Fojt 		close(ctx->s);
307*a1157835SDaniel Fojt 		os_free(ctx);
308*a1157835SDaniel Fojt 		return NULL;
309*a1157835SDaniel Fojt 	}
310*a1157835SDaniel Fojt 
311*a1157835SDaniel Fojt 	return ctx;
312*a1157835SDaniel Fojt }
313*a1157835SDaniel Fojt 
314*a1157835SDaniel Fojt 
crypto_hash_update(struct crypto_hash * ctx,const u8 * data,size_t len)315*a1157835SDaniel Fojt void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
316*a1157835SDaniel Fojt {
317*a1157835SDaniel Fojt 	ssize_t res;
318*a1157835SDaniel Fojt 
319*a1157835SDaniel Fojt 	if (!ctx)
320*a1157835SDaniel Fojt 		return;
321*a1157835SDaniel Fojt 
322*a1157835SDaniel Fojt 	res = send(ctx->t, data, len, MSG_MORE);
323*a1157835SDaniel Fojt 	if (res < 0) {
324*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
325*a1157835SDaniel Fojt 			   "%s: send on AF_ALG socket failed: %s",
326*a1157835SDaniel Fojt 			   __func__, strerror(errno));
327*a1157835SDaniel Fojt 		ctx->failed = 1;
328*a1157835SDaniel Fojt 		return;
329*a1157835SDaniel Fojt 	}
330*a1157835SDaniel Fojt 	if ((size_t) res < len) {
331*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
332*a1157835SDaniel Fojt 			   "%s: send on AF_ALG socket did not accept full buffer (%d/%d)",
333*a1157835SDaniel Fojt 			   __func__, (int) res, (int) len);
334*a1157835SDaniel Fojt 		ctx->failed = 1;
335*a1157835SDaniel Fojt 		return;
336*a1157835SDaniel Fojt 	}
337*a1157835SDaniel Fojt }
338*a1157835SDaniel Fojt 
339*a1157835SDaniel Fojt 
crypto_hash_deinit(struct crypto_hash * ctx)340*a1157835SDaniel Fojt static void crypto_hash_deinit(struct crypto_hash *ctx)
341*a1157835SDaniel Fojt {
342*a1157835SDaniel Fojt 	close(ctx->s);
343*a1157835SDaniel Fojt 	close(ctx->t);
344*a1157835SDaniel Fojt 	os_free(ctx);
345*a1157835SDaniel Fojt }
346*a1157835SDaniel Fojt 
347*a1157835SDaniel Fojt 
crypto_hash_finish(struct crypto_hash * ctx,u8 * mac,size_t * len)348*a1157835SDaniel Fojt int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
349*a1157835SDaniel Fojt {
350*a1157835SDaniel Fojt 	ssize_t res;
351*a1157835SDaniel Fojt 
352*a1157835SDaniel Fojt 	if (!ctx)
353*a1157835SDaniel Fojt 		return -2;
354*a1157835SDaniel Fojt 
355*a1157835SDaniel Fojt 	if (!mac || !len) {
356*a1157835SDaniel Fojt 		crypto_hash_deinit(ctx);
357*a1157835SDaniel Fojt 		return 0;
358*a1157835SDaniel Fojt 	}
359*a1157835SDaniel Fojt 
360*a1157835SDaniel Fojt 	if (ctx->failed) {
361*a1157835SDaniel Fojt 		crypto_hash_deinit(ctx);
362*a1157835SDaniel Fojt 		return -2;
363*a1157835SDaniel Fojt 	}
364*a1157835SDaniel Fojt 
365*a1157835SDaniel Fojt 	if (*len < ctx->mac_len) {
366*a1157835SDaniel Fojt 		crypto_hash_deinit(ctx);
367*a1157835SDaniel Fojt 		*len = ctx->mac_len;
368*a1157835SDaniel Fojt 		return -1;
369*a1157835SDaniel Fojt 	}
370*a1157835SDaniel Fojt 	*len = ctx->mac_len;
371*a1157835SDaniel Fojt 
372*a1157835SDaniel Fojt 	res = recv(ctx->t, mac, ctx->mac_len, 0);
373*a1157835SDaniel Fojt 	if (res < 0) {
374*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
375*a1157835SDaniel Fojt 			   "%s: recv on AF_ALG socket failed: %s",
376*a1157835SDaniel Fojt 			   __func__, strerror(errno));
377*a1157835SDaniel Fojt 		crypto_hash_deinit(ctx);
378*a1157835SDaniel Fojt 		return -2;
379*a1157835SDaniel Fojt 	}
380*a1157835SDaniel Fojt 	if ((size_t) res < ctx->mac_len) {
381*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
382*a1157835SDaniel Fojt 			   "%s: recv on AF_ALG socket did not return full buffer (%d/%d)",
383*a1157835SDaniel Fojt 			   __func__, (int) res, (int) ctx->mac_len);
384*a1157835SDaniel Fojt 		crypto_hash_deinit(ctx);
385*a1157835SDaniel Fojt 		return -2;
386*a1157835SDaniel Fojt 	}
387*a1157835SDaniel Fojt 
388*a1157835SDaniel Fojt 	crypto_hash_deinit(ctx);
389*a1157835SDaniel Fojt 
390*a1157835SDaniel Fojt 	if (TEST_FAIL())
391*a1157835SDaniel Fojt 		return -1;
392*a1157835SDaniel Fojt 	return 0;
393*a1157835SDaniel Fojt }
394*a1157835SDaniel Fojt 
395*a1157835SDaniel Fojt 
396*a1157835SDaniel Fojt struct linux_af_alg_skcipher {
397*a1157835SDaniel Fojt 	int s;
398*a1157835SDaniel Fojt 	int t;
399*a1157835SDaniel Fojt };
400*a1157835SDaniel Fojt 
401*a1157835SDaniel Fojt 
linux_af_alg_skcipher_deinit(struct linux_af_alg_skcipher * skcipher)402*a1157835SDaniel Fojt static void linux_af_alg_skcipher_deinit(struct linux_af_alg_skcipher *skcipher)
403*a1157835SDaniel Fojt {
404*a1157835SDaniel Fojt 	if (!skcipher)
405*a1157835SDaniel Fojt 		return;
406*a1157835SDaniel Fojt 	if (skcipher->s >= 0)
407*a1157835SDaniel Fojt 		close(skcipher->s);
408*a1157835SDaniel Fojt 	if (skcipher->t >= 0)
409*a1157835SDaniel Fojt 		close(skcipher->t);
410*a1157835SDaniel Fojt 	os_free(skcipher);
411*a1157835SDaniel Fojt }
412*a1157835SDaniel Fojt 
413*a1157835SDaniel Fojt 
414*a1157835SDaniel Fojt static struct linux_af_alg_skcipher *
linux_af_alg_skcipher(const char * alg,const u8 * key,size_t key_len)415*a1157835SDaniel Fojt linux_af_alg_skcipher(const char *alg, const u8 *key, size_t key_len)
416*a1157835SDaniel Fojt {
417*a1157835SDaniel Fojt 	struct linux_af_alg_skcipher *skcipher;
418*a1157835SDaniel Fojt 
419*a1157835SDaniel Fojt 	skcipher = os_zalloc(sizeof(*skcipher));
420*a1157835SDaniel Fojt 	if (!skcipher)
421*a1157835SDaniel Fojt 		goto fail;
422*a1157835SDaniel Fojt 	skcipher->t = -1;
423*a1157835SDaniel Fojt 
424*a1157835SDaniel Fojt 	skcipher->s = linux_af_alg_socket("skcipher", alg);
425*a1157835SDaniel Fojt 	if (skcipher->s < 0)
426*a1157835SDaniel Fojt 		goto fail;
427*a1157835SDaniel Fojt 
428*a1157835SDaniel Fojt 	if (setsockopt(skcipher->s, SOL_ALG, ALG_SET_KEY, key, key_len) < 0) {
429*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: setsockopt(ALG_SET_KEY) failed: %s",
430*a1157835SDaniel Fojt 			   __func__, strerror(errno));
431*a1157835SDaniel Fojt 		goto fail;
432*a1157835SDaniel Fojt 	}
433*a1157835SDaniel Fojt 
434*a1157835SDaniel Fojt 	skcipher->t = accept(skcipher->s, NULL, NULL);
435*a1157835SDaniel Fojt 	if (skcipher->t < 0) {
436*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: accept on AF_ALG socket failed: %s",
437*a1157835SDaniel Fojt 			   __func__, strerror(errno));
438*a1157835SDaniel Fojt 		goto fail;
439*a1157835SDaniel Fojt 	}
440*a1157835SDaniel Fojt 
441*a1157835SDaniel Fojt 	return skcipher;
442*a1157835SDaniel Fojt fail:
443*a1157835SDaniel Fojt 	linux_af_alg_skcipher_deinit(skcipher);
444*a1157835SDaniel Fojt 	return NULL;
445*a1157835SDaniel Fojt }
446*a1157835SDaniel Fojt 
447*a1157835SDaniel Fojt 
linux_af_alg_skcipher_oper(struct linux_af_alg_skcipher * skcipher,int enc,const u8 * in,u8 * out)448*a1157835SDaniel Fojt static int linux_af_alg_skcipher_oper(struct linux_af_alg_skcipher *skcipher,
449*a1157835SDaniel Fojt 				      int enc, const u8 *in, u8 *out)
450*a1157835SDaniel Fojt {
451*a1157835SDaniel Fojt 	char buf[CMSG_SPACE(sizeof(u32))];
452*a1157835SDaniel Fojt 	struct iovec io[1];
453*a1157835SDaniel Fojt 	struct msghdr msg;
454*a1157835SDaniel Fojt 	struct cmsghdr *hdr;
455*a1157835SDaniel Fojt 	ssize_t ret;
456*a1157835SDaniel Fojt 	u32 *op;
457*a1157835SDaniel Fojt 
458*a1157835SDaniel Fojt 	io[0].iov_base = (void *) in;
459*a1157835SDaniel Fojt 	io[0].iov_len = AES_BLOCK_SIZE;
460*a1157835SDaniel Fojt 	os_memset(&msg, 0, sizeof(msg));
461*a1157835SDaniel Fojt 	os_memset(buf, 0, sizeof(buf));
462*a1157835SDaniel Fojt 	msg.msg_control = buf;
463*a1157835SDaniel Fojt 	msg.msg_controllen = CMSG_SPACE(sizeof(u32));
464*a1157835SDaniel Fojt 	msg.msg_iov = io;
465*a1157835SDaniel Fojt 	msg.msg_iovlen = 1;
466*a1157835SDaniel Fojt 	hdr = CMSG_FIRSTHDR(&msg);
467*a1157835SDaniel Fojt 	hdr->cmsg_level = SOL_ALG;
468*a1157835SDaniel Fojt 	hdr->cmsg_type = ALG_SET_OP;
469*a1157835SDaniel Fojt 	hdr->cmsg_len = CMSG_LEN(sizeof(u32));
470*a1157835SDaniel Fojt 	op = (u32 *) CMSG_DATA(hdr);
471*a1157835SDaniel Fojt 	*op = enc ? ALG_OP_ENCRYPT : ALG_OP_DECRYPT;
472*a1157835SDaniel Fojt 
473*a1157835SDaniel Fojt 	ret = sendmsg(skcipher->t, &msg, 0);
474*a1157835SDaniel Fojt 	if (ret < 0) {
475*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s",
476*a1157835SDaniel Fojt 			   __func__, strerror(errno));
477*a1157835SDaniel Fojt 		return -1;
478*a1157835SDaniel Fojt 	}
479*a1157835SDaniel Fojt 
480*a1157835SDaniel Fojt 	ret = read(skcipher->t, out, AES_BLOCK_SIZE);
481*a1157835SDaniel Fojt 	if (ret < 0) {
482*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: read failed: %s",
483*a1157835SDaniel Fojt 			   __func__, strerror(errno));
484*a1157835SDaniel Fojt 		return -1;
485*a1157835SDaniel Fojt 	}
486*a1157835SDaniel Fojt 	if (ret < AES_BLOCK_SIZE) {
487*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
488*a1157835SDaniel Fojt 			   "%s: read did not return full data (%d/%d)",
489*a1157835SDaniel Fojt 			   __func__, (int) ret, AES_BLOCK_SIZE);
490*a1157835SDaniel Fojt 		return -1;
491*a1157835SDaniel Fojt 	}
492*a1157835SDaniel Fojt 
493*a1157835SDaniel Fojt 	return 0;
494*a1157835SDaniel Fojt }
495*a1157835SDaniel Fojt 
496*a1157835SDaniel Fojt 
aes_encrypt_init(const u8 * key,size_t len)497*a1157835SDaniel Fojt void * aes_encrypt_init(const u8 *key, size_t len)
498*a1157835SDaniel Fojt {
499*a1157835SDaniel Fojt 	return linux_af_alg_skcipher("ecb(aes)", key, len);
500*a1157835SDaniel Fojt }
501*a1157835SDaniel Fojt 
502*a1157835SDaniel Fojt 
aes_encrypt(void * ctx,const u8 * plain,u8 * crypt)503*a1157835SDaniel Fojt int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
504*a1157835SDaniel Fojt {
505*a1157835SDaniel Fojt 	struct linux_af_alg_skcipher *skcipher = ctx;
506*a1157835SDaniel Fojt 
507*a1157835SDaniel Fojt 	return linux_af_alg_skcipher_oper(skcipher, 1, plain, crypt);
508*a1157835SDaniel Fojt }
509*a1157835SDaniel Fojt 
510*a1157835SDaniel Fojt 
aes_encrypt_deinit(void * ctx)511*a1157835SDaniel Fojt void aes_encrypt_deinit(void *ctx)
512*a1157835SDaniel Fojt {
513*a1157835SDaniel Fojt 	linux_af_alg_skcipher_deinit(ctx);
514*a1157835SDaniel Fojt }
515*a1157835SDaniel Fojt 
516*a1157835SDaniel Fojt 
aes_decrypt_init(const u8 * key,size_t len)517*a1157835SDaniel Fojt void * aes_decrypt_init(const u8 *key, size_t len)
518*a1157835SDaniel Fojt {
519*a1157835SDaniel Fojt 	return linux_af_alg_skcipher("ecb(aes)", key, len);
520*a1157835SDaniel Fojt }
521*a1157835SDaniel Fojt 
522*a1157835SDaniel Fojt 
aes_decrypt(void * ctx,const u8 * crypt,u8 * plain)523*a1157835SDaniel Fojt int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
524*a1157835SDaniel Fojt {
525*a1157835SDaniel Fojt 	struct linux_af_alg_skcipher *skcipher = ctx;
526*a1157835SDaniel Fojt 
527*a1157835SDaniel Fojt 	return linux_af_alg_skcipher_oper(skcipher, 0, crypt, plain);
528*a1157835SDaniel Fojt }
529*a1157835SDaniel Fojt 
530*a1157835SDaniel Fojt 
aes_decrypt_deinit(void * ctx)531*a1157835SDaniel Fojt void aes_decrypt_deinit(void *ctx)
532*a1157835SDaniel Fojt {
533*a1157835SDaniel Fojt 	linux_af_alg_skcipher_deinit(ctx);
534*a1157835SDaniel Fojt }
535*a1157835SDaniel Fojt 
536*a1157835SDaniel Fojt 
rc4_skip(const u8 * key,size_t keylen,size_t skip,u8 * data,size_t data_len)537*a1157835SDaniel Fojt int rc4_skip(const u8 *key, size_t keylen, size_t skip,
538*a1157835SDaniel Fojt 	     u8 *data, size_t data_len)
539*a1157835SDaniel Fojt {
540*a1157835SDaniel Fojt 	struct linux_af_alg_skcipher *skcipher;
541*a1157835SDaniel Fojt 	u8 *skip_buf;
542*a1157835SDaniel Fojt 	char buf[CMSG_SPACE(sizeof(u32))];
543*a1157835SDaniel Fojt 	struct iovec io[2];
544*a1157835SDaniel Fojt 	struct msghdr msg;
545*a1157835SDaniel Fojt 	struct cmsghdr *hdr;
546*a1157835SDaniel Fojt 	ssize_t ret;
547*a1157835SDaniel Fojt 	u32 *op;
548*a1157835SDaniel Fojt 
549*a1157835SDaniel Fojt 	skip_buf = os_zalloc(skip + 1);
550*a1157835SDaniel Fojt 	if (!skip_buf)
551*a1157835SDaniel Fojt 		return -1;
552*a1157835SDaniel Fojt 	skcipher = linux_af_alg_skcipher("ecb(arc4)", key, keylen);
553*a1157835SDaniel Fojt 	if (!skcipher) {
554*a1157835SDaniel Fojt 		os_free(skip_buf);
555*a1157835SDaniel Fojt 		return -1;
556*a1157835SDaniel Fojt 	}
557*a1157835SDaniel Fojt 
558*a1157835SDaniel Fojt 	io[0].iov_base = skip_buf;
559*a1157835SDaniel Fojt 	io[0].iov_len = skip;
560*a1157835SDaniel Fojt 	io[1].iov_base = data;
561*a1157835SDaniel Fojt 	io[1].iov_len = data_len;
562*a1157835SDaniel Fojt 	os_memset(&msg, 0, sizeof(msg));
563*a1157835SDaniel Fojt 	os_memset(buf, 0, sizeof(buf));
564*a1157835SDaniel Fojt 	msg.msg_control = buf;
565*a1157835SDaniel Fojt 	msg.msg_controllen = CMSG_SPACE(sizeof(u32));
566*a1157835SDaniel Fojt 	msg.msg_iov = io;
567*a1157835SDaniel Fojt 	msg.msg_iovlen = 2;
568*a1157835SDaniel Fojt 	hdr = CMSG_FIRSTHDR(&msg);
569*a1157835SDaniel Fojt 	hdr->cmsg_level = SOL_ALG;
570*a1157835SDaniel Fojt 	hdr->cmsg_type = ALG_SET_OP;
571*a1157835SDaniel Fojt 	hdr->cmsg_len = CMSG_LEN(sizeof(u32));
572*a1157835SDaniel Fojt 	op = (u32 *) CMSG_DATA(hdr);
573*a1157835SDaniel Fojt 	*op = ALG_OP_ENCRYPT;
574*a1157835SDaniel Fojt 
575*a1157835SDaniel Fojt 	ret = sendmsg(skcipher->t, &msg, 0);
576*a1157835SDaniel Fojt 	if (ret < 0) {
577*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s",
578*a1157835SDaniel Fojt 			   __func__, strerror(errno));
579*a1157835SDaniel Fojt 		os_free(skip_buf);
580*a1157835SDaniel Fojt 		linux_af_alg_skcipher_deinit(skcipher);
581*a1157835SDaniel Fojt 		return -1;
582*a1157835SDaniel Fojt 	}
583*a1157835SDaniel Fojt 	os_free(skip_buf);
584*a1157835SDaniel Fojt 
585*a1157835SDaniel Fojt 	msg.msg_control = NULL;
586*a1157835SDaniel Fojt 	msg.msg_controllen = 0;
587*a1157835SDaniel Fojt 	ret = recvmsg(skcipher->t, &msg, 0);
588*a1157835SDaniel Fojt 	if (ret < 0) {
589*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: recvmsg failed: %s",
590*a1157835SDaniel Fojt 			   __func__, strerror(errno));
591*a1157835SDaniel Fojt 		linux_af_alg_skcipher_deinit(skcipher);
592*a1157835SDaniel Fojt 		return -1;
593*a1157835SDaniel Fojt 	}
594*a1157835SDaniel Fojt 	linux_af_alg_skcipher_deinit(skcipher);
595*a1157835SDaniel Fojt 
596*a1157835SDaniel Fojt 	if ((size_t) ret < skip + data_len) {
597*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
598*a1157835SDaniel Fojt 			   "%s: recvmsg did not return full data (%d/%d)",
599*a1157835SDaniel Fojt 			   __func__, (int) ret, (int) (skip + data_len));
600*a1157835SDaniel Fojt 		return -1;
601*a1157835SDaniel Fojt 	}
602*a1157835SDaniel Fojt 
603*a1157835SDaniel Fojt 	return 0;
604*a1157835SDaniel Fojt }
605*a1157835SDaniel Fojt 
606*a1157835SDaniel Fojt 
des_encrypt(const u8 * clear,const u8 * key,u8 * cypher)607*a1157835SDaniel Fojt int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
608*a1157835SDaniel Fojt {
609*a1157835SDaniel Fojt 	u8 pkey[8], next, tmp;
610*a1157835SDaniel Fojt 	int i;
611*a1157835SDaniel Fojt 	struct linux_af_alg_skcipher *skcipher;
612*a1157835SDaniel Fojt 	char buf[CMSG_SPACE(sizeof(u32))];
613*a1157835SDaniel Fojt 	struct iovec io[1];
614*a1157835SDaniel Fojt 	struct msghdr msg;
615*a1157835SDaniel Fojt 	struct cmsghdr *hdr;
616*a1157835SDaniel Fojt 	ssize_t ret;
617*a1157835SDaniel Fojt 	u32 *op;
618*a1157835SDaniel Fojt 	int res = -1;
619*a1157835SDaniel Fojt 
620*a1157835SDaniel Fojt 	/* Add parity bits to the key */
621*a1157835SDaniel Fojt 	next = 0;
622*a1157835SDaniel Fojt 	for (i = 0; i < 7; i++) {
623*a1157835SDaniel Fojt 		tmp = key[i];
624*a1157835SDaniel Fojt 		pkey[i] = (tmp >> i) | next | 1;
625*a1157835SDaniel Fojt 		next = tmp << (7 - i);
626*a1157835SDaniel Fojt 	}
627*a1157835SDaniel Fojt 	pkey[i] = next | 1;
628*a1157835SDaniel Fojt 
629*a1157835SDaniel Fojt 	skcipher = linux_af_alg_skcipher("ecb(des)", pkey, sizeof(pkey));
630*a1157835SDaniel Fojt 	if (!skcipher)
631*a1157835SDaniel Fojt 		goto fail;
632*a1157835SDaniel Fojt 
633*a1157835SDaniel Fojt 	io[0].iov_base = (void *) clear;
634*a1157835SDaniel Fojt 	io[0].iov_len = 8;
635*a1157835SDaniel Fojt 	os_memset(&msg, 0, sizeof(msg));
636*a1157835SDaniel Fojt 	os_memset(buf, 0, sizeof(buf));
637*a1157835SDaniel Fojt 	msg.msg_control = buf;
638*a1157835SDaniel Fojt 	msg.msg_controllen = CMSG_SPACE(sizeof(u32));
639*a1157835SDaniel Fojt 	msg.msg_iov = io;
640*a1157835SDaniel Fojt 	msg.msg_iovlen = 1;
641*a1157835SDaniel Fojt 	hdr = CMSG_FIRSTHDR(&msg);
642*a1157835SDaniel Fojt 	hdr->cmsg_level = SOL_ALG;
643*a1157835SDaniel Fojt 	hdr->cmsg_type = ALG_SET_OP;
644*a1157835SDaniel Fojt 	hdr->cmsg_len = CMSG_LEN(sizeof(u32));
645*a1157835SDaniel Fojt 	op = (u32 *) CMSG_DATA(hdr);
646*a1157835SDaniel Fojt 	*op = ALG_OP_ENCRYPT;
647*a1157835SDaniel Fojt 
648*a1157835SDaniel Fojt 	ret = sendmsg(skcipher->t, &msg, 0);
649*a1157835SDaniel Fojt 	if (ret < 0) {
650*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s",
651*a1157835SDaniel Fojt 			   __func__, strerror(errno));
652*a1157835SDaniel Fojt 		goto fail;
653*a1157835SDaniel Fojt 	}
654*a1157835SDaniel Fojt 
655*a1157835SDaniel Fojt 	ret = read(skcipher->t, cypher, 8);
656*a1157835SDaniel Fojt 	if (ret < 0) {
657*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: read failed: %s",
658*a1157835SDaniel Fojt 			   __func__, strerror(errno));
659*a1157835SDaniel Fojt 		goto fail;
660*a1157835SDaniel Fojt 	}
661*a1157835SDaniel Fojt 	if (ret < 8) {
662*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
663*a1157835SDaniel Fojt 			   "%s: read did not return full data (%d/8)",
664*a1157835SDaniel Fojt 			   __func__, (int) ret);
665*a1157835SDaniel Fojt 		goto fail;
666*a1157835SDaniel Fojt 	}
667*a1157835SDaniel Fojt 
668*a1157835SDaniel Fojt 	res = 0;
669*a1157835SDaniel Fojt fail:
670*a1157835SDaniel Fojt 	linux_af_alg_skcipher_deinit(skcipher);
671*a1157835SDaniel Fojt 	return res;
672*a1157835SDaniel Fojt }
673*a1157835SDaniel Fojt 
674*a1157835SDaniel Fojt 
aes_128_cbc_oper(const u8 * key,int enc,const u8 * iv,u8 * data,size_t data_len)675*a1157835SDaniel Fojt static int aes_128_cbc_oper(const u8 *key, int enc, const u8 *iv,
676*a1157835SDaniel Fojt 			    u8 *data, size_t data_len)
677*a1157835SDaniel Fojt {
678*a1157835SDaniel Fojt 	struct linux_af_alg_skcipher *skcipher;
679*a1157835SDaniel Fojt 	char buf[100];
680*a1157835SDaniel Fojt 	struct iovec io[1];
681*a1157835SDaniel Fojt 	struct msghdr msg;
682*a1157835SDaniel Fojt 	struct cmsghdr *hdr;
683*a1157835SDaniel Fojt 	ssize_t ret;
684*a1157835SDaniel Fojt 	u32 *op;
685*a1157835SDaniel Fojt 	struct af_alg_iv *alg_iv;
686*a1157835SDaniel Fojt 	size_t iv_len = AES_BLOCK_SIZE;
687*a1157835SDaniel Fojt 
688*a1157835SDaniel Fojt 	skcipher = linux_af_alg_skcipher("cbc(aes)", key, 16);
689*a1157835SDaniel Fojt 	if (!skcipher)
690*a1157835SDaniel Fojt 		return -1;
691*a1157835SDaniel Fojt 
692*a1157835SDaniel Fojt 	io[0].iov_base = (void *) data;
693*a1157835SDaniel Fojt 	io[0].iov_len = data_len;
694*a1157835SDaniel Fojt 	os_memset(&msg, 0, sizeof(msg));
695*a1157835SDaniel Fojt 	os_memset(buf, 0, sizeof(buf));
696*a1157835SDaniel Fojt 	msg.msg_control = buf;
697*a1157835SDaniel Fojt 	msg.msg_controllen = CMSG_SPACE(sizeof(u32)) +
698*a1157835SDaniel Fojt 		CMSG_SPACE(sizeof(*alg_iv) + iv_len);
699*a1157835SDaniel Fojt 	msg.msg_iov = io;
700*a1157835SDaniel Fojt 	msg.msg_iovlen = 1;
701*a1157835SDaniel Fojt 
702*a1157835SDaniel Fojt 	hdr = CMSG_FIRSTHDR(&msg);
703*a1157835SDaniel Fojt 	hdr->cmsg_level = SOL_ALG;
704*a1157835SDaniel Fojt 	hdr->cmsg_type = ALG_SET_OP;
705*a1157835SDaniel Fojt 	hdr->cmsg_len = CMSG_LEN(sizeof(u32));
706*a1157835SDaniel Fojt 	op = (u32 *) CMSG_DATA(hdr);
707*a1157835SDaniel Fojt 	*op = enc ? ALG_OP_ENCRYPT : ALG_OP_DECRYPT;
708*a1157835SDaniel Fojt 
709*a1157835SDaniel Fojt 	hdr = CMSG_NXTHDR(&msg, hdr);
710*a1157835SDaniel Fojt 	hdr->cmsg_level = SOL_ALG;
711*a1157835SDaniel Fojt 	hdr->cmsg_type = ALG_SET_IV;
712*a1157835SDaniel Fojt 	hdr->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv_len);
713*a1157835SDaniel Fojt 	alg_iv = (struct af_alg_iv *) CMSG_DATA(hdr);
714*a1157835SDaniel Fojt 	alg_iv->ivlen = iv_len;
715*a1157835SDaniel Fojt 	os_memcpy(alg_iv->iv, iv, iv_len);
716*a1157835SDaniel Fojt 
717*a1157835SDaniel Fojt 	ret = sendmsg(skcipher->t, &msg, 0);
718*a1157835SDaniel Fojt 	if (ret < 0) {
719*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s",
720*a1157835SDaniel Fojt 			   __func__, strerror(errno));
721*a1157835SDaniel Fojt 		linux_af_alg_skcipher_deinit(skcipher);
722*a1157835SDaniel Fojt 		return -1;
723*a1157835SDaniel Fojt 	}
724*a1157835SDaniel Fojt 
725*a1157835SDaniel Fojt 	ret = recvmsg(skcipher->t, &msg, 0);
726*a1157835SDaniel Fojt 	if (ret < 0) {
727*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: recvmsg failed: %s",
728*a1157835SDaniel Fojt 			   __func__, strerror(errno));
729*a1157835SDaniel Fojt 		linux_af_alg_skcipher_deinit(skcipher);
730*a1157835SDaniel Fojt 		return -1;
731*a1157835SDaniel Fojt 	}
732*a1157835SDaniel Fojt 	if ((size_t) ret < data_len) {
733*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
734*a1157835SDaniel Fojt 			   "%s: recvmsg not return full data (%d/%d)",
735*a1157835SDaniel Fojt 			   __func__, (int) ret, (int) data_len);
736*a1157835SDaniel Fojt 		linux_af_alg_skcipher_deinit(skcipher);
737*a1157835SDaniel Fojt 		return -1;
738*a1157835SDaniel Fojt 	}
739*a1157835SDaniel Fojt 
740*a1157835SDaniel Fojt 	linux_af_alg_skcipher_deinit(skcipher);
741*a1157835SDaniel Fojt 	return 0;
742*a1157835SDaniel Fojt }
743*a1157835SDaniel Fojt 
744*a1157835SDaniel Fojt 
aes_128_cbc_encrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)745*a1157835SDaniel Fojt int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
746*a1157835SDaniel Fojt {
747*a1157835SDaniel Fojt 	return aes_128_cbc_oper(key, 1, iv, data, data_len);
748*a1157835SDaniel Fojt }
749*a1157835SDaniel Fojt 
750*a1157835SDaniel Fojt 
aes_128_cbc_decrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)751*a1157835SDaniel Fojt int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
752*a1157835SDaniel Fojt {
753*a1157835SDaniel Fojt 	return aes_128_cbc_oper(key, 0, iv, data, data_len);
754*a1157835SDaniel Fojt }
755*a1157835SDaniel Fojt 
756*a1157835SDaniel Fojt 
omac1_aes_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)757*a1157835SDaniel Fojt int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
758*a1157835SDaniel Fojt 		     const u8 *addr[], const size_t *len, u8 *mac)
759*a1157835SDaniel Fojt {
760*a1157835SDaniel Fojt 	return linux_af_alg_hash_vector("cmac(aes)", key, key_len, num_elem,
761*a1157835SDaniel Fojt 					addr, len, mac, AES_BLOCK_SIZE);
762*a1157835SDaniel Fojt }
763*a1157835SDaniel Fojt 
764*a1157835SDaniel Fojt 
omac1_aes_128_vector(const u8 * key,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)765*a1157835SDaniel Fojt int omac1_aes_128_vector(const u8 *key, size_t num_elem,
766*a1157835SDaniel Fojt 			 const u8 *addr[], const size_t *len, u8 *mac)
767*a1157835SDaniel Fojt {
768*a1157835SDaniel Fojt 	return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
769*a1157835SDaniel Fojt }
770*a1157835SDaniel Fojt 
771*a1157835SDaniel Fojt 
omac1_aes_128(const u8 * key,const u8 * data,size_t data_len,u8 * mac)772*a1157835SDaniel Fojt int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
773*a1157835SDaniel Fojt {
774*a1157835SDaniel Fojt 	return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
775*a1157835SDaniel Fojt }
776*a1157835SDaniel Fojt 
777*a1157835SDaniel Fojt 
omac1_aes_256(const u8 * key,const u8 * data,size_t data_len,u8 * mac)778*a1157835SDaniel Fojt int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
779*a1157835SDaniel Fojt {
780*a1157835SDaniel Fojt 	return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
781*a1157835SDaniel Fojt }
782*a1157835SDaniel Fojt 
783*a1157835SDaniel Fojt 
aes_unwrap(const u8 * kek,size_t kek_len,int n,const u8 * cipher,u8 * plain)784*a1157835SDaniel Fojt int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
785*a1157835SDaniel Fojt 	       u8 *plain)
786*a1157835SDaniel Fojt {
787*a1157835SDaniel Fojt 	struct linux_af_alg_skcipher *skcipher;
788*a1157835SDaniel Fojt 	char buf[100];
789*a1157835SDaniel Fojt 	struct iovec io[1];
790*a1157835SDaniel Fojt 	struct msghdr msg;
791*a1157835SDaniel Fojt 	struct cmsghdr *hdr;
792*a1157835SDaniel Fojt 	ssize_t ret;
793*a1157835SDaniel Fojt 	u32 *op;
794*a1157835SDaniel Fojt 	struct af_alg_iv *alg_iv;
795*a1157835SDaniel Fojt 	size_t iv_len = 8;
796*a1157835SDaniel Fojt 
797*a1157835SDaniel Fojt 	skcipher = linux_af_alg_skcipher("kw(aes)", kek, kek_len);
798*a1157835SDaniel Fojt 	if (!skcipher)
799*a1157835SDaniel Fojt 		return -1;
800*a1157835SDaniel Fojt 
801*a1157835SDaniel Fojt 	io[0].iov_base = (void *) (cipher + iv_len);
802*a1157835SDaniel Fojt 	io[0].iov_len = n * 8;
803*a1157835SDaniel Fojt 	os_memset(&msg, 0, sizeof(msg));
804*a1157835SDaniel Fojt 	os_memset(buf, 0, sizeof(buf));
805*a1157835SDaniel Fojt 	msg.msg_control = buf;
806*a1157835SDaniel Fojt 	msg.msg_controllen = CMSG_SPACE(sizeof(u32)) +
807*a1157835SDaniel Fojt 		CMSG_SPACE(sizeof(*alg_iv) + iv_len);
808*a1157835SDaniel Fojt 	msg.msg_iov = io;
809*a1157835SDaniel Fojt 	msg.msg_iovlen = 1;
810*a1157835SDaniel Fojt 
811*a1157835SDaniel Fojt 	hdr = CMSG_FIRSTHDR(&msg);
812*a1157835SDaniel Fojt 	hdr->cmsg_level = SOL_ALG;
813*a1157835SDaniel Fojt 	hdr->cmsg_type = ALG_SET_OP;
814*a1157835SDaniel Fojt 	hdr->cmsg_len = CMSG_LEN(sizeof(u32));
815*a1157835SDaniel Fojt 	op = (u32 *) CMSG_DATA(hdr);
816*a1157835SDaniel Fojt 	*op = ALG_OP_DECRYPT;
817*a1157835SDaniel Fojt 
818*a1157835SDaniel Fojt 	hdr = CMSG_NXTHDR(&msg, hdr);
819*a1157835SDaniel Fojt 	hdr->cmsg_level = SOL_ALG;
820*a1157835SDaniel Fojt 	hdr->cmsg_type = ALG_SET_IV;
821*a1157835SDaniel Fojt 	hdr->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv_len);
822*a1157835SDaniel Fojt 	alg_iv = (struct af_alg_iv *) CMSG_DATA(hdr);
823*a1157835SDaniel Fojt 	alg_iv->ivlen = iv_len;
824*a1157835SDaniel Fojt 	os_memcpy(alg_iv->iv, cipher, iv_len);
825*a1157835SDaniel Fojt 
826*a1157835SDaniel Fojt 	ret = sendmsg(skcipher->t, &msg, 0);
827*a1157835SDaniel Fojt 	if (ret < 0) {
828*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s",
829*a1157835SDaniel Fojt 			   __func__, strerror(errno));
830*a1157835SDaniel Fojt 		return -1;
831*a1157835SDaniel Fojt 	}
832*a1157835SDaniel Fojt 
833*a1157835SDaniel Fojt 	ret = read(skcipher->t, plain, n * 8);
834*a1157835SDaniel Fojt 	if (ret < 0) {
835*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: read failed: %s",
836*a1157835SDaniel Fojt 			   __func__, strerror(errno));
837*a1157835SDaniel Fojt 		linux_af_alg_skcipher_deinit(skcipher);
838*a1157835SDaniel Fojt 		return -1;
839*a1157835SDaniel Fojt 	}
840*a1157835SDaniel Fojt 	if (ret < n * 8) {
841*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
842*a1157835SDaniel Fojt 			   "%s: read not return full data (%d/%d)",
843*a1157835SDaniel Fojt 			   __func__, (int) ret, n * 8);
844*a1157835SDaniel Fojt 		linux_af_alg_skcipher_deinit(skcipher);
845*a1157835SDaniel Fojt 		return -1;
846*a1157835SDaniel Fojt 	}
847*a1157835SDaniel Fojt 
848*a1157835SDaniel Fojt 	linux_af_alg_skcipher_deinit(skcipher);
849*a1157835SDaniel Fojt 	return 0;
850*a1157835SDaniel Fojt }
851*a1157835SDaniel Fojt 
852*a1157835SDaniel Fojt 
853*a1157835SDaniel Fojt struct crypto_cipher {
854*a1157835SDaniel Fojt 	struct linux_af_alg_skcipher *skcipher;
855*a1157835SDaniel Fojt };
856*a1157835SDaniel Fojt 
857*a1157835SDaniel Fojt 
crypto_cipher_init(enum crypto_cipher_alg alg,const u8 * iv,const u8 * key,size_t key_len)858*a1157835SDaniel Fojt struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
859*a1157835SDaniel Fojt 					  const u8 *iv, const u8 *key,
860*a1157835SDaniel Fojt 					  size_t key_len)
861*a1157835SDaniel Fojt {
862*a1157835SDaniel Fojt 	struct crypto_cipher *ctx;
863*a1157835SDaniel Fojt 	const char *name;
864*a1157835SDaniel Fojt 	struct af_alg_iv *alg_iv;
865*a1157835SDaniel Fojt 	size_t iv_len = 0;
866*a1157835SDaniel Fojt 	char buf[100];
867*a1157835SDaniel Fojt 	struct msghdr msg;
868*a1157835SDaniel Fojt 	struct cmsghdr *hdr;
869*a1157835SDaniel Fojt 	ssize_t ret;
870*a1157835SDaniel Fojt 
871*a1157835SDaniel Fojt 	ctx = os_zalloc(sizeof(*ctx));
872*a1157835SDaniel Fojt 	if (!ctx)
873*a1157835SDaniel Fojt 		return NULL;
874*a1157835SDaniel Fojt 
875*a1157835SDaniel Fojt 	switch (alg) {
876*a1157835SDaniel Fojt 	case CRYPTO_CIPHER_ALG_RC4:
877*a1157835SDaniel Fojt 		name = "ecb(arc4)";
878*a1157835SDaniel Fojt 		break;
879*a1157835SDaniel Fojt 	case CRYPTO_CIPHER_ALG_AES:
880*a1157835SDaniel Fojt 		name = "cbc(aes)";
881*a1157835SDaniel Fojt 		iv_len = AES_BLOCK_SIZE;
882*a1157835SDaniel Fojt 		break;
883*a1157835SDaniel Fojt 	case CRYPTO_CIPHER_ALG_3DES:
884*a1157835SDaniel Fojt 		name = "cbc(des3_ede)";
885*a1157835SDaniel Fojt 		iv_len = 8;
886*a1157835SDaniel Fojt 		break;
887*a1157835SDaniel Fojt 	case CRYPTO_CIPHER_ALG_DES:
888*a1157835SDaniel Fojt 		name = "cbc(des)";
889*a1157835SDaniel Fojt 		iv_len = 8;
890*a1157835SDaniel Fojt 		break;
891*a1157835SDaniel Fojt 	default:
892*a1157835SDaniel Fojt 		os_free(ctx);
893*a1157835SDaniel Fojt 		return NULL;
894*a1157835SDaniel Fojt 	}
895*a1157835SDaniel Fojt 
896*a1157835SDaniel Fojt 	ctx->skcipher = linux_af_alg_skcipher(name, key, key_len);
897*a1157835SDaniel Fojt 	if (!ctx->skcipher) {
898*a1157835SDaniel Fojt 		os_free(ctx);
899*a1157835SDaniel Fojt 		return NULL;
900*a1157835SDaniel Fojt 	}
901*a1157835SDaniel Fojt 
902*a1157835SDaniel Fojt 	if (iv && iv_len) {
903*a1157835SDaniel Fojt 		os_memset(&msg, 0, sizeof(msg));
904*a1157835SDaniel Fojt 		os_memset(buf, 0, sizeof(buf));
905*a1157835SDaniel Fojt 		msg.msg_control = buf;
906*a1157835SDaniel Fojt 		msg.msg_controllen = CMSG_SPACE(sizeof(*alg_iv) + iv_len);
907*a1157835SDaniel Fojt 		hdr = CMSG_FIRSTHDR(&msg);
908*a1157835SDaniel Fojt 		hdr->cmsg_level = SOL_ALG;
909*a1157835SDaniel Fojt 		hdr->cmsg_type = ALG_SET_IV;
910*a1157835SDaniel Fojt 		hdr->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv_len);
911*a1157835SDaniel Fojt 		alg_iv = (struct af_alg_iv *) CMSG_DATA(hdr);
912*a1157835SDaniel Fojt 		alg_iv->ivlen = iv_len;
913*a1157835SDaniel Fojt 		os_memcpy(alg_iv->iv, iv, iv_len);
914*a1157835SDaniel Fojt 
915*a1157835SDaniel Fojt 		ret = sendmsg(ctx->skcipher->t, &msg, 0);
916*a1157835SDaniel Fojt 		if (ret < 0) {
917*a1157835SDaniel Fojt 			wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s",
918*a1157835SDaniel Fojt 				   __func__, strerror(errno));
919*a1157835SDaniel Fojt 			linux_af_alg_skcipher_deinit(ctx->skcipher);
920*a1157835SDaniel Fojt 			os_free(ctx);
921*a1157835SDaniel Fojt 			return NULL;
922*a1157835SDaniel Fojt 		}
923*a1157835SDaniel Fojt 	}
924*a1157835SDaniel Fojt 
925*a1157835SDaniel Fojt 	return ctx;
926*a1157835SDaniel Fojt }
927*a1157835SDaniel Fojt 
928*a1157835SDaniel Fojt 
crypto_cipher_oper(struct crypto_cipher * ctx,u32 type,const u8 * in,u8 * out,size_t len)929*a1157835SDaniel Fojt static int crypto_cipher_oper(struct crypto_cipher *ctx, u32 type, const u8 *in,
930*a1157835SDaniel Fojt 			      u8 *out, size_t len)
931*a1157835SDaniel Fojt {
932*a1157835SDaniel Fojt 	char buf[CMSG_SPACE(sizeof(u32))];
933*a1157835SDaniel Fojt 	struct iovec io[1];
934*a1157835SDaniel Fojt 	struct msghdr msg;
935*a1157835SDaniel Fojt 	struct cmsghdr *hdr;
936*a1157835SDaniel Fojt 	ssize_t ret;
937*a1157835SDaniel Fojt 	u32 *op;
938*a1157835SDaniel Fojt 
939*a1157835SDaniel Fojt 	io[0].iov_base = (void *) in;
940*a1157835SDaniel Fojt 	io[0].iov_len = len;
941*a1157835SDaniel Fojt 	os_memset(&msg, 0, sizeof(msg));
942*a1157835SDaniel Fojt 	os_memset(buf, 0, sizeof(buf));
943*a1157835SDaniel Fojt 	msg.msg_control = buf;
944*a1157835SDaniel Fojt 	msg.msg_controllen = CMSG_SPACE(sizeof(u32));
945*a1157835SDaniel Fojt 	msg.msg_iov = io;
946*a1157835SDaniel Fojt 	msg.msg_iovlen = 1;
947*a1157835SDaniel Fojt 	hdr = CMSG_FIRSTHDR(&msg);
948*a1157835SDaniel Fojt 	hdr->cmsg_level = SOL_ALG;
949*a1157835SDaniel Fojt 	hdr->cmsg_type = ALG_SET_OP;
950*a1157835SDaniel Fojt 	hdr->cmsg_len = CMSG_LEN(sizeof(u32));
951*a1157835SDaniel Fojt 	op = (u32 *) CMSG_DATA(hdr);
952*a1157835SDaniel Fojt 	*op = type;
953*a1157835SDaniel Fojt 
954*a1157835SDaniel Fojt 	ret = sendmsg(ctx->skcipher->t, &msg, 0);
955*a1157835SDaniel Fojt 	if (ret < 0) {
956*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: sendmsg failed: %s",
957*a1157835SDaniel Fojt 			   __func__, strerror(errno));
958*a1157835SDaniel Fojt 		return -1;
959*a1157835SDaniel Fojt 	}
960*a1157835SDaniel Fojt 
961*a1157835SDaniel Fojt 	ret = read(ctx->skcipher->t, out, len);
962*a1157835SDaniel Fojt 	if (ret < 0) {
963*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: read failed: %s",
964*a1157835SDaniel Fojt 			   __func__, strerror(errno));
965*a1157835SDaniel Fojt 		return -1;
966*a1157835SDaniel Fojt 	}
967*a1157835SDaniel Fojt 	if (ret < (ssize_t) len) {
968*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
969*a1157835SDaniel Fojt 			   "%s: read did not return full data (%d/%d)",
970*a1157835SDaniel Fojt 			   __func__, (int) ret, (int) len);
971*a1157835SDaniel Fojt 		return -1;
972*a1157835SDaniel Fojt 	}
973*a1157835SDaniel Fojt 
974*a1157835SDaniel Fojt 	return 0;
975*a1157835SDaniel Fojt }
976*a1157835SDaniel Fojt 
977*a1157835SDaniel Fojt 
crypto_cipher_encrypt(struct crypto_cipher * ctx,const u8 * plain,u8 * crypt,size_t len)978*a1157835SDaniel Fojt int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
979*a1157835SDaniel Fojt 			  u8 *crypt, size_t len)
980*a1157835SDaniel Fojt {
981*a1157835SDaniel Fojt 	return crypto_cipher_oper(ctx, ALG_OP_ENCRYPT, plain, crypt, len);
982*a1157835SDaniel Fojt }
983*a1157835SDaniel Fojt 
984*a1157835SDaniel Fojt 
crypto_cipher_decrypt(struct crypto_cipher * ctx,const u8 * crypt,u8 * plain,size_t len)985*a1157835SDaniel Fojt int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
986*a1157835SDaniel Fojt 			  u8 *plain, size_t len)
987*a1157835SDaniel Fojt {
988*a1157835SDaniel Fojt 	return crypto_cipher_oper(ctx, ALG_OP_DECRYPT, crypt, plain, len);
989*a1157835SDaniel Fojt }
990*a1157835SDaniel Fojt 
991*a1157835SDaniel Fojt 
crypto_cipher_deinit(struct crypto_cipher * ctx)992*a1157835SDaniel Fojt void crypto_cipher_deinit(struct crypto_cipher *ctx)
993*a1157835SDaniel Fojt {
994*a1157835SDaniel Fojt 	if (ctx) {
995*a1157835SDaniel Fojt 		linux_af_alg_skcipher_deinit(ctx->skcipher);
996*a1157835SDaniel Fojt 		os_free(ctx);
997*a1157835SDaniel Fojt 	}
998*a1157835SDaniel Fojt }
999*a1157835SDaniel Fojt 
1000*a1157835SDaniel Fojt 
crypto_global_init(void)1001*a1157835SDaniel Fojt int crypto_global_init(void)
1002*a1157835SDaniel Fojt {
1003*a1157835SDaniel Fojt 	return 0;
1004*a1157835SDaniel Fojt }
1005*a1157835SDaniel Fojt 
1006*a1157835SDaniel Fojt 
crypto_global_deinit(void)1007*a1157835SDaniel Fojt void crypto_global_deinit(void)
1008*a1157835SDaniel Fojt {
1009*a1157835SDaniel Fojt }
1010