Skip to contentSkip to conversation

small geode cleanup + fallback

RFC In review [email protected] 3 participants 9 messages Oct 12, 2007 – Oct 19, 2007

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover small geode cleanup + fallback

Hello Herbert,

This patchset started in order to verify broken Geode driver [1] without the actual hardware. [2] contains a version of the geode-aes driver where the hardware routines are replaced with software because I assume that the hardware is actually working (and this is the closest I get). I came to the conclusion that the driver should work (I was able to mkfs,cp, sha1 files on the crypto partition).

This patch set contains a small "clean up" of the driver and a fallback mode for keysize != 128. Hebert, if you like this way of fallback (patch 5) than I would try to hook the s390 driver with something similar.

This way of fallback allocates a "fully working" driver within the actual driver. Therefore if we request cbc(aes) with 192 bit key, than we have 1 fallback blkcipher and 1 fallback cipher (due to the chaining nature of the crypto API).

[1] http://www.mail-archive.com/[email protected]/msg01041.html
[2] git://breakpoint.cc/bigeasy/linux geode_nohw

Sebastian

#1 lore raw

RFC 1/6 AES: move common defines into a header file

This three defines are used in every AES related implementation.

---
 arch/i386/crypto/aes.c       |    4 +---
 arch/s390/crypto/aes_s390.c  |    7 +------
 arch/x86_64/crypto/aes.c     |    6 +-----
 crypto/aes.c                 |    6 +-----
 drivers/crypto/geode-aes.c   |    1 +
 drivers/crypto/padlock-aes.c |    4 +---
 include/crypto/aes.h         |   15 +++++++++++++++
 7 files changed, 21 insertions(+), 22 deletions(-)
 create mode 100644 include/crypto/aes.h
arch/i386/crypto/aes.c +1 -3
index 49aad93..9b0ab50 100644
@@ -38,6 +38,7 @@
  */
 
 #include <asm/byteorder.h>
+#include <crypto/aes.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -48,9 +49,6 @@
 asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
 asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
 
-#define AES_MIN_KEY_SIZE	16
-#define AES_MAX_KEY_SIZE	32
-#define AES_BLOCK_SIZE		16
 #define AES_KS_LENGTH		4 * AES_BLOCK_SIZE
 #define RC_LENGTH		29
 
arch/s390/crypto/aes_s390.c +1 -6
index 3660ca6..a4eff57 100644
@@ -16,17 +16,12 @@
  *
  */
 
+#include <crypto/aes.h>
 #include <crypto/algapi.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include "crypt_s390.h"
 
-#define AES_MIN_KEY_SIZE	16
-#define AES_MAX_KEY_SIZE	32
-
-/* data block size for all key lengths */
-#define AES_BLOCK_SIZE		16
-
 #define AES_KEYLEN_128		1
 #define AES_KEYLEN_192		2
 #define AES_KEYLEN_256		4
arch/x86_64/crypto/aes.c +1 -5
index 5cdb13e..0b38a4c 100644
@@ -54,6 +54,7 @@
 */
 
 #include <asm/byteorder.h>
+#include <crypto/aes.h>
 #include <linux/bitops.h>
 #include <linux/crypto.h>
 #include <linux/errno.h>
@@ -61,11 +62,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 
-#define AES_MIN_KEY_SIZE	16
-#define AES_MAX_KEY_SIZE	32
-
-#define AES_BLOCK_SIZE		16
-
 /*
  * #define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
  */
crypto/aes.c +1 -5
index e244077..9d486a3 100644
@@ -52,6 +52,7 @@
     s/RIJNDAEL(d_key)/D_KEY/g
 */
 
+#include <crypto/aes.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -59,11 +60,6 @@
 #include <linux/crypto.h>
 #include <asm/byteorder.h>
 
-#define AES_MIN_KEY_SIZE	16
-#define AES_MAX_KEY_SIZE	32
-
-#define AES_BLOCK_SIZE		16
-
 /*
  * #define byte(x, nr) ((unsigned char)((x) >> (nr*8))) 
  */
drivers/crypto/geode-aes.c +1 -0
index 6a86958..7c6f13f 100644
@@ -13,6 +13,7 @@
 #include <linux/crypto.h>
 #include <linux/spinlock.h>
 #include <crypto/algapi.h>
+#include <crypto/aes.h>
 
 #include <asm/io.h>
 #include <asm/delay.h>
drivers/crypto/padlock-aes.c +1 -3
index d4501dc..50da8b6 100644
@@ -44,6 +44,7 @@
  */
 
 #include <crypto/algapi.h>
