2009-03-16 01:21:58

by Lee Nipper

[permalink] [raw]
Subject: [PATCH] crypto: talitos - protect against possible null ptr upon error

Added test for null descriptor returned from current_desc.
Also removed the diagnostic from current_desc,
and added one instead in talitos_error
to report an EU error without finding the descriptor.

Signed-off-by: Lee Nipper <[email protected]>
---
drivers/crypto/talitos.c | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index a3918c1..d853530 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -401,10 +401,8 @@ static struct talitos_desc *current_desc(struct device *dev, int ch)

while (priv->fifo[ch][tail].dma_desc != cur_desc) {
tail = (tail + 1) & (priv->fifo_len - 1);
- if (tail == priv->tail[ch]) {
- dev_err(dev, "couldn't locate current descriptor\n");
+ if (tail == priv->tail[ch])
return NULL;
- }
}

return priv->fifo[ch][tail].desc;
@@ -523,8 +521,14 @@ static void talitos_error(unsigned long data, u32 isr, u32 isr_lo)
dev_err(dev, "illegal descriptor header error\n");
if (v_lo & TALITOS_CCPSR_LO_IEU)
dev_err(dev, "invalid execution unit error\n");
- if (v_lo & TALITOS_CCPSR_LO_EU)
- report_eu_error(dev, ch, current_desc(dev, ch));
+ if (v_lo & TALITOS_CCPSR_LO_EU) {
+ struct talitos_desc *desc = current_desc(dev, ch);
+ if (desc)
+ report_eu_error(dev, ch, desc);
+ else
+ dev_err(dev,
+ "EU error, but no descriptor found.\n");
+ }
if (v_lo & TALITOS_CCPSR_LO_GB)
dev_err(dev, "gather boundary error\n");
if (v_lo & TALITOS_CCPSR_LO_GRL)
--
1.5.6.3



2009-03-16 01:21:59

by Lee Nipper

[permalink] [raw]
Subject: [PATCH 1/3] crypto: talitos - scaffolding for new algorithm types

This patch is preparation for adding new algorithm types.

Some elements which are AEAD specific were renamed.
The algorithm template structure was changed to
use crypto_alg, and talitos_alg_alloc was made
more general with respect to algorithm types.

Signed-off-by: Lee Nipper <[email protected]>
---
drivers/crypto/talitos.c | 245 ++++++++++++++++++++++++----------------------
1 files changed, 129 insertions(+), 116 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index d853530..d53e2eb 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -688,8 +688,8 @@ struct talitos_ctx {
unsigned int authsize;
};

-static int aead_authenc_setauthsize(struct crypto_aead *authenc,
- unsigned int authsize)
+static int aead_setauthsize(struct crypto_aead *authenc,
+ unsigned int authsize)
{
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);

@@ -698,8 +698,8 @@ static int aead_authenc_setauthsize(struct crypto_aead *authenc,
return 0;
}

-static int aead_authenc_setkey(struct crypto_aead *authenc,
- const u8 *key, unsigned int keylen)
+static int aead_setkey(struct crypto_aead *authenc,
+ const u8 *key, unsigned int keylen)
{
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
struct rtattr *rta = (void *)key;
@@ -744,7 +744,7 @@ badkey:
}

