crypto: Add support for the Geode AES engine
Subsystems (2)
RFC 1/1 crypto: Add support for the Geode AES engine
Hey all -
I've had a poor excuse for a crypto driver for the Geode LX AES hardware sitting in my Geode GIT tree (and -mm) for some time now. I sent out the original version some time ago (June) and I got some very smart recommendations for changes, but other events transpired, and I didn't do a very good job of following up.
So now, in the interest of getting this out of everybody's hair and on the path to mainstreaming, I'm sending out a newly updated version of the driver for comments. This should be fully updated for all the new API changes in the crypto GIT tree. Once this is acceptable, I would like to get this pulled into the crypto tree.
Thanks,
Jordan
Signature · 4 lines
Jordan Crouse Senior Linux Engineer Advanced Micro Devices, Inc. <www.amd.com/embeddedprocessors>
[PATCH] crypto: Add support for the Geode LX hardware AES engine
This adds support for the AES engine built into the Geode LX processor.
drivers/crypto/Kconfig +13 -0
@@ -51,4 +51,17 @@ config CRYPTO_DEV_PADLOCK_SHA If unsure say M. The compiled module will be called padlock-sha.ko +config CRYPTO_DEV_GEODE + tristate "Support for the Geode LX AES engine" + depends on CRYPTO && X86_32 + select CRYPTO_ALGAPI + select CRYPTO_BLKCIPHER + default m + help + Say 'Y' here to use the AMD Geode LX processor on-board AES + engine for the CryptoAPI AES alogrithm. + + To compile this driver as a module, choose M here: the module + will be called geode-aes. + endmenu
drivers/crypto/Makefile +1 -0
@@ -1,3 +1,4 @@ obj-$(CONFIG_CRYPTO_DEV_PADLOCK) += padlock.o obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o +obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o
drivers/crypto/geode-aes.c new file +477 -0
477 lines not on this page · raw message
drivers/crypto/geode-aes.h new file +42 -0
42 lines not on this page · raw message
Quoted 8 lines · Jordan Crouse
Hey all -
I've had a poor excuse for a crypto driver for the Geode LX AES hardware sitting in my Geode GIT tree (and -mm) for some time now. I sent out the original version some time ago (June) and I got some very smart recommendations for changes, but other events transpired, and I didn't do a very good job of following up.
Quoted 5 lines
So now, in the interest of getting this out of everybody's hair and on the path to mainstreaming, I'm sending out a newly updated version of the driver for comments. This should be fully updated for all the new API changes in the crypto GIT tree. Once this is acceptable, I would like to get this pulled into the crypto tree.
As far as I can see, register access is not protected, how can your driver handle the case when dm-crypt and IPsec simultaneously try to encrypt/decrypt some data, it can happen even around preemt_disable/enable calls and actually crypto processing can happen in interrupt context too (although it is not the best thing to do).
You added timeout for the broken hardware condition, I think it is better to return some error from _crypt() in that case, and, btw, that name is not very good choice.
Quoted 7 lines
Thanks,
JordanSignature · 4 lines
Jordan Crouse Senior Linux Engineer Advanced Micro Devices, Inc. <www.amd.com/embeddedprocessors>
Signature · 1 line
Evgeniy Polyakov
crypto: Add support for the Geode AES engine (v2)
Quoted 5 lines
As far as I can see, register access is not protected, how can your driver handle the case when dm-crypt and IPsec simultaneously try to encrypt/decrypt some data, it can happen even around preemt_disable/enable calls and actually crypto processing can happen in interrupt context too (although it is not the best thing to do).
I was sitting there trying to architect some grand scheme, and then it occured to me that we should just turn off the interrupts all together in the critical area. Its not optimal for performance, but it avoids lots of crazy if statements.
Quoted 3 lines
You added timeout for the broken hardware condition, I think it is better to return some error from
_crypt()in that case, and, btw, that name is not very good choice.
Fixed the name and I return the error. I don't propagate it through the whole chain, because quite frankly, if the crypto engine fails, then its a good bet the processor is on fire. :)
Jordan
Signature · 4 lines
Jordan Crouse Senior Linux Engineer Advanced Micro Devices, Inc. <www.amd.com/embeddedprocessors>
drivers/crypto/Kconfig +13 -0
@@ -51,4 +51,17 @@ config CRYPTO_DEV_PADLOCK_SHA If unsure say M. The compiled module will be called padlock-sha.ko +config CRYPTO_DEV_GEODE + tristate "Support for the Geode LX AES engine" + depends on CRYPTO && X86_32 + select CRYPTO_ALGAPI + select CRYPTO_BLKCIPHER + default m + help + Say 'Y' here to use the AMD Geode LX processor on-board AES + engine for the CryptoAPI AES alogrithm. + + To compile this driver as a module, choose M here: the module + will be called geode-aes. + endmenu
drivers/crypto/Makefile +1 -0
@@ -1,3 +1,4 @@ obj-$(CONFIG_CRYPTO_DEV_PADLOCK) += padlock.o obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o +obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o
drivers/crypto/geode-aes.c new file +481 -0
481 lines not on this page · raw message
drivers/crypto/geode-aes.h new file +42 -0
42 lines not on this page · raw message
Re: crypto: Add support for the Geode AES engine (v3)
Sigh - forgot to do an 'stg refresh' before generating the diff. This one actually compiles.
Jordan
Signature · 4 lines
Jordan Crouse Senior Linux Engineer Advanced Micro Devices, Inc. <www.amd.com/embeddedprocessors>
[PATCH] crypto: Add support for the Geode LX AES hardware
This adds support for the AES engine on the Geode LX processor.
drivers/crypto/Kconfig +13 -0
@@ -51,4 +51,17 @@ config CRYPTO_DEV_PADLOCK_SHA If unsure say M. The compiled module will be called padlock-sha.ko +config CRYPTO_DEV_GEODE + tristate "Support for the Geode LX AES engine" + depends on CRYPTO && X86_32 + select CRYPTO_ALGAPI + select CRYPTO_BLKCIPHER + default m + help + Say 'Y' here to use the AMD Geode LX processor on-board AES + engine for the CryptoAPI AES alogrithm. + + To compile this driver as a module, choose M here: the module + will be called geode-aes. + endmenu
drivers/crypto/Makefile +1 -0
@@ -1,3 +1,4 @@ obj-$(CONFIG_CRYPTO_DEV_PADLOCK) += padlock.o obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o +obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o
drivers/crypto/geode-aes.c new file +486 -0
486 lines not on this page · raw message
drivers/crypto/geode-aes.h new file +42 -0
42 lines not on this page · raw message
Re: crypto: Add support for the Geode AES engine (v2)
In reply to Jordan CrouseQuoted 29 lines · On Thu, 28 Sep 2006 15:47:50 -0600 "Jordan Crouse" <[email protected]>…
Quoted 5 lines
As far as I can see, register access is not protected, how can your driver handle the case when dm-crypt and IPsec simultaneously try to encrypt/decrypt some data, it can happen even around preemt_disable/enable calls and actually crypto processing can happen in interrupt context too (although it is not the best thing to do).
I was sitting there trying to architect some grand scheme, and then it occured to me that we should just turn off the interrupts all together in the critical area. Its not optimal for performance, but it avoids lots of crazy if statements.
Quoted 3 lines
You added timeout for the broken hardware condition, I think it is better to return some error from
_crypt()in that case, and, btw, that name is not very good choice.Fixed the name and I return the error. I don't propagate it through the whole chain, because quite frankly, if the crypto engine fails, then its a good bet the processor is on fire. :)
...
drivers/crypto/Kconfig +0
-0
drivers/crypto/Kconfig config CRYPTO_DEV_PADLOCK_SHA · line 56
Quoted 6 lines
drivers/crypto/Kconfig +3
-0@@ -51,4 +51,17 @@ config CRYPTO_DEV_PADLOCK_SHA If unsure say M. The compiled module will be called padlock-sha.ko +config CRYPTO_DEV_GEODE + tristate "Support for the Geode LX AES engine" + depends on CRYPTO && X86_32
Does it depend on GEODE in some fashion too?
Quoted 12 lines
drivers/crypto/Kconfig +10
-0+ select CRYPTO_ALGAPI + select CRYPTO_BLKCIPHER + default m + help + Say 'Y' here to use the AMD Geode LX processor on-board AES + engine for the CryptoAPI AES alogrithm. + + To compile this driver as a module, choose M here: the module + will be called geode-aes. + endmenu
drivers/crypto/Kconfig config CRYPTO_DEV_PADLOCK_SHA
Quoted 10 lines
drivers/crypto/Kconfig +8
-0+ +/* Useful macros */ + +#define SET_KEY(key) _writefield(AES_WRITEKEY0_REG, key) +#define SET_IV(iv) _writefield(AES_WRITEIV0_REG, iv) +#define GET_IV(iv) _readfield(AES_WRITEIV0_REG, iv) +#define AWRITE(val, reg) (iowrite32(val, _iobase + reg)) +#define AREAD(reg) (ioread32(_iobase + reg))
lower-case static-inlines are nicer...
Or just remove them and open-code it all.
Quoted 52 lines
drivers/crypto/Kconfig +49
-0+/* Static structures */ + +static void __iomem * _iobase; + +/* Write a 128 bit field (either a writable key or IV) */ +static inline void +_writefield(u32 offset, void *value) +{ + int i; + for(i = 0; i < 4; i++) + AWRITE(((u32 *) value)[i], offset + (i * 4)); +} +/* Read a 128 bit field (either a writable key or IV) */ +static inline void +_readfield(u32 offset, void *value) +{ + int i; + for(i = 0; i < 4; i++) + ((u32 *) value)[i] = AREAD(offset + (i * 4)); +} + +unsigned int +geode_aes_crypt(struct geode_aes_op *op) +{ + u32 flags = 0; + int iflags; + + if (op->len == 0 || op->src == op->dst) + return 0; + + if (op->flags & AES_FLAGS_COHERENT) + flags |= (AES_CTRL_DCA | AES_CTRL_SCA); + + if (op->dir == AES_DIR_ENCRYPT) + flags |= AES_CTRL_ENCRYPT; + + /* Start the critical section */ + + spin_lock_irqsave(&lock, iflags); + + if (op->mode == AES_MODE_CBC) { + flags |= AES_CTRL_CBC; + SET_IV(op->iv); + } + + if (op->flags & AES_FLAGS_USRKEY) { + flags |= AES_CTRL_WRKEY; + SET_KEY(op->key); + }
drivers/crypto/Kconfig
Quoted 10 lines
drivers/crypto/Kconfig +10
-0+ + do_crypt(op->src, op->dst, op->len, flags); + + if (op->mode == AES_MODE_CBC) + GET_IV(op->iv); + + spin_lock_irqrestore(&lock, iflags); + + return op->len; +}
Running do_crypt() under spin_lock_irqsave() seems a bit sad from a latency POV.
drivers/crypto/Kconfig
Quoted 4 lines
drivers/crypto/Kconfig +4
-0+/* CRYPTO-API Functions */ + +#define blk_ctx(tfm) ((struct geode_aes_op *) crypto_blkcipher_ctx(tfm)) +#define ctx(tfm) ((struct geode_aes_op *) crypto_tfm_ctx(tfm))
Both crypto_blkcipher_ctx() and crypto_tfm_ctx() return a nice void*. There's no need for the typecast and hence there's really no need for these macros at all. Simply open-code the crypto_blkcipher_ctx() and crypto_tfm_ctx() calls.
Quoted 14 lines
drivers/crypto/Kconfig +14
-0+static int +geode_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int len) +{ + struct geode_aes_op *op = ctx(tfm); + + if (len != AES_KEY_LENGTH) { + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + memcpy(op->key, key, len); + return 0; +} +
drivers/crypto/Kconfig
Quoted 10 lines
drivers/crypto/Kconfig +10
-0+static void +geode_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +{ + struct geode_aes_op *op = ctx(tfm); + + if ((out == NULL) || (in == NULL)) + return; + + op->src = (void *) in; + op->dst = (void *) out;
Unneeded casts
Quoted 9 lines
drivers/crypto/Kconfig +9
-0+ op->mode = AES_MODE_ECB; + op->flags = 0; + op->len = AES_MIN_BLOCK_SIZE; + op->dir = AES_DIR_ENCRYPT; + + geode_aes_crypt(op); +} + +
drivers/crypto/Kconfig
Quoted 10 lines
drivers/crypto/Kconfig +10
-0+static void +geode_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +{ + struct geode_aes_op *op = ctx(tfm); + + if ((out == NULL) || (in == NULL)) + return; + + op->src = (void *) in; + op->dst = (void *) out;
Unneeded casts
Quoted 5 lines
drivers/crypto/Kconfig +5
-0+static int +geode_cbc_decrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, struct scatterlist *src, + unsigned int nbytes) +{
drivers/crypto/Kconfig
Quoted 10 lines
drivers/crypto/Kconfig +10
-0+ struct geode_aes_op *op = blk_ctx(desc->tfm); + struct blkcipher_walk walk; + int err, ret; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt(desc, &walk); + + while((nbytes = walk.nbytes)) { + op->src = (void *) walk.src.virt.addr, + op->dst = (void *) walk.dst.virt.addr;
Unneeded cast
Quoted 12 lines
drivers/crypto/Kconfig +12
-0+ op->mode = AES_MODE_CBC; + op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE); + op->dir = AES_DIR_DECRYPT; + + memcpy(op->iv, walk.iv, AES_IV_LENGTH); + + ret = geode_aes_crypt(op); + + memcpy(walk.iv, op->iv, AES_IV_LENGTH); + nbytes -= ret; + + err = blkcipher_walk_done(desc, &walk, nbytes);
drivers/crypto/Kconfig
Quoted 10 lines
drivers/crypto/Kconfig +6
-0+ } + + return err; +} + op->src = (void *) walk.src.virt.addr, + op->dst = (void *) walk.dst.virt.addr;
Unneeded cast. Please review whole patchset.
drivers/crypto/Kconfig
Quoted 4 lines
drivers/crypto/Kconfig +4
-0+struct pci_device_id geode_aes_tbl[] = { + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LX_AES, PCI_ANY_ID, PCI_ANY_ID} , + { 0, } +};
static?
drivers/crypto/Kconfig
Quoted 6 lines
drivers/crypto/Kconfig +6
-0+static struct pci_driver geode_aes_driver = { + name: "Geode LX AES", + id_table: geode_aes_tbl, + probe: geode_aes_probe, + remove: __devexit_p(geode_aes_remove) +};
Please use `.name = value'
drivers/crypto/Kconfig
Quoted 11 lines
drivers/crypto/Kconfig +11
-0+static int __devinit +geode_aes_init(void) +{ + return pci_module_init(&geode_aes_driver); +} + +static void __devexit +geode_aes_exit(void) +{ + pci_unregister_driver(&geode_aes_driver); +}
These should be __init and __exit, I think?
drivers/crypto/Kconfig
Quoted 13 lines
drivers/crypto/Kconfig +13
-0+struct geode_aes_op { + + void *src; + void *dst; + + u32 mode; + u32 dir; + u32 flags; + int len; + + u8 key[AES_KEY_LENGTH]; + u8 iv[AES_IV_LENGTH]; +};
tabs, please.
A message that is not in the archive (sent off-list or not yet received): LYRIS-4270-86789-2006.09.28-16.10.32--jordan.crouse#[email protected]
Re: crypto: Add support for the Geode AES engine (v4)
Quoted 1 line
Does it depend on GEODE in some fashion too?
Its only available on the Geode platform, but there is no code it needs that is only exposed by CONFIG_MGEODE_LX elsewhere in the kernel. This is just appears as a regular, run of the mill PCI device.
Quoted 16 lines
Quoted 16 lines
(quoted diff) +16
-0+ spin_lock_irqsave(&lock, iflags); + + if (op->mode == AES_MODE_CBC) { + flags |= AES_CTRL_CBC; + SET_IV(op->iv); + } + + if (op->flags & AES_FLAGS_USRKEY) { + flags |= AES_CTRL_WRKEY; + SET_KEY(op->key); + } + + do_crypt(op->src, op->dst, op->len, flags); + + if (op->mode == AES_MODE_CBC) + GET_IV(op->iv);
Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ + spin_lock_irqrestore(&lock, iflags); + + return op->len; +}Running
do_crypt()underspin_lock_irqsave()seems a bit sad from a latency POV.
Indeed - but the problem is that the key and/or the IV need to stay unmodified until the operation completes. The datasheet calls this out specifically:
"This register should not be changed during an AES encryption or decryption operation."
So not only do we need to protect ourselves while changing the fields, we also need to make sure they remain untouched until the whole operation is completed.
Changes made and new version follows. Thanks for the comments.
Jordan
Signature · 4 lines
Jordan Crouse Senior Linux Engineer Advanced Micro Devices, Inc. <www.amd.com/embeddedprocessors>
[PATCH] crypto: Add support for the Geode LX AES hardware
Add a driver to support the AES hardware on the Geode LX processor.
drivers/crypto/Kconfig +13 -0
@@ -51,4 +51,17 @@ config CRYPTO_DEV_PADLOCK_SHA If unsure say M. The compiled module will be called padlock-sha.ko +config CRYPTO_DEV_GEODE + tristate "Support for the Geode LX AES engine" + depends on CRYPTO && X86_32 + select CRYPTO_ALGAPI + select CRYPTO_BLKCIPHER + default m + help + Say 'Y' here to use the AMD Geode LX processor on-board AES + engine for the CryptoAPI AES alogrithm. + + To compile this driver as a module, choose M here: the module + will be called geode-aes. + endmenu
drivers/crypto/Makefile +1 -0
@@ -1,3 +1,4 @@ obj-$(CONFIG_CRYPTO_DEV_PADLOCK) += padlock.o obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o +obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o
drivers/crypto/geode-aes.c new file +474 -0
474 lines not on this page · raw message
drivers/crypto/geode-aes.h new file +42 -0
42 lines not on this page · raw message
Re: crypto: Add support for the Geode AES engine (v4)
Quoted 1 line · On Thu, 28 Sep 2006 17:17:39 -0600 "Jordan Crouse" <[email protected]>…
Add a driver to support the AES hardware on the Geode LX processor.
So... what are you planning on doing with this? Ask Linus to pull that git tree, or what?
Re: crypto: Add support for the Geode AES engine (v4)
Quoted 7 lines · Andrew Morton
Quoted 1 line · On Thu, 28 Sep 2006 17:17:39 -0600 "Jordan Crouse" <[email protected]>…
Add a driver to support the AES hardware on the Geode LX processor.
So... what are you planning on doing with this? Ask Linus to pull that git tree, or what?
Good question - I guess I'm not sure what the correct protocol is here. I should have done this long ago, so I was ready for the 2.6.19 window. I also should have gotten it to the crypto guys first, before putting it in the Geode tree. I guess I never really expected it to be in 2.6.19, I just wanted to get this cleaned up and shipped off. It was mocking me sitting there slowly bit rotting.
As it stands, I think the right move is to get it into the crypto tree to patiently await 2.6.20.
Jordan
Signature · 4 lines
Jordan Crouse Senior Linux Engineer Advanced Micro Devices, Inc. <www.amd.com/embeddedprocessors>
Herbert Xu
maintainerRe: crypto: Add support for the Geode AES engine (v4)
In reply to Jordan CrouseQuoted 2 lines · Jordan Crouse
Changes made and new version follows. Thanks for the comments.
Patch applied. Thanks everybody.
Cheers,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtA message that is not in the archive (sent off-list or not yet received): LYRIS-4270-86779-2006.09.28-04.27.47--jordan.crouse#[email protected]
Quoted 5 lines
As far as I can see, register access is not protected, how can your driver handle the case when dm-crypt and IPsec simultaneously try to encrypt/decrypt some data, it can happen even around preemt_disable/enable calls and actually crypto processing can happen in interrupt context too (although it is not the best thing to do).
I had the mutex in there, but I took it out based on our previous conversations, which probably was a little rash. If CRYPTO_TFM_REQ_MAY_SLEEP is still a valid flag to check, I could use that along with a spin lock of
some sort. I'll think about this a bit more.
Quoted 3 lines
You added timeout for the broken hardware condition, I think it is better to return some error from
_crypt()in that case, and, btw, that name is not very good choice.
I normally use _<blah> for static functions within my module - it helps me remember which commands might be important to others and which are just utility functions for my own use and abuse. I'll change the name.
Thanks,
Jordan
Signature · 4 lines
Jordan Crouse Senior Linux Engineer Advanced Micro Devices, Inc. <www.amd.com/embeddedprocessors>
Quoted 10 lines · Jordan Crouse
Quoted 5 lines
As far as I can see, register access is not protected, how can your driver handle the case when dm-crypt and IPsec simultaneously try to encrypt/decrypt some data, it can happen even around preemt_disable/enable calls and actually crypto processing can happen in interrupt context too (although it is not the best thing to do).
I had the mutex in there, but I took it out based on our previous conversations, which probably was a little rash. If
CRYPTO_TFM_REQ_MAY_SLEEPis still a valid flag to check, I could use that along with a spin lock of
some sort. I'll think about this a bit more.
If it is set, then you can safely sleep there, but if it is not, it does not always mean that sleeping is forbidden.
Signature · 1 line
Evgeniy Polyakov