]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
cfb8: don't truncate output IV if input is shorter than block size
authorDaiki Ueno <dueno@redhat.com>
Fri, 27 Sep 2019 14:12:00 +0000 (16:12 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Tue, 1 Oct 2019 17:29:45 +0000 (19:29 +0200)
Previously cfb8_decrypt didn't update the IV if the input is shorter
than the AES block size.  Reported by Stephan Mueller.

Signed-off-by: Daiki Ueno <dueno@redhat.com>
cfb.c
testsuite/testutils.c

diff --git a/cfb.c b/cfb.c
index 5429fc9c8afa11f3aa72171d68edbfa80bb1a3e9..b9da315927c683f7d7f88b7a5c71741d1f71166f 100644 (file)
--- a/cfb.c
+++ b/cfb.c
@@ -226,10 +226,12 @@ cfb8_decrypt(const void *ctx, nettle_cipher_func *f,
       src += i;
       dst += i;
 
-      memcpy(buffer, buffer + block_size, block_size);
-      memcpy(buffer + block_size, src,
-            length < block_size ? length : block_size);
-
+      if (i == block_size)
+       {
+         memcpy(buffer, buffer + block_size, block_size);
+         memcpy(buffer + block_size, src,
+                length < block_size ? length : block_size);
+       }
     }
 
   memcpy(iv, buffer + i, block_size);
index 2a19c0ac8205a59ef22958b072b8637901af2cc2..b24b498a0bae4cf558f567e7f7cd9726f0186285 100644 (file)
@@ -434,6 +434,7 @@ test_cipher_cfb8(const struct nettle_cipher *cipher,
   uint8_t *data, *data2;
   uint8_t *iv = xalloc(cipher->block_size);
   size_t length;
+  size_t block;
 
   ASSERT (cleartext->length == ciphertext->length);
   length = cleartext->length;
@@ -444,42 +445,56 @@ test_cipher_cfb8(const struct nettle_cipher *cipher,
   data = xalloc(length);
   data2 = xalloc(length);
 
-  cipher->set_encrypt_key(ctx, key->data);
-  memcpy(iv, iiv->data, cipher->block_size);
+  for (block = 1; block <= length; block++)
+    {
+      size_t i;
 
-  cfb8_encrypt(ctx, cipher->encrypt,
-             cipher->block_size, iv,
-             length, data, cleartext->data);
+      cipher->set_encrypt_key(ctx, key->data);
+      memcpy(iv, iiv->data, cipher->block_size);
 
-  if (!MEMEQ(length, data, ciphertext->data))
-    {
-      fprintf(stderr, "CFB8 encrypt failed:\nInput:");
-      tstring_print_hex(cleartext);
-      fprintf(stderr, "\nOutput: ");
-      print_hex(length, data);
-      fprintf(stderr, "\nExpected:");
-      tstring_print_hex(ciphertext);
-      fprintf(stderr, "\n");
-      FAIL();
-    }
-  cipher->set_encrypt_key(ctx, key->data);
-  memcpy(iv, iiv->data, cipher->block_size);
+      for (i = 0; i + block <= length; i += block)
+       {
+         cfb8_encrypt(ctx, cipher->encrypt,
+                      cipher->block_size, iv,
+                      block, data + i, cleartext->data + i);
+       }
 
-  cfb8_decrypt(ctx, cipher->encrypt,
-             cipher->block_size, iv,
-             length, data2, data);
+      if (!MEMEQ(length, data, ciphertext->data))
+       {
+         fprintf(stderr, "CFB8 encrypt failed, block size %lu:\nInput:",
+                 block);
+         tstring_print_hex(cleartext);
+         fprintf(stderr, "\nOutput: ");
+         print_hex(length, data);
+         fprintf(stderr, "\nExpected:");
+         tstring_print_hex(ciphertext);
+         fprintf(stderr, "\n");
+         FAIL();
+       }
+      cipher->set_encrypt_key(ctx, key->data);
+      memcpy(iv, iiv->data, cipher->block_size);
 
-  if (!MEMEQ(length, data2, cleartext->data))
-    {
-      fprintf(stderr, "CFB8 decrypt failed:\nInput:");
-      tstring_print_hex(ciphertext);
-      fprintf(stderr, "\nOutput: ");
-      print_hex(length, data2);
-      fprintf(stderr, "\nExpected:");
-      tstring_print_hex(cleartext);
-      fprintf(stderr, "\n");
-      FAIL();
+      for (i = 0; i + block <= length; i += block)
+       {
+         cfb8_decrypt(ctx, cipher->encrypt,
+                      cipher->block_size, iv,
+                      block, data2 + i, data + i);
+       }
+
+      if (!MEMEQ(length, data2, cleartext->data))
+       {
+         fprintf(stderr, "CFB8 decrypt failed, block size %lu:\nInput:",
+                 block);
+         tstring_print_hex(ciphertext);
+         fprintf(stderr, "\nOutput: ");
+         print_hex(length, data2);
+         fprintf(stderr, "\nExpected:");
+         tstring_print_hex(cleartext);
+         fprintf(stderr, "\n");
+         FAIL();
+       }
     }
+
   cipher->set_encrypt_key(ctx, key->data);
   memcpy(iv, iiv->data, cipher->block_size);
   memcpy(data, cleartext->data, length);