+#include <crypto/aes.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -53,9 +54,6 @@
 #include <asm/byteorder.h>
 #include "padlock.h"
 
-#define AES_MIN_KEY_SIZE	16	/* in uint8_t units */
-#define AES_MAX_KEY_SIZE	32	/* ditto */
-#define AES_BLOCK_SIZE		16	/* ditto */
 #define AES_EXTENDED_KEY_SIZE	64	/* in uint32_t units */
 #define AES_EXTENDED_KEY_SIZE_B	(AES_EXTENDED_KEY_SIZE * sizeof(uint32_t))
 
include/crypto/aes.h new file +15 -0
new file mode 100644
index 0000000..9ff842f
@@ -0,0 +1,15 @@
+/*
+ * Common values for AES algorithms
+ */
+
+#ifndef _CRYPTO_AES_H
+#define _CRYPTO_AES_H
+
+#define AES_MIN_KEY_SIZE	16
+#define AES_MAX_KEY_SIZE	32
+#define AES_KEYSIZE_128		16
+#define AES_KEYSIZE_192		24
+#define AES_KEYSIZE_256		32
+#define AES_BLOCK_SIZE		16
+
+#endif
#2 lore raw

RFC 2/6 geode aes: consistent IV copy

In reply to [email protected]

It is enough if the IV is copied before and after the while loop. With DM-Crypt is seems not be required to save the IV after encrytion because a new IV is used in the request (dunno about other users). It is not save to load the IV within while loop and not save afterwards because we will end up with the wrong IV if the request consists of more than one page.

---
 drivers/crypto/geode-aes.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)
drivers/crypto/geode-aes.c +4 -6
index 7c6f13f..8bcd6d5 100644
@@ -227,6 +227,7 @@ geode_cbc_decrypt(struct blkcipher_desc *desc,
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
 	err = blkcipher_walk_virt(desc, &walk);
+	memcpy(op->iv, walk.iv, AES_IV_LENGTH);
 
 	while((nbytes = walk.nbytes)) {
 		op->src = walk.src.virt.addr,
@@ -235,16 +236,13 @@ geode_cbc_decrypt(struct blkcipher_desc *desc,
 		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);
 	}
 
+	memcpy(walk.iv, op->iv, AES_IV_LENGTH);
 	return err;
 }
 
@@ -259,6 +257,7 @@ geode_cbc_encrypt(struct blkcipher_desc *desc,
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
 	err = blkcipher_walk_virt(desc, &walk);
+	memcpy(op->iv, walk.iv, AES_IV_LENGTH);
 
 	while((nbytes = walk.nbytes)) {
 		op->src = walk.src.virt.addr,
@@ -267,13 +266,12 @@ geode_cbc_encrypt(struct blkcipher_desc *desc,
 		op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE);
 		op->dir = AES_DIR_ENCRYPT;
 
-		memcpy(op->iv, walk.iv, AES_IV_LENGTH);
-
 		ret = geode_aes_crypt(op);
 		nbytes -= ret;
 		err = blkcipher_walk_done(desc, &walk, nbytes);
 	}
 
+	memcpy(walk.iv, op->iv, AES_IV_LENGTH);
 	return err;
 }
 
#3 lore raw

RFC 3/6 geode: relax in busy loop and care about return value

In reply to [email protected]

The code waits in a busy loop until the hardware finishes the encryption or decryption process. This wants a cpu_relax() :)
The busy loop finishes either if the encryption is done or if the counter is zero. If the latter is true than the hardware failed. Since this should not happen, leave a BUG() statement to notice this.

---
 drivers/crypto/geode-aes.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)
drivers/crypto/geode-aes.c +6 -3
index 8bcd6d5..99ea594 100644
@@ -88,9 +88,10 @@ do_crypt(void *src, void *dst, int len, u32 flags)
 	/* Start the operation */
 	iowrite32(AES_CTRL_START | flags, _iobase + AES_CTRLA_REG);
 
-	do
+	do {
 		status = ioread32(_iobase + AES_INTR_REG);
-	while(!(status & AES_INTRA_PENDING) && --counter);
+		cpu_relax();
+	} while(!(status & AES_INTRA_PENDING) && --counter);
 
 	/* Clear the event */
 	iowrite32((status & 0xFF) | AES_INTRA_PENDING, _iobase + AES_INTR_REG);
