crypto: atmel-aes - Fix counter overflow in CTR mode
authorTudor Ambarus <tudor.ambarus@microchip.com>
Thu, 5 Dec 2019 09:54:01 +0000 (09:54 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 14 Feb 2020 21:31:01 +0000 (16:31 -0500)
commit 781a08d9740afa73357f1a60d45d7c93d7cca2dd upstream.

32 bit counter is not supported by neither of our AES IPs, all implement
a 16 bit block counter. Drop the 32 bit block counter logic.

Fixes: fcac83656a3e ("crypto: atmel-aes - fix the counter overflow in CTR mode")
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/crypto/atmel-aes.c

index e3d40a8dfffbc35259f3d2342d6343da343b0521..915253b9c9128242d066c2cbbfa9e807453600c4 100644 (file)
@@ -87,7 +87,6 @@
 struct atmel_aes_caps {
        bool                    has_dualbuff;
        bool                    has_cfb64;
-       bool                    has_ctr32;
        bool                    has_gcm;
        u32                     max_burst_size;
 };
@@ -923,8 +922,9 @@ static int atmel_aes_ctr_transfer(struct atmel_aes_dev *dd)
        struct atmel_aes_ctr_ctx *ctx = atmel_aes_ctr_ctx_cast(dd->ctx);
        struct ablkcipher_request *req = ablkcipher_request_cast(dd->areq);
        struct scatterlist *src, *dst;
-       u32 ctr, blocks;
        size_t datalen;
+       u32 ctr;
+       u16 blocks, start, end;
        bool use_dma, fragmented = false;
 
        /* Check for transfer completion. */
@@ -936,27 +936,17 @@ static int atmel_aes_ctr_transfer(struct atmel_aes_dev *dd)
        datalen = req->nbytes - ctx->offset;
        blocks = DIV_ROUND_UP(datalen, AES_BLOCK_SIZE);
        ctr = be32_to_cpu(ctx->iv[3]);
-       if (dd->caps.has_ctr32) {
-               /* Check 32bit counter overflow. */
-               u32 start = ctr;
-               u32 end = start + blocks - 1;
-
-               if (end < start) {
-                       ctr |= 0xffffffff;
-                       datalen = AES_BLOCK_SIZE * -start;
-                       fragmented = true;
-               }
-       } else {
-               /* Check 16bit counter overflow. */
-               u16 start = ctr & 0xffff;
-               u16 end = start + (u16)blocks - 1;
-
-               if (blocks >> 16 || end < start) {
-                       ctr |= 0xffff;
-                       datalen = AES_BLOCK_SIZE * (0x10000-start);
-                       fragmented = true;
-               }
+
+       /* Check 16bit counter overflow. */
+       start = ctr & 0xffff;
+       end = start + blocks - 1;
+
+       if (blocks >> 16 || end < start) {
+               ctr |= 0xffff;
+               datalen = AES_BLOCK_SIZE * (0x10000 - start);
+               fragmented = true;
        }
+
        use_dma = (datalen >= ATMEL_AES_DMA_THRESHOLD);
 
        /* Jump to offset. */
@@ -1926,7 +1916,6 @@ static void atmel_aes_get_cap(struct atmel_aes_dev *dd)
 {
        dd->caps.has_dualbuff = 0;
        dd->caps.has_cfb64 = 0;
-       dd->caps.has_ctr32 = 0;
        dd->caps.has_gcm = 0;
        dd->caps.max_burst_size = 1;
 
@@ -1935,14 +1924,12 @@ static void atmel_aes_get_cap(struct atmel_aes_dev *dd)
        case 0x500:
                dd->caps.has_dualbuff = 1;
                dd->caps.has_cfb64 = 1;
-               dd->caps.has_ctr32 = 1;
                dd->caps.has_gcm = 1;
                dd->caps.max_burst_size = 4;
                break;
        case 0x200:
                dd->caps.has_dualbuff = 1;
                dd->caps.has_cfb64 = 1;
-               dd->caps.has_ctr32 = 1;
                dd->caps.has_gcm = 1;
                dd->caps.max_burst_size = 4;
                break;