aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>2011-10-18 06:33:02 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2011-11-08 22:53:32 -0500
commit81559f9ad3d88c033e4ec3b6468012dbfda3b31d (patch)
tree68eeeb74c13537984c3d0ddb7bbe2f5c9b06fc62
parentbee3a90ef5366b58250e4369dac3268ced3351aa (diff)
crypto: twofish-x86_64-3way - add lrw support
Patch adds LRW support for twofish-x86_64-3way by using lrw_crypt(). Patch has been tested with tcrypt and automated filesystem tests. Tcrypt benchmarks results (twofish-3way/twofish-asm speed ratios): Intel Celeron T1600 (fam:6, model:15, step:13): size lrw-enc lrw-dec 16B 0.99x 1.00x 64B 1.17x 1.17x 256B 1.26x 1.27x 1024B 1.30x 1.31x 8192B 1.31x 1.32x AMD Phenom II 1055T (fam:16, model:10): size lrw-enc lrw-dec 16B 1.06x 1.01x 64B 1.08x 1.14x 256B 1.19x 1.20x 1024B 1.21x 1.22x 8192B 1.23x 1.24x Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--arch/x86/crypto/twofish_glue_3way.c135
-rw-r--r--crypto/twofish_common.c13
-rw-r--r--include/crypto/twofish.h2
3 files changed, 145 insertions, 5 deletions
diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c
index 5ede9c444c3e..fa9151df3637 100644
--- a/arch/x86/crypto/twofish_glue_3way.c
+++ b/arch/x86/crypto/twofish_glue_3way.c
@@ -32,6 +32,11 @@
32#include <crypto/algapi.h> 32#include <crypto/algapi.h>
33#include <crypto/twofish.h> 33#include <crypto/twofish.h>
34#include <crypto/b128ops.h> 34#include <crypto/b128ops.h>
35#include <crypto/lrw.h>
36
37#if defined(CONFIG_CRYPTO_LRW) || defined(CONFIG_CRYPTO_LRW_MODULE)
38#define HAS_LRW
39#endif
35 40
36/* regular block cipher functions from twofish_x86_64 module */ 41/* regular block cipher functions from twofish_x86_64 module */
37asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, 42asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst,
@@ -432,6 +437,124 @@ static struct crypto_alg blk_ctr_alg = {
432 }, 437 },
433}; 438};
434 439
440#ifdef HAS_LRW
441
442static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
443{
444 const unsigned int bsize = TF_BLOCK_SIZE;
445 struct twofish_ctx *ctx = priv;
446 int i;
447
448 if (nbytes == 3 * bsize) {
449 twofish_enc_blk_3way(ctx, srcdst, srcdst);
450 return;
451 }
452
453 for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
454 twofish_enc_blk(ctx, srcdst, srcdst);
455}
456
457static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
458{
459 const unsigned int bsize = TF_BLOCK_SIZE;
460 struct twofish_ctx *ctx = priv;
461 int i;
462
463 if (nbytes == 3 * bsize) {
464 twofish_dec_blk_3way(ctx, srcdst, srcdst);
465 return;
466 }
467
468 for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
469 twofish_dec_blk(ctx, srcdst, srcdst);
470}
471
472struct twofish_lrw_ctx {
473 struct lrw_table_ctx lrw_table;
474 struct twofish_ctx twofish_ctx;
475};
476
477static int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key,
478 unsigned int keylen)
479{
480 struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
481 int err;
482
483 err = __twofish_setkey(&ctx->twofish_ctx, key, keylen - TF_BLOCK_SIZE,
484 &tfm->crt_flags);
485 if (err)
486 return err;
487
488 return lrw_init_table(&ctx->lrw_table, key + keylen - TF_BLOCK_SIZE);
489}
490
491static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
492 struct scatterlist *src, unsigned int nbytes)
493{
494 struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
495 be128 buf[3];
496 struct lrw_crypt_req req = {
497 .tbuf = buf,
498 .tbuflen = sizeof(buf),
499
500 .table_ctx = &ctx->lrw_table,
501 .crypt_ctx = &ctx->twofish_ctx,
502 .crypt_fn = encrypt_callback,
503 };
504
505 return lrw_crypt(desc, dst, src, nbytes, &req);
506}
507
508static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
509 struct scatterlist *src, unsigned int nbytes)
510{
511 struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
512 be128 buf[3];
513 struct lrw_crypt_req req = {
514 .tbuf = buf,
515 .tbuflen = sizeof(buf),
516
517 .table_ctx = &ctx->lrw_table,
518 .crypt_ctx = &ctx->twofish_ctx,
519 .crypt_fn = decrypt_callback,
520 };
521
522 return lrw_crypt(desc, dst, src, nbytes, &req);
523}
524
525static void lrw_exit_tfm(struct crypto_tfm *tfm)
526{
527 struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
528
529 lrw_free_table(&ctx->lrw_table);
530}
531
532static struct crypto_alg blk_lrw_alg = {
533 .cra_name = "lrw(twofish)",
534 .cra_driver_name = "lrw-twofish-3way",
535 .cra_priority = 300,
536 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
537 .cra_blocksize = TF_BLOCK_SIZE,
538 .cra_ctxsize = sizeof(struct twofish_lrw_ctx),
539 .cra_alignmask = 0,
540 .cra_type = &crypto_blkcipher_type,
541 .cra_module = THIS_MODULE,
542 .cra_list = LIST_HEAD_INIT(blk_lrw_alg.cra_list),
543 .cra_exit = lrw_exit_tfm,
544 .cra_u = {
545 .blkcipher = {
546 .min_keysize = TF_MIN_KEY_SIZE + TF_BLOCK_SIZE,
547 .max_keysize = TF_MAX_KEY_SIZE + TF_BLOCK_SIZE,
548 .ivsize = TF_BLOCK_SIZE,
549 .setkey = lrw_twofish_setkey,
550 .encrypt = lrw_encrypt,
551 .decrypt = lrw_decrypt,
552 },
553 },
554};
555
556#endif
557
435int __init init(void) 558int __init init(void)
436{ 559{
437 int err; 560 int err;
@@ -445,9 +568,18 @@ int __init init(void)
445 err = crypto_register_alg(&blk_ctr_alg); 568 err = crypto_register_alg(&blk_ctr_alg);
446 if (err) 569 if (err)
447 goto ctr_err; 570 goto ctr_err;
571#ifdef HAS_LRW
572 err = crypto_register_alg(&blk_lrw_alg);
573 if (err)
574 goto blk_lrw_err;
575#endif
448 576
449 return 0; 577 return 0;
450 578
579#ifdef HAS_LRW
580blk_lrw_err:
581 crypto_unregister_alg(&blk_ctr_alg);
582#endif
451ctr_err: 583ctr_err:
452 crypto_unregister_alg(&blk_cbc_alg); 584 crypto_unregister_alg(&blk_cbc_alg);
453cbc_err: 585cbc_err:
@@ -458,6 +590,9 @@ ecb_err:
458 590
459void __exit fini(void) 591void __exit fini(void)
460{ 592{
593#ifdef HAS_LRW
594 crypto_unregister_alg(&blk_lrw_alg);
595#endif
461 crypto_unregister_alg(&blk_ctr_alg); 596 crypto_unregister_alg(&blk_ctr_alg);
462 crypto_unregister_alg(&blk_cbc_alg); 597 crypto_unregister_alg(&blk_cbc_alg);
463 crypto_unregister_alg(&blk_ecb_alg); 598 crypto_unregister_alg(&blk_ecb_alg);
diff --git a/crypto/twofish_common.c b/crypto/twofish_common.c
index 0af216c75d7e..5f62c4f9f6e0 100644
--- a/crypto/twofish_common.c
+++ b/crypto/twofish_common.c
@@ -580,12 +580,9 @@ static const u8 calc_sb_tbl[512] = {
580 ctx->a[(j) + 1] = rol32(y, 9) 580 ctx->a[(j) + 1] = rol32(y, 9)
581 581
582/* Perform the key setup. */ 582/* Perform the key setup. */
583int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len) 583int __twofish_setkey(struct twofish_ctx *ctx, const u8 *key,
584 unsigned int key_len, u32 *flags)
584{ 585{
585
586 struct twofish_ctx *ctx = crypto_tfm_ctx(tfm);
587 u32 *flags = &tfm->crt_flags;
588
589 int i, j, k; 586 int i, j, k;
590 587
591 /* Temporaries for CALC_K. */ 588 /* Temporaries for CALC_K. */
@@ -701,7 +698,13 @@ int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len)
701 698
702 return 0; 699 return 0;
703} 700}
701EXPORT_SYMBOL_GPL(__twofish_setkey);
704 702
703int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len)
704{
705 return __twofish_setkey(crypto_tfm_ctx(tfm), key, key_len,
706 &tfm->crt_flags);
707}
705EXPORT_SYMBOL_GPL(twofish_setkey); 708EXPORT_SYMBOL_GPL(twofish_setkey);
706 709
707MODULE_LICENSE("GPL"); 710MODULE_LICENSE("GPL");
diff --git a/include/crypto/twofish.h b/include/crypto/twofish.h
index c408522595c6..095c901a8af3 100644
--- a/include/crypto/twofish.h
+++ b/include/crypto/twofish.h
@@ -17,6 +17,8 @@ struct twofish_ctx {
17 u32 s[4][256], w[8], k[32]; 17 u32 s[4][256], w[8], k[32];
18}; 18};
19 19
20int __twofish_setkey(struct twofish_ctx *ctx, const u8 *key,
21 unsigned int key_len, u32 *flags);
20int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len); 22int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len);
21 23
22#endif 24#endif