I had not problems with using nettle's twofish with standard ecb mode however i'm not sure what's wrong with this cbc mode? The decrypted message will not match the original. (using some hardcoded values like iv just for test purposes).
https://www.lysator.liu.se/~nisse/nettle/nettle.html
const uint8_t key[TWOFISH_KEY_SIZE] = {
0xea, 0xad, 0xdd, 0x6c, 0x32, 0x5a, 0xdc, 0x4f, 0x01, 0x5b, 0x4c,
0xde, 0xbb, 0x45, 0xc9, 0xe5, 0x5a, 0xb7, 0x5f, 0x3b, 0x01, 0x9a,
0xf8, 0x39, 0xd0, 0x74, 0x05, 0xeb, 0xf1, 0xaa, 0xa7, 0x67};
const uint8_t src[TWOFISH_BLOCK_SIZE] = {
0x3a, 0x53, 0xec, 0xae, 0xc0, 0xcf, 0xd3, 0xd8,
0xae, 0x05, 0x5d, 0xc0, 0x07, 0x3c, 0x04, 0x0d};
const uint8_t iv[TWOFISH_BLOCK_SIZE] = {
0xa0, 0xfb, 0x59, 0x3d, 0x70, 0x98, 0xdf, 0x8f,
0xff, 0xa0, 0x3b, 0xd5, 0xc5, 0x8b, 0x2c, 0x45};
uint8_t encrypted[TWOFISH_BLOCK_SIZE];
uint8_t decrypted[TWOFISH_BLOCK_SIZE];
struct CBC_CTX(struct twofish_ctx, TWOFISH_BLOCK_SIZE) ctx;
twofish256_set_key(&ctx.ctx, key);
CBC_SET_IV(&ctx, iv);
CBC_ENCRYPT(&ctx, twofish_encrypt, TWOFISH_BLOCK_SIZE, encrypted, src);
CBC_DECRYPT(&ctx, twofish_decrypt, TWOFISH_BLOCK_SIZE, decrypted,
encrypted);
for(int i = 0; i < TWOFISH_BLOCK_SIZE; i++) {
printf("\n%hhX\n", src[i]);
printf("%hhX\n", encrypted[i]);
printf("%hhX\n-------------------", decrypted[i]);
}
James is right: you need to set the IV again before decryption. From the Nettle documentation:
The final ciphertext block processed is copied into
iv
before returning, so that large message be processed be a sequence of calls tocbc_encrypt
.
I.e. the IV inside the crypto context is lost and replaced by the last block of ciphertext. Hence you need to set it to the correct value again.
Nettle is a low level library, so this construct makes sense; higher level libraries may use streaming or assume that you always provide the complete plaintext/ciphertext in the call.