aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-08-21 07:38:42 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2006-09-20 21:44:35 -0400
commit28ce728a90cce3a0c6c0ed00354299de52db94b1 (patch)
treed5f8c799cb949a5afdfb9db4fb9c4c749820c35e
parentdb131ef9084110d9e82549c0a627e157e8bb99d7 (diff)
[CRYPTO] padlock: Added block cipher versions of CBC/ECB
This patch adds block cipher algorithms for cbc(aes) and ecb(aes) for the PadLock device. Once all users to the old cipher type have been converted the old cbc/ecb PadLock operations will be removed. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/Kconfig1
-rw-r--r--drivers/crypto/padlock-aes.c174
-rw-r--r--drivers/crypto/padlock.h1
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
27config CRYPTO_DEV_PADLOCK_AES 27config 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
300static inline struct aes_ctx *aes_ctx(struct crypto_tfm *tfm) 300static 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
310static inline struct aes_ctx *aes_ctx(struct crypto_tfm *tfm)
311{
312 return aes_ctx_common(crypto_tfm_ctx(tfm));
313}
314
315static inline struct aes_ctx *blk_aes_ctx(struct crypto_blkcipher *tfm)
316{
317 return aes_ctx_common(crypto_blkcipher_ctx(tfm));
318}
319
310static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 320static 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
520static 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
542static 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
564static 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
586static 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
610static 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
632static 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
510static int __init padlock_init(void) 655static 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
681out:
532 return ret; 682 return ret;
683
684cbc_aes_err:
685 crypto_unregister_alg(&ecb_aes_alg);
686ecb_aes_err:
687 crypto_unregister_alg(&aes_alg);
688aes_err:
689 printk(KERN_ERR PFX "VIA PadLock AES initialization failed.\n");
690 goto out;
533} 691}
534 692
535static void __exit padlock_fini(void) 693static 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 */