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 */ |