@@ -102,6 +103,7 @@ geode_aes_crypt(struct geode_aes_op *op)
 {
 	u32 flags = 0;
 	unsigned long iflags;
+	int ret;
 
 	if (op->len == 0)
 		return 0;
@@ -131,7 +133,8 @@ geode_aes_crypt(struct geode_aes_op *op)
 		_writefield(AES_WRITEKEY0_REG, op->key);
 	}
 
-	do_crypt(op->src, op->dst, op->len, flags);
+	ret = do_crypt(op->src, op->dst, op->len, flags);
+	BUG_ON(ret);
 
 	if (op->mode == AES_MODE_CBC)
 		_readfield(AES_WRITEIV0_REG, op->iv);
#4 lore raw

RFC 4/6 geode: move defines into a headerfile

In reply to [email protected]
---
 drivers/crypto/geode-aes.c |   32 --------------------------------
 drivers/crypto/geode-aes.h |   36 ++++++++++++++++++++++++++++++++++--
 2 files changed, 34 insertions(+), 34 deletions(-)
drivers/crypto/geode-aes.c +0 -32
index 99ea594..da6164a 100644
@@ -20,38 +20,6 @@
 
 #include "geode-aes.h"
 
-/* Register definitions */
-
-#define AES_CTRLA_REG  0x0000
-
-#define AES_CTRL_START     0x01
-#define AES_CTRL_DECRYPT   0x00
-#define AES_CTRL_ENCRYPT   0x02
-#define AES_CTRL_WRKEY     0x04
-#define AES_CTRL_DCA       0x08
-#define AES_CTRL_SCA       0x10
-#define AES_CTRL_CBC       0x20
-
-#define AES_INTR_REG  0x0008
-
-#define AES_INTRA_PENDING (1 << 16)
-#define AES_INTRB_PENDING (1 << 17)
-
-#define AES_INTR_PENDING  (AES_INTRA_PENDING | AES_INTRB_PENDING)
-#define AES_INTR_MASK     0x07
-
-#define AES_SOURCEA_REG   0x0010
-#define AES_DSTA_REG      0x0014
-#define AES_LENA_REG      0x0018
-#define AES_WRITEKEY0_REG 0x0030
-#define AES_WRITEIV0_REG  0x0040
-
-/*  A very large counter that is used to gracefully bail out of an
- *  operation in case of trouble
- */
-
-#define AES_OP_TIMEOUT    0x50000
-
 /* Static structures */
 
 static void __iomem * _iobase;
drivers/crypto/geode-aes.h +34 -2
index f479686..2f1d559 100644
@@ -9,9 +9,9 @@
 #ifndef _GEODE_AES_H_
 #define _GEODE_AES_H_
 
-#define AES_KEY_LENGTH 16
+/* driver logic flags */
 #define AES_IV_LENGTH  16
-
+#define AES_KEY_LENGTH 16
 #define AES_MIN_BLOCK_SIZE 16
 
 #define AES_MODE_ECB 0
@@ -22,6 +22,38 @@
 
 #define AES_FLAGS_HIDDENKEY (1 << 0)
 
