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