PageRenderTime 341ms CodeModel.GetById 19ms RepoModel.GetById 2ms app.codeStats 0ms

/crypto/authenc.c

https://bitbucket.org/cresqo/cm7-p500-kernel
C | 725 lines | 578 code | 136 blank | 11 comment | 47 complexity | 12b75c27713b88b3b1fcf0c251dbf386 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
  1. /*
  2. * Authenc: Simple AEAD wrapper for IPsec
  3. *
  4. * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the Free
  8. * Software Foundation; either version 2 of the License, or (at your option)
  9. * any later version.
  10. *
  11. */
  12. #include <crypto/aead.h>
  13. #include <crypto/internal/hash.h>
  14. #include <crypto/internal/skcipher.h>
  15. #include <crypto/authenc.h>
  16. #include <crypto/scatterwalk.h>
  17. #include <linux/err.h>
  18. #include <linux/init.h>
  19. #include <linux/kernel.h>
  20. #include <linux/module.h>
  21. #include <linux/rtnetlink.h>
  22. #include <linux/slab.h>
  23. #include <linux/spinlock.h>
  24. typedef u8 *(*authenc_ahash_t)(struct aead_request *req, unsigned int flags);
  25. struct authenc_instance_ctx {
  26. struct crypto_ahash_spawn auth;
  27. struct crypto_skcipher_spawn enc;
  28. };
  29. struct crypto_authenc_ctx {
  30. unsigned int reqoff;
  31. struct crypto_ahash *auth;
  32. struct crypto_ablkcipher *enc;
  33. };
  34. struct authenc_request_ctx {
  35. unsigned int cryptlen;
  36. struct scatterlist *sg;
  37. struct scatterlist asg[2];
  38. struct scatterlist cipher[2];
  39. crypto_completion_t complete;
  40. crypto_completion_t update_complete;
  41. char tail[];
  42. };
  43. static void authenc_request_complete(struct aead_request *req, int err)
  44. {
  45. if (err != -EINPROGRESS)
  46. aead_request_complete(req, err);
  47. }
  48. static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
  49. unsigned int keylen)
  50. {
  51. unsigned int authkeylen;
  52. unsigned int enckeylen;
  53. struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
  54. struct crypto_ahash *auth = ctx->auth;
  55. struct crypto_ablkcipher *enc = ctx->enc;
  56. struct rtattr *rta = (void *)key;
  57. struct crypto_authenc_key_param *param;
  58. int err = -EINVAL;
  59. if (!RTA_OK(rta, keylen))
  60. goto badkey;
  61. if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
  62. goto badkey;
  63. if (RTA_PAYLOAD(rta) < sizeof(*param))
  64. goto badkey;
  65. param = RTA_DATA(rta);
  66. enckeylen = be32_to_cpu(param->enckeylen);
  67. key += RTA_ALIGN(rta->rta_len);
  68. keylen -= RTA_ALIGN(rta->rta_len);
  69. if (keylen < enckeylen)
  70. goto badkey;
  71. authkeylen = keylen - enckeylen;
  72. crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
  73. crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc) &
  74. CRYPTO_TFM_REQ_MASK);
  75. err = crypto_ahash_setkey(auth, key, authkeylen);
  76. crypto_aead_set_flags(authenc, crypto_ahash_get_flags(auth) &
  77. CRYPTO_TFM_RES_MASK);
  78. if (err)
  79. goto out;
  80. crypto_ablkcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK);
  81. crypto_ablkcipher_set_flags(enc, crypto_aead_get_flags(authenc) &
  82. CRYPTO_TFM_REQ_MASK);
  83. err = crypto_ablkcipher_setkey(enc, key + authkeylen, enckeylen);
  84. crypto_aead_set_flags(authenc, crypto_ablkcipher_get_flags(enc) &
  85. CRYPTO_TFM_RES_MASK);
  86. out:
  87. return err;
  88. badkey:
  89. crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
  90. goto out;
  91. }
  92. static void authenc_chain(struct scatterlist *head, struct scatterlist *sg,
  93. int chain)
  94. {
  95. if (chain) {
  96. head->length += sg->length;
  97. sg = scatterwalk_sg_next(sg);
  98. }
  99. if (sg)
  100. scatterwalk_sg_chain(head, 2, sg);
  101. else
  102. sg_mark_end(head);
  103. }
  104. static void authenc_geniv_ahash_update_done(struct crypto_async_request *areq,
  105. int err)
  106. {
  107. struct aead_request *req = areq->data;
  108. struct crypto_aead *authenc = crypto_aead_reqtfm(req);
  109. struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
  110. struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
  111. struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
  112. if (err)
  113. goto out;
  114. ahash_request_set_crypt(ahreq, areq_ctx->sg, ahreq->result,
  115. areq_ctx->cryptlen);
  116. ahash_request_set_callback(ahreq, aead_request_flags(req) &
  117. CRYPTO_TFM_REQ_MAY_SLEEP,
  118. areq_ctx->complete, req);
  119. err = crypto_ahash_finup(ahreq);
  120. if (err)
  121. goto out;
  122. scatterwalk_map_and_copy(ahreq->result, areq_ctx->sg,
  123. areq_ctx->cryptlen,
  124. crypto_aead_authsize(authenc), 1);
  125. out:
  126. authenc_request_complete(req, err);
  127. }
  128. static void authenc_geniv_ahash_done(struct crypto_async_request *areq, int err)
  129. {
  130. struct aead_request *req = areq->data;
  131. struct crypto_aead *authenc = crypto_aead_reqtfm(req);
  132. struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
  133. struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
  134. struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
  135. if (err)
  136. goto out;
  137. scatterwalk_map_and_copy(ahreq->result, areq_ctx->sg,
  138. areq_ctx->cryptlen,
  139. crypto_aead_authsize(authenc), 1);
  140. out:
  141. aead_request_complete(req, err);
  142. }
  143. static void authenc_verify_ahash_update_done(struct crypto_async_request *areq,
  144. int err)
  145. {
  146. u8 *ihash;
  147. unsigned int authsize;
  148. struct ablkcipher_request *abreq;
  149. struct aead_request *req = areq->data;
  150. struct crypto_aead *authenc = crypto_aead_reqtfm(req);
  151. struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
  152. struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
  153. struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
  154. unsigned int cryptlen = req->cryptlen;
  155. if (err)
  156. goto out;
  157. ahash_request_set_crypt(ahreq, areq_ctx->sg, ahreq->result,
  158. areq_ctx->cryptlen);
  159. ahash_request_set_callback(ahreq, aead_request_flags(req) &
  160. CRYPTO_TFM_REQ_MAY_SLEEP,
  161. areq_ctx->complete, req);
  162. err = crypto_ahash_finup(ahreq);
  163. if (err)
  164. goto out;
  165. authsize = crypto_aead_authsize(authenc);
  166. cryptlen -= authsize;
  167. ihash = ahreq->result + authsize;
  168. scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
  169. authsize, 0);
  170. err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
  171. if (err)
  172. goto out;
  173. abreq = aead_request_ctx(req);
  174. ablkcipher_request_set_tfm(abreq, ctx->enc);
  175. ablkcipher_request_set_callback(abreq, aead_request_flags(req),
  176. req->base.complete, req->base.data);
  177. ablkcipher_request_set_crypt(abreq, req->src, req->dst,
  178. cryptlen, req->iv);
  179. err = crypto_ablkcipher_decrypt(abreq);
  180. out:
  181. authenc_request_complete(req, err);
  182. }
  183. static void authenc_verify_ahash_done(struct crypto_async_request *areq,
  184. int err)
  185. {
  186. u8 *ihash;
  187. unsigned int authsize;
  188. struct ablkcipher_request *abreq;
  189. struct aead_request *req = areq->data;
  190. struct crypto_aead *authenc = crypto_aead_reqtfm(req);
  191. struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
  192. struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
  193. struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
  194. unsigned int cryptlen = req->cryptlen;
  195. if (err)
  196. goto out;
  197. authsize = crypto_aead_authsize(authenc);
  198. cryptlen -= authsize;
  199. ihash = ahreq->result + authsize;
  200. scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
  201. authsize, 0);
  202. err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
  203. if (err)
  204. goto out;
  205. abreq = aead_request_ctx(req);
  206. ablkcipher_request_set_tfm(abreq, ctx->enc);
  207. ablkcipher_request_set_callback(abreq, aead_request_flags(req),
  208. req->base.complete, req->base.data);
  209. ablkcipher_request_set_crypt(abreq, req->src, req->dst,
  210. cryptlen, req->iv);
  211. err = crypto_ablkcipher_decrypt(abreq);
  212. out:
  213. authenc_request_complete(req, err);
  214. }
  215. static u8 *crypto_authenc_ahash_fb(struct aead_request *req, unsigned int flags)
  216. {
  217. struct crypto_aead *authenc = crypto_aead_reqtfm(req);
  218. struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
  219. struct crypto_ahash *auth = ctx->auth;
  220. struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
  221. struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
  222. u8 *hash = areq_ctx->tail;
  223. int err;
  224. hash = (u8 *)ALIGN((unsigned long)hash + crypto_ahash_alignmask(auth),
  225. crypto_ahash_alignmask(auth) + 1);
  226. ahash_request_set_tfm(ahreq, auth);
  227. err = crypto_ahash_init(ahreq);
  228. if (err)
  229. return ERR_PTR(err);
  230. ahash_request_set_crypt(ahreq, req->assoc, hash, req->assoclen);
  231. ahash_request_set_callback(ahreq, aead_request_flags(req) & flags,
  232. areq_ctx->update_complete, req);
  233. err = crypto_ahash_update(ahreq);
  234. if (err)
  235. return ERR_PTR(err);
  236. ahash_request_set_crypt(ahreq, areq_ctx->sg, hash,
  237. areq_ctx->cryptlen);
  238. ahash_request_set_callback(ahreq, aead_request_flags(req) & flags,
  239. areq_ctx->complete, req);
  240. err = crypto_ahash_finup(ahreq);
  241. if (err)
  242. return ERR_PTR(err);
  243. return hash;
  244. }
  245. static u8 *crypto_authenc_ahash(struct aead_request *req, unsigned int flags)
  246. {
  247. struct crypto_aead *authenc = crypto_aead_reqtfm(req);
  248. struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
  249. struct crypto_ahash *auth = ctx->auth;
  250. struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
  251. struct ahash_request *ahreq = (void *)(areq_ctx->tail + ctx->reqoff);
  252. u8 *hash = areq_ctx->tail;
  253. int err;
  254. hash = (u8 *)ALIGN((unsigned long)hash + crypto_ahash_alignmask(auth),
  255. crypto_ahash_alignmask(auth) + 1);
  256. ahash_request_set_tfm(ahreq, auth);
  257. ahash_request_set_crypt(ahreq, areq_ctx->sg, hash,
  258. areq_ctx->cryptlen);
  259. ahash_request_set_callback(ahreq, aead_request_flags(req) & flags,
  260. areq_ctx->complete, req);
  261. err = crypto_ahash_digest(ahreq);
  262. if (err)
  263. return ERR_PTR(err);
  264. return hash;
  265. }
  266. static int crypto_authenc_genicv(struct aead_request *req, u8 *iv,
  267. unsigned int flags)
  268. {
  269. struct crypto_aead *authenc = crypto_aead_reqtfm(req);
  270. struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
  271. struct scatterlist *dst = req->dst;
  272. struct scatterlist *assoc = req->assoc;
  273. struct scatterlist *cipher = areq_ctx->cipher;
  274. struct scatterlist *asg = areq_ctx->asg;
  275. unsigned int ivsize = crypto_aead_ivsize(authenc);
  276. unsigned int cryptlen = req->cryptlen;
  277. authenc_ahash_t authenc_ahash_fn = crypto_authenc_ahash_fb;
  278. struct page *dstp;
  279. u8 *vdst;
  280. u8 *hash;
  281. dstp = sg_page(dst);
  282. vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset;
  283. if (ivsize) {
  284. sg_init_table(cipher, 2);
  285. sg_set_buf(cipher, iv, ivsize);
  286. authenc_chain(cipher, dst, vdst == iv + ivsize);
  287. dst = cipher;
  288. cryptlen += ivsize;
  289. }
  290. if (sg_is_last(assoc)) {
  291. authenc_ahash_fn = crypto_authenc_ahash;
  292. sg_init_table(asg, 2);
  293. sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset);
  294. authenc_chain(asg, dst, 0);
  295. dst = asg;
  296. cryptlen += req->assoclen;
  297. }
  298. areq_ctx->cryptlen = cryptlen;
  299. areq_ctx->sg = dst;
  300. areq_ctx->complete = authenc_geniv_ahash_done;
  301. areq_ctx->update_complete = authenc_geniv_ahash_update_done;
  302. hash = authenc_ahash_fn(req, flags);
  303. if (IS_ERR(hash))
  304. return PTR_ERR(hash);
  305. scatterwalk_map_and_copy(hash, dst, cryptlen,
  306. crypto_aead_authsize(authenc), 1);
  307. return 0;
  308. }
  309. static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
  310. int err)
  311. {
  312. struct aead_request *areq = req->data;
  313. if (!err) {
  314. struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
  315. struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
  316. struct ablkcipher_request *abreq = aead_request_ctx(areq);
  317. u8 *iv = (u8 *)(abreq + 1) +
  318. crypto_ablkcipher_reqsize(ctx->enc);
  319. err = crypto_authenc_genicv(areq, iv, 0);
  320. }
  321. authenc_request_complete(areq, err);
  322. }
  323. static int crypto_authenc_encrypt(struct aead_request *req)
  324. {
  325. struct crypto_aead *authenc = crypto_aead_reqtfm(req);
  326. struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
  327. struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
  328. struct crypto_ablkcipher *enc = ctx->enc;
  329. struct scatterlist *dst = req->dst;
  330. unsigned int cryptlen = req->cryptlen;
  331. struct ablkcipher_request *abreq = (void *)(areq_ctx->tail
  332. + ctx->reqoff);
  333. u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(enc);
  334. int err;
  335. ablkcipher_request_set_tfm(abreq, enc);
  336. ablkcipher_request_set_callback(abreq, aead_request_flags(req),
  337. crypto_authenc_encrypt_done, req);
  338. ablkcipher_request_set_crypt(abreq, req->src, dst, cryptlen, req->iv);
  339. memcpy(iv, req->iv, crypto_aead_ivsize(authenc));
  340. err = crypto_ablkcipher_encrypt(abreq);
  341. if (err)
  342. return err;
  343. return crypto_authenc_genicv(req, iv, CRYPTO_TFM_REQ_MAY_SLEEP);
  344. }
  345. static void crypto_authenc_givencrypt_done(struct crypto_async_request *req,
  346. int err)
  347. {
  348. struct aead_request *areq = req->data;
  349. if (!err) {
  350. struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);
  351. err = crypto_authenc_genicv(areq, greq->giv, 0);
  352. }
  353. authenc_request_complete(areq, err);
  354. }
  355. static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req)
  356. {
  357. struct crypto_aead *authenc = aead_givcrypt_reqtfm(req);
  358. struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
  359. struct aead_request *areq = &req->areq;
  360. struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);
  361. u8 *iv = req->giv;
  362. int err;
  363. skcipher_givcrypt_set_tfm(greq, ctx->enc);
  364. skcipher_givcrypt_set_callback(greq, aead_request_flags(areq),
  365. crypto_authenc_givencrypt_done, areq);
  366. skcipher_givcrypt_set_crypt(greq, areq->src, areq->dst, areq->cryptlen,
  367. areq->iv);
  368. skcipher_givcrypt_set_giv(greq, iv, req->seq);
  369. err = crypto_skcipher_givencrypt(greq);
  370. if (err)
  371. return err;
  372. return crypto_authenc_genicv(areq, iv, CRYPTO_TFM_REQ_MAY_SLEEP);
  373. }
  374. static int crypto_authenc_verify(struct aead_request *req,
  375. authenc_ahash_t authenc_ahash_fn)
  376. {
  377. struct crypto_aead *authenc = crypto_aead_reqtfm(req);
  378. struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
  379. u8 *ohash;
  380. u8 *ihash;
  381. unsigned int authsize;
  382. areq_ctx->complete = authenc_verify_ahash_done;
  383. areq_ctx->update_complete = authenc_verify_ahash_update_done;
  384. ohash = authenc_ahash_fn(req, CRYPTO_TFM_REQ_MAY_SLEEP);
  385. if (IS_ERR(ohash))
  386. return PTR_ERR(ohash);
  387. authsize = crypto_aead_authsize(authenc);
  388. ihash = ohash + authsize;
  389. scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
  390. authsize, 0);
  391. return memcmp(ihash, ohash, authsize) ? -EBADMSG : 0;
  392. }
  393. static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,
  394. unsigned int cryptlen)
  395. {
  396. struct crypto_aead *authenc = crypto_aead_reqtfm(req);
  397. struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
  398. struct scatterlist *src = req->src;
  399. struct scatterlist *assoc = req->assoc;
  400. struct scatterlist *cipher = areq_ctx->cipher;
  401. struct scatterlist *asg = areq_ctx->asg;
  402. unsigned int ivsize = crypto_aead_ivsize(authenc);
  403. authenc_ahash_t authenc_ahash_fn = crypto_authenc_ahash_fb;
  404. struct page *srcp;
  405. u8 *vsrc;
  406. srcp = sg_page(src);
  407. vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset;
  408. if (ivsize) {
  409. sg_init_table(cipher, 2);
  410. sg_set_buf(cipher, iv, ivsize);
  411. authenc_chain(cipher, src, vsrc == iv + ivsize);
  412. src = cipher;
  413. cryptlen += ivsize;
  414. }
  415. if (sg_is_last(assoc)) {
  416. authenc_ahash_fn = crypto_authenc_ahash;
  417. sg_init_table(asg, 2);
  418. sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset);
  419. authenc_chain(asg, src, 0);
  420. src = asg;
  421. cryptlen += req->assoclen;
  422. }
  423. areq_ctx->cryptlen = cryptlen;
  424. areq_ctx->sg = src;
  425. return crypto_authenc_verify(req, authenc_ahash_fn);
  426. }
  427. static int crypto_authenc_decrypt(struct aead_request *req)
  428. {
  429. struct crypto_aead *authenc = crypto_aead_reqtfm(req);
  430. struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
  431. struct ablkcipher_request *abreq = aead_request_ctx(req);
  432. unsigned int cryptlen = req->cryptlen;
  433. unsigned int authsize = crypto_aead_authsize(authenc);
  434. u8 *iv = req->iv;
  435. int err;
  436. if (cryptlen < authsize)
  437. return -EINVAL;
  438. cryptlen -= authsize;
  439. err = crypto_authenc_iverify(req, iv, cryptlen);
  440. if (err)
  441. return err;
  442. ablkcipher_request_set_tfm(abreq, ctx->enc);
  443. ablkcipher_request_set_callback(abreq, aead_request_flags(req),
  444. req->base.complete, req->base.data);
  445. ablkcipher_request_set_crypt(abreq, req->src, req->dst, cryptlen, iv);
  446. return crypto_ablkcipher_decrypt(abreq);
  447. }
  448. static int crypto_authenc_init_tfm(struct crypto_tfm *tfm)
  449. {
  450. struct crypto_instance *inst = crypto_tfm_alg_instance(tfm);
  451. struct authenc_instance_ctx *ictx = crypto_instance_ctx(inst);
  452. struct crypto_authenc_ctx *ctx = crypto_tfm_ctx(tfm);
  453. struct crypto_ahash *auth;
  454. struct crypto_ablkcipher *enc;
  455. int err;
  456. auth = crypto_spawn_ahash(&ictx->auth);
  457. if (IS_ERR(auth))
  458. return PTR_ERR(auth);
  459. enc = crypto_spawn_skcipher(&ictx->enc);
  460. err = PTR_ERR(enc);
  461. if (IS_ERR(enc))
  462. goto err_free_ahash;
  463. ctx->auth = auth;
  464. ctx->enc = enc;
  465. ctx->reqoff = ALIGN(2 * crypto_ahash_digestsize(auth) +
  466. crypto_ahash_alignmask(auth),
  467. crypto_ahash_alignmask(auth) + 1) +
  468. crypto_ablkcipher_ivsize(enc);
  469. tfm->crt_aead.reqsize = sizeof(struct authenc_request_ctx) +
  470. ctx->reqoff +
  471. max_t(unsigned int,
  472. crypto_ahash_reqsize(auth) +
  473. sizeof(struct ahash_request),
  474. sizeof(struct skcipher_givcrypt_request) +
  475. crypto_ablkcipher_reqsize(enc));
  476. return 0;
  477. err_free_ahash:
  478. crypto_free_ahash(auth);
  479. return err;
  480. }
  481. static void crypto_authenc_exit_tfm(struct crypto_tfm *tfm)
  482. {
  483. struct crypto_authenc_ctx *ctx = crypto_tfm_ctx(tfm);
  484. crypto_free_ahash(ctx->auth);
  485. crypto_free_ablkcipher(ctx->enc);
  486. }
  487. static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb)
  488. {
  489. struct crypto_attr_type *algt;
  490. struct crypto_instance *inst;
  491. struct hash_alg_common *auth;
  492. struct crypto_alg *auth_base;
  493. struct crypto_alg *enc;
  494. struct authenc_instance_ctx *ctx;
  495. const char *enc_name;
  496. int err;
  497. algt = crypto_get_attr_type(tb);
  498. err = PTR_ERR(algt);
  499. if (IS_ERR(algt))
  500. return ERR_PTR(err);
  501. if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
  502. return ERR_PTR(-EINVAL);
  503. auth = ahash_attr_alg(tb[1], CRYPTO_ALG_TYPE_HASH,
  504. CRYPTO_ALG_TYPE_AHASH_MASK);
  505. if (IS_ERR(auth))
  506. return ERR_PTR(PTR_ERR(auth));
  507. auth_base = &auth->base;
  508. enc_name = crypto_attr_alg_name(tb[2]);
  509. err = PTR_ERR(enc_name);
  510. if (IS_ERR(enc_name))
  511. goto out_put_auth;
  512. inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
  513. err = -ENOMEM;
  514. if (!inst)
  515. goto out_put_auth;
  516. ctx = crypto_instance_ctx(inst);
  517. err = crypto_init_ahash_spawn(&ctx->auth, auth, inst);
  518. if (err)
  519. goto err_free_inst;
  520. crypto_set_skcipher_spawn(&ctx->enc, inst);
  521. err = crypto_grab_skcipher(&ctx->enc, enc_name, 0,
  522. crypto_requires_sync(algt->type,
  523. algt->mask));
  524. if (err)
  525. goto err_drop_auth;
  526. enc = crypto_skcipher_spawn_alg(&ctx->enc);
  527. err = -ENAMETOOLONG;
  528. if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
  529. "authenc(%s,%s)", auth_base->cra_name, enc->cra_name) >=
  530. CRYPTO_MAX_ALG_NAME)
  531. goto err_drop_enc;
  532. if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
  533. "authenc(%s,%s)", auth_base->cra_driver_name,
  534. enc->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
  535. goto err_drop_enc;
  536. inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD;
  537. inst->alg.cra_flags |= enc->cra_flags & CRYPTO_ALG_ASYNC;
  538. inst->alg.cra_priority = enc->cra_priority *
  539. 10 + auth_base->cra_priority;
  540. inst->alg.cra_blocksize = enc->cra_blocksize;
  541. inst->alg.cra_alignmask = auth_base->cra_alignmask | enc->cra_alignmask;
  542. inst->alg.cra_type = &crypto_aead_type;
  543. inst->alg.cra_aead.ivsize = enc->cra_ablkcipher.ivsize;
  544. inst->alg.cra_aead.maxauthsize = auth->digestsize;
  545. inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_ctx);
  546. inst->alg.cra_init = crypto_authenc_init_tfm;
  547. inst->alg.cra_exit = crypto_authenc_exit_tfm;
  548. inst->alg.cra_aead.setkey = crypto_authenc_setkey;
  549. inst->alg.cra_aead.encrypt = crypto_authenc_encrypt;
  550. inst->alg.cra_aead.decrypt = crypto_authenc_decrypt;
  551. inst->alg.cra_aead.givencrypt = crypto_authenc_givencrypt;
  552. out:
  553. crypto_mod_put(auth_base);
  554. return inst;
  555. err_drop_enc:
  556. crypto_drop_skcipher(&ctx->enc);
  557. err_drop_auth:
  558. crypto_drop_ahash(&ctx->auth);
  559. err_free_inst:
  560. kfree(inst);
  561. out_put_auth:
  562. inst = ERR_PTR(err);
  563. goto out;
  564. }
  565. static void crypto_authenc_free(struct crypto_instance *inst)
  566. {
  567. struct authenc_instance_ctx *ctx = crypto_instance_ctx(inst);
  568. crypto_drop_skcipher(&ctx->enc);
  569. crypto_drop_ahash(&ctx->auth);
  570. kfree(inst);
  571. }
  572. static struct crypto_template crypto_authenc_tmpl = {
  573. .name = "authenc",
  574. .alloc = crypto_authenc_alloc,
  575. .free = crypto_authenc_free,
  576. .module = THIS_MODULE,
  577. };
  578. static int __init crypto_authenc_module_init(void)
  579. {
  580. return crypto_register_template(&crypto_authenc_tmpl);
  581. }
  582. static void __exit crypto_authenc_module_exit(void)
  583. {
  584. crypto_unregister_template(&crypto_authenc_tmpl);
  585. }
  586. module_init(crypto_authenc_module_init);
  587. module_exit(crypto_authenc_module_exit);
  588. MODULE_LICENSE("GPL");
  589. MODULE_DESCRIPTION("Simple AEAD wrapper for IPsec");