twofish_glue_3way.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. /*
  2. * Glue Code for 3-way parallel assembler optimized version of Twofish
  3. *
  4. * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
  5. *
  6. * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by:
  7. * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
  8. * CTR part based on code (crypto/ctr.c) by:
  9. * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  24. * USA
  25. *
  26. */
  27. #include <linux/crypto.h>
  28. #include <linux/init.h>
  29. #include <linux/module.h>
  30. #include <linux/types.h>
  31. #include <crypto/algapi.h>
  32. #include <crypto/twofish.h>
  33. #include <crypto/b128ops.h>
  34. #include <crypto/lrw.h>
  35. #include <crypto/xts.h>
  36. #if defined(CONFIG_CRYPTO_LRW) || defined(CONFIG_CRYPTO_LRW_MODULE)
  37. #define HAS_LRW
  38. #endif
  39. #if defined(CONFIG_CRYPTO_XTS) || defined(CONFIG_CRYPTO_XTS_MODULE)
  40. #define HAS_XTS
  41. #endif
  42. /* regular block cipher functions from twofish_x86_64 module */
  43. asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst,
  44. const u8 *src);
  45. asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst,
  46. const u8 *src);
  47. /* 3-way parallel cipher functions */
  48. asmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
  49. const u8 *src, bool xor);
  50. asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst,
  51. const u8 *src);
  52. static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
  53. const u8 *src)
  54. {
  55. __twofish_enc_blk_3way(ctx, dst, src, false);
  56. }
  57. static inline void twofish_enc_blk_xor_3way(struct twofish_ctx *ctx, u8 *dst,
  58. const u8 *src)
  59. {
  60. __twofish_enc_blk_3way(ctx, dst, src, true);
  61. }
  62. static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk,
  63. void (*fn)(struct twofish_ctx *, u8 *, const u8 *),
  64. void (*fn_3way)(struct twofish_ctx *, u8 *, const u8 *))
  65. {
  66. struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  67. unsigned int bsize = TF_BLOCK_SIZE;
  68. unsigned int nbytes;
  69. int err;
  70. err = blkcipher_walk_virt(desc, walk);
  71. while ((nbytes = walk->nbytes)) {
  72. u8 *wsrc = walk->src.virt.addr;
  73. u8 *wdst = walk->dst.virt.addr;
  74. /* Process three block batch */
  75. if (nbytes >= bsize * 3) {
  76. do {
  77. fn_3way(ctx, wdst, wsrc);
  78. wsrc += bsize * 3;
  79. wdst += bsize * 3;
  80. nbytes -= bsize * 3;
  81. } while (nbytes >= bsize * 3);
  82. if (nbytes < bsize)
  83. goto done;
  84. }
  85. /* Handle leftovers */
  86. do {
  87. fn(ctx, wdst, wsrc);
  88. wsrc += bsize;
  89. wdst += bsize;
  90. nbytes -= bsize;
  91. } while (nbytes >= bsize);
  92. done:
  93. err = blkcipher_walk_done(desc, walk, nbytes);
  94. }
  95. return err;
  96. }
  97. static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  98. struct scatterlist *src, unsigned int nbytes)
  99. {
  100. struct blkcipher_walk walk;
  101. blkcipher_walk_init(&walk, dst, src, nbytes);
  102. return ecb_crypt(desc, &walk, twofish_enc_blk, twofish_enc_blk_3way);
  103. }
  104. static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  105. struct scatterlist *src, unsigned int nbytes)
  106. {
  107. struct blkcipher_walk walk;
  108. blkcipher_walk_init(&walk, dst, src, nbytes);
  109. return ecb_crypt(desc, &walk, twofish_dec_blk, twofish_dec_blk_3way);
  110. }
  111. static struct crypto_alg blk_ecb_alg = {
  112. .cra_name = "ecb(twofish)",
  113. .cra_driver_name = "ecb-twofish-3way",
  114. .cra_priority = 300,
  115. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  116. .cra_blocksize = TF_BLOCK_SIZE,
  117. .cra_ctxsize = sizeof(struct twofish_ctx),
  118. .cra_alignmask = 0,
  119. .cra_type = &crypto_blkcipher_type,
  120. .cra_module = THIS_MODULE,
  121. .cra_list = LIST_HEAD_INIT(blk_ecb_alg.cra_list),
  122. .cra_u = {
  123. .blkcipher = {
  124. .min_keysize = TF_MIN_KEY_SIZE,
  125. .max_keysize = TF_MAX_KEY_SIZE,
  126. .setkey = twofish_setkey,
  127. .encrypt = ecb_encrypt,
  128. .decrypt = ecb_decrypt,
  129. },
  130. },
  131. };
  132. static unsigned int __cbc_encrypt(struct blkcipher_desc *desc,
  133. struct blkcipher_walk *walk)
  134. {
  135. struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  136. unsigned int bsize = TF_BLOCK_SIZE;
  137. unsigned int nbytes = walk->nbytes;
  138. u128 *src = (u128 *)walk->src.virt.addr;
  139. u128 *dst = (u128 *)walk->dst.virt.addr;
  140. u128 *iv = (u128 *)walk->iv;
  141. do {
  142. u128_xor(dst, src, iv);
  143. twofish_enc_blk(ctx, (u8 *)dst, (u8 *)dst);
  144. iv = dst;
  145. src += 1;
  146. dst += 1;
  147. nbytes -= bsize;
  148. } while (nbytes >= bsize);
  149. u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv);
  150. return nbytes;
  151. }
  152. static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  153. struct scatterlist *src, unsigned int nbytes)
  154. {
  155. struct blkcipher_walk walk;
  156. int err;
  157. blkcipher_walk_init(&walk, dst, src, nbytes);
  158. err = blkcipher_walk_virt(desc, &walk);
  159. while ((nbytes = walk.nbytes)) {
  160. nbytes = __cbc_encrypt(desc, &walk);
  161. err = blkcipher_walk_done(desc, &walk, nbytes);
  162. }
  163. return err;
  164. }
  165. static unsigned int __cbc_decrypt(struct blkcipher_desc *desc,
  166. struct blkcipher_walk *walk)
  167. {
  168. struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  169. unsigned int bsize = TF_BLOCK_SIZE;
  170. unsigned int nbytes = walk->nbytes;
  171. u128 *src = (u128 *)walk->src.virt.addr;
  172. u128 *dst = (u128 *)walk->dst.virt.addr;
  173. u128 ivs[3 - 1];
  174. u128 last_iv;
  175. /* Start of the last block. */
  176. src += nbytes / bsize - 1;
  177. dst += nbytes / bsize - 1;
  178. last_iv = *src;
  179. /* Process three block batch */
  180. if (nbytes >= bsize * 3) {
  181. do {
  182. nbytes -= bsize * (3 - 1);
  183. src -= 3 - 1;
  184. dst -= 3 - 1;
  185. ivs[0] = src[0];
  186. ivs[1] = src[1];
  187. twofish_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src);
  188. u128_xor(dst + 1, dst + 1, ivs + 0);
  189. u128_xor(dst + 2, dst + 2, ivs + 1);
  190. nbytes -= bsize;
  191. if (nbytes < bsize)
  192. goto done;
  193. u128_xor(dst, dst, src - 1);
  194. src -= 1;
  195. dst -= 1;
  196. } while (nbytes >= bsize * 3);
  197. if (nbytes < bsize)
  198. goto done;
  199. }
  200. /* Handle leftovers */
  201. for (;;) {
  202. twofish_dec_blk(ctx, (u8 *)dst, (u8 *)src);
  203. nbytes -= bsize;
  204. if (nbytes < bsize)
  205. break;
  206. u128_xor(dst, dst, src - 1);
  207. src -= 1;
  208. dst -= 1;
  209. }
  210. done:
  211. u128_xor(dst, dst, (u128 *)walk->iv);
  212. *(u128 *)walk->iv = last_iv;
  213. return nbytes;
  214. }
  215. static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  216. struct scatterlist *src, unsigned int nbytes)
  217. {
  218. struct blkcipher_walk walk;
  219. int err;
  220. blkcipher_walk_init(&walk, dst, src, nbytes);
  221. err = blkcipher_walk_virt(desc, &walk);
  222. while ((nbytes = walk.nbytes)) {
  223. nbytes = __cbc_decrypt(desc, &walk);
  224. err = blkcipher_walk_done(desc, &walk, nbytes);
  225. }
  226. return err;
  227. }
  228. static struct crypto_alg blk_cbc_alg = {
  229. .cra_name = "cbc(twofish)",
  230. .cra_driver_name = "cbc-twofish-3way",
  231. .cra_priority = 300,
  232. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  233. .cra_blocksize = TF_BLOCK_SIZE,
  234. .cra_ctxsize = sizeof(struct twofish_ctx),
  235. .cra_alignmask = 0,
  236. .cra_type = &crypto_blkcipher_type,
  237. .cra_module = THIS_MODULE,
  238. .cra_list = LIST_HEAD_INIT(blk_cbc_alg.cra_list),
  239. .cra_u = {
  240. .blkcipher = {
  241. .min_keysize = TF_MIN_KEY_SIZE,
  242. .max_keysize = TF_MAX_KEY_SIZE,
  243. .ivsize = TF_BLOCK_SIZE,
  244. .setkey = twofish_setkey,
  245. .encrypt = cbc_encrypt,
  246. .decrypt = cbc_decrypt,
  247. },
  248. },
  249. };
  250. static inline void u128_to_be128(be128 *dst, const u128 *src)
  251. {
  252. dst->a = cpu_to_be64(src->a);
  253. dst->b = cpu_to_be64(src->b);
  254. }
  255. static inline void be128_to_u128(u128 *dst, const be128 *src)
  256. {
  257. dst->a = be64_to_cpu(src->a);
  258. dst->b = be64_to_cpu(src->b);
  259. }
  260. static inline void u128_inc(u128 *i)
  261. {
  262. i->b++;
  263. if (!i->b)
  264. i->a++;
  265. }
  266. static void ctr_crypt_final(struct blkcipher_desc *desc,
  267. struct blkcipher_walk *walk)
  268. {
  269. struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  270. u8 *ctrblk = walk->iv;
  271. u8 keystream[TF_BLOCK_SIZE];
  272. u8 *src = walk->src.virt.addr;
  273. u8 *dst = walk->dst.virt.addr;
  274. unsigned int nbytes = walk->nbytes;
  275. twofish_enc_blk(ctx, keystream, ctrblk);
  276. crypto_xor(keystream, src, nbytes);
  277. memcpy(dst, keystream, nbytes);
  278. crypto_inc(ctrblk, TF_BLOCK_SIZE);
  279. }
  280. static unsigned int __ctr_crypt(struct blkcipher_desc *desc,
  281. struct blkcipher_walk *walk)
  282. {
  283. struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  284. unsigned int bsize = TF_BLOCK_SIZE;
  285. unsigned int nbytes = walk->nbytes;
  286. u128 *src = (u128 *)walk->src.virt.addr;
  287. u128 *dst = (u128 *)walk->dst.virt.addr;
  288. u128 ctrblk;
  289. be128 ctrblocks[3];
  290. be128_to_u128(&ctrblk, (be128 *)walk->iv);
  291. /* Process three block batch */
  292. if (nbytes >= bsize * 3) {
  293. do {
  294. if (dst != src) {
  295. dst[0] = src[0];
  296. dst[1] = src[1];
  297. dst[2] = src[2];
  298. }
  299. /* create ctrblks for parallel encrypt */
  300. u128_to_be128(&ctrblocks[0], &ctrblk);
  301. u128_inc(&ctrblk);
  302. u128_to_be128(&ctrblocks[1], &ctrblk);
  303. u128_inc(&ctrblk);
  304. u128_to_be128(&ctrblocks[2], &ctrblk);
  305. u128_inc(&ctrblk);
  306. twofish_enc_blk_xor_3way(ctx, (u8 *)dst,
  307. (u8 *)ctrblocks);
  308. src += 3;
  309. dst += 3;
  310. nbytes -= bsize * 3;
  311. } while (nbytes >= bsize * 3);
  312. if (nbytes < bsize)
  313. goto done;
  314. }
  315. /* Handle leftovers */
  316. do {
  317. if (dst != src)
  318. *dst = *src;
  319. u128_to_be128(&ctrblocks[0], &ctrblk);
  320. u128_inc(&ctrblk);
  321. twofish_enc_blk(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks);
  322. u128_xor(dst, dst, (u128 *)ctrblocks);
  323. src += 1;
  324. dst += 1;
  325. nbytes -= bsize;
  326. } while (nbytes >= bsize);
  327. done:
  328. u128_to_be128((be128 *)walk->iv, &ctrblk);
  329. return nbytes;
  330. }
  331. static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  332. struct scatterlist *src, unsigned int nbytes)
  333. {
  334. struct blkcipher_walk walk;
  335. int err;
  336. blkcipher_walk_init(&walk, dst, src, nbytes);
  337. err = blkcipher_walk_virt_block(desc, &walk, TF_BLOCK_SIZE);
  338. while ((nbytes = walk.nbytes) >= TF_BLOCK_SIZE) {
  339. nbytes = __ctr_crypt(desc, &walk);
  340. err = blkcipher_walk_done(desc, &walk, nbytes);
  341. }
  342. if (walk.nbytes) {
  343. ctr_crypt_final(desc, &walk);
  344. err = blkcipher_walk_done(desc, &walk, 0);
  345. }
  346. return err;
  347. }
  348. static struct crypto_alg blk_ctr_alg = {
  349. .cra_name = "ctr(twofish)",
  350. .cra_driver_name = "ctr-twofish-3way",
  351. .cra_priority = 300,
  352. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  353. .cra_blocksize = 1,
  354. .cra_ctxsize = sizeof(struct twofish_ctx),
  355. .cra_alignmask = 0,
  356. .cra_type = &crypto_blkcipher_type,
  357. .cra_module = THIS_MODULE,
  358. .cra_list = LIST_HEAD_INIT(blk_ctr_alg.cra_list),
  359. .cra_u = {
  360. .blkcipher = {
  361. .min_keysize = TF_MIN_KEY_SIZE,
  362. .max_keysize = TF_MAX_KEY_SIZE,
  363. .ivsize = TF_BLOCK_SIZE,
  364. .setkey = twofish_setkey,
  365. .encrypt = ctr_crypt,
  366. .decrypt = ctr_crypt,
  367. },
  368. },
  369. };
  370. #if defined(HAS_LRW) || defined(HAS_XTS)
  371. static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
  372. {
  373. const unsigned int bsize = TF_BLOCK_SIZE;
  374. struct twofish_ctx *ctx = priv;
  375. int i;
  376. if (nbytes == 3 * bsize) {
  377. twofish_enc_blk_3way(ctx, srcdst, srcdst);
  378. return;
  379. }
  380. for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
  381. twofish_enc_blk(ctx, srcdst, srcdst);
  382. }
  383. static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
  384. {
  385. const unsigned int bsize = TF_BLOCK_SIZE;
  386. struct twofish_ctx *ctx = priv;
  387. int i;
  388. if (nbytes == 3 * bsize) {
  389. twofish_dec_blk_3way(ctx, srcdst, srcdst);
  390. return;
  391. }
  392. for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
  393. twofish_dec_blk(ctx, srcdst, srcdst);
  394. }
  395. #endif
  396. #ifdef HAS_LRW
  397. struct twofish_lrw_ctx {
  398. struct lrw_table_ctx lrw_table;
  399. struct twofish_ctx twofish_ctx;
  400. };
  401. static int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key,
  402. unsigned int keylen)
  403. {
  404. struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
  405. int err;
  406. err = __twofish_setkey(&ctx->twofish_ctx, key, keylen - TF_BLOCK_SIZE,
  407. &tfm->crt_flags);
  408. if (err)
  409. return err;
  410. return lrw_init_table(&ctx->lrw_table, key + keylen - TF_BLOCK_SIZE);
  411. }
  412. static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  413. struct scatterlist *src, unsigned int nbytes)
  414. {
  415. struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  416. be128 buf[3];
  417. struct lrw_crypt_req req = {
  418. .tbuf = buf,
  419. .tbuflen = sizeof(buf),
  420. .table_ctx = &ctx->lrw_table,
  421. .crypt_ctx = &ctx->twofish_ctx,
  422. .crypt_fn = encrypt_callback,
  423. };
  424. return lrw_crypt(desc, dst, src, nbytes, &req);
  425. }
  426. static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  427. struct scatterlist *src, unsigned int nbytes)
  428. {
  429. struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  430. be128 buf[3];
  431. struct lrw_crypt_req req = {
  432. .tbuf = buf,
  433. .tbuflen = sizeof(buf),
  434. .table_ctx = &ctx->lrw_table,
  435. .crypt_ctx = &ctx->twofish_ctx,
  436. .crypt_fn = decrypt_callback,
  437. };
  438. return lrw_crypt(desc, dst, src, nbytes, &req);
  439. }
  440. static void lrw_exit_tfm(struct crypto_tfm *tfm)
  441. {
  442. struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
  443. lrw_free_table(&ctx->lrw_table);
  444. }
  445. static struct crypto_alg blk_lrw_alg = {
  446. .cra_name = "lrw(twofish)",
  447. .cra_driver_name = "lrw-twofish-3way",
  448. .cra_priority = 300,
  449. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  450. .cra_blocksize = TF_BLOCK_SIZE,
  451. .cra_ctxsize = sizeof(struct twofish_lrw_ctx),
  452. .cra_alignmask = 0,
  453. .cra_type = &crypto_blkcipher_type,
  454. .cra_module = THIS_MODULE,
  455. .cra_list = LIST_HEAD_INIT(blk_lrw_alg.cra_list),
  456. .cra_exit = lrw_exit_tfm,
  457. .cra_u = {
  458. .blkcipher = {
  459. .min_keysize = TF_MIN_KEY_SIZE + TF_BLOCK_SIZE,
  460. .max_keysize = TF_MAX_KEY_SIZE + TF_BLOCK_SIZE,
  461. .ivsize = TF_BLOCK_SIZE,
  462. .setkey = lrw_twofish_setkey,
  463. .encrypt = lrw_encrypt,
  464. .decrypt = lrw_decrypt,
  465. },
  466. },
  467. };
  468. #endif
  469. #ifdef HAS_XTS
  470. struct twofish_xts_ctx {
  471. struct twofish_ctx tweak_ctx;
  472. struct twofish_ctx crypt_ctx;
  473. };
  474. static int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key,
  475. unsigned int keylen)
  476. {
  477. struct twofish_xts_ctx *ctx = crypto_tfm_ctx(tfm);
  478. u32 *flags = &tfm->crt_flags;
  479. int err;
  480. /* key consists of keys of equal size concatenated, therefore
  481. * the length must be even
  482. */
  483. if (keylen % 2) {
  484. *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
  485. return -EINVAL;
  486. }
  487. /* first half of xts-key is for crypt */
  488. err = __twofish_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
  489. if (err)
  490. return err;
  491. /* second half of xts-key is for tweak */
  492. return __twofish_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2,
  493. flags);
  494. }
  495. static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  496. struct scatterlist *src, unsigned int nbytes)
  497. {
  498. struct twofish_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  499. be128 buf[3];
  500. struct xts_crypt_req req = {
  501. .tbuf = buf,
  502. .tbuflen = sizeof(buf),
  503. .tweak_ctx = &ctx->tweak_ctx,
  504. .tweak_fn = XTS_TWEAK_CAST(twofish_enc_blk),
  505. .crypt_ctx = &ctx->crypt_ctx,
  506. .crypt_fn = encrypt_callback,
  507. };
  508. return xts_crypt(desc, dst, src, nbytes, &req);
  509. }
  510. static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  511. struct scatterlist *src, unsigned int nbytes)
  512. {
  513. struct twofish_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  514. be128 buf[3];
  515. struct xts_crypt_req req = {
  516. .tbuf = buf,
  517. .tbuflen = sizeof(buf),
  518. .tweak_ctx = &ctx->tweak_ctx,
  519. .tweak_fn = XTS_TWEAK_CAST(twofish_enc_blk),
  520. .crypt_ctx = &ctx->crypt_ctx,
  521. .crypt_fn = decrypt_callback,
  522. };
  523. return xts_crypt(desc, dst, src, nbytes, &req);
  524. }
  525. static struct crypto_alg blk_xts_alg = {
  526. .cra_name = "xts(twofish)",
  527. .cra_driver_name = "xts-twofish-3way",
  528. .cra_priority = 300,
  529. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  530. .cra_blocksize = TF_BLOCK_SIZE,
  531. .cra_ctxsize = sizeof(struct twofish_xts_ctx),
  532. .cra_alignmask = 0,
  533. .cra_type = &crypto_blkcipher_type,
  534. .cra_module = THIS_MODULE,
  535. .cra_list = LIST_HEAD_INIT(blk_xts_alg.cra_list),
  536. .cra_u = {
  537. .blkcipher = {
  538. .min_keysize = TF_MIN_KEY_SIZE * 2,
  539. .max_keysize = TF_MAX_KEY_SIZE * 2,
  540. .ivsize = TF_BLOCK_SIZE,
  541. .setkey = xts_twofish_setkey,
  542. .encrypt = xts_encrypt,
  543. .decrypt = xts_decrypt,
  544. },
  545. },
  546. };
  547. #endif
  548. int __init init(void)
  549. {
  550. int err;
  551. err = crypto_register_alg(&blk_ecb_alg);
  552. if (err)
  553. goto ecb_err;
  554. err = crypto_register_alg(&blk_cbc_alg);
  555. if (err)
  556. goto cbc_err;
  557. err = crypto_register_alg(&blk_ctr_alg);
  558. if (err)
  559. goto ctr_err;
  560. #ifdef HAS_LRW
  561. err = crypto_register_alg(&blk_lrw_alg);
  562. if (err)
  563. goto blk_lrw_err;
  564. #endif
  565. #ifdef HAS_XTS
  566. err = crypto_register_alg(&blk_xts_alg);
  567. if (err)
  568. goto blk_xts_err;
  569. #endif
  570. return 0;
  571. #ifdef HAS_XTS
  572. crypto_unregister_alg(&blk_xts_alg);
  573. blk_xts_err:
  574. #endif
  575. #ifdef HAS_LRW
  576. crypto_unregister_alg(&blk_lrw_alg);
  577. blk_lrw_err:
  578. #endif
  579. crypto_unregister_alg(&blk_ctr_alg);
  580. ctr_err:
  581. crypto_unregister_alg(&blk_cbc_alg);
  582. cbc_err:
  583. crypto_unregister_alg(&blk_ecb_alg);
  584. ecb_err:
  585. return err;
  586. }
  587. void __exit fini(void)
  588. {
  589. #ifdef HAS_XTS
  590. crypto_unregister_alg(&blk_xts_alg);
  591. #endif
  592. #ifdef HAS_LRW
  593. crypto_unregister_alg(&blk_lrw_alg);
  594. #endif
  595. crypto_unregister_alg(&blk_ctr_alg);
  596. crypto_unregister_alg(&blk_cbc_alg);
  597. crypto_unregister_alg(&blk_ecb_alg);
  598. }
  599. module_init(init);
  600. module_exit(fini);
  601. MODULE_LICENSE("GPL");
  602. MODULE_DESCRIPTION("Twofish Cipher Algorithm, 3-way parallel asm optimized");
  603. MODULE_ALIAS("twofish");
  604. MODULE_ALIAS("twofish-asm");