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