linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] crypto: ccp - more code fixes/cleanup
@ 2014-01-06 19:33 Tom Lendacky
  2014-01-06 19:33 ` [PATCH 1/6] crypto: ccp - Apply appropriate gfp_t type to memory allocations Tom Lendacky
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Tom Lendacky @ 2014-01-06 19:33 UTC (permalink / raw)
  To: linux-crypto, herbert, davem; +Cc: linux-kernel

The following series implements a fix to hash length wrapping as well
as some additional fixes and cleanups (proper gfp_t type on some memory
allocations, scatterlist usage improvements, null request result field
checks and driver enabled/disabled changes).

This patch series is based on the cryptodev-2.6 kernel tree.

---

Tom Lendacky (6):
      crypto: ccp - Apply appropriate gfp_t type to memory allocations
      crypto: ccp - Cleanup scatterlist usage
      crypto: ccp - Check for caller result area before using it
      crypto: ccp - Change data length declarations to u64
      crypto: ccp - Cleanup hash invocation calls
      crypto: ccp - CCP device enabled/disabled changes


 drivers/crypto/ccp/ccp-crypto-aes-cmac.c |   38 +++++++++----
 drivers/crypto/ccp/ccp-crypto-sha.c      |   88 ++++++++++++++++++------------
 drivers/crypto/ccp/ccp-crypto.h          |   10 +++
 drivers/crypto/ccp/ccp-dev.c             |   15 +++++
 drivers/crypto/ccp/ccp-ops.c             |   34 ++++++------
 drivers/crypto/ccp/ccp-pci.c             |    3 +
 include/linux/ccp.h                      |   20 +++++--
 7 files changed, 139 insertions(+), 69 deletions(-)

-- 
Tom Lendacky


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/6] crypto: ccp - Apply appropriate gfp_t type to memory allocations
  2014-01-06 19:33 [PATCH 0/6] crypto: ccp - more code fixes/cleanup Tom Lendacky
@ 2014-01-06 19:33 ` Tom Lendacky
  2014-01-06 19:34 ` [PATCH 2/6] crypto: ccp - Cleanup scatterlist usage Tom Lendacky
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Tom Lendacky @ 2014-01-06 19:33 UTC (permalink / raw)
  To: linux-crypto, herbert, davem; +Cc: linux-kernel

Fix some memory allocations to use the appropriate gfp_t type based
on the CRYPTO_TFM_REQ_MAY_SLEEP flag.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-cmac.c |    5 ++++-
 drivers/crypto/ccp/ccp-crypto-sha.c      |    5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
index 64dd35e..398832c 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
@@ -61,6 +61,7 @@ static int ccp_do_cmac_update(struct ahash_request *req, unsigned int nbytes,
 	unsigned int block_size =
 		crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
 	unsigned int len, need_pad, sg_count;
+	gfp_t gfp;
 	int ret;
 
 	if (!ctx->u.aes.key_len)
@@ -99,7 +100,9 @@ static int ccp_do_cmac_update(struct ahash_request *req, unsigned int nbytes,
 	 * possible data pieces (buffer, input data, padding)
 	 */
 	sg_count = (nbytes) ? sg_nents(req->src) + 2 : 2;
-	ret = sg_alloc_table(&rctx->data_sg, sg_count, GFP_KERNEL);
+	gfp = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
+		GFP_KERNEL : GFP_ATOMIC;
+	ret = sg_alloc_table(&rctx->data_sg, sg_count, gfp);
 	if (ret)
 		return ret;
 
diff --git a/drivers/crypto/ccp/ccp-crypto-sha.c b/drivers/crypto/ccp/ccp-crypto-sha.c
index b0881df..0571940 100644
--- a/drivers/crypto/ccp/ccp-crypto-sha.c
+++ b/drivers/crypto/ccp/ccp-crypto-sha.c
@@ -128,6 +128,7 @@ static int ccp_do_sha_update(struct ahash_request *req, unsigned int nbytes,
 	unsigned int block_size =
 		crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
 	unsigned int len, sg_count;
+	gfp_t gfp;
 	int ret;
 
 	if (!final && ((nbytes + rctx->buf_count) <= block_size)) {
@@ -156,7 +157,9 @@ static int ccp_do_sha_update(struct ahash_request *req, unsigned int nbytes,
 	 * possible data pieces (hmac ipad, buffer, input data)
 	 */
 	sg_count = (nbytes) ? sg_nents(req->src) + 2 : 2;
-	ret = sg_alloc_table(&rctx->data_sg, sg_count, GFP_KERNEL);
+	gfp = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
+		GFP_KERNEL : GFP_ATOMIC;
+	ret = sg_alloc_table(&rctx->data_sg, sg_count, gfp);
 	if (ret)
 		return ret;
 



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/6] crypto: ccp - Cleanup scatterlist usage
  2014-01-06 19:33 [PATCH 0/6] crypto: ccp - more code fixes/cleanup Tom Lendacky
  2014-01-06 19:33 ` [PATCH 1/6] crypto: ccp - Apply appropriate gfp_t type to memory allocations Tom Lendacky
