• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * authencesn.c - AEAD wrapper for IPsec with extended sequence numbers,
3  *                 derived from authenc.c
4  *
5  * Copyright (C) 2010 secunet Security Networks AG
6  * Copyright (C) 2010 Steffen Klassert <steffen.klassert@secunet.com>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the Free
10  * Software Foundation; either version 2 of the License, or (at your option)
11  * any later version.
12  *
13  */
14 
15 #include <crypto/aead.h>
16 #include <crypto/internal/hash.h>
17 #include <crypto/internal/skcipher.h>
18 #include <crypto/authenc.h>
19 #include <crypto/scatterwalk.h>
20 #include <linux/err.h>
21 #include <linux/init.h>
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/rtnetlink.h>
25 #include <linux/slab.h>
26 #include <linux/spinlock.h>
27 
28 struct authenc_esn_instance_ctx {
29 	struct crypto_ahash_spawn auth;
30 	struct crypto_skcipher_spawn enc;
31 };
32 
33 struct crypto_authenc_esn_ctx {
34 	unsigned int reqoff;
35 	struct crypto_ahash *auth;
36 	struct crypto_ablkcipher *enc;
37 };
38 
39 struct authenc_esn_request_ctx {
40 	unsigned int cryptlen;
41 	unsigned int headlen;
42 	unsigned int trailen;
43 	struct scatterlist *sg;
44 	struct scatterlist hsg[2];
45 	struct scatterlist tsg[1];
46 	struct scatterlist cipher[2];
47 	crypto_completion_t complete;
48 	crypto_completion_t update_complete;
49 	crypto_completion_t update_complete2;
50 	char tail[];
51 };
52 
authenc_esn_request_complete(struct aead_request * req,int err)53 static void authenc_esn_request_complete(struct aead_request *req, int err)
54 {
55 	if (err != -EINPROGRESS)
56 		aead_request_complete(req, err);
57 }
58 
crypto_authenc_esn_setkey(struct crypto_aead * authenc_esn,const u8 * key,unsigned int keylen)59 static int crypto_authenc_esn_setkey(struct crypto_aead *authenc_esn, const u8 *key,
60 				     unsigned int keylen)
61 {
62 	unsigned int authkeylen;
63 	unsigned int enckeylen;
64 	struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
65 	struct crypto_ahash *auth = ctx->auth;
66 	struct crypto_ablkcipher *enc = ctx->enc;
67 	struct rtattr *rta = (void *)key;
68 	struct crypto_authenc_key_param *param;
69 	int err = -EINVAL;
70 
71 	if (!RTA_OK(rta, keylen))
72 		goto badkey;
73 	if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
74 		goto badkey;
75 	if (RTA_PAYLOAD(rta) < sizeof(*param))
76 		goto badkey;
77 
78 	param = RTA_DATA(rta);
79 	enckeylen = be32_to_cpu(param->enckeylen);
80 
81 	key += RTA_ALIGN(rta->rta_len);
82 	keylen -= RTA_ALIGN(rta->rta_len);
83 
84 	if (keylen < enckeylen)
85 		goto badkey;
86 
87 	authkeylen = keylen - enckeylen;
88 
89 	crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
90 	crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc_esn) &
91 				     CRYPTO_TFM_REQ_MASK);
92 	err = crypto_ahash_setkey(auth, key, authkeylen);
93 	crypto_aead_set_flags(authenc_esn, crypto_ahash_get_flags(auth) &
94 					   CRYPTO_TFM_RES_MASK);
95 
96 	if (err)
97 		goto out;
98 
99 	crypto_ablkcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK);
100 	crypto_ablkcipher_set_flags(enc, crypto_aead_get_flags(authenc_esn) &
101 					 CRYPTO_TFM_REQ_MASK);
102 	err = crypto_ablkcipher_setkey(enc, key + authkeylen, enckeylen);
103 	crypto_aead_set_flags(authenc_esn, crypto_ablkcipher_get_flags(enc) &
104 					   CRYPTO_TFM_RES_MASK);
105 
106 out:
107 	return err;
108 
109 badkey:
110 	crypto_aead_set_flags(authenc_esn, CRYPTO_TFM_RES_BAD_KEY_LEN);
111 	goto out;
112 }
113 
authenc_esn_geniv_ahash_update_done(struct crypto_async_request * areq,int err)114 static void authenc_esn_geniv_ahash_update_done(struct crypto_async_request *areq,
115 						int err)
116 {
117 	struct aead_request *req = areq->data;
118 	struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
119 	struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
120 	struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
121 	struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
122 
123 	if (err)
124 		goto out;
125 
126 	ahash_request_set_crypt(ahreq, areq_ctx->sg, ahreq->result,
127 				areq_ctx->cryptlen);
128 	ahash_request_set_callback(ahreq, aead_request_flags(req) &
129 					  CRYPTO_TFM_REQ_MAY_SLEEP,
130 				   areq_ctx->update_complete2, req);
131 
132 	err = crypto_ahash_update(ahreq);
133 	if (err)
134 		goto out;
135 
136 	ahash_request_set_crypt(ahreq, areq_ctx->tsg, ahreq->result,
137 				areq_ctx->trailen);
138 	ahash_request_set_callback(ahreq, aead_request_flags(req) &
139 					  CRYPTO_TFM_REQ_MAY_SLEEP,
140 				   areq_ctx->complete, req);
141 
142 	err = crypto_ahash_finup(ahreq);
143 	if (err)
144 		goto out;
145 
146 	scatterwalk_map_and_copy(ahreq->result, areq_ctx->sg,
147 				 areq_ctx->cryptlen,
148 				 crypto_aead_authsize(authenc_esn), 1);
149 
150 out:
151 	authenc_esn_request_complete(req, err);
152 }
153 
authenc_esn_geniv_ahash_update_done2(struct crypto_async_request * areq,int err)154 static void authenc_esn_geniv_ahash_update_done2(struct crypto_async_request *areq,
155 						 int err)
156 {
157 	struct aead_request *req = areq->data;
158 	struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
159 	struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
160 	struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
161 	struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
162 
163 	if (err)
164 		goto out;
165 
166 	ahash_request_set_crypt(ahreq, areq_ctx->tsg, ahreq->result,
167 				areq_ctx->trailen);
168 	ahash_request_set_callback(ahreq, aead_request_flags(req) &
169 					  CRYPTO_TFM_REQ_MAY_SLEEP,
170 				   areq_ctx->complete, req);
171 
172 	err = crypto_ahash_finup(ahreq);
173 	if (err)
174 		goto out;
175 
176 	scatterwalk_map_and_copy(ahreq->result, areq_ctx->sg,
177 				 areq_ctx->cryptlen,
178 				 crypto_aead_authsize(authenc_esn), 1);
179 
180 out:
181 	authenc_esn_request_complete(req, err);
182 }
183 
184 
authenc_esn_geniv_ahash_done(struct crypto_async_request * areq,int err)185 static void authenc_esn_geniv_ahash_done(struct crypto_async_request *areq,
186 					 int err)
187 {
188 	struct aead_request *req = areq->data;
189 	struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
190 	struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
191 	struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
192 	struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
193 
194 	if (err)
195 		goto out;
196 
197 	scatterwalk_map_and_copy(ahreq->result, areq_ctx->sg,
198 				 areq_ctx->cryptlen,
199 				 crypto_aead_authsize(authenc_esn), 1);
200 
201 out:
202 	aead_request_complete(req, err);
203 }
204 
205 
authenc_esn_verify_ahash_update_done(struct crypto_async_request * areq,int err)206 static void authenc_esn_verify_ahash_update_done(struct crypto_async_request *areq,
207 						 int err)
208 {
209 	u8 *ihash;
210 	unsigned int authsize;
211 	struct ablkcipher_request *abreq;
212 	struct aead_request *req = areq->data;
213 	struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
214 	struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
215 	struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
216 	struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
217 	unsigned int cryptlen = req->cryptlen;
218 
219 	if (err)
220 		goto out;
221 
222 	ahash_request_set_crypt(ahreq, areq_ctx->sg, ahreq->result,
223 				areq_ctx->cryptlen);
224 
225 	ahash_request_set_callback(ahreq,
226 				   aead_request_flags(req) &
227 				   CRYPTO_TFM_REQ_MAY_SLEEP,
228 				   areq_ctx->update_complete2, req);
229 
230 	err = crypto_ahash_update(ahreq);
231 	if (err)
232 		goto out;
233 
234 	ahash_request_set_crypt(ahreq, areq_ctx->tsg, ahreq->result,
235 				areq_ctx->trailen);
236 	ahash_request_set_callback(ahreq, aead_request_flags(req) &
237 					  CRYPTO_TFM_REQ_MAY_SLEEP,
238 				   areq_ctx->complete, req);
239 
240 	err = crypto_ahash_finup(ahreq);
241 	if (err)
242 		goto out;
243 
244 	authsize = crypto_aead_authsize(authenc_esn);
245 	cryptlen -= authsize;
246 	ihash = ahreq->result + authsize;
247 	scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
248 				 authsize, 0);
249 
250 	err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
251 	if (err)
252 		goto out;
253 
254 	abreq = aead_request_ctx(req);
255 	ablkcipher_request_set_tfm(abreq, ctx->enc);
256 	ablkcipher_request_set_callback(abreq, aead_request_flags(req),
257 					req->base.complete, req->base.data);
258 	ablkcipher_request_set_crypt(abreq, req->src, req->dst,
259 				     cryptlen, req->iv);
260 
261 	err = crypto_ablkcipher_decrypt(abreq);
262 
263 out:
264 	authenc_esn_request_complete(req, err);
265 }
266 
authenc_esn_verify_ahash_update_done2(struct crypto_async_request * areq,int err)267 static void authenc_esn_verify_ahash_update_done2(struct crypto_async_request *areq,
268 						  int err)
269 {
270 	u8 *ihash;
271 	unsigned int authsize;
272 	struct ablkcipher_request *abreq;
273 	struct aead_request *req = areq->data;
274 	struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
275 	struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
276 	struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
277 	struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
278 	unsigned int cryptlen = req->cryptlen;
279 
280 	if (err)
281 		goto out;
282 
283 	ahash_request_set_crypt(ahreq, areq_ctx->tsg, ahreq->result,
284 				areq_ctx->trailen);
285 	ahash_request_set_callback(ahreq, aead_request_flags(req) &
286 					  CRYPTO_TFM_REQ_MAY_SLEEP,
287 				   areq_ctx->complete, req);
288 
289 	err = crypto_ahash_finup(ahreq);
290 	if (err)
291 		goto out;
292 
293 	authsize = crypto_aead_authsize(authenc_esn);
294 	cryptlen -= authsize;
295 	ihash = ahreq->result + authsize;
296 	scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
297 				 authsize, 0);
298 
299 	err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
300 	if (err)
301 		goto out;
302 
303 	abreq = aead_request_ctx(req);
304 	ablkcipher_request_set_tfm(abreq, ctx->enc);
305 	ablkcipher_request_set_callback(abreq, aead_request_flags(req),
306 					req->base.complete, req->base.data);
307 	ablkcipher_request_set_crypt(abreq, req->src, req->dst,
308 				     cryptlen, req->iv);
309 
310 	err = crypto_ablkcipher_decrypt(abreq);
311 
312 out:
313 	authenc_esn_request_complete(req, err);
314 }
315 
316 
authenc_esn_verify_ahash_done(struct crypto_async_request * areq,int err)317 static void authenc_esn_verify_ahash_done(struct crypto_async_request *areq,
318 					  int err)
319 {
320 	u8 *ihash;
321 	unsigned int authsize;
322 	struct ablkcipher_request *abreq;
323 	struct aead_request *req = areq->data;
324 	struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
325 	struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
326 	struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
327 	struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
328 	unsigned int cryptlen = req->cryptlen;
329 
330 	if (err)
331 		goto out;
332 
333 	authsize = crypto_aead_authsize(authenc_esn);
334 	cryptlen -= authsize;
335 	ihash = ahreq->result + authsize;
336 	scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
337 				 authsize, 0);
338 
339 	err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
340 	if (err)
341 		goto out;
342 
343 	abreq = aead_request_ctx(req);
344 	ablkcipher_request_set_tfm(abreq, ctx->enc);
345 	ablkcipher_request_set_callback(abreq, aead_request_flags(req),
346 					req->base.complete, req->base.data);
347 	ablkcipher_request_set_crypt(abreq, req->src, req->dst,
348 				     cryptlen, req->iv);
349 
350 	err = crypto_ablkcipher_decrypt(abreq);
351 
352 out:
353 	authenc_esn_request_complete(req, err);
354 }
355 
crypto_authenc_esn_ahash(struct aead_request * req,unsigned int flags)356 static u8 *crypto_authenc_esn_ahash(struct aead_request *req,
357 				    unsigned int flags)
358 {
359 	struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
360 	struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
361 	struct crypto_ahash *auth = ctx->auth;
362 	struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
363 	struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
364 	u8 *hash = areq_ctx->tail;
365 	int err;
366 
367 	hash = (u8 *)ALIGN((unsigned long)hash + crypto_ahash_alignmask(auth),
368 			    crypto_ahash_alignmask(auth) + 1);
369 
370 	ahash_request_set_tfm(ahreq, auth);
371 
372 	err = crypto_ahash_init(ahreq);
373 	if (err)
374 		return ERR_PTR(err);
375 
376 	ahash_request_set_crypt(ahreq, areq_ctx->hsg, hash, areq_ctx->headlen);
377 	ahash_request_set_callback(ahreq, aead_request_flags(req) & flags,
378 				   areq_ctx->update_complete, req);
379 
380 	err = crypto_ahash_update(ahreq);
381 	if (err)
382 		return ERR_PTR(err);
383 
384 	ahash_request_set_crypt(ahreq, areq_ctx->sg, hash, areq_ctx->cryptlen);
385 	ahash_request_set_callback(ahreq, aead_request_flags(req) & flags,
386 				   areq_ctx->update_complete2, req);
387 
388 	err = crypto_ahash_update(ahreq);
389 	if (err)
390 		return ERR_PTR(err);
391 
392 	ahash_request_set_crypt(ahreq, areq_ctx->tsg, hash,
393 				areq_ctx->trailen);
394 	ahash_request_set_callback(ahreq, aead_request_flags(req) & flags,
395 				   areq_ctx->complete, req);
396 
397 	err = crypto_ahash_finup(ahreq);
398 	if (err)
399 		return ERR_PTR(err);
400 
401 	return hash;
402 }
403 
crypto_authenc_esn_genicv(struct aead_request * req,u8 * iv,unsigned int flags)404 static int crypto_authenc_esn_genicv(struct aead_request *req, u8 *iv,
405 				     unsigned int flags)
406 {
407 	struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
408 	struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
409 	struct scatterlist *dst = req->dst;
410 	struct scatterlist *assoc = req->assoc;
411 	struct scatterlist *cipher = areq_ctx->cipher;
412 	struct scatterlist *hsg = areq_ctx->hsg;
413 	struct scatterlist *tsg = areq_ctx->tsg;
414 	struct scatterlist *assoc1;
415 	struct scatterlist *assoc2;
416 	unsigned int ivsize = crypto_aead_ivsize(authenc_esn);
417 	unsigned int cryptlen = req->cryptlen;
418 	struct page *dstp;
419 	u8 *vdst;
420 	u8 *hash;
421 
422 	dstp = sg_page(dst);
423 	vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset;
424 
425 	if (ivsize) {
426 		sg_init_table(cipher, 2);
427 		sg_set_buf(cipher, iv, ivsize);
428 		scatterwalk_crypto_chain(cipher, dst, vdst == iv + ivsize, 2);
429 		dst = cipher;
430 		cryptlen += ivsize;
431 	}
432 
433 	if (sg_is_last(assoc))
434 		return -EINVAL;
435 
436 	assoc1 = assoc + 1;
437 	if (sg_is_last(assoc1))
438 		return -EINVAL;
439 
440 	assoc2 = assoc + 2;
441 	if (!sg_is_last(assoc2))
442 		return -EINVAL;
443 
444 	sg_init_table(hsg, 2);
445 	sg_set_page(hsg, sg_page(assoc), assoc->length, assoc->offset);
446 	sg_set_page(hsg + 1, sg_page(assoc2), assoc2->length, assoc2->offset);
447 
448 	sg_init_table(tsg, 1);
449 	sg_set_page(tsg, sg_page(assoc1), assoc1->length, assoc1->offset);
450 
451 	areq_ctx->cryptlen = cryptlen;
452 	areq_ctx->headlen = assoc->length + assoc2->length;
453 	areq_ctx->trailen = assoc1->length;
454 	areq_ctx->sg = dst;
455 
456 	areq_ctx->complete = authenc_esn_geniv_ahash_done;
457 	areq_ctx->update_complete = authenc_esn_geniv_ahash_update_done;
458 	areq_ctx->update_complete2 = authenc_esn_geniv_ahash_update_done2;
459 
460 	hash = crypto_authenc_esn_ahash(req, flags);
461 	if (IS_ERR(hash))
462 		return PTR_ERR(hash);
463 
464 	scatterwalk_map_and_copy(hash, dst, cryptlen,
465 				 crypto_aead_authsize(authenc_esn), 1);
466 	return 0;
467 }
468 
469 
crypto_authenc_esn_encrypt_done(struct crypto_async_request * req,int err)470 static void crypto_authenc_esn_encrypt_done(struct crypto_async_request *req,
471 					    int err)
472 {
473 	struct aead_request *areq = req->data;
474 
475 	if (!err) {
476 		struct crypto_aead *authenc_esn = crypto_aead_reqtfm(areq);
477 		struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
478 		struct ablkcipher_request *abreq = aead_request_ctx(areq);
479 		u8 *iv = (u8 *)(abreq + 1) +
480 			 crypto_ablkcipher_reqsize(ctx->enc);
481 
482 		err = crypto_authenc_esn_genicv(areq, iv, 0);
483 	}
484 
485 	authenc_esn_request_complete(areq, err);
486 }
487 
crypto_authenc_esn_encrypt(struct aead_request * req)488 static int crypto_authenc_esn_encrypt(struct aead_request *req)
489 {
490 	struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
491 	struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
492 	struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
493 	struct crypto_ablkcipher *enc = ctx->enc;
494 	struct scatterlist *dst = req->dst;
495 	unsigned int cryptlen = req->cryptlen;
496 	struct ablkcipher_request *abreq = (void *)(areq_ctx->tail
497 						    + ctx->reqoff);
498 	u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(enc);
499 	int err;
500 
501 	ablkcipher_request_set_tfm(abreq, enc);
502 	ablkcipher_request_set_callback(abreq, aead_request_flags(req),
503 					crypto_authenc_esn_encrypt_done, req);
504 	ablkcipher_request_set_crypt(abreq, req->src, dst, cryptlen, req->iv);
505 
506 	memcpy(iv, req->iv, crypto_aead_ivsize(authenc_esn));
507 
508 	err = crypto_ablkcipher_encrypt(abreq);
509 	if (err)
510 		return err;
511 
512 	return crypto_authenc_esn_genicv(req, iv, CRYPTO_TFM_REQ_MAY_SLEEP);
513 }
514 
crypto_authenc_esn_givencrypt_done(struct crypto_async_request * req,int err)515 static void crypto_authenc_esn_givencrypt_done(struct crypto_async_request *req,
516 					       int err)
517 {
518 	struct aead_request *areq = req->data;
519 
520 	if (!err) {
521 		struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);
522 
523 		err = crypto_authenc_esn_genicv(areq, greq->giv, 0);
524 	}
525 
526 	authenc_esn_request_complete(areq, err);
527 }
528 
crypto_authenc_esn_givencrypt(struct aead_givcrypt_request * req)529 static int crypto_authenc_esn_givencrypt(struct aead_givcrypt_request *req)
530 {
531 	struct crypto_aead *authenc_esn = aead_givcrypt_reqtfm(req);
532 	struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
533 	struct aead_request *areq = &req->areq;
534 	struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);
535 	u8 *iv = req->giv;
536 	int err;
537 
538 	skcipher_givcrypt_set_tfm(greq, ctx->enc);
539 	skcipher_givcrypt_set_callback(greq, aead_request_flags(areq),
540 				       crypto_authenc_esn_givencrypt_done, areq);
541 	skcipher_givcrypt_set_crypt(greq, areq->src, areq->dst, areq->cryptlen,
542 				    areq->iv);
543 	skcipher_givcrypt_set_giv(greq, iv, req->seq);
544 
545 	err = crypto_skcipher_givencrypt(greq);
546 	if (err)
547 		return err;
548 
549 	return crypto_authenc_esn_genicv(areq, iv, CRYPTO_TFM_REQ_MAY_SLEEP);
550 }
551 
crypto_authenc_esn_verify(struct aead_request * req)552 static int crypto_authenc_esn_verify(struct aead_request *req)
553 {
554 	struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
555 	struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
556 	u8 *ohash;
557 	u8 *ihash;
558 	unsigned int authsize;
559 
560 	areq_ctx->complete = authenc_esn_verify_ahash_done;
561 	areq_ctx->update_complete = authenc_esn_verify_ahash_update_done;
562 
563 	ohash = crypto_authenc_esn_ahash(req, CRYPTO_TFM_REQ_MAY_SLEEP);
564 	if (IS_ERR(ohash))
565 		return PTR_ERR(ohash);
566 
567 	authsize = crypto_aead_authsize(authenc_esn);
568 	ihash = ohash + authsize;
569 	scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
570 				 authsize, 0);
571 	return crypto_memneq(ihash, ohash, authsize) ? -EBADMSG : 0;
572 }
573 
crypto_authenc_esn_iverify(struct aead_request * req,u8 * iv,unsigned int cryptlen)574 static int crypto_authenc_esn_iverify(struct aead_request *req, u8 *iv,
575 				      unsigned int cryptlen)
576 {
577 	struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
578 	struct authenc_esn_request_ctx *areq_ctx = aead_request_ctx(req);
579 	struct scatterlist *src = req->src;
580 	struct scatterlist *assoc = req->assoc;
581 	struct scatterlist *cipher = areq_ctx->cipher;
582 	struct scatterlist *hsg = areq_ctx->hsg;
583 	struct scatterlist *tsg = areq_ctx->tsg;
584 	struct scatterlist *assoc1;
585 	struct scatterlist *assoc2;
586 	unsigned int ivsize = crypto_aead_ivsize(authenc_esn);
587 	struct page *srcp;
588 	u8 *vsrc;
589 
590 	srcp = sg_page(src);
591 	vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset;
592 
593 	if (ivsize) {
594 		sg_init_table(cipher, 2);
595 		sg_set_buf(cipher, iv, ivsize);
596 		scatterwalk_crypto_chain(cipher, src, vsrc == iv + ivsize, 2);
597 		src = cipher;
598 		cryptlen += ivsize;
599 	}
600 
601 	if (sg_is_last(assoc))
602 		return -EINVAL;
603 
604 	assoc1 = assoc + 1;
605 	if (sg_is_last(assoc1))
606 		return -EINVAL;
607 
608 	assoc2 = assoc + 2;
609 	if (!sg_is_last(assoc2))
610 		return -EINVAL;
611 
612 	sg_init_table(hsg, 2);
613 	sg_set_page(hsg, sg_page(assoc), assoc->length, assoc->offset);
614 	sg_set_page(hsg + 1, sg_page(assoc2), assoc2->length, assoc2->offset);
615 
616 	sg_init_table(tsg, 1);
617 	sg_set_page(tsg, sg_page(assoc1), assoc1->length, assoc1->offset);
618 
619 	areq_ctx->cryptlen = cryptlen;
620 	areq_ctx->headlen = assoc->length + assoc2->length;
621 	areq_ctx->trailen = assoc1->length;
622 	areq_ctx->sg = src;
623 
624 	areq_ctx->complete = authenc_esn_verify_ahash_done;
625 	areq_ctx->update_complete = authenc_esn_verify_ahash_update_done;
626 	areq_ctx->update_complete2 = authenc_esn_verify_ahash_update_done2;
627 
628 	return crypto_authenc_esn_verify(req);
629 }
630 
crypto_authenc_esn_decrypt(struct aead_request * req)631 static int crypto_authenc_esn_decrypt(struct aead_request *req)
632 {
633 	struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
634 	struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
635 	struct ablkcipher_request *abreq = aead_request_ctx(req);
636 	unsigned int cryptlen = req->cryptlen;
637 	unsigned int authsize = crypto_aead_authsize(authenc_esn);
638 	u8 *iv = req->iv;
639 	int err;
640 
641 	if (cryptlen < authsize)
642 		return -EINVAL;
643 	cryptlen -= authsize;
644 
645 	err = crypto_authenc_esn_iverify(req, iv, cryptlen);
646 	if (err)
647 		return err;
648 
649 	ablkcipher_request_set_tfm(abreq, ctx->enc);
650 	ablkcipher_request_set_callback(abreq, aead_request_flags(req),
651 					req->base.complete, req->base.data);
652 	ablkcipher_request_set_crypt(abreq, req->src, req->dst, cryptlen, iv);
653 
654 	return crypto_ablkcipher_decrypt(abreq);
655 }
656 
crypto_authenc_esn_init_tfm(struct crypto_tfm * tfm)657 static int crypto_authenc_esn_init_tfm(struct crypto_tfm *tfm)
658 {
659 	struct crypto_instance *inst = crypto_tfm_alg_instance(tfm);
660 	struct authenc_esn_instance_ctx *ictx = crypto_instance_ctx(inst);
661 	struct crypto_authenc_esn_ctx *ctx = crypto_tfm_ctx(tfm);
662 	struct crypto_ahash *auth;
663 	struct crypto_ablkcipher *enc;
664 	int err;
665 
666 	auth = crypto_spawn_ahash(&ictx->auth);
667 	if (IS_ERR(auth))
668 		return PTR_ERR(auth);
669 
670 	enc = crypto_spawn_skcipher(&ictx->enc);
671 	err = PTR_ERR(enc);
672 	if (IS_ERR(enc))
673 		goto err_free_ahash;
674 
675 	ctx->auth = auth;
676 	ctx->enc = enc;
677 
678 	ctx->reqoff = ALIGN(2 * crypto_ahash_digestsize(auth) +
679 			    crypto_ahash_alignmask(auth),
680 			    crypto_ahash_alignmask(auth) + 1) +
681 		      crypto_ablkcipher_ivsize(enc);
682 
683 	tfm->crt_aead.reqsize = sizeof(struct authenc_esn_request_ctx) +
684 				ctx->reqoff +
685 				max_t(unsigned int,
686 				crypto_ahash_reqsize(auth) +
687 				sizeof(struct ahash_request),
688 				sizeof(struct skcipher_givcrypt_request) +
689 				crypto_ablkcipher_reqsize(enc));
690 
691 	return 0;
692 
693 err_free_ahash:
694 	crypto_free_ahash(auth);
695 	return err;
696 }
697 
crypto_authenc_esn_exit_tfm(struct crypto_tfm * tfm)698 static void crypto_authenc_esn_exit_tfm(struct crypto_tfm *tfm)
699 {
700 	struct crypto_authenc_esn_ctx *ctx = crypto_tfm_ctx(tfm);
701 
702 	crypto_free_ahash(ctx->auth);
703 	crypto_free_ablkcipher(ctx->enc);
704 }
705 
crypto_authenc_esn_alloc(struct rtattr ** tb)706 static struct crypto_instance *crypto_authenc_esn_alloc(struct rtattr **tb)
707 {
708 	struct crypto_attr_type *algt;
709 	struct crypto_instance *inst;
710 	struct hash_alg_common *auth;
711 	struct crypto_alg *auth_base;
712 	struct crypto_alg *enc;
713 	struct authenc_esn_instance_ctx *ctx;
714 	const char *enc_name;
715 	int err;
716 
717 	algt = crypto_get_attr_type(tb);
718 	if (IS_ERR(algt))
719 		return ERR_CAST(algt);
720 
721 	if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
722 		return ERR_PTR(-EINVAL);
723 
724 	auth = ahash_attr_alg(tb[1], CRYPTO_ALG_TYPE_HASH,
725 			       CRYPTO_ALG_TYPE_AHASH_MASK);
726 	if (IS_ERR(auth))
727 		return ERR_CAST(auth);
728 
729 	auth_base = &auth->base;
730 
731 	enc_name = crypto_attr_alg_name(tb[2]);
732 	err = PTR_ERR(enc_name);
733 	if (IS_ERR(enc_name))
734 		goto out_put_auth;
735 
736 	inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
737 	err = -ENOMEM;
738 	if (!inst)
739 		goto out_put_auth;
740 
741 	ctx = crypto_instance_ctx(inst);
742 
743 	err = crypto_init_ahash_spawn(&ctx->auth, auth, inst);
744 	if (err)
745 		goto err_free_inst;
746 
747 	crypto_set_skcipher_spawn(&ctx->enc, inst);
748 	err = crypto_grab_skcipher(&ctx->enc, enc_name, 0,
749 				   crypto_requires_sync(algt->type,
750 							algt->mask));
751 	if (err)
752 		goto err_drop_auth;
753 
754 	enc = crypto_skcipher_spawn_alg(&ctx->enc);
755 
756 	err = -ENAMETOOLONG;
757 	if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
758 		     "authencesn(%s,%s)", auth_base->cra_name, enc->cra_name) >=
759 	    CRYPTO_MAX_ALG_NAME)
760 		goto err_drop_enc;
761 
762 	if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
763 		     "authencesn(%s,%s)", auth_base->cra_driver_name,
764 		     enc->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
765 		goto err_drop_enc;
766 
767 	inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD;
768 	inst->alg.cra_flags |= enc->cra_flags & CRYPTO_ALG_ASYNC;
769 	inst->alg.cra_priority = enc->cra_priority *
770 				 10 + auth_base->cra_priority;
771 	inst->alg.cra_blocksize = enc->cra_blocksize;
772 	inst->alg.cra_alignmask = auth_base->cra_alignmask | enc->cra_alignmask;
773 	inst->alg.cra_type = &crypto_aead_type;
774 
775 	inst->alg.cra_aead.ivsize = enc->cra_ablkcipher.ivsize;
776 	inst->alg.cra_aead.maxauthsize = auth->digestsize;
777 
778 	inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_esn_ctx);
779 
780 	inst->alg.cra_init = crypto_authenc_esn_init_tfm;
781 	inst->alg.cra_exit = crypto_authenc_esn_exit_tfm;
782 
783 	inst->alg.cra_aead.setkey = crypto_authenc_esn_setkey;
784 	inst->alg.cra_aead.encrypt = crypto_authenc_esn_encrypt;
785 	inst->alg.cra_aead.decrypt = crypto_authenc_esn_decrypt;
786 	inst->alg.cra_aead.givencrypt = crypto_authenc_esn_givencrypt;
787 
788 out:
789 	crypto_mod_put(auth_base);
790 	return inst;
791 
792 err_drop_enc:
793 	crypto_drop_skcipher(&ctx->enc);
794 err_drop_auth:
795 	crypto_drop_ahash(&ctx->auth);
796 err_free_inst:
797 	kfree(inst);
798 out_put_auth:
799 	inst = ERR_PTR(err);
800 	goto out;
801 }
802 
crypto_authenc_esn_free(struct crypto_instance * inst)803 static void crypto_authenc_esn_free(struct crypto_instance *inst)
804 {
805 	struct authenc_esn_instance_ctx *ctx = crypto_instance_ctx(inst);
806 
807 	crypto_drop_skcipher(&ctx->enc);
808 	crypto_drop_ahash(&ctx->auth);
809 	kfree(inst);
810 }
811 
812 static struct crypto_template crypto_authenc_esn_tmpl = {
813 	.name = "authencesn",
814 	.alloc = crypto_authenc_esn_alloc,
815 	.free = crypto_authenc_esn_free,
816 	.module = THIS_MODULE,
817 };
818 
crypto_authenc_esn_module_init(void)819 static int __init crypto_authenc_esn_module_init(void)
820 {
821 	return crypto_register_template(&crypto_authenc_esn_tmpl);
822 }
823 
crypto_authenc_esn_module_exit(void)824 static void __exit crypto_authenc_esn_module_exit(void)
825 {
826 	crypto_unregister_template(&crypto_authenc_esn_tmpl);
827 }
828 
829 module_init(crypto_authenc_esn_module_init);
830 module_exit(crypto_authenc_esn_module_exit);
831 
832 MODULE_LICENSE("GPL");
833 MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>");
834 MODULE_DESCRIPTION("AEAD wrapper for IPsec with extended sequence numbers");
835