...
 
Commits (3)
2019-10-01 Niels Möller <nisse@lysator.liu.se>
* testsuite/testutils.c (test_cipher_cfb8): Reset destination area
between tests. Encrypt/decrypt final partial block.
From Daiki Ueno, fixing bug reported by Stephan Mueller:
* cfb.c (cfb8_decrypt): Don't truncate output IV if input is
shorter than block size.
* testsuite/testutils.c (test_cipher_cfb8): Test splitting input
into multiple calls to cfb8_encrypt and cfb8_decrypt.
2019-09-30 Niels Möller <nisse@lysator.liu.se>
* testsuite/siv-test.c (test_cipher_siv): Fix out-of-bounds read.
......
......@@ -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);
......
......@@ -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;
......@@ -441,45 +442,70 @@ test_cipher_cfb8(const struct nettle_cipher *cipher,
ASSERT (key->length == cipher->key_size);
ASSERT (iiv->length == cipher->block_size);
data = xalloc(length);
data2 = xalloc(length);
data = xalloc(length + 1);
data2 = xalloc(length + 1);
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);
memset(data, 0x17, length + 1);
for (i = 0; i + block <= length; i += block)
{
cfb8_encrypt(ctx, cipher->encrypt,
cipher->block_size, iv,
block, data + i, cleartext->data + i);
}
cfb8_encrypt(ctx, cipher->encrypt,
cipher->block_size, iv,
length - i, 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();
}
ASSERT (data[length] == 0x17);
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();
cipher->set_encrypt_key(ctx, key->data);
memcpy(iv, iiv->data, cipher->block_size);
memset(data2, 0x17, length + 1);
for (i = 0; i + block <= length; i += block)
{
cfb8_decrypt(ctx, cipher->encrypt,
cipher->block_size, iv,
block, data2 + i, data + i);
}
cfb8_decrypt(ctx, cipher->encrypt,
cipher->block_size, iv,
length - i, 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();
}
ASSERT (data[length] == 0x17);
}
cipher->set_encrypt_key(ctx, key->data);
memcpy(iv, iiv->data, cipher->block_size);
memcpy(data, cleartext->data, length);
......