ltq-deu: aes-ctr: process all input data
authorMathias Kresin <dev@kresin.me>
Sun, 18 Apr 2021 12:37:24 +0000 (14:37 +0200)
committerHauke Mehrtens <hauke@hauke-m.de>
Wed, 5 Jan 2022 22:05:38 +0000 (23:05 +0100)
Even if the minimum blocksize is set to 16 (AES_BLOCK_SIZE), the crypto
manager tests pass 499 bytes of data to the aes-ctr encryption, from
which only 496 bytes are actually encrypted.

Reading the comment regarding the minimum blocksize, it only states that
it's the "smallest possible unit which can be transformed with this
algorithm". Which doesn't necessarily mean, the data have to be a
multiple of the minimal blocksize.

All kernel hardware crypto driver enforce a minimum blocksize of 1,
which perfect fine works for the lantiq data encryption unit as well.

Lower the blocksize limit to 1, to process not padded data as well.
In AES for processing the remaining bytes, uninitialized pointers
were used.
This patch fixes using uninitialized pointers and wrong offsets.

Signed-off-by: Mathias Kresin <dev@kresin.me>
[fix commit title prefix]
Signed-off-by: Daniel Kestrel <kestrel1974@t-online.de>
package/kernel/lantiq/ltq-deu/src/ifxmips_aes.c

index 62ce5631819dc15f8a0131831298d68831be33f9..ab30293340d975a7354e97c9d92e151a03cf77fd 100644 (file)
@@ -251,25 +251,24 @@ void ifx_deu_aes (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
 
     /* To handle all non-aligned bytes (not aligned to 16B size) */
     if (byte_cnt) {
-        u8 *input[16];
-        u8 *output[16];
+        u8 temparea[16] = {0,};
 
-        memcpy(input, ((u32 *) in_arg + (i * 4)), byte_cnt);
+        memcpy(temparea, ((u32 *) in_arg + (i * 4)), byte_cnt);
 
-        aes->ID3R = INPUT_ENDIAN_SWAP(*((u32 *) input + (i * 4) + 0));
-        aes->ID2R = INPUT_ENDIAN_SWAP(*((u32 *) input + (i * 4) + 1));
-        aes->ID1R = INPUT_ENDIAN_SWAP(*((u32 *) input + (i * 4) + 2));
-        aes->ID0R = INPUT_ENDIAN_SWAP(*((u32 *) input + (i * 4) + 3));    /* start crypto */
+        aes->ID3R = INPUT_ENDIAN_SWAP(*((u32 *) temparea + 0));
+        aes->ID2R = INPUT_ENDIAN_SWAP(*((u32 *) temparea + 1));
+        aes->ID1R = INPUT_ENDIAN_SWAP(*((u32 *) temparea + 2));
+        aes->ID0R = INPUT_ENDIAN_SWAP(*((u32 *) temparea + 3));    /* start crypto */
 
         while (aes->controlr.BUS) {
         }
 
-        *((volatile u32 *) output + (i * 4) + 0) = aes->OD3R;
-        *((volatile u32 *) output + (i * 4) + 1) = aes->OD2R;
-        *((volatile u32 *) output + (i * 4) + 2) = aes->OD1R;
-        *((volatile u32 *) output + (i * 4) + 3) = aes->OD0R;
+        *((volatile u32 *) temparea + 0) = aes->OD3R;
+        *((volatile u32 *) temparea + 1) = aes->OD2R;
+        *((volatile u32 *) temparea + 2) = aes->OD1R;
+        *((volatile u32 *) temparea + 3) = aes->OD0R;
 
-        memcpy(((u32 *) out_arg + (i * 4)), output, byte_cnt);
+        memcpy(((u32 *) out_arg + (i * 4)), temparea, byte_cnt);
     }
 
     //tc.chen : copy iv_arg back
@@ -671,20 +670,15 @@ int ctr_basic_aes_encrypt(struct blkcipher_desc *desc,
     struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
     struct blkcipher_walk walk;
     int err;
-    unsigned int enc_bytes;
 
     blkcipher_walk_init(&walk, dst, src, nbytes);
     err = blkcipher_walk_virt(desc, &walk);
 
-    while ((nbytes = enc_bytes = walk.nbytes)) {
-            u8 *iv = walk.iv;
-            enc_bytes -= (nbytes % AES_BLOCK_SIZE);
-            ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
-                       iv, enc_bytes, CRYPTO_DIR_ENCRYPT, 0);
-        nbytes &= AES_BLOCK_SIZE - 1;
-        err = blkcipher_walk_done(desc, &walk, nbytes);
+    while ((nbytes = walk.nbytes)) {
+        ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+                        walk.iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);
+        err = blkcipher_walk_done(desc, &walk, 0);
     }
-
     return err;
 }
 
@@ -704,18 +698,14 @@ int ctr_basic_aes_decrypt(struct blkcipher_desc *desc,
     struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
     struct blkcipher_walk walk;
     int err;
-    unsigned int dec_bytes;
 
     blkcipher_walk_init(&walk, dst, src, nbytes);
     err = blkcipher_walk_virt(desc, &walk);
 
-    while ((nbytes = dec_bytes = walk.nbytes)) {
-        u8 *iv = walk.iv;
-            dec_bytes -= (nbytes % AES_BLOCK_SIZE);
-            ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
-                       iv, dec_bytes, CRYPTO_DIR_DECRYPT, 0);
-        nbytes &= AES_BLOCK_SIZE - 1;
-        err = blkcipher_walk_done(desc, &walk, nbytes);
+    while ((nbytes = walk.nbytes)) {
+        ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+                        walk.iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
+        err = blkcipher_walk_done(desc, &walk, 0);
     }
 
     return err;
@@ -729,7 +719,7 @@ struct crypto_alg ifxdeu_ctr_basic_aes_alg = {
     .cra_driver_name    =   "ifxdeu-ctr(aes)",
     .cra_priority   =   400,
     .cra_flags      =   CRYPTO_ALG_TYPE_BLKCIPHER,
-    .cra_blocksize      =   AES_BLOCK_SIZE,
+    .cra_blocksize      =   1,
     .cra_ctxsize        =   sizeof(struct aes_ctx),
     .cra_type       =   &crypto_blkcipher_type,
     .cra_module     =   THIS_MODULE,
@@ -869,7 +859,7 @@ struct crypto_alg ifxdeu_ctr_rfc3686_aes_alg = {
     .cra_driver_name    =   "ifxdeu-ctr-rfc3686(aes)",
     .cra_priority       =   400,
     .cra_flags         =   CRYPTO_ALG_TYPE_BLKCIPHER,
-    .cra_blocksize      =   AES_BLOCK_SIZE,
+    .cra_blocksize      =   1,
     .cra_ctxsize        =   sizeof(struct aes_ctx),
     .cra_type          =   &crypto_blkcipher_type,
     .cra_module        =   THIS_MODULE,