diff options
| -rw-r--r-- | drivers/crypto/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/crypto/padlock-aes.c | 174 | ||||
| -rw-r--r-- | drivers/crypto/padlock.h | 1 |
3 files changed, 169 insertions, 7 deletions
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 86c99cd333fa..adb554153f67 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig | |||
| @@ -27,6 +27,7 @@ config CRYPTO_DEV_PADLOCK | |||
| 27 | config CRYPTO_DEV_PADLOCK_AES | 27 | config CRYPTO_DEV_PADLOCK_AES |
| 28 | tristate "PadLock driver for AES algorithm" | 28 | tristate "PadLock driver for AES algorithm" |
| 29 | depends on CRYPTO_DEV_PADLOCK | 29 | depends on CRYPTO_DEV_PADLOCK |
| 30 | select CRYPTO_BLKCIPHER | ||
| 30 | default m | 31 | default m |
| 31 | help | 32 | help |
| 32 | Use VIA PadLock for AES algorithm. | 33 | Use VIA PadLock for AES algorithm. |
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 3e683709243e..f53301e836d9 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c | |||
| @@ -43,11 +43,11 @@ | |||
| 43 | * --------------------------------------------------------------------------- | 43 | * --------------------------------------------------------------------------- |
| 44 | */ | 44 | */ |
| 45 | 45 | ||
| 46 | #include <crypto/algapi.h> | ||
| 46 | #include <linux/module.h> | 47 | #include <linux/module.h> |
| 47 | #include <linux/init.h> | 48 | #include <linux/init.h> |
| 48 | #include <linux/types.h> | 49 | #include <linux/types.h> |
| 49 | #include <linux/errno.h> | 50 | #include <linux/errno.h> |
| 50 | #include <linux/crypto.h> | ||
| 51 | #include <linux/interrupt.h> | 51 | #include <linux/interrupt.h> |
| 52 | #include <linux/kernel.h> | 52 | #include <linux/kernel.h> |
| 53 | #include <asm/byteorder.h> | 53 | #include <asm/byteorder.h> |
| @@ -297,9 +297,9 @@ aes_hw_extkey_available(uint8_t key_len) | |||
| 297 | return 0; | 297 | return 0; |
| 298 | } | 298 | } |
| 299 | 299 | ||
| 300 | static inline struct aes_ctx *aes_ctx(struct crypto_tfm *tfm) | 300 | static inline struct aes_ctx *aes_ctx_common(void *ctx) |
| 301 | { | 301 | { |
| 302 | unsigned long addr = (unsigned long)crypto_tfm_ctx(tfm); | 302 | unsigned long addr = (unsigned long)ctx; |
| 303 | unsigned long align = PADLOCK_ALIGNMENT; | 303 | unsigned long align = PADLOCK_ALIGNMENT; |
| 304 | 304 | ||
| 305 | if (align <= crypto_tfm_ctx_alignment()) | 305 | if (align <= crypto_tfm_ctx_alignment()) |
| @@ -307,6 +307,16 @@ static inline struct aes_ctx *aes_ctx(struct crypto_tfm *tfm) | |||
| 307 | return (struct aes_ctx *)ALIGN(addr, align); | 307 | return (struct aes_ctx *)ALIGN(addr, align); |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | static inline struct aes_ctx *aes_ctx(struct crypto_tfm *tfm) | ||
| 311 | { | ||
| 312 | return aes_ctx_common(crypto_tfm_ctx(tfm)); | ||
| 313 | } | ||
| 314 | |||
| 315 | static inline struct aes_ctx *blk_aes_ctx(struct crypto_blkcipher *tfm) | ||
| 316 | { | ||
| 317 | return aes_ctx_common(crypto_blkcipher_ctx(tfm)); | ||
| 318 | } | ||
| 319 | |||
| 310 | static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | 320 | static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, |
| 311 | unsigned int key_len) | 321 | unsigned int key_len) |
| 312 | { | 322 | { |
| @@ -507,6 +517,141 @@ static struct crypto_alg aes_alg = { | |||
| 507 | } | 517 | } |
| 508 | }; | 518 | }; |
| 509 | 519 | ||
| 520 | static int ecb_aes_encrypt(struct blkcipher_desc *desc, | ||
| 521 | struct scatterlist *dst, struct scatterlist *src, | ||
| 522 | unsigned int nbytes) | ||
| 523 | { | ||
| 524 | struct aes_ctx *ctx = blk_aes_ctx(desc->tfm); | ||
| 525 | struct blkcipher_walk walk; | ||
| 526 | int err; | ||
| 527 | |||
| 528 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 529 | err = blkcipher_walk_virt(desc, &walk); | ||
| 530 | |||
| 531 | while ((nbytes = walk.nbytes)) { | ||
| 532 | padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr, | ||
| 533 | ctx->E, &ctx->cword.encrypt, | ||
| 534 | nbytes / AES_BLOCK_SIZE); | ||
| 535 | nbytes &= AES_BLOCK_SIZE - 1; | ||
| 536 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 537 | } | ||
| 538 | |||
| 539 | return err; | ||
| 540 | } | ||
| 541 | |||
| 542 | static int ecb_aes_decrypt(struct blkcipher_desc *desc, | ||
| 543 | struct scatterlist *dst, struct scatterlist *src, | ||
| 544 | unsigned int nbytes) | ||
| 545 | { | ||
| 546 | struct aes_ctx *ctx = blk_aes_ctx(desc->tfm); | ||
| 547 | struct blkcipher_walk walk; | ||
| 548 | int err; | ||
| 549 | |||
| 550 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 551 | err = blkcipher_walk_virt(desc, &walk); | ||
| 552 | |||
| 553 | while ((nbytes = walk.nbytes)) { | ||
| 554 | padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr, | ||
| 555 | ctx->D, &ctx->cword.decrypt, | ||
| 556 | nbytes / AES_BLOCK_SIZE); | ||
| 557 | nbytes &= AES_BLOCK_SIZE - 1; | ||
| 558 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 559 | } | ||
| 560 | |||
| 561 | return err; | ||
| 562 | } | ||
| 563 | |||
| 564 | static struct crypto_alg ecb_aes_alg = { | ||
| 565 | .cra_name = "ecb(aes)", | ||
| 566 | .cra_driver_name = "ecb-aes-padlock", | ||
| 567 | .cra_priority = PADLOCK_COMPOSITE_PRIORITY, | ||
| 568 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 569 | .cra_blocksize = AES_BLOCK_SIZE, | ||
| 570 | .cra_ctxsize = sizeof(struct aes_ctx), | ||
| 571 | .cra_alignmask = PADLOCK_ALIGNMENT - 1, | ||
| 572 | .cra_type = &crypto_blkcipher_type, | ||
| 573 | .cra_module = THIS_MODULE, | ||
| 574 | .cra_list = LIST_HEAD_INIT(ecb_aes_alg.cra_list), | ||
| 575 | .cra_u = { | ||
| 576 | .blkcipher = { | ||
| 577 | .min_keysize = AES_MIN_KEY_SIZE, | ||
| 578 | .max_keysize = AES_MAX_KEY_SIZE, | ||
| 579 | .setkey = aes_set_key, | ||
| 580 | .encrypt = ecb_aes_encrypt, | ||
| 581 | .decrypt = ecb_aes_decrypt, | ||
| 582 | } | ||
| 583 | } | ||
| 584 | }; | ||
| 585 | |||
| 586 | static int cbc_aes_encrypt(struct blkcipher_desc *desc, | ||
| 587 | struct scatterlist *dst, struct scatterlist *src, | ||
| 588 | unsigned int nbytes) | ||
| 589 | { | ||
| 590 | struct aes_ctx *ctx = blk_aes_ctx(desc->tfm); | ||
| 591 | struct blkcipher_walk walk; | ||
| 592 | int err; | ||
| 593 | |||
| 594 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 595 | err = blkcipher_walk_virt(desc, &walk); | ||
| 596 | |||
| 597 | while ((nbytes = walk.nbytes)) { | ||
| 598 | u8 *iv = padlock_xcrypt_cbc(walk.src.virt.addr, | ||
| 599 | walk.dst.virt.addr, ctx->E, | ||
| 600 | walk.iv, &ctx->cword.encrypt, | ||
| 601 | nbytes / AES_BLOCK_SIZE); | ||
| 602 | memcpy(walk.iv, iv, AES_BLOCK_SIZE); | ||
| 603 | nbytes &= AES_BLOCK_SIZE - 1; | ||
| 604 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 605 | } | ||
| 606 | |||
| 607 | return err; | ||
| 608 | } | ||
| 609 | |||
| 610 | static int cbc_aes_decrypt(struct blkcipher_desc *desc, | ||
| 611 | struct scatterlist *dst, struct scatterlist *src, | ||
| 612 | unsigned int nbytes) | ||
| 613 | { | ||
| 614 | struct aes_ctx *ctx = blk_aes_ctx(desc->tfm); | ||
| 615 | struct blkcipher_walk walk; | ||
| 616 | int err; | ||
| 617 | |||
| 618 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 619 | err = blkcipher_walk_virt(desc, &walk); | ||
| 620 | |||
| 621 | while ((nbytes = walk.nbytes)) { | ||
| 622 | padlock_xcrypt_cbc(walk.src.virt.addr, walk.dst.virt.addr, | ||
| 623 | ctx->D, walk.iv, &ctx->cword.decrypt, | ||
| 624 | nbytes / AES_BLOCK_SIZE); | ||
| 625 | nbytes &= AES_BLOCK_SIZE - 1; | ||
| 626 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 627 | } | ||
| 628 | |||
| 629 | return err; | ||
| 630 | } | ||
| 631 | |||
| 632 | static struct crypto_alg cbc_aes_alg = { | ||
| 633 | .cra_name = "cbc(aes)", | ||
| 634 | .cra_driver_name = "cbc-aes-padlock", | ||
| 635 | .cra_priority = PADLOCK_COMPOSITE_PRIORITY, | ||
| 636 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 637 | .cra_blocksize = AES_BLOCK_SIZE, | ||
| 638 | .cra_ctxsize = sizeof(struct aes_ctx), | ||
| 639 | .cra_alignmask = PADLOCK_ALIGNMENT - 1, | ||
| 640 | .cra_type = &crypto_blkcipher_type, | ||
| 641 | .cra_module = THIS_MODULE, | ||
| 642 | .cra_list = LIST_HEAD_INIT(cbc_aes_alg.cra_list), | ||
| 643 | .cra_u = { | ||
| 644 | .blkcipher = { | ||
| 645 | .min_keysize = AES_MIN_KEY_SIZE, | ||
| 646 | .max_keysize = AES_MAX_KEY_SIZE, | ||
| 647 | .ivsize = AES_BLOCK_SIZE, | ||
| 648 | .setkey = aes_set_key, | ||
| 649 | .encrypt = cbc_aes_encrypt, | ||
| 650 | .decrypt = cbc_aes_decrypt, | ||
| 651 | } | ||
| 652 | } | ||
| 653 | }; | ||
| 654 | |||
| 510 | static int __init padlock_init(void) | 655 | static int __init padlock_init(void) |
| 511 | { | 656 | { |
| 512 | int ret; | 657 | int ret; |
| @@ -522,18 +667,33 @@ static int __init padlock_init(void) | |||
| 522 | } | 667 | } |
| 523 | 668 | ||
| 524 | gen_tabs(); | 669 | gen_tabs(); |
| 525 | if ((ret = crypto_register_alg(&aes_alg))) { | 670 | if ((ret = crypto_register_alg(&aes_alg))) |
| 526 | printk(KERN_ERR PFX "VIA PadLock AES initialization failed.\n"); | 671 | goto aes_err; |
| 527 | return ret; | 672 | |
| 528 | } | 673 | if ((ret = crypto_register_alg(&ecb_aes_alg))) |
| 674 | goto ecb_aes_err; | ||
| 675 | |||
| 676 | if ((ret = crypto_register_alg(&cbc_aes_alg))) | ||
| 677 | goto cbc_aes_err; | ||
| 529 | 678 | ||
| 530 | printk(KERN_NOTICE PFX "Using VIA PadLock ACE for AES algorithm.\n"); | 679 | printk(KERN_NOTICE PFX "Using VIA PadLock ACE for AES algorithm.\n"); |
| 531 | 680 | ||
| 681 | out: | ||
| 532 | return ret; | 682 | return ret; |
| 683 | |||
| 684 | cbc_aes_err: | ||
| 685 | crypto_unregister_alg(&ecb_aes_alg); | ||
| 686 | ecb_aes_err: | ||
| 687 | crypto_unregister_alg(&aes_alg); | ||
| 688 | aes_err: | ||
| 689 | printk(KERN_ERR PFX "VIA PadLock AES initialization failed.\n"); | ||
| 690 | goto out; | ||
| 533 | } | 691 | } |
| 534 | 692 | ||
| 535 | static void __exit padlock_fini(void) | 693 | static void __exit padlock_fini(void) |
| 536 | { | 694 | { |
| 695 | crypto_unregister_alg(&cbc_aes_alg); | ||
| 696 | crypto_unregister_alg(&ecb_aes_alg); | ||
| 537 | crypto_unregister_alg(&aes_alg); | 697 | crypto_unregister_alg(&aes_alg); |
| 538 | } | 698 | } |
| 539 | 699 | ||
diff --git a/drivers/crypto/padlock.h b/drivers/crypto/padlock.h index 7e3385b0904d..b728e4518bd1 100644 --- a/drivers/crypto/padlock.h +++ b/drivers/crypto/padlock.h | |||
| @@ -18,5 +18,6 @@ | |||
| 18 | #define PFX "padlock: " | 18 | #define PFX "padlock: " |
| 19 | 19 | ||
| 20 | #define PADLOCK_CRA_PRIORITY 300 | 20 | #define PADLOCK_CRA_PRIORITY 300 |
| 21 | #define PADLOCK_COMPOSITE_PRIORITY 400 | ||
| 21 | 22 | ||
| 22 | #endif /* _CRYPTO_PADLOCK_H */ | 23 | #endif /* _CRYPTO_PADLOCK_H */ |
