Commit d069033b authored by Patrick McHardy's avatar Patrick McHardy Committed by Herbert Xu

[HIFN]: Fix data alignment checks

    
The check for misalignment of the scatterlist data has two bugs:

- the source buffer doesn't need to be aligned at all
- the destination buffer and its size needs to be aligned to a multiple
  of 4, not to the crypto alg blocksize
    
Introduce symbolic constant for destination buffer alignment requirements,
use it instead of the crypto alg blocksize and remove the unnecessary
checks for source buffer alignment and change cra_alignmask to zero.
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 94eaa1bd
...@@ -369,6 +369,8 @@ static atomic_t hifn_dev_number; ...@@ -369,6 +369,8 @@ static atomic_t hifn_dev_number;
#define HIFN_D_DST_RSIZE 80*4 #define HIFN_D_DST_RSIZE 80*4
#define HIFN_D_RES_RSIZE 24*4 #define HIFN_D_RES_RSIZE 24*4
#define HIFN_D_DST_DALIGN 4
#define HIFN_QUEUE_LENGTH HIFN_D_CMD_RSIZE-5 #define HIFN_QUEUE_LENGTH HIFN_D_CMD_RSIZE-5
#define AES_MIN_KEY_SIZE 16 #define AES_MIN_KEY_SIZE 16
...@@ -1458,10 +1460,6 @@ static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist ...@@ -1458,10 +1460,6 @@ static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist
static int ablkcipher_walk(struct ablkcipher_request *req, static int ablkcipher_walk(struct ablkcipher_request *req,
struct ablkcipher_walk *w) struct ablkcipher_walk *w)
{ {
unsigned blocksize =
crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm(req));
unsigned alignmask =
crypto_ablkcipher_alignmask(crypto_ablkcipher_reqtfm(req));
struct scatterlist *src, *dst, *t; struct scatterlist *src, *dst, *t;
void *daddr; void *daddr;
unsigned int nbytes = req->nbytes, offset, copy, diff; unsigned int nbytes = req->nbytes, offset, copy, diff;
...@@ -1477,14 +1475,12 @@ static int ablkcipher_walk(struct ablkcipher_request *req, ...@@ -1477,14 +1475,12 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
dst = &req->dst[idx]; dst = &req->dst[idx];
dprintk("\n%s: slen: %u, dlen: %u, soff: %u, doff: %u, offset: %u, " dprintk("\n%s: slen: %u, dlen: %u, soff: %u, doff: %u, offset: %u, "
"blocksize: %u, nbytes: %u.\n", "nbytes: %u.\n",
__func__, src->length, dst->length, src->offset, __func__, src->length, dst->length, src->offset,
dst->offset, offset, blocksize, nbytes); dst->offset, offset, nbytes);
if (src->length & (blocksize - 1) || if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
src->offset & (alignmask - 1) || !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) ||
dst->length & (blocksize - 1) ||
dst->offset & (alignmask - 1) ||
offset) { offset) {
unsigned slen = src->length - offset; unsigned slen = src->length - offset;
unsigned dlen = PAGE_SIZE; unsigned dlen = PAGE_SIZE;
...@@ -1498,8 +1494,8 @@ static int ablkcipher_walk(struct ablkcipher_request *req, ...@@ -1498,8 +1494,8 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
idx += err; idx += err;
copy = slen & ~(blocksize - 1); copy = slen & ~(HIFN_D_DST_DALIGN - 1);
diff = slen & (blocksize - 1); diff = slen & (HIFN_D_DST_DALIGN - 1);
if (dlen < nbytes) { if (dlen < nbytes) {
/* /*
...@@ -1507,7 +1503,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req, ...@@ -1507,7 +1503,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
* to put there additional blocksized chunk, * to put there additional blocksized chunk,
* so we mark that page as containing only * so we mark that page as containing only
* blocksize aligned chunks: * blocksize aligned chunks:
* t->length = (slen & ~(blocksize - 1)); * t->length = (slen & ~(HIFN_D_DST_DALIGN - 1));
* and increase number of bytes to be processed * and increase number of bytes to be processed
* in next chunk: * in next chunk:
* nbytes += diff; * nbytes += diff;
...@@ -1567,10 +1563,6 @@ static int hifn_setup_session(struct ablkcipher_request *req) ...@@ -1567,10 +1563,6 @@ static int hifn_setup_session(struct ablkcipher_request *req)
unsigned int nbytes = req->nbytes, idx = 0, len; unsigned int nbytes = req->nbytes, idx = 0, len;
int err = -EINVAL, sg_num; int err = -EINVAL, sg_num;
struct scatterlist *src, *dst, *t; struct scatterlist *src, *dst, *t;
unsigned blocksize =
crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm(req));
unsigned alignmask =
crypto_ablkcipher_alignmask(crypto_ablkcipher_reqtfm(req));
if (ctx->iv && !ctx->ivsize && ctx->mode != ACRYPTO_MODE_ECB) if (ctx->iv && !ctx->ivsize && ctx->mode != ACRYPTO_MODE_ECB)
goto err_out_exit; goto err_out_exit;
...@@ -1578,17 +1570,13 @@ static int hifn_setup_session(struct ablkcipher_request *req) ...@@ -1578,17 +1570,13 @@ static int hifn_setup_session(struct ablkcipher_request *req)
ctx->walk.flags = 0; ctx->walk.flags = 0;
while (nbytes) { while (nbytes) {
src = &req->src[idx];
dst = &req->dst[idx]; dst = &req->dst[idx];
if (src->length & (blocksize - 1) || if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
src->offset & (alignmask - 1) || !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN))
dst->length & (blocksize - 1) ||
dst->offset & (alignmask - 1)) {
ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED; ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED;
}
nbytes -= src->length; nbytes -= dst->length;
idx++; idx++;
} }
...@@ -2523,9 +2511,7 @@ static int hifn_alg_alloc(struct hifn_device *dev, struct hifn_alg_template *t) ...@@ -2523,9 +2511,7 @@ static int hifn_alg_alloc(struct hifn_device *dev, struct hifn_alg_template *t)
alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC; alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC;
alg->alg.cra_blocksize = t->bsize; alg->alg.cra_blocksize = t->bsize;
alg->alg.cra_ctxsize = sizeof(struct hifn_context); alg->alg.cra_ctxsize = sizeof(struct hifn_context);
alg->alg.cra_alignmask = 15; alg->alg.cra_alignmask = 0;
if (t->bsize == 8)
alg->alg.cra_alignmask = 3;
alg->alg.cra_type = &crypto_ablkcipher_type; alg->alg.cra_type = &crypto_ablkcipher_type;
alg->alg.cra_module = THIS_MODULE; alg->alg.cra_module = THIS_MODULE;
alg->alg.cra_u.ablkcipher = t->ablkcipher; alg->alg.cra_u.ablkcipher = t->ablkcipher;
......
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