serpent_sse2_glue.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070
  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 struct crypto_alg blk_ecb_alg = {
  127. .cra_name = "__ecb-serpent-sse2",
  128. .cra_driver_name = "__driver-ecb-serpent-sse2",
  129. .cra_priority = 0,
  130. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  131. .cra_blocksize = SERPENT_BLOCK_SIZE,
  132. .cra_ctxsize = sizeof(struct serpent_ctx),
  133. .cra_alignmask = 0,
  134. .cra_type = &crypto_blkcipher_type,
  135. .cra_module = THIS_MODULE,
  136. .cra_list = LIST_HEAD_INIT(blk_ecb_alg.cra_list),
  137. .cra_u = {
  138. .blkcipher = {
  139. .min_keysize = SERPENT_MIN_KEY_SIZE,
  140. .max_keysize = SERPENT_MAX_KEY_SIZE,
  141. .setkey = serpent_setkey,
  142. .encrypt = ecb_encrypt,
  143. .decrypt = ecb_decrypt,
  144. },
  145. },
  146. };
  147. static unsigned int __cbc_encrypt(struct blkcipher_desc *desc,
  148. struct blkcipher_walk *walk)
  149. {
  150. struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  151. const unsigned int bsize = SERPENT_BLOCK_SIZE;
  152. unsigned int nbytes = walk->nbytes;
  153. u128 *src = (u128 *)walk->src.virt.addr;
  154. u128 *dst = (u128 *)walk->dst.virt.addr;
  155. u128 *iv = (u128 *)walk->iv;
  156. do {
  157. u128_xor(dst, src, iv);
  158. __serpent_encrypt(ctx, (u8 *)dst, (u8 *)dst);
  159. iv = dst;
  160. src += 1;
  161. dst += 1;
  162. nbytes -= bsize;
  163. } while (nbytes >= bsize);
  164. u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv);
  165. return nbytes;
  166. }
  167. static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  168. struct scatterlist *src, unsigned int nbytes)
  169. {
  170. struct blkcipher_walk walk;
  171. int err;
  172. blkcipher_walk_init(&walk, dst, src, nbytes);
  173. err = blkcipher_walk_virt(desc, &walk);
  174. while ((nbytes = walk.nbytes)) {
  175. nbytes = __cbc_encrypt(desc, &walk);
  176. err = blkcipher_walk_done(desc, &walk, nbytes);
  177. }
  178. return err;
  179. }
  180. static unsigned int __cbc_decrypt(struct blkcipher_desc *desc,
  181. struct blkcipher_walk *walk)
  182. {
  183. struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  184. const unsigned int bsize = SERPENT_BLOCK_SIZE;
  185. unsigned int nbytes = walk->nbytes;
  186. u128 *src = (u128 *)walk->src.virt.addr;
  187. u128 *dst = (u128 *)walk->dst.virt.addr;
  188. u128 ivs[SERPENT_PARALLEL_BLOCKS - 1];
  189. u128 last_iv;
  190. int i;
  191. /* Start of the last block. */
  192. src += nbytes / bsize - 1;
  193. dst += nbytes / bsize - 1;
  194. last_iv = *src;
  195. /* Process multi-block batch */
  196. if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) {
  197. do {
  198. nbytes -= bsize * (SERPENT_PARALLEL_BLOCKS - 1);
  199. src -= SERPENT_PARALLEL_BLOCKS - 1;
  200. dst -= SERPENT_PARALLEL_BLOCKS - 1;
  201. for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++)
  202. ivs[i] = src[i];
  203. serpent_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src);
  204. for (i = 0; i < SERPENT_PARALLEL_BLOCKS - 1; i++)
  205. u128_xor(dst + (i + 1), dst + (i + 1), ivs + i);
  206. nbytes -= bsize;
  207. if (nbytes < bsize)
  208. goto done;
  209. u128_xor(dst, dst, src - 1);
  210. src -= 1;
  211. dst -= 1;
  212. } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS);
  213. if (nbytes < bsize)
  214. goto done;
  215. }
  216. /* Handle leftovers */
  217. for (;;) {
  218. __serpent_decrypt(ctx, (u8 *)dst, (u8 *)src);
  219. nbytes -= bsize;
  220. if (nbytes < bsize)
  221. break;
  222. u128_xor(dst, dst, src - 1);
  223. src -= 1;
  224. dst -= 1;
  225. }
  226. done:
  227. u128_xor(dst, dst, (u128 *)walk->iv);
  228. *(u128 *)walk->iv = last_iv;
  229. return nbytes;
  230. }
  231. static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  232. struct scatterlist *src, unsigned int nbytes)
  233. {
  234. bool fpu_enabled = false;
  235. struct blkcipher_walk walk;
  236. int err;
  237. blkcipher_walk_init(&walk, dst, src, nbytes);
  238. err = blkcipher_walk_virt(desc, &walk);
  239. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  240. while ((nbytes = walk.nbytes)) {
  241. fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes);
  242. nbytes = __cbc_decrypt(desc, &walk);
  243. err = blkcipher_walk_done(desc, &walk, nbytes);
  244. }
  245. serpent_fpu_end(fpu_enabled);
  246. return err;
  247. }
  248. static struct crypto_alg blk_cbc_alg = {
  249. .cra_name = "__cbc-serpent-sse2",
  250. .cra_driver_name = "__driver-cbc-serpent-sse2",
  251. .cra_priority = 0,
  252. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  253. .cra_blocksize = SERPENT_BLOCK_SIZE,
  254. .cra_ctxsize = sizeof(struct serpent_ctx),
  255. .cra_alignmask = 0,
  256. .cra_type = &crypto_blkcipher_type,
  257. .cra_module = THIS_MODULE,
  258. .cra_list = LIST_HEAD_INIT(blk_cbc_alg.cra_list),
  259. .cra_u = {
  260. .blkcipher = {
  261. .min_keysize = SERPENT_MIN_KEY_SIZE,
  262. .max_keysize = SERPENT_MAX_KEY_SIZE,
  263. .setkey = serpent_setkey,
  264. .encrypt = cbc_encrypt,
  265. .decrypt = cbc_decrypt,
  266. },
  267. },
  268. };
  269. static inline void u128_to_be128(be128 *dst, const u128 *src)
  270. {
  271. dst->a = cpu_to_be64(src->a);
  272. dst->b = cpu_to_be64(src->b);
  273. }
  274. static inline void be128_to_u128(u128 *dst, const be128 *src)
  275. {
  276. dst->a = be64_to_cpu(src->a);
  277. dst->b = be64_to_cpu(src->b);
  278. }
  279. static inline void u128_inc(u128 *i)
  280. {
  281. i->b++;
  282. if (!i->b)
  283. i->a++;
  284. }
  285. static void ctr_crypt_final(struct blkcipher_desc *desc,
  286. struct blkcipher_walk *walk)
  287. {
  288. struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  289. u8 *ctrblk = walk->iv;
  290. u8 keystream[SERPENT_BLOCK_SIZE];
  291. u8 *src = walk->src.virt.addr;
  292. u8 *dst = walk->dst.virt.addr;
  293. unsigned int nbytes = walk->nbytes;
  294. __serpent_encrypt(ctx, keystream, ctrblk);
  295. crypto_xor(keystream, src, nbytes);
  296. memcpy(dst, keystream, nbytes);
  297. crypto_inc(ctrblk, SERPENT_BLOCK_SIZE);
  298. }
  299. static unsigned int __ctr_crypt(struct blkcipher_desc *desc,
  300. struct blkcipher_walk *walk)
  301. {
  302. struct serpent_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  303. const unsigned int bsize = SERPENT_BLOCK_SIZE;
  304. unsigned int nbytes = walk->nbytes;
  305. u128 *src = (u128 *)walk->src.virt.addr;
  306. u128 *dst = (u128 *)walk->dst.virt.addr;
  307. u128 ctrblk;
  308. be128 ctrblocks[SERPENT_PARALLEL_BLOCKS];
  309. int i;
  310. be128_to_u128(&ctrblk, (be128 *)walk->iv);
  311. /* Process multi-block batch */
  312. if (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS) {
  313. do {
  314. /* create ctrblks for parallel encrypt */
  315. for (i = 0; i < SERPENT_PARALLEL_BLOCKS; i++) {
  316. if (dst != src)
  317. dst[i] = src[i];
  318. u128_to_be128(&ctrblocks[i], &ctrblk);
  319. u128_inc(&ctrblk);
  320. }
  321. serpent_enc_blk_xway_xor(ctx, (u8 *)dst,
  322. (u8 *)ctrblocks);
  323. src += SERPENT_PARALLEL_BLOCKS;
  324. dst += SERPENT_PARALLEL_BLOCKS;
  325. nbytes -= bsize * SERPENT_PARALLEL_BLOCKS;
  326. } while (nbytes >= bsize * SERPENT_PARALLEL_BLOCKS);
  327. if (nbytes < bsize)
  328. goto done;
  329. }
  330. /* Handle leftovers */
  331. do {
  332. if (dst != src)
  333. *dst = *src;
  334. u128_to_be128(&ctrblocks[0], &ctrblk);
  335. u128_inc(&ctrblk);
  336. __serpent_encrypt(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks);
  337. u128_xor(dst, dst, (u128 *)ctrblocks);
  338. src += 1;
  339. dst += 1;
  340. nbytes -= bsize;
  341. } while (nbytes >= bsize);
  342. done:
  343. u128_to_be128((be128 *)walk->iv, &ctrblk);
  344. return nbytes;
  345. }
  346. static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  347. struct scatterlist *src, unsigned int nbytes)
  348. {
  349. bool fpu_enabled = false;
  350. struct blkcipher_walk walk;
  351. int err;
  352. blkcipher_walk_init(&walk, dst, src, nbytes);
  353. err = blkcipher_walk_virt_block(desc, &walk, SERPENT_BLOCK_SIZE);
  354. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  355. while ((nbytes = walk.nbytes) >= SERPENT_BLOCK_SIZE) {
  356. fpu_enabled = serpent_fpu_begin(fpu_enabled, nbytes);
  357. nbytes = __ctr_crypt(desc, &walk);
  358. err = blkcipher_walk_done(desc, &walk, nbytes);
  359. }
  360. serpent_fpu_end(fpu_enabled);
  361. if (walk.nbytes) {
  362. ctr_crypt_final(desc, &walk);
  363. err = blkcipher_walk_done(desc, &walk, 0);
  364. }
  365. return err;
  366. }
  367. static struct crypto_alg blk_ctr_alg = {
  368. .cra_name = "__ctr-serpent-sse2",
  369. .cra_driver_name = "__driver-ctr-serpent-sse2",
  370. .cra_priority = 0,
  371. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  372. .cra_blocksize = 1,
  373. .cra_ctxsize = sizeof(struct serpent_ctx),
  374. .cra_alignmask = 0,
  375. .cra_type = &crypto_blkcipher_type,
  376. .cra_module = THIS_MODULE,
  377. .cra_list = LIST_HEAD_INIT(blk_ctr_alg.cra_list),
  378. .cra_u = {
  379. .blkcipher = {
  380. .min_keysize = SERPENT_MIN_KEY_SIZE,
  381. .max_keysize = SERPENT_MAX_KEY_SIZE,
  382. .ivsize = SERPENT_BLOCK_SIZE,
  383. .setkey = serpent_setkey,
  384. .encrypt = ctr_crypt,
  385. .decrypt = ctr_crypt,
  386. },
  387. },
  388. };
  389. struct crypt_priv {
  390. struct serpent_ctx *ctx;
  391. bool fpu_enabled;
  392. };
  393. static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
  394. {
  395. const unsigned int bsize = SERPENT_BLOCK_SIZE;
  396. struct crypt_priv *ctx = priv;
  397. int i;
  398. ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes);
  399. if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) {
  400. serpent_enc_blk_xway(ctx->ctx, srcdst, srcdst);
  401. return;
  402. }
  403. for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
  404. __serpent_encrypt(ctx->ctx, srcdst, srcdst);
  405. }
  406. static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
  407. {
  408. const unsigned int bsize = SERPENT_BLOCK_SIZE;
  409. struct crypt_priv *ctx = priv;
  410. int i;
  411. ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes);
  412. if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) {
  413. serpent_dec_blk_xway(ctx->ctx, srcdst, srcdst);
  414. return;
  415. }
  416. for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
  417. __serpent_decrypt(ctx->ctx, srcdst, srcdst);
  418. }
  419. struct serpent_lrw_ctx {
  420. struct lrw_table_ctx lrw_table;
  421. struct serpent_ctx serpent_ctx;
  422. };
  423. static int lrw_serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
  424. unsigned int keylen)
  425. {
  426. struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
  427. int err;
  428. err = __serpent_setkey(&ctx->serpent_ctx, key, keylen -
  429. SERPENT_BLOCK_SIZE);
  430. if (err)
  431. return err;
  432. return lrw_init_table(&ctx->lrw_table, key + keylen -
  433. SERPENT_BLOCK_SIZE);
  434. }
  435. static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  436. struct scatterlist *src, unsigned int nbytes)
  437. {
  438. struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  439. be128 buf[SERPENT_PARALLEL_BLOCKS];
  440. struct crypt_priv crypt_ctx = {
  441. .ctx = &ctx->serpent_ctx,
  442. .fpu_enabled = false,
  443. };
  444. struct lrw_crypt_req req = {
  445. .tbuf = buf,
  446. .tbuflen = sizeof(buf),
  447. .table_ctx = &ctx->lrw_table,
  448. .crypt_ctx = &crypt_ctx,
  449. .crypt_fn = encrypt_callback,
  450. };
  451. int ret;
  452. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  453. ret = lrw_crypt(desc, dst, src, nbytes, &req);
  454. serpent_fpu_end(crypt_ctx.fpu_enabled);
  455. return ret;
  456. }
  457. static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  458. struct scatterlist *src, unsigned int nbytes)
  459. {
  460. struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  461. be128 buf[SERPENT_PARALLEL_BLOCKS];
  462. struct crypt_priv crypt_ctx = {
  463. .ctx = &ctx->serpent_ctx,
  464. .fpu_enabled = false,
  465. };
  466. struct lrw_crypt_req req = {
  467. .tbuf = buf,
  468. .tbuflen = sizeof(buf),
  469. .table_ctx = &ctx->lrw_table,
  470. .crypt_ctx = &crypt_ctx,
  471. .crypt_fn = decrypt_callback,
  472. };
  473. int ret;
  474. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  475. ret = lrw_crypt(desc, dst, src, nbytes, &req);
  476. serpent_fpu_end(crypt_ctx.fpu_enabled);
  477. return ret;
  478. }
  479. static void lrw_exit_tfm(struct crypto_tfm *tfm)
  480. {
  481. struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
  482. lrw_free_table(&ctx->lrw_table);
  483. }
  484. static struct crypto_alg blk_lrw_alg = {
  485. .cra_name = "__lrw-serpent-sse2",
  486. .cra_driver_name = "__driver-lrw-serpent-sse2",
  487. .cra_priority = 0,
  488. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  489. .cra_blocksize = SERPENT_BLOCK_SIZE,
  490. .cra_ctxsize = sizeof(struct serpent_lrw_ctx),
  491. .cra_alignmask = 0,
  492. .cra_type = &crypto_blkcipher_type,
  493. .cra_module = THIS_MODULE,
  494. .cra_list = LIST_HEAD_INIT(blk_lrw_alg.cra_list),
  495. .cra_exit = lrw_exit_tfm,
  496. .cra_u = {
  497. .blkcipher = {
  498. .min_keysize = SERPENT_MIN_KEY_SIZE +
  499. SERPENT_BLOCK_SIZE,
  500. .max_keysize = SERPENT_MAX_KEY_SIZE +
  501. SERPENT_BLOCK_SIZE,
  502. .ivsize = SERPENT_BLOCK_SIZE,
  503. .setkey = lrw_serpent_setkey,
  504. .encrypt = lrw_encrypt,
  505. .decrypt = lrw_decrypt,
  506. },
  507. },
  508. };
  509. struct serpent_xts_ctx {
  510. struct serpent_ctx tweak_ctx;
  511. struct serpent_ctx crypt_ctx;
  512. };
  513. static int xts_serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
  514. unsigned int keylen)
  515. {
  516. struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm);
  517. u32 *flags = &tfm->crt_flags;
  518. int err;
  519. /* key consists of keys of equal size concatenated, therefore
  520. * the length must be even
  521. */
  522. if (keylen % 2) {
  523. *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
  524. return -EINVAL;
  525. }
  526. /* first half of xts-key is for crypt */
  527. err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2);
  528. if (err)
  529. return err;
  530. /* second half of xts-key is for tweak */
  531. return __serpent_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2);
  532. }
  533. static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  534. struct scatterlist *src, unsigned int nbytes)
  535. {
  536. struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  537. be128 buf[SERPENT_PARALLEL_BLOCKS];
  538. struct crypt_priv crypt_ctx = {
  539. .ctx = &ctx->crypt_ctx,
  540. .fpu_enabled = false,
  541. };
  542. struct xts_crypt_req req = {
  543. .tbuf = buf,
  544. .tbuflen = sizeof(buf),
  545. .tweak_ctx = &ctx->tweak_ctx,
  546. .tweak_fn = XTS_TWEAK_CAST(__serpent_encrypt),
  547. .crypt_ctx = &crypt_ctx,
  548. .crypt_fn = encrypt_callback,
  549. };
  550. int ret;
  551. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  552. ret = xts_crypt(desc, dst, src, nbytes, &req);
  553. serpent_fpu_end(crypt_ctx.fpu_enabled);
  554. return ret;
  555. }
  556. static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  557. struct scatterlist *src, unsigned int nbytes)
  558. {
  559. struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  560. be128 buf[SERPENT_PARALLEL_BLOCKS];
  561. struct crypt_priv crypt_ctx = {
  562. .ctx = &ctx->crypt_ctx,
  563. .fpu_enabled = false,
  564. };
  565. struct xts_crypt_req req = {
  566. .tbuf = buf,
  567. .tbuflen = sizeof(buf),
  568. .tweak_ctx = &ctx->tweak_ctx,
  569. .tweak_fn = XTS_TWEAK_CAST(__serpent_encrypt),
  570. .crypt_ctx = &crypt_ctx,
  571. .crypt_fn = decrypt_callback,
  572. };
  573. int ret;
  574. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  575. ret = xts_crypt(desc, dst, src, nbytes, &req);
  576. serpent_fpu_end(crypt_ctx.fpu_enabled);
  577. return ret;
  578. }
  579. static struct crypto_alg blk_xts_alg = {
  580. .cra_name = "__xts-serpent-sse2",
  581. .cra_driver_name = "__driver-xts-serpent-sse2",
  582. .cra_priority = 0,
  583. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  584. .cra_blocksize = SERPENT_BLOCK_SIZE,
  585. .cra_ctxsize = sizeof(struct serpent_xts_ctx),
  586. .cra_alignmask = 0,
  587. .cra_type = &crypto_blkcipher_type,
  588. .cra_module = THIS_MODULE,
  589. .cra_list = LIST_HEAD_INIT(blk_xts_alg.cra_list),
  590. .cra_u = {
  591. .blkcipher = {
  592. .min_keysize = SERPENT_MIN_KEY_SIZE * 2,
  593. .max_keysize = SERPENT_MAX_KEY_SIZE * 2,
  594. .ivsize = SERPENT_BLOCK_SIZE,
  595. .setkey = xts_serpent_setkey,
  596. .encrypt = xts_encrypt,
  597. .decrypt = xts_decrypt,
  598. },
  599. },
  600. };
  601. static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key,
  602. unsigned int key_len)
  603. {
  604. struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm);
  605. struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base;
  606. int err;
  607. crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
  608. crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm)
  609. & CRYPTO_TFM_REQ_MASK);
  610. err = crypto_ablkcipher_setkey(child, key, key_len);
  611. crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child)
  612. & CRYPTO_TFM_RES_MASK);
  613. return err;
  614. }
  615. static int __ablk_encrypt(struct ablkcipher_request *req)
  616. {
  617. struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
  618. struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm);
  619. struct blkcipher_desc desc;
  620. desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm);
  621. desc.info = req->info;
  622. desc.flags = 0;
  623. return crypto_blkcipher_crt(desc.tfm)->encrypt(
  624. &desc, req->dst, req->src, req->nbytes);
  625. }
  626. static int ablk_encrypt(struct ablkcipher_request *req)
  627. {
  628. struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
  629. struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm);
  630. if (!irq_fpu_usable()) {
  631. struct ablkcipher_request *cryptd_req =
  632. ablkcipher_request_ctx(req);
  633. memcpy(cryptd_req, req, sizeof(*req));
  634. ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
  635. return crypto_ablkcipher_encrypt(cryptd_req);
  636. } else {
  637. return __ablk_encrypt(req);
  638. }
  639. }
  640. static int ablk_decrypt(struct ablkcipher_request *req)
  641. {
  642. struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
  643. struct async_serpent_ctx *ctx = crypto_ablkcipher_ctx(tfm);
  644. if (!irq_fpu_usable()) {
  645. struct ablkcipher_request *cryptd_req =
  646. ablkcipher_request_ctx(req);
  647. memcpy(cryptd_req, req, sizeof(*req));
  648. ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
  649. return crypto_ablkcipher_decrypt(cryptd_req);
  650. } else {
  651. struct blkcipher_desc desc;
  652. desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm);
  653. desc.info = req->info;
  654. desc.flags = 0;
  655. return crypto_blkcipher_crt(desc.tfm)->decrypt(
  656. &desc, req->dst, req->src, req->nbytes);
  657. }
  658. }
  659. static void ablk_exit(struct crypto_tfm *tfm)
  660. {
  661. struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm);
  662. cryptd_free_ablkcipher(ctx->cryptd_tfm);
  663. }
  664. static void ablk_init_common(struct crypto_tfm *tfm,
  665. struct cryptd_ablkcipher *cryptd_tfm)
  666. {
  667. struct async_serpent_ctx *ctx = crypto_tfm_ctx(tfm);
  668. ctx->cryptd_tfm = cryptd_tfm;
  669. tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) +
  670. crypto_ablkcipher_reqsize(&cryptd_tfm->base);
  671. }
  672. static int ablk_ecb_init(struct crypto_tfm *tfm)
  673. {
  674. struct cryptd_ablkcipher *cryptd_tfm;
  675. cryptd_tfm = cryptd_alloc_ablkcipher("__driver-ecb-serpent-sse2", 0, 0);
  676. if (IS_ERR(cryptd_tfm))
  677. return PTR_ERR(cryptd_tfm);
  678. ablk_init_common(tfm, cryptd_tfm);
  679. return 0;
  680. }
  681. static struct crypto_alg ablk_ecb_alg = {
  682. .cra_name = "ecb(serpent)",
  683. .cra_driver_name = "ecb-serpent-sse2",
  684. .cra_priority = 400,
  685. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
  686. .cra_blocksize = SERPENT_BLOCK_SIZE,
  687. .cra_ctxsize = sizeof(struct async_serpent_ctx),
  688. .cra_alignmask = 0,
  689. .cra_type = &crypto_ablkcipher_type,
  690. .cra_module = THIS_MODULE,
  691. .cra_list = LIST_HEAD_INIT(ablk_ecb_alg.cra_list),
  692. .cra_init = ablk_ecb_init,
  693. .cra_exit = ablk_exit,
  694. .cra_u = {
  695. .ablkcipher = {
  696. .min_keysize = SERPENT_MIN_KEY_SIZE,
  697. .max_keysize = SERPENT_MAX_KEY_SIZE,
  698. .setkey = ablk_set_key,
  699. .encrypt = ablk_encrypt,
  700. .decrypt = ablk_decrypt,
  701. },
  702. },
  703. };
  704. static int ablk_cbc_init(struct crypto_tfm *tfm)
  705. {
  706. struct cryptd_ablkcipher *cryptd_tfm;
  707. cryptd_tfm = cryptd_alloc_ablkcipher("__driver-cbc-serpent-sse2", 0, 0);
  708. if (IS_ERR(cryptd_tfm))
  709. return PTR_ERR(cryptd_tfm);
  710. ablk_init_common(tfm, cryptd_tfm);
  711. return 0;
  712. }
  713. static struct crypto_alg ablk_cbc_alg = {
  714. .cra_name = "cbc(serpent)",
  715. .cra_driver_name = "cbc-serpent-sse2",
  716. .cra_priority = 400,
  717. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
  718. .cra_blocksize = SERPENT_BLOCK_SIZE,
  719. .cra_ctxsize = sizeof(struct async_serpent_ctx),
  720. .cra_alignmask = 0,
  721. .cra_type = &crypto_ablkcipher_type,
  722. .cra_module = THIS_MODULE,
  723. .cra_list = LIST_HEAD_INIT(ablk_cbc_alg.cra_list),
  724. .cra_init = ablk_cbc_init,
  725. .cra_exit = ablk_exit,
  726. .cra_u = {
  727. .ablkcipher = {
  728. .min_keysize = SERPENT_MIN_KEY_SIZE,
  729. .max_keysize = SERPENT_MAX_KEY_SIZE,
  730. .ivsize = SERPENT_BLOCK_SIZE,
  731. .setkey = ablk_set_key,
  732. .encrypt = __ablk_encrypt,
  733. .decrypt = ablk_decrypt,
  734. },
  735. },
  736. };
  737. static int ablk_ctr_init(struct crypto_tfm *tfm)
  738. {
  739. struct cryptd_ablkcipher *cryptd_tfm;
  740. cryptd_tfm = cryptd_alloc_ablkcipher("__driver-ctr-serpent-sse2", 0, 0);
  741. if (IS_ERR(cryptd_tfm))
  742. return PTR_ERR(cryptd_tfm);
  743. ablk_init_common(tfm, cryptd_tfm);
  744. return 0;
  745. }
  746. static struct crypto_alg ablk_ctr_alg = {
  747. .cra_name = "ctr(serpent)",
  748. .cra_driver_name = "ctr-serpent-sse2",
  749. .cra_priority = 400,
  750. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
  751. .cra_blocksize = 1,
  752. .cra_ctxsize = sizeof(struct async_serpent_ctx),
  753. .cra_alignmask = 0,
  754. .cra_type = &crypto_ablkcipher_type,
  755. .cra_module = THIS_MODULE,
  756. .cra_list = LIST_HEAD_INIT(ablk_ctr_alg.cra_list),
  757. .cra_init = ablk_ctr_init,
  758. .cra_exit = ablk_exit,
  759. .cra_u = {
  760. .ablkcipher = {
  761. .min_keysize = SERPENT_MIN_KEY_SIZE,
  762. .max_keysize = SERPENT_MAX_KEY_SIZE,
  763. .ivsize = SERPENT_BLOCK_SIZE,
  764. .setkey = ablk_set_key,
  765. .encrypt = ablk_encrypt,
  766. .decrypt = ablk_encrypt,
  767. .geniv = "chainiv",
  768. },
  769. },
  770. };
  771. static int ablk_lrw_init(struct crypto_tfm *tfm)
  772. {
  773. struct cryptd_ablkcipher *cryptd_tfm;
  774. cryptd_tfm = cryptd_alloc_ablkcipher("__driver-lrw-serpent-sse2", 0, 0);
  775. if (IS_ERR(cryptd_tfm))
  776. return PTR_ERR(cryptd_tfm);
  777. ablk_init_common(tfm, cryptd_tfm);
  778. return 0;
  779. }
  780. static struct crypto_alg ablk_lrw_alg = {
  781. .cra_name = "lrw(serpent)",
  782. .cra_driver_name = "lrw-serpent-sse2",
  783. .cra_priority = 400,
  784. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
  785. .cra_blocksize = SERPENT_BLOCK_SIZE,
  786. .cra_ctxsize = sizeof(struct async_serpent_ctx),
  787. .cra_alignmask = 0,
  788. .cra_type = &crypto_ablkcipher_type,
  789. .cra_module = THIS_MODULE,
  790. .cra_list = LIST_HEAD_INIT(ablk_lrw_alg.cra_list),
  791. .cra_init = ablk_lrw_init,
  792. .cra_exit = ablk_exit,
  793. .cra_u = {
  794. .ablkcipher = {
  795. .min_keysize = SERPENT_MIN_KEY_SIZE +
  796. SERPENT_BLOCK_SIZE,
  797. .max_keysize = SERPENT_MAX_KEY_SIZE +
  798. SERPENT_BLOCK_SIZE,
  799. .ivsize = SERPENT_BLOCK_SIZE,
  800. .setkey = ablk_set_key,
  801. .encrypt = ablk_encrypt,
  802. .decrypt = ablk_decrypt,
  803. },
  804. },
  805. };
  806. static int ablk_xts_init(struct crypto_tfm *tfm)
  807. {
  808. struct cryptd_ablkcipher *cryptd_tfm;
  809. cryptd_tfm = cryptd_alloc_ablkcipher("__driver-xts-serpent-sse2", 0, 0);
  810. if (IS_ERR(cryptd_tfm))
  811. return PTR_ERR(cryptd_tfm);
  812. ablk_init_common(tfm, cryptd_tfm);
  813. return 0;
  814. }
  815. static struct crypto_alg ablk_xts_alg = {
  816. .cra_name = "xts(serpent)",
  817. .cra_driver_name = "xts-serpent-sse2",
  818. .cra_priority = 400,
  819. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
  820. .cra_blocksize = SERPENT_BLOCK_SIZE,
  821. .cra_ctxsize = sizeof(struct async_serpent_ctx),
  822. .cra_alignmask = 0,
  823. .cra_type = &crypto_ablkcipher_type,
  824. .cra_module = THIS_MODULE,
  825. .cra_list = LIST_HEAD_INIT(ablk_xts_alg.cra_list),
  826. .cra_init = ablk_xts_init,
  827. .cra_exit = ablk_exit,
  828. .cra_u = {
  829. .ablkcipher = {
  830. .min_keysize = SERPENT_MIN_KEY_SIZE * 2,
  831. .max_keysize = SERPENT_MAX_KEY_SIZE * 2,
  832. .ivsize = SERPENT_BLOCK_SIZE,
  833. .setkey = ablk_set_key,
  834. .encrypt = ablk_encrypt,
  835. .decrypt = ablk_decrypt,
  836. },
  837. },
  838. };
  839. static int __init serpent_sse2_init(void)
  840. {
  841. int err;
  842. if (!cpu_has_xmm2) {
  843. printk(KERN_INFO "SSE2 instructions are not detected.\n");
  844. return -ENODEV;
  845. }
  846. err = crypto_register_alg(&blk_ecb_alg);
  847. if (err)
  848. goto blk_ecb_err;
  849. err = crypto_register_alg(&blk_cbc_alg);
  850. if (err)
  851. goto blk_cbc_err;
  852. err = crypto_register_alg(&blk_ctr_alg);
  853. if (err)
  854. goto blk_ctr_err;
  855. err = crypto_register_alg(&ablk_ecb_alg);
  856. if (err)
  857. goto ablk_ecb_err;
  858. err = crypto_register_alg(&ablk_cbc_alg);
  859. if (err)
  860. goto ablk_cbc_err;
  861. err = crypto_register_alg(&ablk_ctr_alg);
  862. if (err)
  863. goto ablk_ctr_err;
  864. err = crypto_register_alg(&blk_lrw_alg);
  865. if (err)
  866. goto blk_lrw_err;
  867. err = crypto_register_alg(&ablk_lrw_alg);
  868. if (err)
  869. goto ablk_lrw_err;
  870. err = crypto_register_alg(&blk_xts_alg);
  871. if (err)
  872. goto blk_xts_err;
  873. err = crypto_register_alg(&ablk_xts_alg);
  874. if (err)
  875. goto ablk_xts_err;
  876. return err;
  877. crypto_unregister_alg(&ablk_xts_alg);
  878. ablk_xts_err:
  879. crypto_unregister_alg(&blk_xts_alg);
  880. blk_xts_err:
  881. crypto_unregister_alg(&ablk_lrw_alg);
  882. ablk_lrw_err:
  883. crypto_unregister_alg(&blk_lrw_alg);
  884. blk_lrw_err:
  885. crypto_unregister_alg(&ablk_ctr_alg);
  886. ablk_ctr_err:
  887. crypto_unregister_alg(&ablk_cbc_alg);
  888. ablk_cbc_err:
  889. crypto_unregister_alg(&ablk_ecb_alg);
  890. ablk_ecb_err:
  891. crypto_unregister_alg(&blk_ctr_alg);
  892. blk_ctr_err:
  893. crypto_unregister_alg(&blk_cbc_alg);
  894. blk_cbc_err:
  895. crypto_unregister_alg(&blk_ecb_alg);
  896. blk_ecb_err:
  897. return err;
  898. }
  899. static void __exit serpent_sse2_exit(void)
  900. {
  901. crypto_unregister_alg(&ablk_xts_alg);
  902. crypto_unregister_alg(&blk_xts_alg);
  903. crypto_unregister_alg(&ablk_lrw_alg);
  904. crypto_unregister_alg(&blk_lrw_alg);
  905. crypto_unregister_alg(&ablk_ctr_alg);
  906. crypto_unregister_alg(&ablk_cbc_alg);
  907. crypto_unregister_alg(&ablk_ecb_alg);
  908. crypto_unregister_alg(&blk_ctr_alg);
  909. crypto_unregister_alg(&blk_cbc_alg);
  910. crypto_unregister_alg(&blk_ecb_alg);
  911. }
  912. module_init(serpent_sse2_init);
  913. module_exit(serpent_sse2_exit);
  914. MODULE_DESCRIPTION("Serpent Cipher Algorithm, SSE2 optimized");
  915. MODULE_LICENSE("GPL");
  916. MODULE_ALIAS("serpent");