twofish_glue_3way.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  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. /* regular block cipher functions from twofish_x86_64 module */
  35. asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst,
  36. const u8 *src);
  37. asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst,
  38. const u8 *src);
  39. /* 3-way parallel cipher functions */
  40. asmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
  41. const u8 *src, bool xor);
  42. asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst,
  43. const u8 *src);
  44. static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
  45. const u8 *src)
  46. {
  47. __twofish_enc_blk_3way(ctx, dst, src, false);
  48. }
  49. static inline void twofish_enc_blk_xor_3way(struct twofish_ctx *ctx, u8 *dst,
  50. const u8 *src)
  51. {
  52. __twofish_enc_blk_3way(ctx, dst, src, true);
  53. }
  54. static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk,
  55. void (*fn)(struct twofish_ctx *, u8 *, const u8 *),
  56. void (*fn_3way)(struct twofish_ctx *, u8 *, const u8 *))
  57. {
  58. struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  59. unsigned int bsize = TF_BLOCK_SIZE;
  60. unsigned int nbytes;
  61. int err;
  62. err = blkcipher_walk_virt(desc, walk);
  63. while ((nbytes = walk->nbytes)) {
  64. u8 *wsrc = walk->src.virt.addr;
  65. u8 *wdst = walk->dst.virt.addr;
  66. /* Process three block batch */
  67. if (nbytes >= bsize * 3) {
  68. do {
  69. fn_3way(ctx, wdst, wsrc);
  70. wsrc += bsize * 3;
  71. wdst += bsize * 3;
  72. nbytes -= bsize * 3;
  73. } while (nbytes >= bsize * 3);
  74. if (nbytes < bsize)
  75. goto done;
  76. }
  77. /* Handle leftovers */
  78. do {
  79. fn(ctx, wdst, wsrc);
  80. wsrc += bsize;
  81. wdst += bsize;
  82. nbytes -= bsize;
  83. } while (nbytes >= bsize);
  84. done:
  85. err = blkcipher_walk_done(desc, walk, nbytes);
  86. }
  87. return err;
  88. }
  89. static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  90. struct scatterlist *src, unsigned int nbytes)
  91. {
  92. struct blkcipher_walk walk;
  93. blkcipher_walk_init(&walk, dst, src, nbytes);
  94. return ecb_crypt(desc, &walk, twofish_enc_blk, twofish_enc_blk_3way);
  95. }
  96. static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  97. struct scatterlist *src, unsigned int nbytes)
  98. {
  99. struct blkcipher_walk walk;
  100. blkcipher_walk_init(&walk, dst, src, nbytes);
  101. return ecb_crypt(desc, &walk, twofish_dec_blk, twofish_dec_blk_3way);
  102. }
  103. static struct crypto_alg blk_ecb_alg = {
  104. .cra_name = "ecb(twofish)",
  105. .cra_driver_name = "ecb-twofish-3way",
  106. .cra_priority = 300,
  107. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  108. .cra_blocksize = TF_BLOCK_SIZE,
  109. .cra_ctxsize = sizeof(struct twofish_ctx),
  110. .cra_alignmask = 0,
  111. .cra_type = &crypto_blkcipher_type,
  112. .cra_module = THIS_MODULE,
  113. .cra_list = LIST_HEAD_INIT(blk_ecb_alg.cra_list),
  114. .cra_u = {
  115. .blkcipher = {
  116. .min_keysize = TF_MIN_KEY_SIZE,
  117. .max_keysize = TF_MAX_KEY_SIZE,
  118. .setkey = twofish_setkey,
  119. .encrypt = ecb_encrypt,
  120. .decrypt = ecb_decrypt,
  121. },
  122. },
  123. };
  124. static unsigned int __cbc_encrypt(struct blkcipher_desc *desc,
  125. struct blkcipher_walk *walk)
  126. {
  127. struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  128. unsigned int bsize = TF_BLOCK_SIZE;
  129. unsigned int nbytes = walk->nbytes;
  130. u128 *src = (u128 *)walk->src.virt.addr;
  131. u128 *dst = (u128 *)walk->dst.virt.addr;
  132. u128 *iv = (u128 *)walk->iv;
  133. do {
  134. u128_xor(dst, src, iv);
  135. twofish_enc_blk(ctx, (u8 *)dst, (u8 *)dst);
  136. iv = dst;
  137. src += 1;
  138. dst += 1;
  139. nbytes -= bsize;
  140. } while (nbytes >= bsize);
  141. u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv);
  142. return nbytes;
  143. }
  144. static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  145. struct scatterlist *src, unsigned int nbytes)
  146. {
  147. struct blkcipher_walk walk;
  148. int err;
  149. blkcipher_walk_init(&walk, dst, src, nbytes);
  150. err = blkcipher_walk_virt(desc, &walk);
  151. while ((nbytes = walk.nbytes)) {
  152. nbytes = __cbc_encrypt(desc, &walk);
  153. err = blkcipher_walk_done(desc, &walk, nbytes);
  154. }
  155. return err;
  156. }
  157. static unsigned int __cbc_decrypt(struct blkcipher_desc *desc,
  158. struct blkcipher_walk *walk)
  159. {
  160. struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  161. unsigned int bsize = TF_BLOCK_SIZE;
  162. unsigned int nbytes = walk->nbytes;
  163. u128 *src = (u128 *)walk->src.virt.addr;
  164. u128 *dst = (u128 *)walk->dst.virt.addr;
  165. u128 ivs[3 - 1];
  166. u128 last_iv;
  167. /* Start of the last block. */
  168. src += nbytes / bsize - 1;
  169. dst += nbytes / bsize - 1;
  170. last_iv = *src;
  171. /* Process three block batch */
  172. if (nbytes >= bsize * 3) {
  173. do {
  174. nbytes -= bsize * (3 - 1);
  175. src -= 3 - 1;
  176. dst -= 3 - 1;
  177. ivs[0] = src[0];
  178. ivs[1] = src[1];
  179. twofish_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src);
  180. u128_xor(dst + 1, dst + 1, ivs + 0);
  181. u128_xor(dst + 2, dst + 2, ivs + 1);
  182. nbytes -= bsize;
  183. if (nbytes < bsize)
  184. goto done;
  185. u128_xor(dst, dst, src - 1);
  186. src -= 1;
  187. dst -= 1;
  188. } while (nbytes >= bsize * 3);
  189. if (nbytes < bsize)
  190. goto done;
  191. }
  192. /* Handle leftovers */
  193. for (;;) {
  194. twofish_dec_blk(ctx, (u8 *)dst, (u8 *)src);
  195. nbytes -= bsize;
  196. if (nbytes < bsize)
  197. break;
  198. u128_xor(dst, dst, src - 1);
  199. src -= 1;
  200. dst -= 1;
  201. }
  202. done:
  203. u128_xor(dst, dst, (u128 *)walk->iv);
  204. *(u128 *)walk->iv = last_iv;
  205. return nbytes;
  206. }
  207. static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  208. struct scatterlist *src, unsigned int nbytes)
  209. {
  210. struct blkcipher_walk walk;
  211. int err;
  212. blkcipher_walk_init(&walk, dst, src, nbytes);
  213. err = blkcipher_walk_virt(desc, &walk);
  214. while ((nbytes = walk.nbytes)) {
  215. nbytes = __cbc_decrypt(desc, &walk);
  216. err = blkcipher_walk_done(desc, &walk, nbytes);
  217. }
  218. return err;
  219. }
  220. static struct crypto_alg blk_cbc_alg = {
  221. .cra_name = "cbc(twofish)",
  222. .cra_driver_name = "cbc-twofish-3way",
  223. .cra_priority = 300,
  224. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  225. .cra_blocksize = TF_BLOCK_SIZE,
  226. .cra_ctxsize = sizeof(struct twofish_ctx),
  227. .cra_alignmask = 0,
  228. .cra_type = &crypto_blkcipher_type,
  229. .cra_module = THIS_MODULE,
  230. .cra_list = LIST_HEAD_INIT(blk_cbc_alg.cra_list),
  231. .cra_u = {
  232. .blkcipher = {
  233. .min_keysize = TF_MIN_KEY_SIZE,
  234. .max_keysize = TF_MAX_KEY_SIZE,
  235. .ivsize = TF_BLOCK_SIZE,
  236. .setkey = twofish_setkey,
  237. .encrypt = cbc_encrypt,
  238. .decrypt = cbc_decrypt,
  239. },
  240. },
  241. };
  242. static inline void u128_to_be128(be128 *dst, const u128 *src)
  243. {
  244. dst->a = cpu_to_be64(src->a);
  245. dst->b = cpu_to_be64(src->b);
  246. }
  247. static inline void be128_to_u128(u128 *dst, const be128 *src)
  248. {
  249. dst->a = be64_to_cpu(src->a);
  250. dst->b = be64_to_cpu(src->b);
  251. }
  252. static inline void u128_inc(u128 *i)
  253. {
  254. i->b++;
  255. if (!i->b)
  256. i->a++;
  257. }
  258. static void ctr_crypt_final(struct blkcipher_desc *desc,
  259. struct blkcipher_walk *walk)
  260. {
  261. struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  262. u8 *ctrblk = walk->iv;
  263. u8 keystream[TF_BLOCK_SIZE];
  264. u8 *src = walk->src.virt.addr;
  265. u8 *dst = walk->dst.virt.addr;
  266. unsigned int nbytes = walk->nbytes;
  267. twofish_enc_blk(ctx, keystream, ctrblk);
  268. crypto_xor(keystream, src, nbytes);
  269. memcpy(dst, keystream, nbytes);
  270. crypto_inc(ctrblk, TF_BLOCK_SIZE);
  271. }
  272. static unsigned int __ctr_crypt(struct blkcipher_desc *desc,
  273. struct blkcipher_walk *walk)
  274. {
  275. struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  276. unsigned int bsize = TF_BLOCK_SIZE;
  277. unsigned int nbytes = walk->nbytes;
  278. u128 *src = (u128 *)walk->src.virt.addr;
  279. u128 *dst = (u128 *)walk->dst.virt.addr;
  280. u128 ctrblk;
  281. be128 ctrblocks[3];
  282. be128_to_u128(&ctrblk, (be128 *)walk->iv);
  283. /* Process three block batch */
  284. if (nbytes >= bsize * 3) {
  285. do {
  286. if (dst != src) {
  287. dst[0] = src[0];
  288. dst[1] = src[1];
  289. dst[2] = src[2];
  290. }
  291. /* create ctrblks for parallel encrypt */
  292. u128_to_be128(&ctrblocks[0], &ctrblk);
  293. u128_inc(&ctrblk);
  294. u128_to_be128(&ctrblocks[1], &ctrblk);
  295. u128_inc(&ctrblk);
  296. u128_to_be128(&ctrblocks[2], &ctrblk);
  297. u128_inc(&ctrblk);
  298. twofish_enc_blk_xor_3way(ctx, (u8 *)dst,
  299. (u8 *)ctrblocks);
  300. src += 3;
  301. dst += 3;
  302. nbytes -= bsize * 3;
  303. } while (nbytes >= bsize * 3);
  304. if (nbytes < bsize)
  305. goto done;
  306. }
  307. /* Handle leftovers */
  308. do {
  309. if (dst != src)
  310. *dst = *src;
  311. u128_to_be128(&ctrblocks[0], &ctrblk);
  312. u128_inc(&ctrblk);
  313. twofish_enc_blk(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks);
  314. u128_xor(dst, dst, (u128 *)ctrblocks);
  315. src += 1;
  316. dst += 1;
  317. nbytes -= bsize;
  318. } while (nbytes >= bsize);
  319. done:
  320. u128_to_be128((be128 *)walk->iv, &ctrblk);
  321. return nbytes;
  322. }
  323. static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  324. struct scatterlist *src, unsigned int nbytes)
  325. {
  326. struct blkcipher_walk walk;
  327. int err;
  328. blkcipher_walk_init(&walk, dst, src, nbytes);
  329. err = blkcipher_walk_virt_block(desc, &walk, TF_BLOCK_SIZE);
  330. while ((nbytes = walk.nbytes) >= TF_BLOCK_SIZE) {
  331. nbytes = __ctr_crypt(desc, &walk);
  332. err = blkcipher_walk_done(desc, &walk, nbytes);
  333. }
  334. if (walk.nbytes) {
  335. ctr_crypt_final(desc, &walk);
  336. err = blkcipher_walk_done(desc, &walk, 0);
  337. }
  338. return err;
  339. }
  340. static struct crypto_alg blk_ctr_alg = {
  341. .cra_name = "ctr(twofish)",
  342. .cra_driver_name = "ctr-twofish-3way",
  343. .cra_priority = 300,
  344. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  345. .cra_blocksize = 1,
  346. .cra_ctxsize = sizeof(struct twofish_ctx),
  347. .cra_alignmask = 0,
  348. .cra_type = &crypto_blkcipher_type,
  349. .cra_module = THIS_MODULE,
  350. .cra_list = LIST_HEAD_INIT(blk_ctr_alg.cra_list),
  351. .cra_u = {
  352. .blkcipher = {
  353. .min_keysize = TF_MIN_KEY_SIZE,
  354. .max_keysize = TF_MAX_KEY_SIZE,
  355. .ivsize = TF_BLOCK_SIZE,
  356. .setkey = twofish_setkey,
  357. .encrypt = ctr_crypt,
  358. .decrypt = ctr_crypt,
  359. },
  360. },
  361. };
  362. int __init init(void)
  363. {
  364. int err;
  365. err = crypto_register_alg(&blk_ecb_alg);
  366. if (err)
  367. goto ecb_err;
  368. err = crypto_register_alg(&blk_cbc_alg);
  369. if (err)
  370. goto cbc_err;
  371. err = crypto_register_alg(&blk_ctr_alg);
  372. if (err)
  373. goto ctr_err;
  374. return 0;
  375. ctr_err:
  376. crypto_unregister_alg(&blk_cbc_alg);
  377. cbc_err:
  378. crypto_unregister_alg(&blk_ecb_alg);
  379. ecb_err:
  380. return err;
  381. }
  382. void __exit fini(void)
  383. {
  384. crypto_unregister_alg(&blk_ctr_alg);
  385. crypto_unregister_alg(&blk_cbc_alg);
  386. crypto_unregister_alg(&blk_ecb_alg);
  387. }
  388. module_init(init);
  389. module_exit(fini);
  390. MODULE_LICENSE("GPL");
  391. MODULE_DESCRIPTION("Twofish Cipher Algorithm, 3-way parallel asm optimized");
  392. MODULE_ALIAS("twofish");
  393. MODULE_ALIAS("twofish-asm");