ni...@lysator.liu.se (Niels Möller) writes:

> Daiki Ueno <u...@gnu.org> writes:
>
>> We realized that cfb8_decrypt doesn't update the IV correctly when the
>> input is shorter than AES block size.  The attached patches should fix
>> it.
>
> For testing, I think it would be good to take the testvectors for cfb8,
> and split into multiple calls to cfb8_*crypt, in several ways. And check
> they all give the same result. A bit like it's done in arcfour-test.c,
> or the test_cipher_stream (#if:ed out, not sure if it's worth reviving).

Indeed, thank you for the suggestion.  I'm attaching updated patches.

Regards,
-- 
Daiki Ueno
>From 2f6c2be5ec9668dc7691e5bf9e54f8ef1dde1d87 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <du...@redhat.com>
Date: Fri, 27 Sep 2019 16:12:00 +0200
Subject: [PATCH 1/2] cfb8: don't truncate output IV if input is shorter than
 block size

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 <du...@redhat.com>
---
 cfb.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/cfb.c b/cfb.c
index 5429fc9c..b9da3159 100644
--- 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);
-- 
2.21.0

>From e96bb66747ffd1dff9bded6cdb69ba866dc20f01 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <du...@redhat.com>
Date: Tue, 1 Oct 2019 10:47:40 +0200
Subject: [PATCH 2/2] test: check all possible block sizes in test_cipher_cfb8

Signed-off-by: Daiki Ueno <du...@redhat.com>
---
 testsuite/testutils.c | 77 ++++++++++++++++++++++++++-----------------
 1 file changed, 46 insertions(+), 31 deletions(-)

diff --git a/testsuite/testutils.c b/testsuite/testutils.c
index 2a19c0ac..b24b498a 100644
--- a/testsuite/testutils.c
+++ b/testsuite/testutils.c
@@ -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);
-- 
2.21.0

_______________________________________________
nettle-bugs mailing list
nettle-bugs@lists.lysator.liu.se
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs

Reply via email to