mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-10 07:10:27 +00:00
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: Corentin Labbe <clabbe@baylibre.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
db0c62bcd4
commit
c35e523a8b
@ -487,7 +487,7 @@ static int allocate_flows(struct sun8i_ss_dev *ss)
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if (!ss->flows[i].pad)
|
||||
goto error_engine;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <crypto/sha1.h>
|
||||
#include <crypto/sha2.h>
|
||||
#include <crypto/md5.h>
|
||||
@ -262,6 +263,9 @@ static bool sun8i_ss_hash_need_fallback(struct ahash_request *areq)
|
||||
|
||||
if (areq->nbytes == 0)
|
||||
return true;
|
||||
if (areq->nbytes >= MAX_PAD_SIZE - 64)
|
||||
return true;
|
||||
|
||||
/* we need to reserve one SG for the padding one */
|
||||
if (sg_nents(areq->src) > MAX_SG - 1)
|
||||
return true;
|
||||
@ -270,10 +274,13 @@ static bool sun8i_ss_hash_need_fallback(struct ahash_request *areq)
|
||||
/* SS can operate hash only on full block size
|
||||
* since SS support only MD5,sha1,sha224 and sha256, blocksize
|
||||
* 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;
|
||||
sg = sg_next(sg);
|
||||
}
|
||||
@ -361,6 +368,7 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
|
||||
goto theend;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
len = areq->nbytes;
|
||||
sg = areq->src;
|
||||
i = 0;
|
||||
@ -369,12 +377,19 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
|
||||
sg = sg_next(sg);
|
||||
continue;
|
||||
}
|
||||
rctx->t_src[i].addr = sg_dma_address(sg);
|
||||
todo = min(len, sg_dma_len(sg));
|
||||
rctx->t_src[i].len = todo / 4;
|
||||
len -= todo;
|
||||
rctx->t_dst[i].addr = addr_res;
|
||||
rctx->t_dst[i].len = digestsize / 4;
|
||||
/* only the last SG could be with a size not modulo64 */
|
||||
if (todo % 64 == 0) {
|
||||
rctx->t_src[i].addr = sg_dma_address(sg);
|
||||
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);
|
||||
i++;
|
||||
}
|
||||
@ -384,8 +399,10 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
|
||||
goto theend;
|
||||
}
|
||||
|
||||
if (j > 0)
|
||||
i--;
|
||||
|
||||
byte_count = areq->nbytes;
|
||||
j = 0;
|
||||
bf[j++] = cpu_to_le32(0x80);
|
||||
|
||||
fill = 64 - (byte_count % 64);
|
||||
|
@ -82,6 +82,8 @@
|
||||
#define PRNG_DATA_SIZE (160 / 8)
|
||||
#define PRNG_SEED_SIZE DIV_ROUND_UP(175, 8)
|
||||
|
||||
#define MAX_PAD_SIZE 4096
|
||||
|
||||
/*
|
||||
* struct ss_clock - Describe clocks used by sun8i-ss
|
||||
* @name: Name of clock needed by this variant
|
||||
|
Loading…
x
Reference in New Issue
Block a user