+/* Register definitions */
+
+#define AES_CTRLA_REG  0x0000
+
+#define AES_CTRL_START     0x01
+#define AES_CTRL_DECRYPT   0x00
+#define AES_CTRL_ENCRYPT   0x02
+#define AES_CTRL_WRKEY     0x04
+#define AES_CTRL_DCA       0x08
+#define AES_CTRL_SCA       0x10
+#define AES_CTRL_CBC       0x20
+
+#define AES_INTR_REG  0x0008
+
+#define AES_INTRA_PENDING (1 << 16)
+#define AES_INTRB_PENDING (1 << 17)
+
+#define AES_INTR_PENDING  (AES_INTRA_PENDING | AES_INTRB_PENDING)
+#define AES_INTR_MASK     0x07
+
+#define AES_SOURCEA_REG   0x0010
+#define AES_DSTA_REG      0x0014
+#define AES_LENA_REG      0x0018
+#define AES_WRITEKEY0_REG 0x0030
+#define AES_WRITEIV0_REG  0x0040
+
+/*  A very large counter that is used to gracefully bail out of an
+ *  operation in case of trouble
+ */
+
+#define AES_OP_TIMEOUT    0x50000
+
 struct geode_aes_op {
 
 	void *src;
#5 lore raw

RFC 5/6 geode add fallback for unsupported modes.

In reply to [email protected]

The Geode AES crypto engine supports only 128 bit long key. This patch adds fallback for other key sizes which are required by the AES standard.

---
 drivers/crypto/geode-aes.c |  188 +++++++++++++++++++++++++++++++++++++++-----
 drivers/crypto/geode-aes.h |    6 ++
 2 files changed, 173 insertions(+), 21 deletions(-)
drivers/crypto/geode-aes.c +167 -21
index da6164a..761d600 100644
@@ -118,14 +118,82 @@ static int
 geode_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int len)
 {
 	struct geode_aes_op *op = crypto_tfm_ctx(tfm);
+	unsigned int type;
+	unsigned int ret;
 
-	if (len != AES_KEY_LENGTH) {
+	op->keylen = len;
+
+	if (len == AES_KEY_LENGTH) {
+		memcpy(op->key, key, len);
+		return 0;
+	}
+
+	if (len != 24 && len != 32) {
+		/* not supported at all */
 		tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
 		return -EINVAL;
 	}
 
-	memcpy(op->key, key, len);
-	return 0;
+	/*
+	 * The requested key size is not supported by HW, do a fallback
+	 */
+
+	type = tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
+
+	/* propagate requested flags to the fallback driver */
+	op->fallback.blk->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
+	op->fallback.blk->base.crt_flags |= (tfm->crt_flags & CRYPTO_TFM_REQ_MASK);
+
+	if (type == CRYPTO_ALG_TYPE_BLKCIPHER) {
+		ret = crypto_blkcipher_setkey(op->fallback.blk, key, len);
+
+	} else if (type == CRYPTO_ALG_TYPE_CIPHER) {
+		ret = crypto_cipher_setkey(op->fallback.cip, key, len);
+
+	} else {
+		printk(KERN_ERR "Neither a cipher nor a block cipher. %x / %x\n",
+				type, tfm->crt_flags);
+		return -EINVAL;
+	}
+
+	if (ret) {
+		tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
+		tfm->crt_flags |= (op->fallback.blk->base.crt_flags & CRYPTO_TFM_RES_MASK);
+	}
+	return ret;
+}
+
+static int fallback_blk_dec(struct blkcipher_desc *desc,
+		struct scatterlist *dst, struct scatterlist *src,
+		unsigned int nbytes)
+{
+	unsigned int ret;
+	struct crypto_blkcipher *tfm;
+	struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm);
+
+	tfm = desc->tfm;
+	desc->tfm = op->fallback.blk;
+
+	ret = crypto_blkcipher_decrypt(desc, dst, src, nbytes);
+
+	desc->tfm = tfm;
+	return ret;
+}
+static int fallback_blk_enc(struct blkcipher_desc *desc,
+		struct scatterlist *dst, struct scatterlist *src,
+		unsigned int nbytes)
+{
+	unsigned int ret;
+	struct crypto_blkcipher *tfm;
+	struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm);
+
+	tfm = desc->tfm;
+	desc->tfm = op->fallback.blk;
+
+	ret = crypto_blkcipher_encrypt(desc, dst, src, nbytes);
+
+	desc->tfm = tfm;
+	return ret;
 }
 
 static void