/*
- * ipsec_esp_edesc - s/w-extended ipsec_esp descriptor
+ * talitos_edesc - s/w-extended descriptor
* @src_nents: number of segments in input scatterlist
* @dst_nents: number of segments in output scatterlist
* @dma_len: length of dma mapped link_tbl space
@@ -756,7 +756,7 @@ badkey:
* is greater than 1, an integrity check value is concatenated to the end
* of link_tbl data
*/
-struct ipsec_esp_edesc {
+struct talitos_edesc {
int src_nents;
int dst_nents;
int dma_len;
@@ -766,7 +766,7 @@ struct ipsec_esp_edesc {
};

static void ipsec_esp_unmap(struct device *dev,
- struct ipsec_esp_edesc *edesc,
+ struct talitos_edesc *edesc,
struct aead_request *areq)
{
unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6], DMA_FROM_DEVICE);
@@ -799,8 +799,8 @@ static void ipsec_esp_encrypt_done(struct device *dev,
int err)
{
struct aead_request *areq = context;
- struct ipsec_esp_edesc *edesc =
- container_of(desc, struct ipsec_esp_edesc, desc);
+ struct talitos_edesc *edesc =
+ container_of(desc, struct talitos_edesc, desc);
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
struct scatterlist *sg;
@@ -827,8 +827,8 @@ static void ipsec_esp_decrypt_swauth_done(struct device *dev,
int err)
{
struct aead_request *req = context;
- struct ipsec_esp_edesc *edesc =
- container_of(desc, struct ipsec_esp_edesc, desc);
+ struct talitos_edesc *edesc =
+ container_of(desc, struct talitos_edesc, desc);
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
struct scatterlist *sg;
@@ -859,8 +859,8 @@ static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
int err)
{
struct aead_request *req = context;
- struct ipsec_esp_edesc *edesc =
- container_of(desc, struct ipsec_esp_edesc, desc);
+ struct talitos_edesc *edesc =
+ container_of(desc, struct talitos_edesc, desc);

ipsec_esp_unmap(dev, edesc, req);

@@ -914,7 +914,7 @@ static int sg_to_link_tbl(struct scatterlist *sg, int sg_count,
/*
* fill in and submit ipsec_esp descriptor
*/
-static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
+static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
u8 *giv, u64 seq,
void (*callback) (struct device *dev,
struct talitos_desc *desc,
@@ -1056,14 +1056,14 @@ static int sg_count(struct scatterlist *sg_list, int nbytes)
}

/*
- * allocate and map the ipsec_esp extended descriptor
+ * allocate and map the extended descriptor
*/
-static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq,
+static struct talitos_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq,
int icv_stashing)
{
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
- struct ipsec_esp_edesc *edesc;
+ struct talitos_edesc *edesc;
int src_nents, dst_nents, alloc_len, dma_len;
gfp_t flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
GFP_ATOMIC;
@@ -1088,7 +1088,7 @@ static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq,
* allowing for two separate entries for ICV and generated ICV (+ 2),
* and the ICV data itself
*/
- alloc_len = sizeof(struct ipsec_esp_edesc);
+ alloc_len = sizeof(struct talitos_edesc);
if (src_nents || dst_nents) {
dma_len = (src_nents + dst_nents + 2) *
sizeof(struct talitos_ptr) + ctx->authsize;
@@ -1113,11 +1113,11 @@ static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq,
return edesc;
}

-static int aead_authenc_encrypt(struct aead_request *req)
+static int aead_encrypt(struct aead_request *req)
{
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
- struct ipsec_esp_edesc *edesc;
+ struct talitos_edesc *edesc;

/* allocate extended descriptor */
edesc = ipsec_esp_edesc_alloc(req, 0);
@@ -1132,13 +1132,13 @@ static int aead_authenc_encrypt(struct aead_request *req)



-static int aead_authenc_decrypt(struct aead_request *req)
+static int aead_decrypt(struct aead_request *req)
{
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
unsigned int authsize = ctx->authsize;
struct talitos_private *priv = dev_get_drvdata(ctx->dev);
- struct ipsec_esp_edesc *edesc;
+ struct talitos_edesc *edesc;
struct scatterlist *sg;
void *icvdata;

@@ -1184,13 +1184,12 @@ static int aead_authenc_decrypt(struct aead_request *req)
}
}

-static int aead_authenc_givencrypt(
- struct aead_givcrypt_request *req)
+static int aead_givencrypt(struct aead_givcrypt_request *req)
{
struct aead_request *areq = &req->areq;
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
- struct ipsec_esp_edesc *edesc;
+ struct talitos_edesc *edesc;

/* allocate extended descriptor */
edesc = ipsec_esp_edesc_alloc(areq, 0);
@@ -1209,30 +1208,30 @@ static int aead_authenc_givencrypt(
}

struct talitos_alg_template {
- char name[CRYPTO_MAX_ALG_NAME];
- char driver_name[CRYPTO_MAX_ALG_NAME];
- unsigned int blocksize;
- struct aead_alg aead;
- struct device *dev;
+ struct crypto_alg alg;
__be32 desc_hdr_template;
};

static struct talitos_alg_template driver_algs[] = {
- /* single-pass ipsec_esp descriptor */
+ /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
{
- .name = "authenc(hmac(sha1),cbc(aes))",
- .driver_name = "authenc-hmac-sha1-cbc-aes-talitos",
- .blocksize = AES_BLOCK_SIZE,
- .aead = {
- .setkey = aead_authenc_setkey,
- .setauthsize = aead_authenc_setauthsize,
- .encrypt = aead_authenc_encrypt,
- .decrypt = aead_authenc_decrypt,
- .givencrypt = aead_authenc_givencrypt,
- .geniv = "<built-in>",
- .ivsize = AES_BLOCK_SIZE,
- .maxauthsize = SHA1_DIGEST_SIZE,
- },
+ .alg = {
+ .cra_name = "authenc(hmac(sha1),cbc(aes))",
+ .cra_driver_name = "authenc-hmac-sha1-cbc-aes-talitos",
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_aead_type,
+ .cra_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = AES_BLOCK_SIZE,
+ .maxauthsize = SHA1_DIGEST_SIZE,
+ }
+ },
.desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
DESC_HDR_SEL0_AESU |
DESC_HDR_MODE0_AESU_CBC |
@@ -1242,19 +1241,23 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_MODE1_MDEU_SHA1_HMAC,
},
{
- .name = "authenc(hmac(sha1),cbc(des3_ede))",
- .driver_name = "authenc-hmac-sha1-cbc-3des-talitos",
- .blocksize = DES3_EDE_BLOCK_SIZE,
- .aead = {
- .setkey = aead_authenc_setkey,
- .setauthsize = aead_authenc_setauthsize,
- .encrypt = aead_authenc_encrypt,
- .decrypt = aead_authenc_decrypt,
- .givencrypt = aead_authenc_givencrypt,
- .geniv = "<built-in>",
- .ivsize = DES3_EDE_BLOCK_SIZE,
- .maxauthsize = SHA1_DIGEST_SIZE,
- },
+ .alg = {
+ .cra_name = "authenc(hmac(sha1),cbc(des3_ede))",
+ .cra_driver_name = "authenc-hmac-sha1-cbc-3des-talitos",
+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_aead_type,
+ .cra_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ .maxauthsize = SHA1_DIGEST_SIZE,
+ }
+ },
.desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
DESC_HDR_SEL0_DEU |
DESC_HDR_MODE0_DEU_CBC |
@@ -1265,19 +1268,23 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_MODE1_MDEU_SHA1_HMAC,
},
{
- .name = "authenc(hmac(sha256),cbc(aes))",
- .driver_name = "authenc-hmac-sha256-cbc-aes-talitos",
- .blocksize = AES_BLOCK_SIZE,
- .aead = {
- .setkey = aead_authenc_setkey,
- .setauthsize = aead_authenc_setauthsize,
- .encrypt = aead_authenc_encrypt,
- .decrypt = aead_authenc_decrypt,
- .givencrypt = aead_authenc_givencrypt,
- .geniv = "<built-in>",
- .ivsize = AES_BLOCK_SIZE,
- .maxauthsize = SHA256_DIGEST_SIZE,
- },
+ .alg = {
+ .cra_name = "authenc(hmac(sha256),cbc(aes))",
+ .cra_driver_name = "authenc-hmac-sha256-cbc-aes-talitos",
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_aead_type,
+ .cra_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = AES_BLOCK_SIZE,
+ .maxauthsize = SHA256_DIGEST_SIZE,
+ }
+ },
.desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
DESC_HDR_SEL0_AESU |
DESC_HDR_MODE0_AESU_CBC |
@@ -1287,19 +1294,23 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_MODE1_MDEU_SHA256_HMAC,
},
{
- .name = "authenc(hmac(sha256),cbc(des3_ede))",
- .driver_name = "authenc-hmac-sha256-cbc-3des-talitos",
- .blocksize = DES3_EDE_BLOCK_SIZE,
- .aead = {
- .setkey = aead_authenc_setkey,
- .setauthsize = aead_authenc_setauthsize,
- .encrypt = aead_authenc_encrypt,
- .decrypt = aead_authenc_decrypt,
- .givencrypt = aead_authenc_givencrypt,
- .geniv = "<built-in>",
- .ivsize = DES3_EDE_BLOCK_SIZE,
- .maxauthsize = SHA256_DIGEST_SIZE,
- },
+ .alg = {
+ .cra_name = "authenc(hmac(sha256),cbc(des3_ede))",
+ .cra_driver_name = "authenc-hmac-sha256-cbc-3des-talitos",
+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_aead_type,
+ .cra_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ .maxauthsize = SHA256_DIGEST_SIZE,
+ }
+ },
.desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
DESC_HDR_SEL0_DEU |
DESC_HDR_MODE0_DEU_CBC |
@@ -1310,19 +1321,23 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_MODE1_MDEU_SHA256_HMAC,
},
{
- .name = "authenc(hmac(md5),cbc(aes))",
- .driver_name = "authenc-hmac-md5-cbc-aes-talitos",
- .blocksize = AES_BLOCK_SIZE,
- .aead = {
- .setkey = aead_authenc_setkey,
- .setauthsize = aead_authenc_setauthsize,
- .encrypt = aead_authenc_encrypt,
- .decrypt = aead_authenc_decrypt,
- .givencrypt = aead_authenc_givencrypt,
- .geniv = "<built-in>",
- .ivsize = AES_BLOCK_SIZE,
- .maxauthsize = MD5_DIGEST_SIZE,
- },
+ .alg = {
+ .cra_name = "authenc(hmac(md5),cbc(aes))",
+ .cra_driver_name = "authenc-hmac-md5-cbc-aes-talitos",
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_aead_type,
+ .cra_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = AES_BLOCK_SIZE,
+ .maxauthsize = MD5_DIGEST_SIZE,
+ }
+ },
.desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
DESC_HDR_SEL0_AESU |
DESC_HDR_MODE0_AESU_CBC |
@@ -1332,19 +1347,23 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_MODE1_MDEU_MD5_HMAC,
},
{
- .name = "authenc(hmac(md5),cbc(des3_ede))",
- .driver_name = "authenc-hmac-md5-cbc-3des-talitos",
- .blocksize = DES3_EDE_BLOCK_SIZE,
- .aead = {
- .setkey = aead_authenc_setkey,
- .setauthsize = aead_authenc_setauthsize,
- .encrypt = aead_authenc_encrypt,
- .decrypt = aead_authenc_decrypt,
- .givencrypt = aead_authenc_givencrypt,
- .geniv = "<built-in>",
- .ivsize = DES3_EDE_BLOCK_SIZE,
- .maxauthsize = MD5_DIGEST_SIZE,
- },
+ .alg = {
+ .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
+ .cra_driver_name = "authenc-hmac-md5-cbc-3des-talitos",
+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_aead_type,
+ .cra_aead = {
+ .setkey = aead_setkey,
+ .setauthsize = aead_setauthsize,
+ .encrypt = aead_encrypt,
+ .decrypt = aead_decrypt,
+ .givencrypt = aead_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ .maxauthsize = MD5_DIGEST_SIZE,
+ }
+ },
.desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP |
DESC_HDR_SEL0_DEU |
DESC_HDR_MODE0_DEU_CBC |
@@ -1457,19 +1476,13 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
return ERR_PTR(-ENOMEM);

alg = &t_alg->crypto_alg;
+ *alg = template->alg;

- snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name);
- snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
- template->driver_name);
alg->cra_module = THIS_MODULE;
alg->cra_init = talitos_cra_init;
alg->cra_priority = TALITOS_CRA_PRIORITY;
- alg->cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC;
- alg->cra_blocksize = template->blocksize;
alg->cra_alignmask = 0;
- alg->cra_type = &crypto_aead_type;
alg->cra_ctxsize = sizeof(struct talitos_ctx);
- alg->cra_u.aead = template->aead;

