diff options
Diffstat (limited to 'arch/x86/crypto/twofish_glue_3way.c')
-rw-r--r-- | arch/x86/crypto/twofish_glue_3way.c | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c index 5ede9c444c3e..7fee8c152f93 100644 --- a/arch/x86/crypto/twofish_glue_3way.c +++ b/arch/x86/crypto/twofish_glue_3way.c | |||
@@ -32,6 +32,8 @@ | |||
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 | #include <crypto/xts.h> | ||
35 | 37 | ||
36 | /* regular block cipher functions from twofish_x86_64 module */ | 38 | /* regular block cipher functions from twofish_x86_64 module */ |
37 | asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, | 39 | asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, |
@@ -432,6 +434,209 @@ static struct crypto_alg blk_ctr_alg = { | |||
432 | }, | 434 | }, |
433 | }; | 435 | }; |
434 | 436 | ||
437 | static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) | ||
438 | { | ||
439 | const unsigned int bsize = TF_BLOCK_SIZE; | ||
440 | struct twofish_ctx *ctx = priv; | ||
441 | int i; | ||
442 | |||
443 | if (nbytes == 3 * bsize) { | ||
444 | twofish_enc_blk_3way(ctx, srcdst, srcdst); | ||
445 | return; | ||
446 | } | ||
447 | |||
448 | for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) | ||
449 | twofish_enc_blk(ctx, srcdst, srcdst); | ||
450 | } | ||
451 | |||
452 | static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes) | ||
453 | { | ||
454 | const unsigned int bsize = TF_BLOCK_SIZE; | ||
455 | struct twofish_ctx *ctx = priv; | ||
456 | int i; | ||
457 | |||
458 | if (nbytes == 3 * bsize) { | ||
459 | twofish_dec_blk_3way(ctx, srcdst, srcdst); | ||
460 | return; | ||
461 | } | ||
462 | |||
463 | for (i = 0; i < nbytes / bsize; i++, srcdst += bsize) | ||
464 | twofish_dec_blk(ctx, srcdst, srcdst); | ||
465 | } | ||
466 | |||
467 | struct twofish_lrw_ctx { | ||
468 | struct lrw_table_ctx lrw_table; | ||
469 | struct twofish_ctx twofish_ctx; | ||
470 | }; | ||
471 | |||
472 | static int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, | ||
473 | unsigned int keylen) | ||
474 | { | ||
475 | struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm); | ||
476 | int err; | ||
477 | |||
478 | err = __twofish_setkey(&ctx->twofish_ctx, key, keylen - TF_BLOCK_SIZE, | ||
479 | &tfm->crt_flags); | ||
480 | if (err) | ||
481 | return err; | ||
482 | |||
483 | return lrw_init_table(&ctx->lrw_table, key + keylen - TF_BLOCK_SIZE); | ||
484 | } | ||
485 | |||
486 | static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
487 | struct scatterlist *src, unsigned int nbytes) | ||
488 | { | ||
489 | struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
490 | be128 buf[3]; | ||
491 | struct lrw_crypt_req req = { | ||
492 | .tbuf = buf, | ||
493 | .tbuflen = sizeof(buf), | ||
494 | |||
495 | .table_ctx = &ctx->lrw_table, | ||
496 | .crypt_ctx = &ctx->twofish_ctx, | ||
497 | .crypt_fn = encrypt_callback, | ||
498 | }; | ||
499 | |||
500 | return lrw_crypt(desc, dst, src, nbytes, &req); | ||
501 | } | ||
502 | |||
503 | static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
504 | struct scatterlist *src, unsigned int nbytes) | ||
505 | { | ||
506 | struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
507 | be128 buf[3]; | ||
508 | struct lrw_crypt_req req = { | ||
509 | .tbuf = buf, | ||
510 | .tbuflen = sizeof(buf), | ||
511 | |||
512 | .table_ctx = &ctx->lrw_table, | ||
513 | .crypt_ctx = &ctx->twofish_ctx, | ||
514 | .crypt_fn = decrypt_callback, | ||
515 | }; | ||
516 | |||
517 | return lrw_crypt(desc, dst, src, nbytes, &req); | ||
518 | } | ||
519 | |||
520 | static void lrw_exit_tfm(struct crypto_tfm *tfm) | ||
521 | { | ||
522 | struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm); | ||
523 | |||
524 | lrw_free_table(&ctx->lrw_table); | ||
525 | } | ||
526 | |||
527 | static struct crypto_alg blk_lrw_alg = { | ||
528 | .cra_name = "lrw(twofish)", | ||
529 | .cra_driver_name = "lrw-twofish-3way", | ||
530 | .cra_priority = 300, | ||
531 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
532 | .cra_blocksize = TF_BLOCK_SIZE, | ||
533 | .cra_ctxsize = sizeof(struct twofish_lrw_ctx), | ||
534 | .cra_alignmask = 0, | ||
535 | .cra_type = &crypto_blkcipher_type, | ||
536 | .cra_module = THIS_MODULE, | ||
537 | .cra_list = LIST_HEAD_INIT(blk_lrw_alg.cra_list), | ||
538 | .cra_exit = lrw_exit_tfm, | ||
539 | .cra_u = { | ||
540 | .blkcipher = { | ||
541 | .min_keysize = TF_MIN_KEY_SIZE + TF_BLOCK_SIZE, | ||
542 | .max_keysize = TF_MAX_KEY_SIZE + TF_BLOCK_SIZE, | ||
543 | .ivsize = TF_BLOCK_SIZE, | ||
544 | .setkey = lrw_twofish_setkey, | ||
545 | .encrypt = lrw_encrypt, | ||
546 | .decrypt = lrw_decrypt, | ||
547 | }, | ||
548 | }, | ||
549 | }; | ||
550 | |||
551 | struct twofish_xts_ctx { | ||
552 | struct twofish_ctx tweak_ctx; | ||
553 | struct twofish_ctx crypt_ctx; | ||
554 | }; | ||
555 | |||
556 | static int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key, | ||
557 | unsigned int keylen) | ||
558 | { | ||
559 | struct twofish_xts_ctx *ctx = crypto_tfm_ctx(tfm); | ||
560 | u32 *flags = &tfm->crt_flags; | ||
561 | int err; | ||
562 | |||
563 | /* key consists of keys of equal size concatenated, therefore | ||
564 | * the length must be even | ||
565 | */ | ||
566 | if (keylen % 2) { | ||
567 | *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | ||
568 | return -EINVAL; | ||
569 | } | ||
570 | |||
571 | /* first half of xts-key is for crypt */ | ||
572 | err = __twofish_setkey(&ctx->crypt_ctx, key, keylen / 2, flags); | ||
573 | if (err) | ||
574 | return err; | ||
575 | |||
576 | /* second half of xts-key is for tweak */ | ||
577 | return __twofish_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2, | ||
578 | flags); | ||
579 | } | ||
580 | |||
581 | static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
582 | struct scatterlist *src, unsigned int nbytes) | ||
583 | { | ||
584 | struct twofish_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
585 | be128 buf[3]; | ||
586 | struct xts_crypt_req req = { | ||
587 | .tbuf = buf, | ||
588 | .tbuflen = sizeof(buf), | ||
589 | |||
590 | .tweak_ctx = &ctx->tweak_ctx, | ||
591 | .tweak_fn = XTS_TWEAK_CAST(twofish_enc_blk), | ||
592 | .crypt_ctx = &ctx->crypt_ctx, | ||
593 | .crypt_fn = encrypt_callback, | ||
594 | }; | ||
595 | |||
596 | return xts_crypt(desc, dst, src, nbytes, &req); | ||
597 | } | ||
598 | |||
599 | static int xts_decrypt(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 = decrypt_callback, | ||
612 | }; | ||
613 | |||
614 | return xts_crypt(desc, dst, src, nbytes, &req); | ||
615 | } | ||
616 | |||
617 | static struct crypto_alg blk_xts_alg = { | ||
618 | .cra_name = "xts(twofish)", | ||
619 | .cra_driver_name = "xts-twofish-3way", | ||
620 | .cra_priority = 300, | ||
621 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
622 | .cra_blocksize = TF_BLOCK_SIZE, | ||
623 | .cra_ctxsize = sizeof(struct twofish_xts_ctx), | ||
624 | .cra_alignmask = 0, | ||
625 | .cra_type = &crypto_blkcipher_type, | ||
626 | .cra_module = THIS_MODULE, | ||
627 | .cra_list = LIST_HEAD_INIT(blk_xts_alg.cra_list), | ||
628 | .cra_u = { | ||
629 | .blkcipher = { | ||
630 | .min_keysize = TF_MIN_KEY_SIZE * 2, | ||
631 | .max_keysize = TF_MAX_KEY_SIZE * 2, | ||
632 | .ivsize = TF_BLOCK_SIZE, | ||
633 | .setkey = xts_twofish_setkey, | ||
634 | .encrypt = xts_encrypt, | ||
635 | .decrypt = xts_decrypt, | ||
636 | }, | ||
637 | }, | ||
638 | }; | ||
639 | |||
435 | int __init init(void) | 640 | int __init init(void) |
436 | { | 641 | { |
437 | int err; | 642 | int err; |
@@ -445,9 +650,20 @@ int __init init(void) | |||
445 | err = crypto_register_alg(&blk_ctr_alg); | 650 | err = crypto_register_alg(&blk_ctr_alg); |
446 | if (err) | 651 | if (err) |
447 | goto ctr_err; | 652 | goto ctr_err; |
653 | err = crypto_register_alg(&blk_lrw_alg); | ||
654 | if (err) | ||
655 | goto blk_lrw_err; | ||
656 | err = crypto_register_alg(&blk_xts_alg); | ||
657 | if (err) | ||
658 | goto blk_xts_err; | ||
448 | 659 | ||
449 | return 0; | 660 | return 0; |
450 | 661 | ||
662 | crypto_unregister_alg(&blk_xts_alg); | ||
663 | blk_xts_err: | ||
664 | crypto_unregister_alg(&blk_lrw_alg); | ||
665 | blk_lrw_err: | ||
666 | crypto_unregister_alg(&blk_ctr_alg); | ||
451 | ctr_err: | 667 | ctr_err: |
452 | crypto_unregister_alg(&blk_cbc_alg); | 668 | crypto_unregister_alg(&blk_cbc_alg); |
453 | cbc_err: | 669 | cbc_err: |
@@ -458,6 +674,8 @@ ecb_err: | |||
458 | 674 | ||
459 | void __exit fini(void) | 675 | void __exit fini(void) |
460 | { | 676 | { |
677 | crypto_unregister_alg(&blk_xts_alg); | ||
678 | crypto_unregister_alg(&blk_lrw_alg); | ||
461 | crypto_unregister_alg(&blk_ctr_alg); | 679 | crypto_unregister_alg(&blk_ctr_alg); |
462 | crypto_unregister_alg(&blk_cbc_alg); | 680 | crypto_unregister_alg(&blk_cbc_alg); |
463 | crypto_unregister_alg(&blk_ecb_alg); | 681 | crypto_unregister_alg(&blk_ecb_alg); |