@@ -133,8 +201,10 @@ geode_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
 {
 	struct geode_aes_op *op = crypto_tfm_ctx(tfm);
 
-	if ((out == NULL) || (in == NULL))
+	if (unlikely(op->keylen != 16)) {
+		crypto_cipher_encrypt_one(op->fallback.cip, out, in);
 		return;
+	}
 
 	op->src = (void *) in;
 	op->dst = (void *) out;
@@ -152,8 +222,10 @@ geode_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
 {
 	struct geode_aes_op *op = crypto_tfm_ctx(tfm);
 
-	if ((out == NULL) || (in == NULL))
+	if (unlikely(op->keylen != 16)) {
+		crypto_cipher_decrypt_one(op->fallback.cip, out, in);
 		return;
+	}
 
 	op->src = (void *) in;
 	op->dst = (void *) out;
@@ -165,21 +237,76 @@ geode_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
 	geode_aes_crypt(op);
 }
 
+static int fallback_init(struct crypto_tfm *tfm)
+{
+	const char *name = tfm->__crt_alg->cra_name;
+	unsigned int type;
+	struct geode_aes_op *op = crypto_tfm_ctx(tfm);
+
+	type = tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
+
+	if (type == CRYPTO_ALG_TYPE_BLKCIPHER) {
+		op->fallback.blk = crypto_alloc_blkcipher(name, 0,
+				CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
+
+	} else if (type == CRYPTO_ALG_TYPE_CIPHER) {
+		op->fallback.cip = crypto_alloc_cipher(name, 0,
+				CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
+	} else {
+		printk(KERN_ERR "%s is neither a cipher nor a block cipher: %x\n",
+				name, type);
+		return -EINVAL;
+	}
+
+	/*
+	 * cipher / blkcipher, this is the same pointer for both. One check is
+	 * enough
+	 */
+	if (IS_ERR(op->fallback.blk)) {
+		printk(KERN_ERR "Error allocating fallback algo %s\n", name);
+		return PTR_ERR(op->fallback.blk);
+	}
+
+	return 0;
+}
+
+static void fallback_exit(struct crypto_tfm *tfm)
+{
+	unsigned int type;
+	struct geode_aes_op *op = crypto_tfm_ctx(tfm);
+
+	type = tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
+	if (type == CRYPTO_ALG_TYPE_BLKCIPHER) {
+		crypto_free_blkcipher(op->fallback.blk);
+		op->fallback.blk = NULL;
+		return;
+
+	} else if (type == CRYPTO_ALG_TYPE_CIPHER) {
+		crypto_free_cipher(op->fallback.cip);
+		op->fallback.cip = NULL;
+		return;
+	}
+
+	WARN_ON(1);
+}
 
 static struct crypto_alg geode_alg = {
 	.cra_name               =       "aes",
-	.cra_driver_name	=       "geode-aes-128",
+	.cra_driver_name	=       "geode-aes",
 	.cra_priority           =       300,
 	.cra_alignmask          =       15,
-	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER |
+					CRYPTO_ALG_NEED_FALLBACK,
+	.cra_init               =       fallback_init,
+	.cra_exit               =       fallback_exit,
 	.cra_blocksize		=	AES_MIN_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct geode_aes_op),
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(geode_alg.cra_list),
 	.cra_u			=	{
 		.cipher = {
-			.cia_min_keysize	=  AES_KEY_LENGTH,
-			.cia_max_keysize	=  AES_KEY_LENGTH,
+			.cia_min_keysize	=  AES_MIN_KEY_SIZE,
+			.cia_max_keysize	=  AES_MAX_KEY_SIZE,
 			.cia_setkey		=  geode_setkey,
 			.cia_encrypt		=  geode_encrypt,
 			.cia_decrypt		=  geode_decrypt
@@ -196,6 +323,9 @@ geode_cbc_decrypt(struct blkcipher_desc *desc,
 	struct blkcipher_walk walk;
 	int err, ret;
 
+	if (unlikely(op->keylen != 16))
+		return fallback_blk_dec(desc, dst, src, nbytes);
+
 	blkcipher_walk_init(&walk, dst, src, nbytes);
 	err = blkcipher_walk_virt(desc, &walk);
 	memcpy(op->iv, walk.iv, AES_IV_LENGTH);
@@ -226,6 +356,9 @@ geode_cbc_encrypt(struct blkcipher_desc *desc,
 	struct blkcipher_walk walk;
 	int err, ret;
 
+	if (unlikely(op->keylen != 16))
+		return fallback_blk_enc(desc, dst, src, nbytes);
+
 	blkcipher_walk_init(&walk, dst, src, nbytes);
 	err = blkcipher_walk_virt(desc, &walk);
 	memcpy(op->iv, walk.iv, AES_IV_LENGTH);
@@ -248,9 +381,12 @@ geode_cbc_encrypt(struct blkcipher_desc *desc,
 
 static struct crypto_alg geode_cbc_alg = {
 	.cra_name		=	"cbc(aes)",
-	.cra_driver_name	=	"cbc-aes-geode-128",
-	.cra_priority		=	400,
-	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
+	.cra_driver_name	=	"cbc-aes-geode",
+	.cra_priority		=	300,
+	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER |
+					CRYPTO_ALG_NEED_FALLBACK,
+	.cra_init               =       fallback_init,
+	.cra_exit               =       fallback_exit,
 	.cra_blocksize		=	AES_MIN_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct geode_aes_op),
 	.cra_alignmask		=	15,
@@ -259,8 +395,8 @@ static struct crypto_alg geode_cbc_alg = {
 	.cra_list		=	LIST_HEAD_INIT(geode_cbc_alg.cra_list),
 	.cra_u			=	{
 		.blkcipher = {
-			.min_keysize		=	AES_KEY_LENGTH,
-			.max_keysize		=	AES_KEY_LENGTH,
+			.min_keysize		=	AES_MIN_KEY_SIZE,
+			.max_keysize		=	AES_MAX_KEY_SIZE,
 			.setkey			=	geode_setkey,
 			.encrypt		=	geode_cbc_encrypt,
 			.decrypt		=	geode_cbc_decrypt,
@@ -278,6 +414,9 @@ geode_ecb_decrypt(struct blkcipher_desc *desc,
 	struct blkcipher_walk walk;
 	int err, ret;
 
+	if (unlikely(op->keylen != 16))
+		return fallback_blk_dec(desc, dst, src, nbytes);
+
 	blkcipher_walk_init(&walk, dst, src, nbytes);
 	err = blkcipher_walk_virt(desc, &walk);
 
@@ -305,6 +444,9 @@ geode_ecb_encrypt(struct blkcipher_desc *desc,
 	struct blkcipher_walk walk;
 	int err, ret;
 
+	if (unlikely(op->keylen != 16))
+		return fallback_blk_enc(desc, dst, src, nbytes);
+
 	blkcipher_walk_init(&walk, dst, src, nbytes);
 	err = blkcipher_walk_virt(desc, &walk);
 
@@ -325,9 +467,12 @@ geode_ecb_encrypt(struct blkcipher_desc *desc,
 
 static struct crypto_alg geode_ecb_alg = {
 	.cra_name		=	"ecb(aes)",
-	.cra_driver_name	=	"ecb-aes-geode-128",
-	.cra_priority		=	400,
-	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
+	.cra_driver_name	=	"ecb-aes-geode",
+	.cra_priority		=	300,
+	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER |
+					CRYPTO_ALG_NEED_FALLBACK,
+	.cra_init               =       fallback_init,
+	.cra_exit               =       fallback_exit,
 	.cra_blocksize		=	AES_MIN_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct geode_aes_op),
 	.cra_alignmask		=	15,
@@ -336,8 +481,8 @@ static struct crypto_alg geode_ecb_alg = {
 	.cra_list		=	LIST_HEAD_INIT(geode_ecb_alg.cra_list),
 	.cra_u			=	{
 		.blkcipher = {
-			.min_keysize		=	AES_KEY_LENGTH,
-			.max_keysize		=	AES_KEY_LENGTH,
+			.min_keysize		=	AES_MIN_KEY_SIZE,
+			.max_keysize		=	AES_MAX_KEY_SIZE,
 			.setkey			=	geode_setkey,
 			.encrypt		=	geode_ecb_encrypt,
 			.decrypt		=	geode_ecb_decrypt,
@@ -368,7 +513,7 @@ geode_aes_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	if ((ret = pci_enable_device(dev)))
 		return ret;
 
-	if ((ret = pci_request_regions(dev, "geode-aes-128")))
+	if ((ret = pci_request_regions(dev, "geode-aes")))
 		goto eenable;
 
 	_iobase = pci_iomap(dev, 0, 0);
@@ -392,7 +537,8 @@ geode_aes_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	if ((ret = crypto_register_alg(&geode_cbc_alg)))
 		goto eecb;
 
-	printk(KERN_NOTICE "geode-aes: GEODE AES engine enabled.\n");
+	printk(KERN_NOTICE "geode-aes: GEODE AES engine enabled. "
+			"Only 128-bit keys are supported by the Hardware.\n");
 	return 0;
 
  eecb:
drivers/crypto/geode-aes.h +6 -0
index 2f1d559..14cc763 100644
@@ -66,6 +66,12 @@ struct geode_aes_op {
 
 	u8 key[AES_KEY_LENGTH];
 	u8 iv[AES_IV_LENGTH];
+
+	union {
+		struct crypto_blkcipher *blk;
+		struct crypto_cipher *cip;
+	} fallback;
+	u32 keylen;
 };
 
 #endif
#6 lore raw

RFC 6/6 geode: use proper defines

In reply to [email protected]

Use proper defines for constants even if they point to the same value:
- there is no min/max blocksize, there is one for AES.
- the size of the IV is the algorithm's block size in case of CBC.
- there is no key size for AES but three different :)

This is a nitpicker patch, no added value :)

---
 drivers/crypto/geode-aes.c |   44 ++++++++++++++++++++++----------------------
 drivers/crypto/geode-aes.h |    9 +++------
 2 files changed, 25 insertions(+), 28 deletions(-)
drivers/crypto/geode-aes.c +22 -22
index 761d600..5c7ed90 100644
@@ -123,12 +123,12 @@ geode_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int len)
 
 	op->keylen = len;
 
-	if (len == AES_KEY_LENGTH) {
+	if (len == AES_KEYSIZE_128) {
 		memcpy(op->key, key, len);
 		return 0;
 	}
 
-	if (len != 24 && len != 32) {
+	if (len != AES_KEYSIZE_192 && len != AES_KEYSIZE_256) {
 		/* not supported at all */
 		tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
 		return -EINVAL;
@@ -201,7 +201,7 @@ geode_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
 {
 	struct geode_aes_op *op = crypto_tfm_ctx(tfm);
 
-	if (unlikely(op->keylen != 16)) {
+	if (unlikely(op->keylen != AES_KEYSIZE_128)) {
 		crypto_cipher_encrypt_one(op->fallback.cip, out, in);
 		return;
 	}
@@ -210,7 +210,7 @@ geode_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
 	op->dst = (void *) out;
 	op->mode = AES_MODE_ECB;
 	op->flags = 0;
-	op->len = AES_MIN_BLOCK_SIZE;
+	op->len = AES_BLOCK_SIZE;
 	op->dir = AES_DIR_ENCRYPT;
 
 	geode_aes_crypt(op);
@@ -222,7 +222,7 @@ geode_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
 {
 	struct geode_aes_op *op = crypto_tfm_ctx(tfm);
 
-	if (unlikely(op->keylen != 16)) {
+	if (unlikely(op->keylen != AES_KEYSIZE_128)) {
 		crypto_cipher_decrypt_one(op->fallback.cip, out, in);
 		return;
 	}
@@ -231,7 +231,7 @@ geode_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
 	op->dst = (void *) out;
 	op->mode = AES_MODE_ECB;
 	op->flags = 0;
-	op->len = AES_MIN_BLOCK_SIZE;
+	op->len = AES_BLOCK_SIZE;
 	op->dir = AES_DIR_DECRYPT;
 
 	geode_aes_crypt(op);
@@ -299,7 +299,7 @@ static struct crypto_alg geode_alg = {
 					CRYPTO_ALG_NEED_FALLBACK,
 	.cra_init               =       fallback_init,
 	.cra_exit               =       fallback_exit,
-	.cra_blocksize		=	AES_MIN_BLOCK_SIZE,
+	.cra_blocksize		=	AES_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct geode_aes_op),
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(geode_alg.cra_list),
@@ -323,18 +323,18 @@ geode_cbc_decrypt(struct blkcipher_desc *desc,
 	struct blkcipher_walk walk;
 	int err, ret;
 
-	if (unlikely(op->keylen != 16))
+	if (unlikely(op->keylen != AES_KEYSIZE_128))
 		return fallback_blk_dec(desc, dst, src, nbytes);
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
 	err = blkcipher_walk_virt(desc, &walk);
-	memcpy(op->iv, walk.iv, AES_IV_LENGTH);
+	memcpy(op->iv, walk.iv, AES_BLOCK_SIZE);
 
 	while((nbytes = walk.nbytes)) {
 		op->src = walk.src.virt.addr,
 		op->dst = walk.dst.virt.addr;
 		op->mode = AES_MODE_CBC;
-		op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE);
+		op->len = nbytes - (nbytes % AES_BLOCK_SIZE);
 		op->dir = AES_DIR_DECRYPT;
 
 		ret = geode_aes_crypt(op);
@@ -343,7 +343,7 @@ geode_cbc_decrypt(struct blkcipher_desc *desc,
 		err = blkcipher_walk_done(desc, &walk, nbytes);
 	}
 
-	memcpy(walk.iv, op->iv, AES_IV_LENGTH);
+	memcpy(walk.iv, op->iv, AES_BLOCK_SIZE);
 	return err;
 }
 
@@ -356,18 +356,18 @@ geode_cbc_encrypt(struct blkcipher_desc *desc,
 	struct blkcipher_walk walk;
 	int err, ret;
 
-	if (unlikely(op->keylen != 16))
+	if (unlikely(op->keylen != AES_KEYSIZE_128))
 		return fallback_blk_enc(desc, dst, src, nbytes);
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
 	err = blkcipher_walk_virt(desc, &walk);
-	memcpy(op->iv, walk.iv, AES_IV_LENGTH);
+	memcpy(op->iv, walk.iv, AES_BLOCK_SIZE);
 
 	while((nbytes = walk.nbytes)) {
 		op->src = walk.src.virt.addr,
 		op->dst = walk.dst.virt.addr;
 		op->mode = AES_MODE_CBC;
-		op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE);
+		op->len = nbytes - (nbytes % AES_BLOCK_SIZE);
 		op->dir = AES_DIR_ENCRYPT;
 
 		ret = geode_aes_crypt(op);
@@ -375,7 +375,7 @@ geode_cbc_encrypt(struct blkcipher_desc *desc,
 		err = blkcipher_walk_done(desc, &walk, nbytes);
 	}
 
-	memcpy(walk.iv, op->iv, AES_IV_LENGTH);
+	memcpy(walk.iv, op->iv, AES_BLOCK_SIZE);
 	return err;
 }
 
@@ -387,7 +387,7 @@ static struct crypto_alg geode_cbc_alg = {
 					CRYPTO_ALG_NEED_FALLBACK,
 	.cra_init               =       fallback_init,
 	.cra_exit               =       fallback_exit,
-	.cra_blocksize		=	AES_MIN_BLOCK_SIZE,
+	.cra_blocksize		=	AES_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct geode_aes_op),
 	.cra_alignmask		=	15,
 	.cra_type		=	&crypto_blkcipher_type,
@@ -400,7 +400,7 @@ static struct crypto_alg geode_cbc_alg = {
 			.setkey			=	geode_setkey,
 			.encrypt		=	geode_cbc_encrypt,
 			.decrypt		=	geode_cbc_decrypt,
-			.ivsize			=	AES_IV_LENGTH,
+			.ivsize			=	AES_BLOCK_SIZE,
 		}
 	}
 };
@@ -414,7 +414,7 @@ geode_ecb_decrypt(struct blkcipher_desc *desc,
 	struct blkcipher_walk walk;
 	int err, ret;
 
-	if (unlikely(op->keylen != 16))
+	if (unlikely(op->keylen != AES_KEYSIZE_128))
 		return fallback_blk_dec(desc, dst, src, nbytes);
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
@@ -424,7 +424,7 @@ geode_ecb_decrypt(struct blkcipher_desc *desc,
 		op->src = walk.src.virt.addr,
 		op->dst = walk.dst.virt.addr;
 		op->mode = AES_MODE_ECB;
-		op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE);
+		op->len = nbytes - (nbytes % AES_BLOCK_SIZE);
 		op->dir = AES_DIR_DECRYPT;
 
 		ret = geode_aes_crypt(op);
@@ -444,7 +444,7 @@ geode_ecb_encrypt(struct blkcipher_desc *desc,
 	struct blkcipher_walk walk;
 	int err, ret;
 
-	if (unlikely(op->keylen != 16))
+	if (unlikely(op->keylen != AES_KEYSIZE_128))
 		return fallback_blk_enc(desc, dst, src, nbytes);
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
@@ -454,7 +454,7 @@ geode_ecb_encrypt(struct blkcipher_desc *desc,
 		op->src = walk.src.virt.addr,
 		op->dst = walk.dst.virt.addr;
 		op->mode = AES_MODE_ECB;
-		op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE);
+		op->len = nbytes - (nbytes % AES_BLOCK_SIZE);
 		op->dir = AES_DIR_ENCRYPT;
 
 		ret = geode_aes_crypt(op);
@@ -473,7 +473,7 @@ static struct crypto_alg geode_ecb_alg = {
 					CRYPTO_ALG_NEED_FALLBACK,
 	.cra_init               =       fallback_init,
 	.cra_exit               =       fallback_exit,
-	.cra_blocksize		=	AES_MIN_BLOCK_SIZE,
+	.cra_blocksize		=	AES_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct geode_aes_op),
 	.cra_alignmask		=	15,
 	.cra_type		=	&crypto_blkcipher_type,
drivers/crypto/geode-aes.h +3 -6
index 14cc763..a395df8 100644
@@ -8,12 +8,9 @@
 
 #ifndef _GEODE_AES_H_
 #define _GEODE_AES_H_
+#include <crypto/aes.h>
 
 /* driver logic flags */
-#define AES_IV_LENGTH  16
-#define AES_KEY_LENGTH 16
-#define AES_MIN_BLOCK_SIZE 16
-
 #define AES_MODE_ECB 0
 #define AES_MODE_CBC 1
 
@@ -64,8 +61,8 @@ struct geode_aes_op {
 	u32 flags;
 	int len;
 
-	u8 key[AES_KEY_LENGTH];
-	u8 iv[AES_IV_LENGTH];
+	u8 key[AES_KEYSIZE_128];
+	u8 iv[AES_BLOCK_SIZE];
 
 	union {
 		struct crypto_blkcipher *blk;
maintainer
#8 lore raw
Quoted 3 lines · Sebastian Siewior

I saw you applied 1/6 to your cryptodev tree. What about 2-6 (especially the fallback approach)?

Could you please repost?

I think I deleted them because the first patch in the original series didn't apply.

Thanks,

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.txt