t_alg->desc_hdr_template = template->desc_hdr_template;
t_alg->dev = dev;
--
1.5.6.3


2009-03-16 01:22:02

by Lee Nipper

[permalink] [raw]
Subject: [PATCH 2/3] crypto: talitos - Add ablkcipher algorithms

Add these ablkcipher algorithms:
cbc(aes),
cbc(des3_ede).

ipsec_esp_edesc is renamed to talitos_edesc
to use it in ablkcipher routines.
Added handling of chained scatterlists with zero length entry
because eseqiv uses it.
Added new map and unmap routines.

Signed-off-by: Lee Nipper <[email protected]>
---
drivers/crypto/talitos.c | 393 +++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 355 insertions(+), 38 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index d53e2eb..3338668 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -44,9 +44,14 @@
#include <crypto/sha.h>
#include <crypto/aead.h>
#include <crypto/authenc.h>
+#include <crypto/skcipher.h>
+#include <crypto/scatterwalk.h>

#include "talitos.h"

+static int testablkcipher = 0;
+module_param(testablkcipher, int, 0);
+
#define TALITOS_TIMEOUT 100000
#define TALITOS_MAX_DATA_LEN 65535

@@ -759,12 +764,62 @@ badkey:
struct talitos_edesc {
int src_nents;
int dst_nents;
+ int src_is_chained;
+ int dst_is_chained;
int dma_len;
dma_addr_t dma_link_tbl;
struct talitos_desc desc;
struct talitos_ptr link_tbl[0];
};

+static int talitos_map_sg(struct device *dev, struct scatterlist *sg,
+ unsigned int nents, enum dma_data_direction dir,
+ int chained)
+{
+ if (unlikely(chained))
+ while (sg) {
+ dma_map_sg(dev, sg, 1, dir);
+ sg = scatterwalk_sg_next(sg);
+ }
+ else
+ dma_map_sg(dev, sg, nents, dir);
+ return nents;
+}
+
+static void talitos_unmap_sg_chain(struct device *dev, struct scatterlist *sg,
+ enum dma_data_direction dir)
+{
+ while (sg) {
+ dma_unmap_sg(dev, sg, 1, dir);
+ sg = scatterwalk_sg_next(sg);
+ }
+}
+
+static void talitos_sg_unmap(struct device *dev,
+ struct talitos_edesc *edesc,
+ struct scatterlist *src,
+ struct scatterlist *dst)
+{
+ unsigned int src_nents = edesc->src_nents ? : 1;
+ unsigned int dst_nents = edesc->dst_nents ? : 1;
+
+ if (src != dst) {
+ if (edesc->src_is_chained)
+ talitos_unmap_sg_chain(dev, src, DMA_TO_DEVICE);
+ else
+ dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
+
+ if (edesc->dst_is_chained)
+ talitos_unmap_sg_chain(dev, dst, DMA_FROM_DEVICE);
+ else
+ dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
+ } else
+ if (edesc->src_is_chained)
+ talitos_unmap_sg_chain(dev, src, DMA_BIDIRECTIONAL);
+ else
+ dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
+}
+
static void ipsec_esp_unmap(struct device *dev,
struct talitos_edesc *edesc,
struct aead_request *areq)
@@ -776,15 +831,7 @@ static void ipsec_esp_unmap(struct device *dev,

dma_unmap_sg(dev, areq->assoc, 1, DMA_TO_DEVICE);

- if (areq->src != areq->dst) {
- dma_unmap_sg(dev, areq->src, edesc->src_nents ? : 1,
- DMA_TO_DEVICE);
- dma_unmap_sg(dev, areq->dst, edesc->dst_nents ? : 1,
- DMA_FROM_DEVICE);
- } else {
- dma_unmap_sg(dev, areq->src, edesc->src_nents ? : 1,
- DMA_BIDIRECTIONAL);
- }
+ talitos_sg_unmap(dev, edesc, areq->src, areq->dst);

if (edesc->dma_len)
dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
@@ -890,7 +937,7 @@ static int sg_to_link_tbl(struct scatterlist *sg, int sg_count,
link_tbl_ptr->j_extent = 0;
link_tbl_ptr++;
cryptlen -= sg_dma_len(sg);
- sg = sg_next(sg);
+ sg = scatterwalk_sg_next(sg);
}

/* adjust (decrease) last one (or two) entry's len to cryptlen */
@@ -956,12 +1003,11 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
desc->ptr[4].len = cpu_to_be16(cryptlen);
desc->ptr[4].j_extent = authsize;

- if (areq->src == areq->dst)
- sg_count = dma_map_sg(dev, areq->src, edesc->src_nents ? : 1,
- DMA_BIDIRECTIONAL);
- else
- sg_count = dma_map_sg(dev, areq->src, edesc->src_nents ? : 1,
- DMA_TO_DEVICE);
+ sg_count = talitos_map_sg(dev, areq->src,
+ edesc->src_nents ? : 1,
+ (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
+ DMA_TO_DEVICE,
+ edesc->src_is_chained);

if (sg_count == 1) {
desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src));
@@ -990,8 +1036,10 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
desc->ptr[5].j_extent = authsize;

if (areq->src != areq->dst) {
- sg_count = dma_map_sg(dev, areq->dst, edesc->dst_nents ? : 1,
- DMA_FROM_DEVICE);
+ sg_count = talitos_map_sg(dev, areq->dst,
+ edesc->dst_nents ? : 1,
+ DMA_FROM_DEVICE,
+ edesc->dst_is_chained);
}

if (sg_count == 1) {
@@ -1041,15 +1089,18 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
/*
* derive number of elements in scatterlist
*/
-static int sg_count(struct scatterlist *sg_list, int nbytes)
+static int sg_count(struct scatterlist *sg_list, int nbytes, int *chained)
{
struct scatterlist *sg = sg_list;
int sg_nents = 0;

- while (nbytes) {
+ *chained = 0;
+ while (nbytes > 0) {
sg_nents++;
nbytes -= sg->length;
- sg = sg_next(sg);
+ if (!sg_is_last(sg) && (sg + 1)->length == 0)
+ *chained = 1;
+ sg = scatterwalk_sg_next(sg);
}

return sg_nents;
@@ -1058,28 +1109,32 @@ static int sg_count(struct scatterlist *sg_list, int nbytes)
/*
* allocate and map the extended descriptor
*/
-static struct talitos_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq,
- int icv_stashing)
+static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
+ struct scatterlist *src,
+ struct scatterlist *dst,
+ unsigned int cryptlen,
+ unsigned int authsize,
+ int icv_stashing,
+ u32 cryptoflags)
{
- struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
- struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
struct talitos_edesc *edesc;
int src_nents, dst_nents, alloc_len, dma_len;
- gfp_t flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
+ int src_chained, dst_chained = 0;
+ gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
GFP_ATOMIC;

- if (areq->cryptlen + ctx->authsize > TALITOS_MAX_DATA_LEN) {
- dev_err(ctx->dev, "cryptlen exceeds h/w max limit\n");
+ if (cryptlen + authsize > TALITOS_MAX_DATA_LEN) {
+ dev_err(dev, "length exceeds h/w max limit\n");
return ERR_PTR(-EINVAL);
}

- src_nents = sg_count(areq->src, areq->cryptlen + ctx->authsize);
+ src_nents = sg_count(src, cryptlen + authsize, &src_chained);
src_nents = (src_nents == 1) ? 0 : src_nents;

- if (areq->dst == areq->src) {
+ if (dst == src) {
dst_nents = src_nents;
} else {
- dst_nents = sg_count(areq->dst, areq->cryptlen + ctx->authsize);
+ dst_nents = sg_count(dst, cryptlen + authsize, &dst_chained);
dst_nents = (dst_nents == 1) ? 0 : dst_nents;
}

@@ -1091,28 +1146,41 @@ static struct talitos_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq,
alloc_len = sizeof(struct talitos_edesc);
if (src_nents || dst_nents) {
dma_len = (src_nents + dst_nents + 2) *
- sizeof(struct talitos_ptr) + ctx->authsize;
+ sizeof(struct talitos_ptr) + authsize;
alloc_len += dma_len;
} else {
dma_len = 0;
- alloc_len += icv_stashing ? ctx->authsize : 0;
+ alloc_len += icv_stashing ? authsize : 0;
}

edesc = kmalloc(alloc_len, GFP_DMA | flags);
if (!edesc) {
- dev_err(ctx->dev, "could not allocate edescriptor\n");
+ dev_err(dev, "could not allocate edescriptor\n");
return ERR_PTR(-ENOMEM);
}

edesc->src_nents = src_nents;
edesc->dst_nents = dst_nents;
+ edesc->src_is_chained = src_chained;
+ edesc->dst_is_chained = dst_chained;
edesc->dma_len = dma_len;
- edesc->dma_link_tbl = dma_map_single(ctx->dev, &edesc->link_tbl[0],
+ edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0],
edesc->dma_len, DMA_BIDIRECTIONAL);

return edesc;
}

+static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq,
+ int icv_stashing)
+{
+ struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
+
+ return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
+ areq->cryptlen, ctx->authsize, icv_stashing,
+ areq->base.flags);
+}
+
static int aead_encrypt(struct aead_request *req)
{
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
@@ -1120,7 +1188,7 @@ static int aead_encrypt(struct aead_request *req)
struct talitos_edesc *edesc;

/* allocate extended descriptor */
- edesc = ipsec_esp_edesc_alloc(req, 0);
+ edesc = aead_edesc_alloc(req, 0);
if (IS_ERR(edesc))
return PTR_ERR(edesc);

@@ -1145,7 +1213,7 @@ static int aead_decrypt(struct aead_request *req)
req->cryptlen -= authsize;

/* allocate extended descriptor */
- edesc = ipsec_esp_edesc_alloc(req, 1);
+ edesc = aead_edesc_alloc(req, 1);
if (IS_ERR(edesc))
return PTR_ERR(edesc);

@@ -1192,7 +1260,7 @@ static int aead_givencrypt(struct aead_givcrypt_request *req)
struct talitos_edesc *edesc;

/* allocate extended descriptor */
- edesc = ipsec_esp_edesc_alloc(areq, 0);
+ edesc = aead_edesc_alloc(areq, 0);
if (IS_ERR(edesc))
return PTR_ERR(edesc);

@@ -1207,6 +1275,201 @@ static int aead_givencrypt(struct aead_givcrypt_request *req)
ipsec_esp_encrypt_done);
}

