diff options
author | Tom Lendacky <thomas.lendacky@amd.com> | 2014-01-06 13:34:17 -0600 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2014-01-15 11:33:39 +0800 |
commit | 81a59f000e1d4a60a03081a1fc64aee46d6f0c3e (patch) | |
tree | 95c4c83dc6175c6aa6f286676fbbd6c77419d5b8 /drivers/crypto/ccp/ccp-crypto-aes-cmac.c | |
parent | 393897c5156a415533ff85aa381458840417b032 (diff) | |
download | op-kernel-dev-81a59f000e1d4a60a03081a1fc64aee46d6f0c3e.zip op-kernel-dev-81a59f000e1d4a60a03081a1fc64aee46d6f0c3e.tar.gz |
crypto: ccp - Change data length declarations to u64
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>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/ccp/ccp-crypto-aes-cmac.c')
-rw-r--r-- | drivers/crypto/ccp/ccp-crypto-aes-cmac.c | 21 |
1 files changed, 13 insertions, 8 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; |