serpent_sse2_glue.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945
  1. /*
  2. * Glue Code for SSE2 assembler versions of Serpent Cipher
  3. *
  4. * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
  5. *
  6. * Glue code based on aesni-intel_glue.c by:
  7. * Copyright (C) 2008, Intel Corp.
  8. * Author: Huang Ying <ying.huang@intel.com>
  9. *
  10. * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by:
  11. * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
  12. * CTR part based on code (crypto/ctr.c) by:
  13. * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
  14. *
  15. * This program is free software; you can redistribute it and/or modify
  16. * it under the terms of the GNU General Public License as published by
  17. * the Free Software Foundation; either version 2 of the License, or
  18. * (at your option) any later version.
  19. *
  20. * This program is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program; if not, write to the Free Software
  27. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  28. * USA
  29. *
  30. */
  31. #include <linux/module.h>
  32. #include <linux/hardirq.h>
  33. #include <linux/types.h>
  34. #include <linux/crypto.h>
  35. #include <linux/err.h>
  36. #include <crypto/algapi.h>
  37. #include <crypto/serpent.h>
  38. #include <crypto/cryptd.h>
  39. #include <crypto/b128ops.h>
  40. #include <crypto/ctr.h>
  41. #include <crypto/lrw.h>
  42. #include <crypto/xts.h>
  43. #include <asm/i387.h>
  44. #include <asm/serpent.h>
  45. #include <crypto/scatterwalk.h>
  46. #include <linux/workqueue.h>
  47. #include <linux/spinlock.h>
  48. struct async_serpent_ctx {
  49. struct cryptd_ablkcipher *cryptd_tfm;
  50. };
  51. static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes)
  52. {
  53. if (fpu_enabled)
  54. return true;
  55. /* SSE2 is only used when chunk to be processed is large enough, so
  56. * do not enable FPU until it is necessary.
  57. */
  58. if (nbytes < SERPENT_BLOCK_SIZE * SERPENT_PARALLEL_BLOCKS)
  59. return false;
  60. kernel_fpu_begin();
  61. return true;
  62. }
  63. static inline void serpent_fpu_end(bool fpu_enabled)
  64. {
  65. if (fpu_enabled)
  66. kernel_fpu_end();
  67. }
  68. static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk,
  69. bool enc)
  70. {
  71. bool fpu_enabled = false;
  72. struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  73. const unsigned int bsize = SERPENT_BLOCK_SIZE;
  74. unsigned int nbytes;
  75. int err;
  76. err = blkcipher_walk_virt(desc, walk);
  77. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  78. while ((nbytes = walk->nbytes)) {
  79. u8 *wsrc = walk->src.virt.addr;
  80. u8 *wdst = walk->dst.virt.addr;
  81. fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes);
  82. /* Process multi-block batch */
  83. if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) {
  84. do {
  85. if (enc)
  86. serpent_enc_blk_xway(ctx, wdst, wsrc);
  87. else
  88. serpent_dec_blk_xway(ctx, wdst, wsrc);
  89. wsrc += bsize * SERPENT_PARALLEL_BLOCKS;
  90. wdst += bsize * SERPENT_PARALLEL_BLOCKS;
  91. nbytes -= bsize * SERPENT_PARALLEL_BLOCKS;
  92. } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS);
  93. if (nbytes < bsize)
  94. goto done;
  95. }
  96. /* Handle leftovers */
  97. do {
  98. if (enc)
  99. __serpent_encrypt(ctx, wdst, wsrc);
  100. else
  101. __serpent_decrypt(ctx, wdst, wsrc);
  102. wsrc += bsize;
  103. wdst += bsize;
  104. nbytes -= bsize;
  105. } while (nbytes >= bsize);
  106. done:
  107. err = blkcipher_walk_done(desc, walk, nbytes);
  108. }
  109. serpent_fpu_end(fpu_enabled);
  110. return err;
  111. }
  112. static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  113. struct scatterlist *src, unsigned int nbytes)
  114. {
  115. struct blkcipher_walk walk;
  116. blkcipher_walk_init(&walk, dst, src, nbytes);
  117. return ecb_crypt(desc, &walk, true);
  118. }
  119. static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  120. struct scatterlist *src, unsigned int nbytes)
  121. {
  122. struct blkcipher_walk walk;
  123. blkcipher_walk_init(&walk, dst, src, nbytes);
  124. return ecb_crypt(desc, &walk, false);
  125. }
  126. static unsigned int __cbc_encrypt(struct blkcipher_desc *desc,
  127. struct blkcipher_walk *walk)
  128. {
  129. struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  130. const unsigned int bsize = SERPENT_BLOCK_SIZE;
  131. unsigned int nbytes = walk->nbytes;
  132. u128 *src = (u128 *)walk->src.virt.addr;
  133. u128 *dst = (u128 *)walk->dst.virt.addr;
  134. u128 *iv = (u128 *)walk->iv;
  135. do {
  136. u128_xor(dst, src, iv);
  137. __serpent_encrypt(ctx, (u8 *)dst, (u8 *)dst);
  138. iv = dst;
  139. src += 1;
  140. dst += 1;
  141. nbytes -= bsize;
  142. } while (nbytes >= bsize);
  143. u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv);
  144. return nbytes;
  145. }
  146. static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  147. struct scatterlist *src, unsigned int nbytes)
  148. {
  149. struct blkcipher_walk walk;
  150. int err;
  151. blkcipher_walk_init(&walk, dst, src, nbytes);
  152. err = blkcipher_walk_virt(desc, &walk);
  153. while ((nbytes = walk.nbytes)) {
  154. nbytes = __cbc_encrypt(desc, &walk);
  155. err = blkcipher_walk_done(desc, &walk, nbytes);
  156. }
  157. return err;
  158. }
  159. static unsigned int __cbc_decrypt(struct blkcipher_desc *desc,
  160. struct blkcipher_walk *walk)
  161. {
  162. struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  163. const unsigned int bsize = SERPENT_BLOCK_SIZE;
  164. unsigned int nbytes = walk->nbytes;
  165. u128 *src = (u128 *)walk->src.virt.addr;
  166. u128 *dst = (u128 *)walk->dst.virt.addr;
  167. u128 ivs[SERPENT_PARALLEL_BLOCKS - 1];
  168. u128 last_iv;
  169. int i;
  170. /* Start of the last block. */
  171. src += nbytes / bsize - 1;
  172. dst += nbytes / bsize - 1;
  173. last_iv = *src;
  174. /* Process multi-block batch */
  175. if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) {
  176. do {
  177. nbytes -= bsize * (SERPENT_PARALLEL_BLOCKS - 1);
  178. src -= SERPENT_PARALLEL_BLOCKS - 1;
  179. dst -= SERPENT_PARALLEL_BLOCKS - 1;
  180. for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++)
  181. ivs[i] = src[i];
  182. serpent_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src);
  183. for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++)
  184. u128_xor(dst + (i + 1), dst + (i + 1), ivs + i);
  185. nbytes -= bsize;
  186. if (nbytes < bsize)
  187. goto done;
  188. u128_xor(dst, dst, src - 1);
  189. src -= 1;
  190. dst -= 1;
  191. } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS);
  192. if (nbytes < bsize)
  193. goto done;
  194. }
  195. /* Handle leftovers */
  196. for (;;) {
  197. __serpent_decrypt(ctx, (u8 *)dst, (u8 *)src);
  198. nbytes -= bsize;
  199. if (nbytes < bsize)
  200. break;
  201. u128_xor(dst, dst, src - 1);
  202. src -= 1;
  203. dst -= 1;
  204. }
  205. done:
  206. u128_xor(dst, dst, (u128 *)walk->iv);
  207. *(u128 *)walk->iv = last_iv;
  208. return nbytes;
  209. }
  210. static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  211. struct scatterlist *src, unsigned int nbytes)
  212. {
  213. bool fpu_enabled = false;
  214. struct blkcipher_walk walk;
  215. int err;
  216. blkcipher_walk_init(&walk, dst, src, nbytes);
  217. err = blkcipher_walk_virt(desc, &walk);
  218. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  219. while ((nbytes = walk.nbytes)) {
  220. fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes);
  221. nbytes = __cbc_decrypt(desc, &walk);
  222. err = blkcipher_walk_done(desc, &walk, nbytes);
  223. }
  224. serpent_fpu_end(fpu_enabled);
  225. return err;
  226. }
  227. static inline void u128_to_be128(be128 *dst, const u128 *src)
  228. {
  229. dst->a = cpu_to_be64(src->a);
  230. dst->b = cpu_to_be64(src->b);
  231. }
  232. static inline void be128_to_u128(u128 *dst, const be128 *src)
  233. {
  234. dst->a = be64_to_cpu(src->a);
  235. dst->b = be64_to_cpu(src->b);
  236. }
  237. static inline void u128_inc(u128 *i)
  238. {
  239. i->b++;
  240. if (!i->b)
  241. i->a++;
  242. }
  243. static void ctr_crypt_final(struct blkcipher_desc *desc,
  244. struct blkcipher_walk *walk)
  245. {
  246. struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  247. u8 *ctrblk = walk->iv;
  248. u8 keystream[SERPENT_BLOCK_SIZE];
  249. u8 *src = walk->src.virt.addr;
  250. u8 *dst = walk->dst.virt.addr;
  251. unsigned int nbytes = walk->nbytes;
  252. __serpent_encrypt(ctx, keystream, ctrblk);
  253. crypto_xor(keystream, src, nbytes);
  254. memcpy(dst, keystream, nbytes);
  255. crypto_inc(ctrblk, SERPENT_BLOCK_SIZE);
  256. }
  257. static unsigned int __ctr_crypt(struct blkcipher_desc *desc,
  258. struct blkcipher_walk *walk)
  259. {
  260. struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  261. const unsigned int bsize = SERPENT_BLOCK_SIZE;
  262. unsigned int nbytes = walk->nbytes;
  263. u128 *src = (u128 *)walk->src.virt.addr;
  264. u128 *dst = (u128 *)walk->dst.virt.addr;
  265. u128 ctrblk;
  266. be128 ctrblocks[SERPENT_PARALLEL_BLOCKS];
  267. int i;
  268. be128_to_u128(&ctrblk, (be128 *)walk->iv);
  269. /* Process multi-block batch */
  270. if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) {
  271. do {
  272. /* create ctrblks for parallel encrypt */
  273. for (i = 0; i < SERPENT_PARALLEL_BLOCKS; i++) {
  274. if (dst != src)
  275. dst[i] = src[i];
  276. u128_to_be128(&ctrblocks[i], &ctrblk);
  277. u128_inc(&ctrblk);
  278. }
  279. serpent_enc_blk_xway_xor(ctx, (u8 *)dst,
  280. (u8 *)ctrblocks);
  281. src += SERPENT_PARALLEL_BLOCKS;
  282. dst += SERPENT_PARALLEL_BLOCKS;
  283. nbytes -= bsize * SERPENT_PARALLEL_BLOCKS;
  284. } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS);
  285. if (nbytes < bsize)
  286. goto done;
  287. }
  288. /* Handle leftovers */
  289. do {
  290. if (dst != src)
  291. *dst = *src;
  292. u128_to_be128(&ctrblocks[0], &ctrblk);
  293. u128_inc(&ctrblk);
  294. __serpent_encrypt(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks);
  295. u128_xor(dst, dst, (u128 *)ctrblocks);
  296. src += 1;
  297. dst += 1;
  298. nbytes -= bsize;
  299. } while (nbytes >= bsize);
  300. done:
  301. u128_to_be128((be128 *)walk->iv, &ctrblk);
  302. return nbytes;
  303. }
  304. static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  305. struct scatterlist *src, unsigned int nbytes)
  306. {
  307. bool fpu_enabled = false;
  308. struct blkcipher_walk walk;
  309. int err;
  310. blkcipher_walk_init(&walk, dst, src, nbytes);
  311. err = blkcipher_walk_virt_block(desc, &walk, SERPENT_BLOCK_SIZE);
  312. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  313. while ((nbytes = walk.nbytes) >= SERPENT_BLOCK_SIZE) {
  314. fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes);
  315. nbytes = __ctr_crypt(desc, &walk);
  316. err = blkcipher_walk_done(desc, &walk, nbytes);
  317. }
  318. serpent_fpu_end(fpu_enabled);
  319. if (walk.nbytes) {
  320. ctr_crypt_final(desc, &walk);
  321. err = blkcipher_walk_done(desc, &walk, 0);
  322. }
  323. return err;
  324. }
  325. struct crypt_priv {
  326. struct serpent_ctx *ctx;
  327. bool fpu_enabled;
  328. };
  329. static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
  330. {
  331. const unsigned int bsize = SERPENT_BLOCK_SIZE;
  332. struct crypt_priv *ctx = priv;
  333. int i;
  334. ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes);
  335. if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) {
  336. serpent_enc_blk_xway(ctx->ctx, srcdst, srcdst);
  337. return;
  338. }
  339. for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
  340. __serpent_encrypt(ctx->ctx, srcdst, srcdst);
  341. }
  342. static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
  343. {
  344. const unsigned int bsize = SERPENT_BLOCK_SIZE;
  345. struct crypt_priv *ctx = priv;
  346. int i;
  347. ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes);
  348. if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) {
  349. serpent_dec_blk_xway(ctx->ctx, srcdst, srcdst);
  350. return;
  351. }
  352. for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
  353. __serpent_decrypt(ctx->ctx, srcdst, srcdst);
  354. }
  355. struct serpent_lrw_ctx {
  356. struct lrw_table_ctx lrw_table;
  357. struct serpent_ctx serpent_ctx;
  358. };
  359. static int lrw_serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
  360. unsigned int keylen)
  361. {
  362. struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
  363. int err;
  364. err = __serpent_setkey(&ctx->serpent_ctx, key, keylen -
  365. SERPENT_BLOCK_SIZE);
  366. if (err)
  367. return err;
  368. return lrw_init_table(&ctx->lrw_table, key + keylen -
  369. SERPENT_BLOCK_SIZE);
  370. }
  371. static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  372. struct scatterlist *src, unsigned int nbytes)
  373. {
  374. struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  375. be128 buf[SERPENT_PARALLEL_BLOCKS];
  376. struct crypt_priv crypt_ctx = {
  377. .ctx = &ctx->serpent_ctx,
  378. .fpu_enabled = false,
  379. };
  380. struct lrw_crypt_req req = {
  381. .tbuf = buf,
  382. .tbuflen = sizeof(buf),
  383. .table_ctx = &ctx->lrw_table,
  384. .crypt_ctx = &crypt_ctx,
  385. .crypt_fn = encrypt_callback,
  386. };
  387. int ret;
  388. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  389. ret = lrw_crypt(desc, dst, src, nbytes, &req);
  390. serpent_fpu_end(crypt_ctx.fpu_enabled);
  391. return ret;
  392. }
  393. static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  394. struct scatterlist *src, unsigned int nbytes)
  395. {
  396. struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  397. be128 buf[SERPENT_PARALLEL_BLOCKS];
  398. struct crypt_priv crypt_ctx = {
  399. .ctx = &ctx->serpent_ctx,
  400. .fpu_enabled = false,
  401. };
  402. struct lrw_crypt_req req = {
  403. .tbuf = buf,
  404. .tbuflen = sizeof(buf),
  405. .table_ctx = &ctx->lrw_table,
  406. .crypt_ctx = &crypt_ctx,
  407. .crypt_fn = decrypt_callback,
  408. };
  409. int ret;
  410. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  411. ret = lrw_crypt(desc, dst, src, nbytes, &req);
  412. serpent_fpu_end(crypt_ctx.fpu_enabled);
  413. return ret;
  414. }
  415. static void lrw_exit_tfm(struct crypto_tfm *tfm)
  416. {
  417. struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
  418. lrw_free_table(&ctx->lrw_table);
  419. }
  420. struct serpent_xts_ctx {
  421. struct serpent_ctx tweak_ctx;
  422. struct serpent_ctx crypt_ctx;
  423. };
  424. static int xts_serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
  425. unsigned int keylen)
  426. {
  427. struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm);
  428. u32 *flags = &tfm->crt_flags;
  429. int err;
  430. /* key consists of keys of equal size concatenated, therefore
  431. * the length must be even
  432. */
  433. if (keylen % 2) {
  434. *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
  435. return -EINVAL;
  436. }
  437. /* first half of xts-key is for crypt */
  438. err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2);
  439. if (err)
  440. return err;
  441. /* second half of xts-key is for tweak */
  442. return __serpent_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2);
  443. }
  444. static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  445. struct scatterlist *src, unsigned int nbytes)
  446. {
  447. struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  448. be128 buf[SERPENT_PARALLEL_BLOCKS];
  449. struct crypt_priv crypt_ctx = {
  450. .ctx = &ctx->crypt_ctx,
  451. .fpu_enabled = false,
  452. };
  453. struct xts_crypt_req req = {
  454. .tbuf = buf,
  455. .tbuflen = sizeof(buf),
  456. .tweak_ctx = &ctx->tweak_ctx,
  457. .tweak_fn = XTS_TWEAK_CAST(__serpent_encrypt),
  458. .crypt_ctx = &crypt_ctx,
  459. .crypt_fn = encrypt_callback,
  460. };
  461. int ret;
  462. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  463. ret = xts_crypt(desc, dst, src, nbytes, &req);
  464. serpent_fpu_end(crypt_ctx.fpu_enabled);
  465. return ret;
  466. }
  467. static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  468. struct scatterlist *src, unsigned int nbytes)
  469. {
  470. struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  471. be128 buf[SERPENT_PARALLEL_BLOCKS];
  472. struct crypt_priv crypt_ctx = {
  473. .ctx = &ctx->crypt_ctx,
  474. .fpu_enabled = false,
  475. };
  476. struct xts_crypt_req req = {
  477. .tbuf = buf,
  478. .tbuflen = sizeof(buf),
  479. .tweak_ctx = &ctx->tweak_ctx,
  480. .tweak_fn = XTS_TWEAK_CAST(__serpent_encrypt),
  481. .crypt_ctx = &crypt_ctx,
  482. .crypt_fn = decrypt_callback,
  483. };
  484. int ret;
  485. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  486. ret = xts_crypt(desc, dst, src, nbytes, &req);
  487. serpent_fpu_end(crypt_ctx.fpu_enabled);
  488. return ret;
  489. }
  490. static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key,
  491. unsigned int key_len)
  492. {
  493. struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm);
  494. struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base;
  495. int err;
  496. crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
  497. crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm)
  498. & CRYPTO_TFM_REQ_MASK);
  499. err = crypto_ablkcipher_setkey(child, key, key_len);
  500. crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child)
  501. & CRYPTO_TFM_RES_MASK);
  502. return err;
  503. }
  504. static int __ablk_encrypt(struct ablkcipher_request *req)
  505. {
  506. struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
  507. struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm);
  508. struct blkcipher_desc desc;
  509. desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm);
  510. desc.info = req->info;
  511. desc.flags = 0;
  512. return crypto_blkcipher_crt(desc.tfm)->encrypt(
  513. &desc, req->dst, req->src, req->nbytes);
  514. }
  515. static int ablk_encrypt(struct ablkcipher_request *req)
  516. {
  517. struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
  518. struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm);
  519. if (!irq_fpu_usable()) {
  520. struct ablkcipher_request *cryptd_req =
  521. ablkcipher_request_ctx(req);
  522. memcpy(cryptd_req, req, sizeof(*req));
  523. ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
  524. return crypto_ablkcipher_encrypt(cryptd_req);
  525. } else {
  526. return __ablk_encrypt(req);
  527. }
  528. }
  529. static int ablk_decrypt(struct ablkcipher_request *req)
  530. {
  531. struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
  532. struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm);
  533. if (!irq_fpu_usable()) {
  534. struct ablkcipher_request *cryptd_req =
  535. ablkcipher_request_ctx(req);
  536. memcpy(cryptd_req, req, sizeof(*req));
  537. ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
  538. return crypto_ablkcipher_decrypt(cryptd_req);
  539. } else {
  540. struct blkcipher_desc desc;
  541. desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm);
  542. desc.info = req->info;
  543. desc.flags = 0;
  544. return crypto_blkcipher_crt(desc.tfm)->decrypt(
  545. &desc, req->dst, req->src, req->nbytes);
  546. }
  547. }
  548. static void ablk_exit(struct crypto_tfm *tfm)
  549. {
  550. struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm);
  551. cryptd_free_ablkcipher(ctx->cryptd_tfm);
  552. }
  553. static int ablk_init(struct crypto_tfm *tfm)
  554. {
  555. struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm);
  556. struct cryptd_ablkcipher *cryptd_tfm;
  557. char drv_name[CRYPTO_MAX_ALG_NAME];
  558. snprintf(drv_name, sizeof(drv_name), "__driver-%s",
  559. crypto_tfm_alg_driver_name(tfm));
  560. cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0);
  561. if (IS_ERR(cryptd_tfm))
  562. return PTR_ERR(cryptd_tfm);
  563. ctx->cryptd_tfm = cryptd_tfm;
  564. tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) +
  565. crypto_ablkcipher_reqsize(&cryptd_tfm->base);
  566. return 0;
  567. }
  568. static struct crypto_alg serpent_algs[10] = { {
  569. .cra_name = "__ecb-serpent-sse2",
  570. .cra_driver_name = "__driver-ecb-serpent-sse2",
  571. .cra_priority = 0,
  572. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  573. .cra_blocksize = SERPENT_BLOCK_SIZE,
  574. .cra_ctxsize = sizeof(struct serpent_ctx),
  575. .cra_alignmask = 0,
  576. .cra_type = &crypto_blkcipher_type,
  577. .cra_module = THIS_MODULE,
  578. .cra_list = LIST_HEAD_INIT(serpent_algs[0].cra_list),
  579. .cra_u = {
  580. .blkcipher = {
  581. .min_keysize = SERPENT_MIN_KEY_SIZE,
  582. .max_keysize = SERPENT_MAX_KEY_SIZE,
  583. .setkey = serpent_setkey,
  584. .encrypt = ecb_encrypt,
  585. .decrypt = ecb_decrypt,
  586. },
  587. },
  588. }, {
  589. .cra_name = "__cbc-serpent-sse2",
  590. .cra_driver_name = "__driver-cbc-serpent-sse2",
  591. .cra_priority = 0,
  592. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  593. .cra_blocksize = SERPENT_BLOCK_SIZE,
  594. .cra_ctxsize = sizeof(struct serpent_ctx),
  595. .cra_alignmask = 0,
  596. .cra_type = &crypto_blkcipher_type,
  597. .cra_module = THIS_MODULE,
  598. .cra_list = LIST_HEAD_INIT(serpent_algs[1].cra_list),
  599. .cra_u = {
  600. .blkcipher = {
  601. .min_keysize = SERPENT_MIN_KEY_SIZE,
  602. .max_keysize = SERPENT_MAX_KEY_SIZE,
  603. .setkey = serpent_setkey,
  604. .encrypt = cbc_encrypt,
  605. .decrypt = cbc_decrypt,
  606. },
  607. },
  608. }, {
  609. .cra_name = "__ctr-serpent-sse2",
  610. .cra_driver_name = "__driver-ctr-serpent-sse2",
  611. .cra_priority = 0,
  612. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  613. .cra_blocksize = 1,
  614. .cra_ctxsize = sizeof(struct serpent_ctx),
  615. .cra_alignmask = 0,
  616. .cra_type = &crypto_blkcipher_type,
  617. .cra_module = THIS_MODULE,
  618. .cra_list = LIST_HEAD_INIT(serpent_algs[2].cra_list),
  619. .cra_u = {
  620. .blkcipher = {
  621. .min_keysize = SERPENT_MIN_KEY_SIZE,
  622. .max_keysize = SERPENT_MAX_KEY_SIZE,
  623. .ivsize = SERPENT_BLOCK_SIZE,
  624. .setkey = serpent_setkey,
  625. .encrypt = ctr_crypt,
  626. .decrypt = ctr_crypt,
  627. },
  628. },
  629. }, {
  630. .cra_name = "__lrw-serpent-sse2",
  631. .cra_driver_name = "__driver-lrw-serpent-sse2",
  632. .cra_priority = 0,
  633. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  634. .cra_blocksize = SERPENT_BLOCK_SIZE,
  635. .cra_ctxsize = sizeof(struct serpent_lrw_ctx),
  636. .cra_alignmask = 0,
  637. .cra_type = &crypto_blkcipher_type,
  638. .cra_module = THIS_MODULE,
  639. .cra_list = LIST_HEAD_INIT(serpent_algs[3].cra_list),
  640. .cra_exit = lrw_exit_tfm,
  641. .cra_u = {
  642. .blkcipher = {
  643. .min_keysize = SERPENT_MIN_KEY_SIZE +
  644. SERPENT_BLOCK_SIZE,
  645. .max_keysize = SERPENT_MAX_KEY_SIZE +
  646. SERPENT_BLOCK_SIZE,
  647. .ivsize = SERPENT_BLOCK_SIZE,
  648. .setkey = lrw_serpent_setkey,
  649. .encrypt = lrw_encrypt,
  650. .decrypt = lrw_decrypt,
  651. },
  652. },
  653. }, {
  654. .cra_name = "__xts-serpent-sse2",
  655. .cra_driver_name = "__driver-xts-serpent-sse2",
  656. .cra_priority = 0,
  657. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  658. .cra_blocksize = SERPENT_BLOCK_SIZE,
  659. .cra_ctxsize = sizeof(struct serpent_xts_ctx),
  660. .cra_alignmask = 0,
  661. .cra_type = &crypto_blkcipher_type,
  662. .cra_module = THIS_MODULE,
  663. .cra_list = LIST_HEAD_INIT(serpent_algs[4].cra_list),
  664. .cra_u = {
  665. .blkcipher = {
  666. .min_keysize = SERPENT_MIN_KEY_SIZE * 2,
  667. .max_keysize = SERPENT_MAX_KEY_SIZE * 2,
  668. .ivsize = SERPENT_BLOCK_SIZE,
  669. .setkey = xts_serpent_setkey,
  670. .encrypt = xts_encrypt,
  671. .decrypt = xts_decrypt,
  672. },
  673. },
  674. }, {
  675. .cra_name = "ecb(serpent)",
  676. .cra_driver_name = "ecb-serpent-sse2",
  677. .cra_priority = 400,
  678. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
  679. .cra_blocksize = SERPENT_BLOCK_SIZE,
  680. .cra_ctxsize = sizeof(struct async_serpent_ctx),
  681. .cra_alignmask = 0,
  682. .cra_type = &crypto_ablkcipher_type,
  683. .cra_module = THIS_MODULE,
  684. .cra_list = LIST_HEAD_INIT(serpent_algs[5].cra_list),
  685. .cra_init = ablk_init,
  686. .cra_exit = ablk_exit,
  687. .cra_u = {
  688. .ablkcipher = {
  689. .min_keysize = SERPENT_MIN_KEY_SIZE,
  690. .max_keysize = SERPENT_MAX_KEY_SIZE,
  691. .setkey = ablk_set_key,
  692. .encrypt = ablk_encrypt,
  693. .decrypt = ablk_decrypt,
  694. },
  695. },
  696. }, {
  697. .cra_name = "cbc(serpent)",
  698. .cra_driver_name = "cbc-serpent-sse2",
  699. .cra_priority = 400,
  700. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
  701. .cra_blocksize = SERPENT_BLOCK_SIZE,
  702. .cra_ctxsize = sizeof(struct async_serpent_ctx),
  703. .cra_alignmask = 0,
  704. .cra_type = &crypto_ablkcipher_type,
  705. .cra_module = THIS_MODULE,
  706. .cra_list = LIST_HEAD_INIT(serpent_algs[6].cra_list),
  707. .cra_init = ablk_init,
  708. .cra_exit = ablk_exit,
  709. .cra_u = {
  710. .ablkcipher = {
  711. .min_keysize = SERPENT_MIN_KEY_SIZE,
  712. .max_keysize = SERPENT_MAX_KEY_SIZE,
  713. .ivsize = SERPENT_BLOCK_SIZE,
  714. .setkey = ablk_set_key,
  715. .encrypt = __ablk_encrypt,
  716. .decrypt = ablk_decrypt,
  717. },
  718. },
  719. }, {
  720. .cra_name = "ctr(serpent)",
  721. .cra_driver_name = "ctr-serpent-sse2",
  722. .cra_priority = 400,
  723. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
  724. .cra_blocksize = 1,
  725. .cra_ctxsize = sizeof(struct async_serpent_ctx),
  726. .cra_alignmask = 0,
  727. .cra_type = &crypto_ablkcipher_type,
  728. .cra_module = THIS_MODULE,
  729. .cra_list = LIST_HEAD_INIT(serpent_algs[7].cra_list),
  730. .cra_init = ablk_init,
  731. .cra_exit = ablk_exit,
  732. .cra_u = {
  733. .ablkcipher = {
  734. .min_keysize = SERPENT_MIN_KEY_SIZE,
  735. .max_keysize = SERPENT_MAX_KEY_SIZE,
  736. .ivsize = SERPENT_BLOCK_SIZE,
  737. .setkey = ablk_set_key,
  738. .encrypt = ablk_encrypt,
  739. .decrypt = ablk_encrypt,
  740. .geniv = "chainiv",
  741. },
  742. },
  743. }, {
  744. .cra_name = "lrw(serpent)",
  745. .cra_driver_name = "lrw-serpent-sse2",
  746. .cra_priority = 400,
  747. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
  748. .cra_blocksize = SERPENT_BLOCK_SIZE,
  749. .cra_ctxsize = sizeof(struct async_serpent_ctx),
  750. .cra_alignmask = 0,
  751. .cra_type = &crypto_ablkcipher_type,
  752. .cra_module = THIS_MODULE,
  753. .cra_list = LIST_HEAD_INIT(serpent_algs[8].cra_list),
  754. .cra_init = ablk_init,
  755. .cra_exit = ablk_exit,
  756. .cra_u = {
  757. .ablkcipher = {
  758. .min_keysize = SERPENT_MIN_KEY_SIZE +
  759. SERPENT_BLOCK_SIZE,
  760. .max_keysize = SERPENT_MAX_KEY_SIZE +
  761. SERPENT_BLOCK_SIZE,
  762. .ivsize = SERPENT_BLOCK_SIZE,
  763. .setkey = ablk_set_key,
  764. .encrypt = ablk_encrypt,
  765. .decrypt = ablk_decrypt,
  766. },
  767. },
  768. }, {
  769. .cra_name = "xts(serpent)",
  770. .cra_driver_name = "xts-serpent-sse2",
  771. .cra_priority = 400,
  772. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
  773. .cra_blocksize = SERPENT_BLOCK_SIZE,
  774. .cra_ctxsize = sizeof(struct async_serpent_ctx),
  775. .cra_alignmask = 0,
  776. .cra_type = &crypto_ablkcipher_type,
  777. .cra_module = THIS_MODULE,
  778. .cra_list = LIST_HEAD_INIT(serpent_algs[9].cra_list),
  779. .cra_init = ablk_init,
  780. .cra_exit = ablk_exit,
  781. .cra_u = {
  782. .ablkcipher = {
  783. .min_keysize = SERPENT_MIN_KEY_SIZE * 2,
  784. .max_keysize = SERPENT_MAX_KEY_SIZE * 2,
  785. .ivsize = SERPENT_BLOCK_SIZE,
  786. .setkey = ablk_set_key,
  787. .encrypt = ablk_encrypt,
  788. .decrypt = ablk_decrypt,
  789. },
  790. },
  791. } };
  792. static int __init serpent_sse2_init(void)
  793. {
  794. if (!cpu_has_xmm2) {
  795. printk(KERN_INFO "SSE2 instructions are not detected.\n");
  796. return -ENODEV;
  797. }
  798. return crypto_register_algs(serpent_algs, ARRAY_SIZE(serpent_algs));
  799. }
  800. static void __exit serpent_sse2_exit(void)
  801. {
  802. crypto_unregister_algs(serpent_algs, ARRAY_SIZE(serpent_algs));
  803. }
  804. module_init(serpent_sse2_init);
  805. module_exit(serpent_sse2_exit);
  806. MODULE_DESCRIPTION("Serpent Cipher Algorithm, SSE2 optimized");
  807. MODULE_LICENSE("GPL");
  808. MODULE_ALIAS("serpent");