+static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
+ const u8 *key, unsigned int keylen)
+{
+ struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+ struct ablkcipher_alg *alg = crypto_ablkcipher_alg(cipher);
+
+ if (keylen > TALITOS_MAX_KEY_SIZE)
+ goto badkey;
+
+ if (keylen < alg->min_keysize || keylen > alg->max_keysize)
+ goto badkey;
+
+ memcpy(&ctx->key, key, keylen);
+ ctx->keylen = keylen;
+
+ return 0;
+
+badkey:
+ crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+}
+
+static void common_nonsnoop_unmap(struct device *dev,
+ struct talitos_edesc *edesc,
+ struct ablkcipher_request *areq)
+{
+ unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
+ unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE);
+ unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
+
+ talitos_sg_unmap(dev, edesc, areq->src, areq->dst);
+
+ if (edesc->dma_len)
+ dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
+ DMA_BIDIRECTIONAL);
+}
+
+static void ablkcipher_done(struct device *dev,
+ struct talitos_desc *desc, void *context,
+ int err)
+{
+ struct ablkcipher_request *areq = context;
+ struct talitos_edesc *edesc =
+ container_of(desc, struct talitos_edesc, desc);
+
+ common_nonsnoop_unmap(dev, edesc, areq);
+
+ kfree(edesc);
+
+ areq->base.complete(&areq->base, err);
+}
+
+static int common_nonsnoop(struct talitos_edesc *edesc,
+ struct ablkcipher_request *areq,
+ u8 *giv,
+ void (*callback) (struct device *dev,
+ struct talitos_desc *desc,
+ void *context, int error))
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+ struct device *dev = ctx->dev;
+ struct talitos_desc *desc = &edesc->desc;
+ unsigned int cryptlen = areq->nbytes;
+ unsigned int ivsize;
+ int sg_count, ret;
+
+ /* first DWORD empty */
+ desc->ptr[0].len = 0;
+ desc->ptr[0].ptr = 0;
+ desc->ptr[0].j_extent = 0;
+
+ /* cipher iv */
+ ivsize = crypto_ablkcipher_ivsize(cipher);
+ map_single_talitos_ptr(dev, &desc->ptr[1], ivsize, giv ?: areq->info, 0,
+ DMA_TO_DEVICE);
+
+ /* cipher key */
+ map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
+ (char *)&ctx->key, 0, DMA_TO_DEVICE);
+
+ /*
+ * cipher in
+ */
+ desc->ptr[3].len = cpu_to_be16(cryptlen);
+ desc->ptr[3].j_extent = 0;
+
+ sg_count = talitos_map_sg(dev, areq->src,
+ edesc->src_nents ? : 1,
+ (areq->src == areq->dst) ? DMA_BIDIRECTIONAL :
+ DMA_TO_DEVICE,
+ edesc->src_is_chained);
+
+ if (sg_count == 1) {
+ desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->src));
+ } else {
+ sg_count = sg_to_link_tbl(areq->src, sg_count, cryptlen,
+ &edesc->link_tbl[0]);
+ if (sg_count > 1) {
+ desc->ptr[3].j_extent |= DESC_PTR_LNKTBL_JUMP;
+ desc->ptr[3].ptr = cpu_to_be32(edesc->dma_link_tbl);
+ dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
+ edesc->dma_len, DMA_BIDIRECTIONAL);
+ } else {
+ /* Only one segment now, so no link tbl needed */
+ desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->src));
+ }
+ }
+
+ /* cipher out */
+ desc->ptr[4].len = cpu_to_be16(cryptlen);
+ desc->ptr[4].j_extent = 0;
+
+ if (areq->src != areq->dst) {
+ sg_count = talitos_map_sg(dev, areq->dst,
+ edesc->dst_nents ? : 1,
+ DMA_FROM_DEVICE,
+ edesc->dst_is_chained);
+ }
+
+ if (sg_count == 1) {
+ desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->dst));
+ } else {
+ struct talitos_ptr *link_tbl_ptr =
+ &edesc->link_tbl[edesc->src_nents + 1];
+
+ desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP;
+ desc->ptr[4].ptr = cpu_to_be32((struct talitos_ptr *)
+ edesc->dma_link_tbl +
+ edesc->src_nents + 1);
+ sg_count = sg_to_link_tbl(areq->dst, sg_count, cryptlen,
+ link_tbl_ptr);
+ dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
+ edesc->dma_len, DMA_BIDIRECTIONAL);
+ }
+
+ /* iv out */
+ map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv, 0,
+ DMA_FROM_DEVICE);
+
+ /* last DWORD empty */
+ desc->ptr[6].len = 0;
+ desc->ptr[6].ptr = 0;
+ desc->ptr[6].j_extent = 0;
+
+ ret = talitos_submit(dev, desc, callback, areq);
+ if (ret != -EINPROGRESS) {
+ common_nonsnoop_unmap(dev, edesc, areq);
+ kfree(edesc);
+ }
+ return ret;
+}
+
+static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
+ return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst, areq->nbytes,
+ 0, 0, areq->base.flags);
+}
+
+static int ablkcipher_encrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+ struct talitos_edesc *edesc;
+
+ /* allocate extended descriptor */
+ edesc = ablkcipher_edesc_alloc(areq);
+ if (IS_ERR(edesc))
+ return PTR_ERR(edesc);
+
+ /* set encrypt */
+ edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
+
+ return common_nonsnoop(edesc, areq, NULL, ablkcipher_done);
+}
+
+static int ablkcipher_decrypt(struct ablkcipher_request *areq)
+{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+ struct talitos_edesc *edesc;
+
+ /* allocate extended descriptor */
+ edesc = ablkcipher_edesc_alloc(areq);
+ if (IS_ERR(edesc))
+ return PTR_ERR(edesc);
+
+ edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
+
+ return common_nonsnoop(edesc, areq, NULL, ablkcipher_done);
+}
+
struct talitos_alg_template {
struct crypto_alg alg;
__be32 desc_hdr_template;
@@ -1372,6 +1635,52 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_MODE1_MDEU_INIT |
DESC_HDR_MODE1_MDEU_PAD |
DESC_HDR_MODE1_MDEU_MD5_HMAC,
+ },
+ /* ABLKCIPHER algorithms. */
+ {
+ .alg = {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "cbc-aes-talitos",
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+ CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_ablkcipher = {
+ .setkey = ablkcipher_setkey,
+ .encrypt = ablkcipher_encrypt,
+ .decrypt = ablkcipher_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_AESU |
+ DESC_HDR_MODE0_AESU_CBC,
+ },
+ {
+ .alg = {
+ .cra_name = "cbc(des3_ede)",
+ .cra_driver_name = "cbc-3des-talitos",
+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+ CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_ablkcipher = {
+ .setkey = ablkcipher_setkey,
+ .encrypt = ablkcipher_encrypt,
+ .decrypt = ablkcipher_decrypt,
+ .geniv = "eseqiv",
+ .min_keysize = DES3_EDE_KEY_SIZE,
+ .max_keysize = DES3_EDE_KEY_SIZE,
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_DEU |
+ DESC_HDR_MODE0_DEU_CBC |
+ DESC_HDR_MODE0_DEU_3DES,
}
};

@@ -1641,6 +1950,14 @@ static int talitos_probe(struct of_device *ofdev,
if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
struct talitos_crypto_alg *t_alg;

+ /* For testing, we can omit the AEAD algorithms
+ * and use the ABLKCIPHER algorithms for IPsec.
+ */
+ if (testablkcipher &&
+ ((driver_algs[i].alg.cra_flags & CRYPTO_ALG_TYPE_MASK)
+ == CRYPTO_ALG_TYPE_AEAD))
+ continue;
+
t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
if (IS_ERR(t_alg)) {
err = PTR_ERR(t_alg);
--
1.5.6.3


2009-03-16 01:22:06

by Lee Nipper

[permalink] [raw]
Subject: [PATCH 3/3] crypto: talitos - Add ahash algorithms (1st cut, digest only)

This patch adds simple ahash algorithms for
sha1, hmac(sha1),
sha256, hmac(sha256),
sha384, hmac(sha384),
sha512. hmac(sha512).
md5, hmac(md5).

The implementation provides digest only,
as the update and final functions are omitted.

Signed-off-by: Lee Nipper <[email protected]>
---
drivers/crypto/talitos.c | 464 ++++++++++++++++++++++++++++++++++++++++++++-
drivers/crypto/talitos.h | 5 +
2 files changed, 458 insertions(+), 11 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 3338668..0c29785 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -46,6 +46,7 @@
#include <crypto/authenc.h>
#include <crypto/skcipher.h>
#include <crypto/scatterwalk.h>
+#include <crypto/internal/hash.h>

#include "talitos.h"

@@ -681,6 +682,7 @@ static void talitos_unregister_rng(struct device *dev)
#define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */

#define MD5_DIGEST_SIZE 16
+#define MD5_BLOCK_SIZE 64

struct talitos_ctx {
struct device *dev;
@@ -809,10 +811,14 @@ static void talitos_sg_unmap(struct device *dev,
else
dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);

- if (edesc->dst_is_chained)
- talitos_unmap_sg_chain(dev, dst, DMA_FROM_DEVICE);
- else
- dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
+ if (dst) {
+ if (edesc->dst_is_chained)
+ talitos_unmap_sg_chain(dev, dst,
+ DMA_FROM_DEVICE);
+ else
+ dma_unmap_sg(dev, dst, dst_nents,
+ DMA_FROM_DEVICE);
+ }
} else
if (edesc->src_is_chained)
talitos_unmap_sg_chain(dev, src, DMA_BIDIRECTIONAL);
@@ -1112,6 +1118,7 @@ static int sg_count(struct scatterlist *sg_list, int nbytes, int *chained)
static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
struct scatterlist *src,
struct scatterlist *dst,
+ u8 *hash_result,
unsigned int cryptlen,
unsigned int authsize,
int icv_stashing,
@@ -1131,11 +1138,15 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
src_nents = sg_count(src, cryptlen + authsize, &src_chained);
src_nents = (src_nents == 1) ? 0 : src_nents;

- if (dst == src) {
- dst_nents = src_nents;
+ if (hash_result) {
+ dst_nents = 0;
} else {
- dst_nents = sg_count(dst, cryptlen + authsize, &dst_chained);
- dst_nents = (dst_nents == 1) ? 0 : dst_nents;
+ if (dst == src) {
+ dst_nents = src_nents;
+ } else {
+ dst_nents = sg_count(dst, cryptlen + authsize, &dst_chained);
+ dst_nents = (dst_nents == 1) ? 0 : dst_nents;
+ }
}

/*
@@ -1176,7 +1187,7 @@ static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq,
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);

- return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst,
+ return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst, NULL,
areq->cryptlen, ctx->authsize, icv_stashing,
areq->base.flags);
}
@@ -1433,8 +1444,8 @@ static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *a
struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);

- return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst, areq->nbytes,
- 0, 0, areq->base.flags);
+ return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst, NULL,
+ areq->nbytes, 0, 0, areq->base.flags);
}

static int ablkcipher_encrypt(struct ablkcipher_request *areq)
@@ -1470,6 +1481,246 @@ static int ablkcipher_decrypt(struct ablkcipher_request *areq)
return common_nonsnoop(edesc, areq, NULL, ablkcipher_done);
}

+static void common_nonsnoop_hash_unmap(struct device *dev,
+ struct talitos_edesc *edesc,
+ struct ahash_request *areq)
+{
+ unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
+
+ if (edesc->desc.ptr[2].len)
+ unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2],
+ DMA_TO_DEVICE);
+
+ talitos_sg_unmap(dev, edesc, areq->src, NULL);
+
+ if (edesc->dma_len)
+ dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
+ DMA_BIDIRECTIONAL);
+
+}
+
+static void ahash_done(struct device *dev,
+ struct talitos_desc *desc, void *context,
+ int err)
+{
+ struct ahash_request *areq = context;
+ struct talitos_edesc *edesc =
+ container_of(desc, struct talitos_edesc, desc);
+
+ common_nonsnoop_hash_unmap(dev, edesc, areq);
+
+ kfree(edesc);
+
+ areq->base.complete(&areq->base, err);
+}
+
+static int common_nonsnoop_hash(struct talitos_edesc *edesc,
+ struct ahash_request *areq,
+ void (*callback) (struct device *dev,
+ struct talitos_desc *desc,
+ void *context, int error))
+{
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+ struct device *dev = ctx->dev;
+ struct talitos_desc *desc = &edesc->desc;
+ unsigned int length = areq->nbytes;
+ int sg_count, ret;
+
+ /* first DWORD empty */
+ desc->ptr[0].len = 0;
+ desc->ptr[0].ptr = 0;
+ desc->ptr[0].j_extent = 0;
+
+ /* second DWORD empty */
+ desc->ptr[1].len = 0;
+ desc->ptr[1].ptr = 0;
+ desc->ptr[1].j_extent = 0;
+
+ /* cipher key */
+ if (ctx->keylen)
+ map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
+ (char *)&ctx->key, 0, DMA_TO_DEVICE);
+ else {
+ desc->ptr[2].len = 0;
+ desc->ptr[2].ptr = 0;
+ desc->ptr[2].j_extent = 0;
+ }
+
+ /*
+ * data in
+ */
+ desc->ptr[3].len = cpu_to_be16(length);
+ desc->ptr[3].j_extent = 0;
+
+ sg_count = talitos_map_sg(dev, areq->src,
+ edesc->src_nents ? : 1,
+ DMA_TO_DEVICE,
+ edesc->src_is_chained);
+
+ if (sg_count == 1) {
+ desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->src));
+ } else {
+ sg_count = sg_to_link_tbl(areq->src, sg_count, length,
+ &edesc->link_tbl[0]);
+ if (sg_count > 1) {
+ desc->ptr[3].j_extent |= DESC_PTR_LNKTBL_JUMP;
+ desc->ptr[3].ptr = cpu_to_be32(edesc->dma_link_tbl);
+ dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
+ edesc->dma_len, DMA_BIDIRECTIONAL);
+ } else {
+ /* Only one segment now, so no link tbl needed */
+ desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->src));
+ }
+ }
+
+ /* fifth DWORD empty */
+ desc->ptr[4].len = 0;
+ desc->ptr[4].ptr = 0;
+ desc->ptr[4].j_extent = 0;
+
+ /* hash/HMAC out */
+ map_single_talitos_ptr(dev, &desc->ptr[5], crypto_ahash_digestsize(tfm),
+ areq->result, 0, DMA_FROM_DEVICE);
+
+ /* last DWORD empty */
+ desc->ptr[6].len = 0;
+ desc->ptr[6].ptr = 0;
+ desc->ptr[6].j_extent = 0;
+
+ ret = talitos_submit(dev, desc, callback, areq);
+ if (ret != -EINPROGRESS) {
+ common_nonsnoop_hash_unmap(dev, edesc, areq);
+ kfree(edesc);
+ }
+ return ret;
+}
+
+static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq)
+{
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+
+ return talitos_edesc_alloc(ctx->dev, areq->src, NULL, areq->result,
+ areq->nbytes, 0, 0, areq->base.flags);
+}
+
+static int ahash_init(struct ahash_request *req)
+{
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+
+ /* Initialize the context */
+ ctx->keylen = 0;
+
+ return 0;
+}
+
+static int ahash_digest(struct ahash_request *areq)
+{
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+ struct talitos_edesc *edesc;
+
+
+ /* allocate extended descriptor */
+ edesc = ahash_edesc_alloc(areq);
+ if (IS_ERR(edesc))
+ return PTR_ERR(edesc);
+
+ /* We are using only one descriptor for digest op, so always pad */
+ edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_MDEU_PAD;
+
+ /* set hmac */
+ if (ctx->keylen)
+ edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
+
+ return common_nonsnoop_hash(edesc, areq, ahash_done);
+}
+
+struct keyhash_result {
+ struct completion completion;
+ int err;
+};
+
+static void keyhash_complete(struct crypto_async_request *req, int err)
+{
+ struct keyhash_result *res = req->data;
+
+ if (err == -EINPROGRESS)
+ return;
+
+ res->err = err;
+ complete(&res->completion);
+}
+
+static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
+ unsigned int blocksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
+ unsigned int digestsize = crypto_ahash_digestsize(tfm);
+ unsigned int keysize = keylen;
+ u8 hash[64];
+
+ /* The code below for keylen > blocksize was an attempt
+ * to do the correct thing for large hash keys. However, it still
+ * fails to help an HMAC work correctly with the test module which
+ * checks a key larger than the block size. I leave it here
+ * in case it is close to doing the right thing.
+ */
+ if (keylen > blocksize) {
+ /* Must hash the key in separate operation */
+ struct scatterlist sg[1];
+ struct ahash_request *req;
+ struct keyhash_result hresult;
+ int ret;
+
+ init_completion(&hresult.completion);
+
+ req = ahash_request_alloc(tfm, GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+ /* Keep keylen 0 during hash of the long key */
+ ctx->keylen = 0;
+ ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ keyhash_complete, &hresult);
+
+ sg_init_one(&sg[0], key, keylen);
+
+ ahash_request_set_crypt(req, sg, hash, keylen);
+ ret = crypto_ahash_digest(req);
+ switch (ret) {
+ case 0:
+ break;
+ case -EINPROGRESS:
+ case -EBUSY:
+ ret = wait_for_completion_interruptible(
+ &hresult.completion);
+ if (!ret)
+ ret = hresult.err;
+ break;
+ default:
+ break;
+ }
+ ahash_request_free(req);
+ if (ret)
+ goto badkey;
+ keysize = digestsize;
+ memcpy(ctx->key, hash, digestsize);
+ } else {
+ memcpy(ctx->key, key, keysize);
+ }
+
+ ctx->keylen = keysize;
+
+ return 0;
+
+badkey:
+ crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+}
+
struct talitos_alg_template {
struct crypto_alg alg;
__be32 desc_hdr_template;
@@ -1681,6 +1932,197 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_SEL0_DEU |
DESC_HDR_MODE0_DEU_CBC |
DESC_HDR_MODE0_DEU_3DES,
+ },
+ /* AHASH algorithms. */
+ {
+ .alg = {
+ .cra_name = "sha1",
+ .cra_driver_name = "sha1-talitos",
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type,
+ .cra_ahash = {
+ .init = ahash_init,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .digestsize = SHA1_DIGEST_SIZE,
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUA |
+ DESC_HDR_MODE0_MDEU_INIT |
+ DESC_HDR_MODE0_MDEU_SHA1,
+ },
+ {
+ .alg = {
+ .cra_name = "sha256",
+ .cra_driver_name = "sha256-talitos",
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type,
+ .cra_ahash = {
+ .init = ahash_init,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .digestsize = SHA256_DIGEST_SIZE
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUA |
+ DESC_HDR_MODE0_MDEU_INIT |
+ DESC_HDR_MODE0_MDEU_SHA256,
+ },
+ {
+ .alg = {
+ .cra_name = "sha384",
+ .cra_driver_name = "sha384-talitos",
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type,
+ .cra_ahash = {
+ .init = ahash_init,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .digestsize = SHA384_DIGEST_SIZE,
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUB |
+ DESC_HDR_MODE0_MDEU_INIT |
+ DESC_HDR_MODE0_MDEU_SHA384,
+ },
+ {
+ .alg = {
+ .cra_name = "sha512",
+ .cra_driver_name = "sha512-talitos",
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type,
+ .cra_ahash = {
+ .init = ahash_init,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .digestsize = SHA512_DIGEST_SIZE
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUB |
+ DESC_HDR_MODE0_MDEU_INIT |
+ DESC_HDR_MODE0_MDEU_SHA512,
+ },
+ {
+ .alg = {
+ .cra_name = "hmac(sha1)",
+ .cra_driver_name = "hmac-sha1-talitos",
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type,
+ .cra_ahash = {
+ .init = ahash_init,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .digestsize = SHA1_DIGEST_SIZE,
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUA |
+ DESC_HDR_MODE0_MDEU_INIT |
+ DESC_HDR_MODE0_MDEU_SHA1,
+ },
+ {
+ .alg = {
+ .cra_name = "hmac(sha256)",
+ .cra_driver_name = "hmac-sha256-talitos",
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type,
+ .cra_ahash = {
+ .init = ahash_init,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .digestsize = SHA256_DIGEST_SIZE
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUA |
+ DESC_HDR_MODE0_MDEU_INIT |
+ DESC_HDR_MODE0_MDEU_SHA256,
+ },
+ {
+ .alg = {
+ .cra_name = "hmac(sha384)",
+ .cra_driver_name = "hmac-sha384-talitos",
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type,
+ .cra_ahash = {
+ .init = ahash_init,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .digestsize = SHA384_DIGEST_SIZE,
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUB |
+ DESC_HDR_MODE0_MDEU_INIT |
+ DESC_HDR_MODE0_MDEU_SHA384,
+ },
+ {
+ .alg = {
+ .cra_name = "hmac(sha512)",
+ .cra_driver_name = "hmac-sha512-talitos",
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type,
+ .cra_ahash = {
+ .init = ahash_init,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .digestsize = SHA512_DIGEST_SIZE
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUB |
+ DESC_HDR_MODE0_MDEU_INIT |
+ DESC_HDR_MODE0_MDEU_SHA512,
+ },
+ {
+ .alg = {
+ .cra_name = "md5",
+ .cra_driver_name = "md5-talitos",
+ .cra_blocksize = MD5_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type,
+ .cra_ahash = {
+ .init = ahash_init,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .digestsize = MD5_DIGEST_SIZE,
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUA |
+ DESC_HDR_MODE0_MDEU_INIT |
+ DESC_HDR_MODE0_MDEU_MD5,
+ },
+ {
+ .alg = {
+ .cra_name = "hmac(md5)",
+ .cra_driver_name = "hmac-md5-talitos",
+ .cra_blocksize = MD5_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+ .cra_type = &crypto_ahash_type,
+ .cra_ahash = {
+ .init = ahash_init,
+ .digest = ahash_digest,
+ .setkey = ahash_setkey,
+ .digestsize = MD5_DIGEST_SIZE,
+ }
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_MDEUA |
+ DESC_HDR_MODE0_MDEU_INIT |
+ DESC_HDR_MODE0_MDEU_MD5,
}
};

diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
index 575981f..85deb0a 100644
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -162,6 +162,8 @@
#define DESC_HDR_MODE0_MDEU_MD5 cpu_to_be32(0x00200000)
#define DESC_HDR_MODE0_MDEU_SHA256 cpu_to_be32(0x00100000)
#define DESC_HDR_MODE0_MDEU_SHA1 cpu_to_be32(0x00000000)
+#define DESC_HDR_MODE0_MDEU_SHA384 cpu_to_be32(0x00000000) /*MDEUB*/
+#define DESC_HDR_MODE0_MDEU_SHA512 cpu_to_be32(0x00200000) /*MDEUB*/
#define DESC_HDR_MODE0_MDEU_MD5_HMAC (DESC_HDR_MODE0_MDEU_MD5 | \
DESC_HDR_MODE0_MDEU_HMAC)
#define DESC_HDR_MODE0_MDEU_SHA256_HMAC (DESC_HDR_MODE0_MDEU_SHA256 | \
@@ -183,6 +185,9 @@
#define DESC_HDR_MODE1_MDEU_MD5 cpu_to_be32(0x00000200)
#define DESC_HDR_MODE1_MDEU_SHA256 cpu_to_be32(0x00000100)
#define DESC_HDR_MODE1_MDEU_SHA1 cpu_to_be32(0x00000000)
+#define DESC_HDR_MODE1_MDEU_SHA384 cpu_to_be32(0x00000000) /*MDEUB*/
+#define DESC_HDR_MODE1_MDEU_SHA512 cpu_to_be32(0x00000200) /*MDEUB*/
+
#define DESC_HDR_MODE1_MDEU_MD5_HMAC (DESC_HDR_MODE1_MDEU_MD5 | \
DESC_HDR_MODE1_MDEU_HMAC)
#define DESC_HDR_MODE1_MDEU_SHA256_HMAC (DESC_HDR_MODE1_MDEU_SHA256 | \
--
1.5.6.3


2009-03-24 21:05:20

by Kim Phillips

[permalink] [raw]
Subject: Re: [PATCH] crypto: talitos - protect against possible null ptr upon error

On Sun, 15 Mar 2009 20:21:47 -0500
Lee Nipper <[email protected]> wrote:

> Added test for null descriptor returned from current_desc.
> Also removed the diagnostic from current_desc,
> and added one instead in talitos_error
> to report an EU error without finding the descriptor.

Hi Lee, thanks for this - I'm not clear on how the channel error gets
triggered, points to an EU, and all of this without a referencing a
current descriptor. How did you run into this case? Assuming one does
get propagated back, what error status does the callback receive?
afaict, interrupt mitigation should not be intervening in this case.

Kim

2009-03-24 23:16:12

by Kim Phillips

[permalink] [raw]
Subject: Re: [PATCH 1/3] crypto: talitos - scaffolding for new algorithm types

On Sun, 15 Mar 2009 20:21:48 -0500
Lee Nipper <[email protected]> wrote:

> This patch is preparation for adding new algorithm types.
>
> Some elements which are AEAD specific were renamed.
> The algorithm template structure was changed to
> use crypto_alg, and talitos_alg_alloc was made
> more general with respect to algorithm types.
>
> Signed-off-by: Lee Nipper <[email protected]>

Acked-by: Kim Phillips <[email protected]>

Thanks for fixing up the algorithm registration code, Lee.

Kim

2009-03-24 23:39:23

by Kim Phillips

[permalink] [raw]
Subject: Re: [PATCH 2/3] crypto: talitos - Add ablkcipher algorithms

On Sun, 15 Mar 2009 20:21:49 -0500
Lee Nipper <[email protected]> wrote:

> Add these ablkcipher algorithms:
> cbc(aes),
> cbc(des3_ede).
>
> ipsec_esp_edesc is renamed to talitos_edesc
> to use it in ablkcipher routines.

erm...actually that shows up in the prior patch (1/3) :).

> + if (sg_count == 1) {
> + desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->src));
> + } else {
> + sg_count = sg_to_link_tbl(areq->src, sg_count, cryptlen,
> + &edesc->link_tbl[0]);
> + if (sg_count > 1) {
> + desc->ptr[3].j_extent |= DESC_PTR_LNKTBL_JUMP;
> + desc->ptr[3].ptr = cpu_to_be32(edesc->dma_link_tbl);
> + dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
> + edesc->dma_len, DMA_BIDIRECTIONAL);
> + } else {
> + /* Only one segment now, so no link tbl needed */
> + desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->src));
> + }
> + }

can we change this to something like:

if (sg_count > 1 && sg_to_link_tbl(areq->src, sg_count, cryptlen,
&edesc->link_tbl[0] > 1) {
desc->ptr[3].j_extent |= DESC_PTR_LNKTBL_JUMP;
desc->ptr[3].ptr = cpu_to_be32(edesc->dma_link_tbl);
dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
edesc->dma_len, DMA_BIDIRECTIONAL);
} else {
/* Only one segment, no link tbl needed */
desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->src));
}

for readability's sake?

> +
> + /* cipher out */
> + desc->ptr[4].len = cpu_to_be16(cryptlen);
> + desc->ptr[4].j_extent = 0;
> +
> + if (areq->src != areq->dst) {
> + sg_count = talitos_map_sg(dev, areq->dst,
> + edesc->dst_nents ? : 1,
> + DMA_FROM_DEVICE,
> + edesc->dst_is_chained);
> + }

braces not necessary

> + /* iv out */
> + map_single_talitos_ptr(dev, &desc->ptr[5], ivsize, ctx->iv, 0,
> + DMA_FROM_DEVICE);

it seems that the device's IV output is not being used anywhere, and
ablkciphers don't have givencrypt's, so this should be safe to remove.

> @@ -1641,6 +1950,14 @@ static int talitos_probe(struct of_device *ofdev,
> if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
> struct talitos_crypto_alg *t_alg;
>
> + /* For testing, we can omit the AEAD algorithms
> + * and use the ABLKCIPHER algorithms for IPsec.
> + */
> + if (testablkcipher &&
> + ((driver_algs[i].alg.cra_flags & CRYPTO_ALG_TYPE_MASK)
> + == CRYPTO_ALG_TYPE_AEAD))
> + continue;
> +

I'd rather let aead tests continue to fail until they get their own
tests; it'll serve as a good reminder to get around to it one day.

Thanks,

Kim

2009-03-24 23:52:47

by Kim Phillips

[permalink] [raw]
Subject: Re: [PATCH 3/3] crypto: talitos - Add ahash algorithms (1st cut, digest only)

On Sun, 15 Mar 2009 20:21:50 -0500
Lee Nipper <[email protected]> wrote:

> + /* first DWORD empty */
> + desc->ptr[0].len = 0;
> + desc->ptr[0].ptr = 0;
> + desc->ptr[0].j_extent = 0;
> +
> + /* second DWORD empty */
> + desc->ptr[1].len = 0;
> + desc->ptr[1].ptr = 0;
> + desc->ptr[1].j_extent = 0;
> +
> + /* cipher key */
> + if (ctx->keylen)
> + map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
> + (char *)&ctx->key, 0, DMA_TO_DEVICE);
> + else {
> + desc->ptr[2].len = 0;
> + desc->ptr[2].ptr = 0;
> + desc->ptr[2].j_extent = 0;
> + }

just

map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
(char *)&ctx->key, 0, DMA_TO_DEVICE);

should do since theoretically the device should ignore pointer entries
with len == 0 and j_extent == 0 (unless you have observed otherwise
practically).

> + if (sg_count == 1) {
> + desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->src));
> + } else {
> + sg_count = sg_to_link_tbl(areq->src, sg_count, length,
> + &edesc->link_tbl[0]);
> + if (sg_count > 1) {
> + desc->ptr[3].j_extent |= DESC_PTR_LNKTBL_JUMP;
> + desc->ptr[3].ptr = cpu_to_be32(edesc->dma_link_tbl);
> + dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
> + edesc->dma_len, DMA_BIDIRECTIONAL);
> + } else {
> + /* Only one segment now, so no link tbl needed */
> + desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->src));
> + }
> + }

same readability comment as in prior patch.

> diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
> index 575981f..85deb0a 100644
> --- a/drivers/crypto/talitos.h
> +++ b/drivers/crypto/talitos.h
> @@ -162,6 +162,8 @@
> #define DESC_HDR_MODE0_MDEU_MD5 cpu_to_be32(0x00200000)
> #define DESC_HDR_MODE0_MDEU_SHA256 cpu_to_be32(0x00100000)
> #define DESC_HDR_MODE0_MDEU_SHA1 cpu_to_be32(0x00000000)
> +#define DESC_HDR_MODE0_MDEU_SHA384 cpu_to_be32(0x00000000) /*MDEUB*/
> +#define DESC_HDR_MODE0_MDEU_SHA512 cpu_to_be32(0x00200000) /*MDEUB*/
> #define DESC_HDR_MODE0_MDEU_MD5_HMAC (DESC_HDR_MODE0_MDEU_MD5 | \
> DESC_HDR_MODE0_MDEU_HMAC)
> #define DESC_HDR_MODE0_MDEU_SHA256_HMAC (DESC_HDR_MODE0_MDEU_SHA256 | \
> @@ -183,6 +185,9 @@
> #define DESC_HDR_MODE1_MDEU_MD5 cpu_to_be32(0x00000200)
> #define DESC_HDR_MODE1_MDEU_SHA256 cpu_to_be32(0x00000100)
> #define DESC_HDR_MODE1_MDEU_SHA1 cpu_to_be32(0x00000000)
> +#define DESC_HDR_MODE1_MDEU_SHA384 cpu_to_be32(0x00000000) /*MDEUB*/
> +#define DESC_HDR_MODE1_MDEU_SHA512 cpu_to_be32(0x00000200) /*MDEUB*/

DESC_HDR_MODE0_MDEUB_SHA384 instead of having the comment?

Kim

2009-03-25 04:06:19

by Lee Nipper

[permalink] [raw]
Subject: Re: [PATCH] crypto: talitos - protect against possible null ptr upon error

On Tue, Mar 24, 2009 at 16:23, Kim Phillips <[email protected]> wrote:
> On Sun, 15 Mar 2009 20:21:47 -0500
> Lee Nipper <[email protected]> wrote:
>
>> Added test for null descriptor returned from current_desc.
>> Also removed the diagnostic from current_desc,
>> and added one instead in talitos_error
>> to report an EU error without finding the descriptor.
>
> Hi Lee, thanks for this - I'm not clear on how the channel error gets
> triggered, points to an EU, and all of this without a referencing a
> current descriptor.

I don't remember the exact case when I observed it, but I did.
In any case, it seemed the code needed the protection against the
failed look up case (prevent null pointer use).

> How did you run into this case?

I had a misconfigured descriptor (I think), and the problem case is
not in the code.

> Assuming one does
> get propagated back, what error status does the callback receive?

Ug. If I were still at Freescale and had access to my logs, I could
answer with detail, But that's not the case.

> afaict, interrupt mitigation should not be intervening in this case.
>

That's right.
The interrupt with error status was occurring, and it was handling it
during the isr..

Thanks,
Lee