@ 2014-01-06 19:34 ` Tom Lendacky
  2014-01-06 19:34 ` [PATCH 3/6] crypto: ccp - Check for caller result area before using it Tom Lendacky
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Tom Lendacky @ 2014-01-06 19:34 UTC (permalink / raw)
  To: linux-crypto, herbert, davem; +Cc: linux-kernel

Cleanup up the usage of scatterlists to make the code cleaner
and avoid extra memory allocations when not needed.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-cmac.c |    6 ++-
 drivers/crypto/ccp/ccp-crypto-sha.c      |   53 ++++++++++++++++--------------
 2 files changed, 33 insertions(+), 26 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
index 398832c..646c8d1 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
@@ -125,8 +125,10 @@ static int ccp_do_cmac_update(struct ahash_request *req, unsigned int nbytes,
 		sg_init_one(&rctx->pad_sg, rctx->pad, pad_length);
 		sg = ccp_crypto_sg_table_add(&rctx->data_sg, &rctx->pad_sg);
 	}
-	if (sg)
+	if (sg) {
 		sg_mark_end(sg);
+		sg = rctx->data_sg.sgl;
+	}
 
 	/* Initialize the K1/K2 scatterlist */
 	if (final)
@@ -143,7 +145,7 @@ static int ccp_do_cmac_update(struct ahash_request *req, unsigned int nbytes,
 	rctx->cmd.u.aes.key_len = ctx->u.aes.key_len;
 	rctx->cmd.u.aes.iv = &rctx->iv_sg;
 	rctx->cmd.u.aes.iv_len = AES_BLOCK_SIZE;
-	rctx->cmd.u.aes.src = (sg) ? rctx->data_sg.sgl : NULL;
+	rctx->cmd.u.aes.src = sg;
 	rctx->cmd.u.aes.src_len = rctx->hash_cnt;
 	rctx->cmd.u.aes.dst = NULL;
 	rctx->cmd.u.aes.cmac_key = cmac_key_sg;
diff --git a/drivers/crypto/ccp/ccp-crypto-sha.c b/drivers/crypto/ccp/ccp-crypto-sha.c
index 0571940..bf913cb 100644
--- a/drivers/crypto/ccp/ccp-crypto-sha.c
+++ b/drivers/crypto/ccp/ccp-crypto-sha.c
@@ -122,7 +122,6 @@ static int ccp_do_sha_update(struct ahash_request *req, unsigned int nbytes,
 			     unsigned int final)
 {
 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-	struct ccp_ctx *ctx = crypto_ahash_ctx(tfm);
 	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
 	struct scatterlist *sg;
 	unsigned int block_size =
@@ -153,35 +152,32 @@ static int ccp_do_sha_update(struct ahash_request *req, unsigned int nbytes,
 	/* Initialize the context scatterlist */
 	sg_init_one(&rctx->ctx_sg, rctx->ctx, sizeof(rctx->ctx));
 
-	/* Build the data scatterlist table - allocate enough entries for all
-	 * possible data pieces (hmac ipad, buffer, input data)
-	 */
-	sg_count = (nbytes) ? sg_nents(req->src) + 2 : 2;
-	gfp = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
-		GFP_KERNEL : GFP_ATOMIC;
-	ret = sg_alloc_table(&rctx->data_sg, sg_count, gfp);
-	if (ret)
-		return ret;
-
 	sg = NULL;
-	if (rctx->first && ctx->u.sha.key_len) {
-		rctx->hash_cnt += block_size;
-
-		sg_init_one(&rctx->pad_sg, ctx->u.sha.ipad, block_size);
-		sg = ccp_crypto_sg_table_add(&rctx->data_sg, &rctx->pad_sg);
-	}
+	if (rctx->buf_count && nbytes) {
+		/* Build the data scatterlist table - allocate enough entries
+		 * for both data pieces (buffer and input data)
+		 */
+		gfp = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
+			GFP_KERNEL : GFP_ATOMIC;
+		sg_count = sg_nents(req->src) + 1;
+		ret = sg_alloc_table(&rctx->data_sg, sg_count, gfp);
+		if (ret)
+			return ret;
 
-	if (rctx->buf_count) {
 		sg_init_one(&rctx->buf_sg, rctx->buf, rctx->buf_count);
 		sg = ccp_crypto_sg_table_add(&rctx->data_sg, &rctx->buf_sg);
-	}
-
-	if (nbytes)
 		sg = ccp_crypto_sg_table_add(&rctx->data_sg, req->src);
-
-	if (sg)
 		sg_mark_end(sg);
 
+		sg = rctx->data_sg.sgl;
+	} else if (rctx->buf_count) {
+		sg_init_one(&rctx->buf_sg, rctx->buf, rctx->buf_count);
+
+		sg = &rctx->buf_sg;
+	} else if (nbytes) {
+		sg = req->src;
+	}
+
 	rctx->msg_bits += (rctx->hash_cnt << 3);	/* Total in bits */
 
 	memset(&rctx->cmd, 0, sizeof(rctx->cmd));
@@ -190,7 +186,7 @@ static int ccp_do_sha_update(struct ahash_request *req, unsigned int nbytes,
 	rctx->cmd.u.sha.type = rctx->type;
 	rctx->cmd.u.sha.ctx = &rctx->ctx_sg;
 	rctx->cmd.u.sha.ctx_len = sizeof(rctx->ctx);
-	rctx->cmd.u.sha.src = (sg) ? rctx->data_sg.sgl : NULL;
+	rctx->cmd.u.sha.src = sg;
 	rctx->cmd.u.sha.src_len = rctx->hash_cnt;
 	rctx->cmd.u.sha.final = rctx->final;
 	rctx->cmd.u.sha.msg_bits = rctx->msg_bits;
@@ -205,9 +201,12 @@ static int ccp_do_sha_update(struct ahash_request *req, unsigned int nbytes,
 static int ccp_sha_init(struct ahash_request *req)
 {
 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct ccp_ctx *ctx = crypto_ahash_ctx(tfm);
 	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
 	struct ccp_crypto_ahash_alg *alg =
 		ccp_crypto_ahash_alg(crypto_ahash_tfm(tfm));
+	unsigned int block_size =
+		crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
 
 	memset(rctx, 0, sizeof(*rctx));
 
@@ -215,6 +214,12 @@ static int ccp_sha_init(struct ahash_request *req)
 	rctx->type = alg->type;
 	rctx->first = 1;
 
+	if (ctx->u.sha.key_len) {
+		/* Buffer the HMAC key for first update */
+		memcpy(rctx->buf, ctx->u.sha.ipad, block_size);
+		rctx->buf_count = block_size;
+	}
+
 	return 0;
 }
 



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/6] crypto: ccp - Check for caller result area before using it
  2014-01-06 19:33 [PATCH 0/6] crypto: ccp - more code fixes/cleanup Tom Lendacky
  2014-01-06 19:33 ` [PATCH 1/6] crypto: ccp - Apply appropriate gfp_t type to memory allocations Tom Lendacky
  2014-01-06 19:34 ` [PATCH 2/6] crypto: ccp - Cleanup scatterlist usage Tom Lendacky
@ 2014-01-06 19:34 ` Tom Lendacky
  2014-01-06 19:34 ` [PATCH 4/6] crypto: ccp - Change data length declarations to u64 Tom Lendacky
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Tom Lendacky @ 2014-01-06 19:34 UTC (permalink / raw)
  To: linux-crypto, herbert, davem; +Cc: linux-kernel

For a hash operation, the caller doesn't have to supply a result
area on every call so don't use it / update it if it hasn't
been supplied.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-cmac.c |    4 +++-
 drivers/crypto/ccp/ccp-crypto-sha.c      |    7 +++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
index 646c8d1..c6b8f9e 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
@@ -43,7 +43,9 @@ static int ccp_aes_cmac_complete(struct crypto_async_request *async_req,
 	} else
 		rctx->buf_count = 0;
 
-	memcpy(req->result, rctx->iv, digest_size);
+	/* Update result area if supplied */
+	if (req->result)
+		memcpy(req->result, rctx->iv, digest_size);
 
 e_free:
 	sg_free_table(&rctx->data_sg);
diff --git a/drivers/crypto/ccp/ccp-crypto-sha.c b/drivers/crypto/ccp/ccp-crypto-sha.c
index bf913cb..183d16e 100644
--- a/drivers/crypto/ccp/ccp-crypto-sha.c
+++ b/drivers/crypto/ccp/ccp-crypto-sha.c
@@ -74,6 +74,7 @@ static int ccp_sha_finish_hmac(struct crypto_async_request *async_req)
 	struct ahash_request *req = ahash_request_cast(async_req);
 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 	struct ccp_ctx *ctx = crypto_ahash_ctx(tfm);
+	struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req);
 	struct scatterlist sg[2];
 	unsigned int block_size =
 		crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
@@ -81,7 +82,7 @@ static int ccp_sha_finish_hmac(struct crypto_async_request *async_req)
 
 	sg_init_table(sg, ARRAY_SIZE(sg));
 	sg_set_buf(&sg[0], ctx->u.sha.opad, block_size);
-	sg_set_buf(&sg[1], req->result, digest_size);
+	sg_set_buf(&sg[1], rctx->ctx, digest_size);
 
 	return ccp_sync_hash(ctx->u.sha.hmac_tfm, req->result, sg,
 			     block_size + digest_size);
@@ -106,7 +107,9 @@ static int ccp_sha_complete(struct crypto_async_request *async_req, int ret)
 	} else
 		rctx->buf_count = 0;
 
-	memcpy(req->result, rctx->ctx, digest_size);
+	/* Update result area if supplied */
+	if (req->result)
+		memcpy(req->result, rctx->ctx, digest_size);
 
 	/* If we're doing an HMAC, we need to perform that on the final op */
 	if (rctx->final && ctx->u.sha.key_len)



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/6] crypto: ccp - Change data length declarations to u64
  2014-01-06 19:33 [PATCH 0/6] crypto: ccp - more code fixes/cleanup Tom Lendacky
                   ` (2 preceding siblings ...)
  2014-01-06 19:34 ` [PATCH 3/6] crypto: ccp - Check for caller result area before using it Tom Lendacky
@ 2014-01-06 19:34 ` Tom Lendacky
  2014-01-06 19:34 ` [PATCH 5/6] crypto: ccp - Cleanup hash invocation calls Tom Lendacky
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Tom Lendacky @ 2014-01-06 19:34 UTC (permalink / raw)
  To: linux-crypto, herbert, davem; +Cc: linux-kernel

When performing a hash operation if the amount of data buffered and a
request at or near the maximum data length is received then the length
calcuation could wrap causing an error in executing the hash operation.
Fix this by using a u64 type for the input and output data lengths in
all CCP operations.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-cmac.c |   21 +++++++++++--------
 drivers/crypto/ccp/ccp-crypto-sha.c      |   21 +++++++++++--------
 drivers/crypto/ccp/ccp-crypto.h          |   10 +++++++--
 drivers/crypto/ccp/ccp-ops.c             |   34 +++++++++++++++++-------------
 include/linux/ccp.h                      |    8 ++++---
 5 files changed, 57 insertions(+), 37 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
index c6b8f9e..a52b97a 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
@@ -37,8 +37,9 @@ static int ccp_aes_cmac_complete(struct crypto_async_request *async_req,
 
 	if (rctx->hash_rem) {
 		/* Save remaining data to buffer */
-		scatterwalk_map_and_copy(rctx->buf, rctx->cmd.u.aes.src,
-					 rctx->hash_cnt, rctx->hash_rem, 0);
+		unsigned int offset = rctx->nbytes - rctx->hash_rem;
+		scatterwalk_map_and_copy(rctx->buf, rctx->src,
+					 offset, rctx->hash_rem, 0);
 		rctx->buf_count = rctx->hash_rem;
 	} else
 		rctx->buf_count = 0;
@@ -62,8 +63,9 @@ static int ccp_do_cmac_update(struct ahash_request *req, unsigned int nbytes,
 	struct scatterlist *sg, *cmac_key_sg = NULL;
 	unsigned int block_size =
 		crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
-	unsigned int len, need_pad, sg_count;
+	unsigned int need_pad, sg_count;
 	gfp_t gfp;
+	u64 len;
 	int ret;
 
 	if (!ctx->u.aes.key_len)
@@ -72,7 +74,9 @@ static int ccp_do_cmac_update(struct ahash_request *req, unsigned int nbytes,
 	if (nbytes)
 		rctx->null_msg = 0;
 
-	if (!final && ((nbytes + rctx->buf_count) <= block_size)) {
+	len = (u64)rctx->buf_count + (u64)nbytes;
+
+	if (!final && (len <= block_size)) {
 		scatterwalk_map_and_copy(rctx->buf + rctx->buf_count, req->src,
 					 0, nbytes, 0);
 		rctx->buf_count += nbytes;
@@ -80,12 +84,13 @@ static int ccp_do_cmac_update(struct ahash_request *req, unsigned int nbytes,
 		return 0;
 	}
 
-	len = rctx->buf_count + nbytes;
+	rctx->src = req->src;
+	rctx->nbytes = nbytes;
 
 	rctx->final = final;
-	rctx->hash_cnt = final ? len : len & ~(block_size - 1);
-	rctx->hash_rem = final ?   0 : len &  (block_size - 1);
-	if (!final && (rctx->hash_cnt == len)) {
+	rctx->hash_rem = final ? 0 : len & (block_size - 1);
+	rctx->hash_cnt = len - rctx->hash_rem;
+	if (!final && !rctx->hash_rem) {
 		/* CCP can't do zero length final, so keep some data around */
 		rctx->hash_cnt -= block_size;
 		rctx->hash_rem = block_size;
diff --git a/drivers/crypto/ccp/ccp-crypto-sha.c b/drivers/crypto/ccp/ccp-crypto-sha.c
index 183d16e..d30f6c8 100644
--- a/drivers/crypto/ccp/ccp-crypto-sha.c
+++ b/drivers/crypto/ccp/ccp-crypto-sha.c
@@ -101,8 +101,9 @@ static int ccp_sha_complete(struct crypto_async_request *async_req, int ret)
 
 	if (rctx->hash_rem) {
 		/* Save remaining data to buffer */
-		scatterwalk_map_and_copy(rctx->buf, rctx->cmd.u.sha.src,
-					 rctx->hash_cnt, rctx->hash_rem, 0);
+		unsigned int offset = rctx->nbytes - rctx->hash_rem;
+		scatterwalk_map_and_copy(rctx->buf, rctx->src,
+					 offset, rctx->hash_rem, 0);
 		rctx->buf_count = rctx->hash_rem;
 	} else
 		rctx->buf_count = 0;
@@ -129,11 +130,14 @@ static int ccp_do_sha_update(struct ahash_request *req, unsigned int nbytes,
 	struct scatterlist *sg;
 	unsigned int block_size =
 		crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
-	unsigned int len, sg_count;
+	unsigned int sg_count;
 	gfp_t gfp;
+	u64 len;
 	int ret;
 
-	if (!final && ((nbytes + rctx->buf_count) <= block_size)) {
+	len = (u64)rctx->buf_count + (u64)nbytes;
+
+	if (!final && (len <= block_size)) {
 		scatterwalk_map_and_copy(rctx->buf + rctx->buf_count, req->src,
 					 0, nbytes, 0);
 		rctx->buf_count += nbytes;
@@ -141,12 +145,13 @@ static int ccp_do_sha_update(struct ahash_request *req, unsigned int nbytes,
 		return 0;
 	}
 
-	len = rctx->buf_count + nbytes;
+	rctx->src = req->src;
+	rctx->nbytes = nbytes;
 
 	rctx->final = final;
-	rctx->hash_cnt = final ? len : len & ~(block_size - 1);
-	rctx->hash_rem = final ?   0 : len &  (block_size - 1);
-	if (!final && (rctx->hash_cnt == len)) {
+	rctx->hash_rem = final ? 0 : len & (block_size - 1);
+	rctx->hash_cnt = len - rctx->hash_rem;
+	if (!final && !rctx->hash_rem) {
 		/* CCP can't do zero length final, so keep some data around */
 		rctx->hash_cnt -= block_size;
 		rctx->hash_rem = block_size;
diff --git a/drivers/crypto/ccp/ccp-crypto.h b/drivers/crypto/ccp/ccp-crypto.h
index 13ea6ea..b222231 100644
--- a/drivers/crypto/ccp/ccp-crypto.h
+++ b/drivers/crypto/ccp/ccp-crypto.h
@@ -110,7 +110,10 @@ struct ccp_aes_cmac_req_ctx {
 	unsigned int null_msg;
 	unsigned int final;
 
-	unsigned int hash_cnt;
+	struct scatterlist *src;
+	unsigned int nbytes;
+
+	u64 hash_cnt;
 	unsigned int hash_rem;
 
 	struct sg_table data_sg;
@@ -149,7 +152,10 @@ struct ccp_sha_req_ctx {
 	unsigned int first;
 	unsigned int final;
 
-	unsigned int hash_cnt;
+	struct scatterlist *src;
+	unsigned int nbytes;
+
+	u64 hash_cnt;
 	unsigned int hash_rem;
 
 	struct sg_table data_sg;
diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index 4be0910..71ed3ad 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -60,9 +60,9 @@ struct ccp_sg_workarea {
 	unsigned int dma_count;
 	enum dma_data_direction dma_dir;
 
-	u32 sg_used;
+	unsigned int sg_used;
 
-	u32 bytes_left;
+	u64 bytes_left;
 };
 
 struct ccp_data {
@@ -466,7 +466,7 @@ static void ccp_sg_free(struct ccp_sg_workarea *wa)
 }
 
 static int ccp_init_sg_workarea(struct ccp_sg_workarea *wa, struct device *dev,
-				struct scatterlist *sg, unsigned int len,
+				struct scatterlist *sg, u64 len,
 				enum dma_data_direction dma_dir)
 {
 	memset(wa, 0, sizeof(*wa));
@@ -499,7 +499,7 @@ static int ccp_init_sg_workarea(struct ccp_sg_workarea *wa, struct device *dev,
 
 static void ccp_update_sg_workarea(struct ccp_sg_workarea *wa, unsigned int len)
 {
-	unsigned int nbytes = min(len, wa->bytes_left);
+	unsigned int nbytes = min_t(u64, len, wa->bytes_left);
 
 	if (!wa->sg)
 		return;
@@ -653,7 +653,7 @@ static void ccp_free_data(struct ccp_data *data, struct ccp_cmd_queue *cmd_q)
 }
 
 static int ccp_init_data(struct ccp_data *data, struct ccp_cmd_queue *cmd_q,
-			 struct scatterlist *sg, unsigned int sg_len,
+			 struct scatterlist *sg, u64 sg_len,
 			 unsigned int dm_len,
 			 enum dma_data_direction dir)
 {
@@ -691,17 +691,20 @@ static unsigned int ccp_queue_buf(struct ccp_data *data, unsigned int from)
 	if (!sg_wa->sg)
 		return 0;
 
-	/* Perform the copy operation */
-	nbytes = min(sg_wa->bytes_left, dm_wa->length);
+	/* Perform the copy operation
+	 *   nbytes will always be <= UINT_MAX because dm_wa->length is
+	 *   an unsigned int
+	 */
+	nbytes = min_t(u64, sg_wa->bytes_left, dm_wa->length);
 	scatterwalk_map_and_copy(dm_wa->address, sg_wa->sg, sg_wa->sg_used,
 				 nbytes, from);
 
 	/* Update the structures and generate the count */
 	buf_count = 0;
 	while (sg_wa->bytes_left && (buf_count < dm_wa->length)) {
-		nbytes = min3(sg_wa->sg->length - sg_wa->sg_used,
-			      dm_wa->length - buf_count,
-			      sg_wa->bytes_left);
+		nbytes = min(sg_wa->sg->length - sg_wa->sg_used,
+			     dm_wa->length - buf_count);
+		nbytes = min_t(u64, sg_wa->bytes_left, nbytes);
 
 		buf_count += nbytes;
 		ccp_update_sg_workarea(sg_wa, nbytes);
@@ -728,14 +731,15 @@ static void ccp_prepare_data(struct ccp_data *src, struct ccp_data *dst,
 
 	/* The CCP can only DMA from/to one address each per operation. This
 	 * requires that we find the smallest DMA area between the source
-	 * and destination.
+	 * and destination. The resulting len values will always be <= UINT_MAX
+	 * because the dma length is an unsigned int.
 	 */
-	sg_src_len = min(sg_dma_len(src->sg_wa.sg) - src->sg_wa.sg_used,
-			 src->sg_wa.bytes_left);
+	sg_src_len = sg_dma_len(src->sg_wa.sg) - src->sg_wa.sg_used;
+	sg_src_len = min_t(u64, src->sg_wa.bytes_left, sg_src_len);
 
 	if (dst) {
-		sg_dst_len = min(sg_dma_len(dst->sg_wa.sg) - dst->sg_wa.sg_used,
-				 src->sg_wa.bytes_left);
+		sg_dst_len = sg_dma_len(dst->sg_wa.sg) - dst->sg_wa.sg_used;
+		sg_dst_len = min_t(u64, src->sg_wa.bytes_left, sg_dst_len);
 		op_len = min(sg_src_len, sg_dst_len);
 	} else
 		op_len = sg_src_len;
diff --git a/include/linux/ccp.h b/include/linux/ccp.h
index e8c2349..12f1cfd 100644
--- a/include/linux/ccp.h
+++ b/include/linux/ccp.h
@@ -133,7 +133,7 @@ struct ccp_aes_engine {
 	u32 iv_len;		/* In bytes */
 
 	struct scatterlist *src, *dst;
-	u32 src_len;		/* In bytes */
+	u64 src_len;		/* In bytes */
 
 	u32 cmac_final;		/* Indicates final cmac cmd */
 	struct scatterlist *cmac_key;	/* K1/K2 cmac key required for
@@ -190,7 +190,7 @@ struct ccp_xts_aes_engine {
 	u32 iv_len;		/* In bytes */
 
 	struct scatterlist *src, *dst;
-	u32 src_len;		/* In bytes */
+	u64 src_len;		/* In bytes */
 
 	u32 final;
 };
@@ -237,7 +237,7 @@ struct ccp_sha_engine {
 	u32 ctx_len;		/* In bytes */
 
 	struct scatterlist *src;
-	u32 src_len;		/* In bytes */
+	u64 src_len;		/* In bytes */
 
 	u32 final;		/* Indicates final sha cmd */
 	u64 msg_bits;		/* Message length in bits required for
@@ -328,7 +328,7 @@ struct ccp_passthru_engine {
 	u32 mask_len;		/* In bytes */
 
 	struct scatterlist *src, *dst;
-	u32 src_len;		/* In bytes */
+	u64 src_len;		/* In bytes */
 
 	u32 final;
 };



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/6] crypto: ccp - Cleanup hash invocation calls
  2014-01-06 19:33 [PATCH 0/6] crypto: ccp - more code fixes/cleanup Tom Lendacky
                   ` (3 preceding siblings ...)
  2014-01-06 19:34 ` [PATCH 4/6] crypto: ccp - Change data length declarations to u64 Tom Lendacky
@ 2014-01-06 19:34 ` Tom Lendacky
  2014-01-06 19:34 ` [PATCH 6/6] crypto: ccp - CCP device enabled/disabled changes Tom Lendacky
  2014-01-15  3:42 ` [PATCH 0/6] crypto: ccp - more code fixes/cleanup Herbert Xu
  6 siblings, 0 replies; 8+ messages in thread
From: Tom Lendacky @ 2014-01-06 19:34 UTC (permalink / raw)
  To: linux-crypto, herbert, davem; +Cc: linux-kernel

Cleanup the ahash digest invocations to check the init
return code and make use of the finup routine.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
 drivers/crypto/ccp/ccp-crypto-aes-cmac.c |    2 +-
 drivers/crypto/ccp/ccp-crypto-sha.c      |    8 ++++++--
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
index a52b97a..8e162ad 100644
--- a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
+++ b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c
@@ -198,7 +198,7 @@ static int ccp_aes_cmac_digest(struct ahash_request *req)
 	if (ret)
 		return ret;
 
-	return ccp_do_cmac_update(req, req->nbytes, 1);
+	return ccp_aes_cmac_finup(req);
 }
 
 static int ccp_aes_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
diff --git a/drivers/crypto/ccp/ccp-crypto-sha.c b/drivers/crypto/ccp/ccp-crypto-sha.c
index d30f6c8..3867290 100644
--- a/drivers/crypto/ccp/ccp-crypto-sha.c
+++ b/drivers/crypto/ccp/ccp-crypto-sha.c
@@ -248,9 +248,13 @@ static int ccp_sha_finup(struct ahash_request *req)
 
 static int ccp_sha_digest(struct ahash_request *req)
 {
-	ccp_sha_init(req);
+	int ret;
 
-	return ccp_do_sha_update(req, req->nbytes, 1);
+	ret = ccp_sha_init(req);
+	if (ret)
+		return ret;
+
+	return ccp_sha_finup(req);
 }
 
 static int ccp_sha_setkey(struct crypto_ahash *tfm, const u8 *key,



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/6] crypto: ccp - CCP device enabled/disabled changes
  2014-01-06 19:33 [PATCH 0/6] crypto: ccp - more code fixes/cleanup Tom Lendacky
                   ` (4 preceding siblings ...)
  2014-01-06 19:34 ` [PATCH 5/6] crypto: ccp - Cleanup hash invocation calls Tom Lendacky
@ 2014-01-06 19:34 ` Tom Lendacky
  2014-01-15  3:42 ` [PATCH 0/6] crypto: ccp - more code fixes/cleanup Herbert Xu
  6 siblings, 0 replies; 8+ messages in thread
From: Tom Lendacky @ 2014-01-06 19:34 UTC (permalink / raw)
  To: linux-crypto, herbert, davem; +Cc: linux-kernel

The CCP cannot be hot-plugged so it will either be there
or it won't.  Do not allow the driver to stay loaded if the
CCP does not successfully initialize.

Provide stub routines in the ccp.h file that return -ENODEV
if the CCP has not been configured in the build.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
 drivers/crypto/ccp/ccp-dev.c |   15 ++++++++++++++-
 drivers/crypto/ccp/ccp-pci.c |    3 +++
 include/linux/ccp.h          |   12 ++++++++++++
 3 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c
index b2038a7..c3bc212 100644
--- a/drivers/crypto/ccp/ccp-dev.c
+++ b/drivers/crypto/ccp/ccp-dev.c
@@ -552,6 +552,7 @@ static const struct x86_cpu_id ccp_support[] = {
 static int __init ccp_mod_init(void)
 {
 	struct cpuinfo_x86 *cpuinfo = &boot_cpu_data;
+	int ret;
 
 	if (!x86_match_cpu(ccp_support))
 		return -ENODEV;
@@ -560,7 +561,19 @@ static int __init ccp_mod_init(void)
 	case 22:
 		if ((cpuinfo->x86_model < 48) || (cpuinfo->x86_model > 63))
 			return -ENODEV;
-		return ccp_pci_init();
+
+		ret = ccp_pci_init();
+		if (ret)
+			return ret;
+
+		/* Don't leave the driver loaded if init failed */
+		if (!ccp_get_device()) {
+			ccp_pci_exit();
+			return -ENODEV;
+		}
+
+		return 0;
+
 		break;
 	}
 
diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/ccp-pci.c
index 1fbeaf1..11836b7 100644
--- a/drivers/crypto/ccp/ccp-pci.c
+++ b/drivers/crypto/ccp/ccp-pci.c
@@ -268,6 +268,9 @@ static void ccp_pci_remove(struct pci_dev *pdev)
 	struct device *dev = &pdev->dev;
 	struct ccp_device *ccp = dev_get_drvdata(dev);
 
+	if (!ccp)
+		return;
+
 	ccp_destroy(ccp);
 
 	pci_iounmap(pdev, ccp->io_map);
diff --git a/include/linux/ccp.h b/include/linux/ccp.h
index 12f1cfd..b941ab9 100644
--- a/include/linux/ccp.h
+++ b/include/linux/ccp.h
@@ -23,6 +23,9 @@
 struct ccp_device;
 struct ccp_cmd;
 
+#if defined(CONFIG_CRYPTO_DEV_CCP_DD) || \
+	defined(CONFIG_CRYPTO_DEV_CCP_DD_MODULE)
+
 /**
  * ccp_enqueue_cmd - queue an operation for processing by the CCP
  *
@@ -48,6 +51,15 @@ struct ccp_cmd;
  */
 int ccp_enqueue_cmd(struct ccp_cmd *cmd);
 
+#else /* CONFIG_CRYPTO_DEV_CCP_DD is not enabled */
+
+static inline int ccp_enqueue_cmd(struct ccp_cmd *cmd)
+{
+	return -ENODEV;
+}
+
+#endif /* CONFIG_CRYPTO_DEV_CCP_DD */
+
 
 /***** AES engine *****/
 /**



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/6] crypto: ccp - more code fixes/cleanup
  2014-01-06 19:33 [PATCH 0/6] crypto: ccp - more code fixes/cleanup Tom Lendacky
                   ` (5 preceding siblings ...)
  2014-01-06 19:34 ` [PATCH 6/6] crypto: ccp - CCP device enabled/disabled changes Tom Lendacky
@ 2014-01-15  3:42 ` Herbert Xu
  6 siblings, 0 replies; 8+ messages in thread
From: Herbert Xu @ 2014-01-15  3:42 UTC (permalink / raw)
  To: Tom Lendacky; +Cc: linux-crypto, davem, linux-kernel

On Mon, Jan 06, 2014 at 01:33:53PM -0600, Tom Lendacky wrote:
> The following series implements a fix to hash length wrapping as well
> as some additional fixes and cleanups (proper gfp_t type on some memory
> allocations, scatterlist usage improvements, null request result field
> checks and driver enabled/disabled changes).
> 
> This patch series is based on the cryptodev-2.6 kernel tree.

All applied.  Thanks!
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-01-15  3:42 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-06 19:33 [PATCH 0/6] crypto: ccp - more code fixes/cleanup Tom Lendacky
2014-01-06 19:33 ` [PATCH 1/6] crypto: ccp - Apply appropriate gfp_t type to memory allocations Tom Lendacky
2014-01-06 19:34 ` [PATCH 2/6] crypto: ccp - Cleanup scatterlist usage Tom Lendacky
2014-01-06 19:34 ` [PATCH 3/6] crypto: ccp - Check for caller result area before using it Tom Lendacky
2014-01-06 19:34 ` [PATCH 4/6] crypto: ccp - Change data length declarations to u64 Tom Lendacky
2014-01-06 19:34 ` [PATCH 5/6] crypto: ccp - Cleanup hash invocation calls Tom Lendacky
2014-01-06 19:34 ` [PATCH 6/6] crypto: ccp - CCP device enabled/disabled changes Tom Lendacky
2014-01-15  3:42 ` [PATCH 0/6] crypto: ccp - more code fixes/cleanup Herbert Xu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).