From: Daiki Ueno Date: Fri, 27 Sep 2019 14:12:00 +0000 (+0200) Subject: cfb8: don't truncate output IV if input is shorter than block size X-Git-Tag: nettle_3.6rc1~81 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f4a9c842621baf5d71aa9cc3989851f44dc46861;p=thirdparty%2Fnettle.git 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 --- 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); 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);