crypto: sun8i-ce - do not fallback if cryptlen is less than sg length
authorCorentin Labbe <clabbe@baylibre.com>
Mon, 2 May 2022 20:19:29 +0000 (20:19 +0000)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 13 May 2022 09:24:48 +0000 (17:24 +0800)
The sg length could be more than remaining data on it.
So check the length requirement against the minimum between those two
values.

Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c

index 315a62e..74b4e91 100644 (file)
@@ -27,6 +27,7 @@ static int sun8i_ce_cipher_need_fallback(struct skcipher_request *areq)
        struct scatterlist *sg;
        struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
        struct sun8i_ce_alg_template *algt;
+       unsigned int todo, len;
 
        algt = container_of(alg, struct sun8i_ce_alg_template, alg.skcipher);
 
@@ -51,28 +52,35 @@ static int sun8i_ce_cipher_need_fallback(struct skcipher_request *areq)
                return true;
        }
 
+       len = areq->cryptlen;
        sg = areq->src;
        while (sg) {
                if (!IS_ALIGNED(sg->offset, sizeof(u32))) {
                        algt->stat_fb_srcali++;
                        return true;
                }
-               if (sg->length % 4) {
+               todo = min(len, sg->length);
+               if (todo % 4) {
                        algt->stat_fb_srclen++;
                        return true;
                }
+               len -= todo;
                sg = sg_next(sg);
        }
+
+       len = areq->cryptlen;
        sg = areq->dst;
        while (sg) {
                if (!IS_ALIGNED(sg->offset, sizeof(u32))) {
                        algt->stat_fb_dstali++;
                        return true;
                }
-               if (sg->length % 4) {
+               todo = min(len, sg->length);
+               if (todo % 4) {
                        algt->stat_fb_dstlen++;
                        return true;
                }
+               len -= todo;
                sg = sg_next(sg);
        }
        return false;