diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2011-10-18 06:33:43 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2011-11-08 22:57:57 -0500 |
commit | bae6d3038b7faff187f4207448a40b9912cf787d (patch) | |
tree | f61e5e596f57c36d949488cf8ddced982e0f68d4 /arch/x86/crypto | |
parent | 131f754161bc01fcf7fbbb08c754ed0e5a62b524 (diff) |
crypto: twofish-x86_64-3way - add xts support
Patch adds XTS support for twofish-x86_64-3way by using xts_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 xts-enc xts-dec
16B 0.98x 1.00x
64B 1.14x 1.15x
256B 1.23x 1.25x
1024B 1.26x 1.29x
8192B 1.28x 1.30x
AMD Phenom II 1055T (fam:16, model:10):
size xts-enc xts-dec
16B 1.03x 1.03x
64B 1.13x 1.16x
256B 1.20x 1.20x
1024B 1.22x 1.22x
8192B 1.22x 1.21x
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'arch/x86/crypto')
-rw-r--r-- | arch/x86/crypto/twofish_glue_3way.c | 119 |
1 files changed, 117 insertions, 2 deletions
diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c index fa9151df3637..954f59eeb7b4 100644 --- a/arch/x86/crypto/twofish_glue_3way.c +++ b/arch/x86/crypto/twofish_glue_3way.c | |||
@@ -33,11 +33,16 @@ | |||
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> | 35 | #include <crypto/lrw.h> |
36 | #include <crypto/xts.h> | ||
36 | 37 | ||
37 | #if defined(CONFIG_CRYPTO_LRW) || defined(CONFIG_CRYPTO_LRW_MODULE) | 38 | #if defined(CONFIG_CRYPTO_LRW) || defined(CONFIG_CRYPTO_LRW_MODULE) |
38 | #define HAS_LRW | 39 | #define HAS_LRW |
39 | #endif | 40 | #endif |
40 | 41 | ||
42 | #if defined(CONFIG_CRYPTO_XTS) || defined(CONFIG_CRYPTO_XTS_MODULE) | ||
43 | #define HAS_XTS | ||
44 | #endif | ||
45 | |||
41 | /* regular block cipher functions from twofish_x86_64 module */ | 46 | /* regular block cipher functions from twofish_x86_64 module */ |
42 | asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, | 47 | asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, |
43 | const u8 *src); | 48 | const u8 *src); |
@@ -437,7 +442,7 @@ static struct crypto_alg blk_ctr_alg = { | |||
437 | }, | 442 | }, |
438 | }; | 443 | }; |
439 | 444 | ||
440 | #ifdef HAS_LRW | 445 | #if defined(HAS_LRW) || defined(HAS_XTS) |
441 | 446 | ||
442 | static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) | 447 | static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) |
443 | { | 448 | { |
@@ -469,6 +474,10 @@ static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) | |||
469 | twofish_dec_blk(ctx, srcdst, srcdst); | 474 | twofish_dec_blk(ctx, srcdst, srcdst); |
470 | } | 475 | } |
471 | 476 | ||
477 | #endif | ||
478 | |||
479 | #ifdef HAS_LRW | ||
480 | |||
472 | struct twofish_lrw_ctx { | 481 | struct twofish_lrw_ctx { |
473 | struct lrw_table_ctx lrw_table; | 482 | struct lrw_table_ctx lrw_table; |
474 | struct twofish_ctx twofish_ctx; | 483 | struct twofish_ctx twofish_ctx; |
@@ -555,6 +564,99 @@ static struct crypto_alg blk_lrw_alg = { | |||
555 | 564 | ||
556 | #endif | 565 | #endif |
557 | 566 | ||
567 | #ifdef HAS_XTS | ||
568 | |||
569 | struct twofish_xts_ctx { | ||
570 | struct twofish_ctx tweak_ctx; | ||
571 | struct twofish_ctx crypt_ctx; | ||
572 | }; | ||
573 | |||
574 | static int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, | ||
575 | unsigned int keylen) | ||
576 | { | ||
577 | struct twofish_xts_ctx *ctx = crypto_tfm_ctx(tfm); | ||
578 | u32 *flags = &tfm->crt_flags; | ||
579 | int err; | ||
580 | |||
581 | /* key consists of keys of equal size concatenated, therefore | ||
582 | * the length must be even | ||
583 | */ | ||
584 | if (keylen % 2) { | ||
585 | *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | |||
589 | /* first half of xts-key is for crypt */ | ||
590 | err = __twofish_setkey(&ctx->crypt_ctx, key, keylen / 2, flags); | ||
591 | if (err) | ||
592 | return err; | ||
593 | |||
594 | /* second half of xts-key is for tweak */ | ||
595 | return __twofish_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2, | ||
596 | flags); | ||
597 | } | ||
598 | |||
599 | static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
600 | struct scatterlist *src, unsigned int nbytes) | ||
601 | { | ||
602 | struct twofish_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
603 | be128 buf[3]; | ||
604 | struct xts_crypt_req req = { | ||
605 | .tbuf = buf, | ||
606 | .tbuflen = sizeof(buf), | ||
607 | |||
608 | .tweak_ctx = &ctx->tweak_ctx, | ||
609 | .tweak_fn = XTS_TWEAK_CAST(twofish_enc_blk), | ||
610 | .crypt_ctx = &ctx->crypt_ctx, | ||
611 | .crypt_fn = encrypt_callback, | ||
612 | }; | ||
613 | |||
614 | return xts_crypt(desc, dst, src, nbytes, &req); | ||
615 | } | ||
616 | |||
617 | static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
618 | struct scatterlist *src, unsigned int nbytes) | ||
619 | { | ||
620 | struct twofish_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
621 | be128 buf[3]; | ||
622 | struct xts_crypt_req req = { | ||
623 | .tbuf = buf, | ||
624 | .tbuflen = sizeof(buf), | ||
625 | |||
626 | .tweak_ctx = &ctx->tweak_ctx, | ||
627 | .tweak_fn = XTS_TWEAK_CAST(twofish_enc_blk), | ||
628 | .crypt_ctx = &ctx->crypt_ctx, | ||
629 | .crypt_fn = decrypt_callback, | ||
630 | }; | ||
631 | |||
632 | return xts_crypt(desc, dst, src, nbytes, &req); | ||
633 | } | ||
634 | |||
635 | static struct crypto_alg blk_xts_alg = { | ||
636 | .cra_name = "xts(twofish)", | ||
637 | .cra_driver_name = "xts-twofish-3way", | ||
638 | .cra_priority = 300, | ||
639 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
640 | .cra_blocksize = TF_BLOCK_SIZE, | ||
641 | .cra_ctxsize = sizeof(struct twofish_xts_ctx), | ||
642 | .cra_alignmask = 0, | ||
643 | .cra_type = &crypto_blkcipher_type, | ||
644 | .cra_module = THIS_MODULE, | ||
645 | .cra_list = LIST_HEAD_INIT(blk_xts_alg.cra_list), | ||
646 | .cra_u = { | ||
647 | .blkcipher = { | ||
648 | .min_keysize = TF_MIN_KEY_SIZE * 2, | ||
649 | .max_keysize = TF_MAX_KEY_SIZE * 2, | ||
650 | .ivsize = TF_BLOCK_SIZE, | ||
651 | .setkey = xts_twofish_setkey, | ||
652 | .encrypt = xts_encrypt, | ||
653 | .decrypt = xts_decrypt, | ||
654 | }, | ||
655 | }, | ||
656 | }; | ||
657 | |||
658 | #endif | ||
659 | |||
558 | int __init init(void) | 660 | int __init init(void) |
559 | { | 661 | { |
560 | int err; | 662 | int err; |
@@ -573,13 +675,23 @@ int __init init(void) | |||
573 | if (err) | 675 | if (err) |
574 | goto blk_lrw_err; | 676 | goto blk_lrw_err; |
575 | #endif | 677 | #endif |
678 | #ifdef HAS_XTS | ||
679 | err = crypto_register_alg(&blk_xts_alg); | ||
680 | if (err) | ||
681 | goto blk_xts_err; | ||
682 | #endif | ||
576 | 683 | ||
577 | return 0; | 684 | return 0; |
578 | 685 | ||
686 | #ifdef HAS_XTS | ||
687 | crypto_unregister_alg(&blk_xts_alg); | ||
688 | blk_xts_err: | ||
689 | #endif | ||
579 | #ifdef HAS_LRW | 690 | #ifdef HAS_LRW |
691 | crypto_unregister_alg(&blk_lrw_alg); | ||
580 | blk_lrw_err: | 692 | blk_lrw_err: |
581 | crypto_unregister_alg(&blk_ctr_alg); | ||
582 | #endif | 693 | #endif |
694 | crypto_unregister_alg(&blk_ctr_alg); | ||
583 | ctr_err: | 695 | ctr_err: |
584 | crypto_unregister_alg(&blk_cbc_alg); | 696 | crypto_unregister_alg(&blk_cbc_alg); |
585 | cbc_err: | 697 | cbc_err: |
@@ -590,6 +702,9 @@ ecb_err: | |||
590 | 702 | ||
591 | void __exit fini(void) | 703 | void __exit fini(void) |
592 | { | 704 | { |
705 | #ifdef HAS_XTS | ||
706 | crypto_unregister_alg(&blk_xts_alg); | ||
707 | #endif | ||
593 | #ifdef HAS_LRW | 708 | #ifdef HAS_LRW |
594 | crypto_unregister_alg(&blk_lrw_alg); | 709 | crypto_unregister_alg(&blk_lrw_alg); |
595 | #endif | 710 | #endif |