Commit c35e523a authored by Corentin Labbe's avatar Corentin Labbe Committed by Herbert Xu

crypto: sun8i-ss - handle requests if last block is not modulo 64

The current sun8i-ss handle only requests with all SG length being
modulo 64.
But the last SG could be always handled by copying it on the pad buffer.
Signed-off-by: default avatarCorentin Labbe <clabbe@baylibre.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent db0c62bc
...@@ -487,7 +487,7 @@ static int allocate_flows(struct sun8i_ss_dev *ss) ...@@ -487,7 +487,7 @@ static int allocate_flows(struct sun8i_ss_dev *ss)
} }
/* the padding could be up to two block. */ /* the padding could be up to two block. */
ss->flows[i].pad = devm_kmalloc(ss->dev, SHA256_BLOCK_SIZE * 2, ss->flows[i].pad = devm_kmalloc(ss->dev, MAX_PAD_SIZE,
GFP_KERNEL | GFP_DMA); GFP_KERNEL | GFP_DMA);
if (!ss->flows[i].pad) if (!ss->flows[i].pad)
goto error_engine; goto error_engine;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <crypto/internal/hash.h> #include <crypto/internal/hash.h>
#include <crypto/scatterwalk.h>
#include <crypto/sha1.h> #include <crypto/sha1.h>
#include <crypto/sha2.h> #include <crypto/sha2.h>
#include <crypto/md5.h> #include <crypto/md5.h>
...@@ -262,6 +263,9 @@ static bool sun8i_ss_hash_need_fallback(struct ahash_request *areq) ...@@ -262,6 +263,9 @@ static bool sun8i_ss_hash_need_fallback(struct ahash_request *areq)
if (areq->nbytes == 0) if (areq->nbytes == 0)
return true; return true;
if (areq->nbytes >= MAX_PAD_SIZE - 64)
return true;
/* we need to reserve one SG for the padding one */ /* we need to reserve one SG for the padding one */
if (sg_nents(areq->src) > MAX_SG - 1) if (sg_nents(areq->src) > MAX_SG - 1)
return true; return true;
...@@ -270,10 +274,13 @@ static bool sun8i_ss_hash_need_fallback(struct ahash_request *areq) ...@@ -270,10 +274,13 @@ static bool sun8i_ss_hash_need_fallback(struct ahash_request *areq)
/* SS can operate hash only on full block size /* SS can operate hash only on full block size
* since SS support only MD5,sha1,sha224 and sha256, blocksize * since SS support only MD5,sha1,sha224 and sha256, blocksize
* is always 64 * is always 64
* TODO: handle request if last SG is not len%64
* but this will need to copy data on a new SG of size=64
*/ */
if (sg->length % 64 || !IS_ALIGNED(sg->offset, sizeof(u32))) /* Only the last block could be bounced to the pad buffer */
if (sg->length % 64 && sg_next(sg))
return true;
if (!IS_ALIGNED(sg->offset, sizeof(u32)))
return true;
if (sg->length % 4)
return true; return true;
sg = sg_next(sg); sg = sg_next(sg);
} }
...@@ -361,6 +368,7 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq) ...@@ -361,6 +368,7 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
goto theend; goto theend;
} }
j = 0;
len = areq->nbytes; len = areq->nbytes;
sg = areq->src; sg = areq->src;
i = 0; i = 0;
...@@ -369,12 +377,19 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq) ...@@ -369,12 +377,19 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
sg = sg_next(sg); sg = sg_next(sg);
continue; continue;
} }
rctx->t_src[i].addr = sg_dma_address(sg);
todo = min(len, sg_dma_len(sg)); todo = min(len, sg_dma_len(sg));
rctx->t_src[i].len = todo / 4; /* only the last SG could be with a size not modulo64 */
len -= todo; if (todo % 64 == 0) {
rctx->t_dst[i].addr = addr_res; rctx->t_src[i].addr = sg_dma_address(sg);
rctx->t_dst[i].len = digestsize / 4; rctx->t_src[i].len = todo / 4;
rctx->t_dst[i].addr = addr_res;
rctx->t_dst[i].len = digestsize / 4;
len -= todo;
} else {
scatterwalk_map_and_copy(bf, sg, 0, todo, 0);
j += todo / 4;
len -= todo;
}
sg = sg_next(sg); sg = sg_next(sg);
i++; i++;
} }
...@@ -384,8 +399,10 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq) ...@@ -384,8 +399,10 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
goto theend; goto theend;
} }
if (j > 0)
i--;
byte_count = areq->nbytes; byte_count = areq->nbytes;
j = 0;
bf[j++] = cpu_to_le32(0x80); bf[j++] = cpu_to_le32(0x80);
fill = 64 - (byte_count % 64); fill = 64 - (byte_count % 64);
......
...@@ -82,6 +82,8 @@ ...@@ -82,6 +82,8 @@
#define PRNG_DATA_SIZE (160 / 8) #define PRNG_DATA_SIZE (160 / 8)
#define PRNG_SEED_SIZE DIV_ROUND_UP(175, 8) #define PRNG_SEED_SIZE DIV_ROUND_UP(175, 8)
#define MAX_PAD_SIZE 4096
/* /*
* struct ss_clock - Describe clocks used by sun8i-ss * struct ss_clock - Describe clocks used by sun8i-ss
* @name: Name of clock needed by this variant * @name: Name of clock needed by this variant
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment