Hi all, this is my first post.
I've got a little project I want to use wolfcrypt for, and before getting started on the production system I just threw together a bit of proof-of-concept code. Then I got unexpected results so I added a bunch of print lines for debug purposes, and here's the code as it stands:
#include <stdio.h>
#include <wolfssl/wolfcrypt/aes.h>
size_t padLength(size_t plainLength){
size_t numBlocks = plainLength / AES_BLOCK_SIZE;
return (numBlocks+1) * AES_BLOCK_SIZE;
}
void printBytes(byte *array, size_t length){
for (size_t i=0; i<length; ++i){
printf("%02X ", array[i]);
}
}
size_t unpadLength(byte *array, size_t length){
return length-(array[length-1]);
}
int main() {
int error;
byte key[] = "1234567890abcdef01234567";
byte iv[] = "1234567890abcdef";
Aes aesEncrypt;
Aes aesDecrypt;
printf("\nIV before SetKey(Encrypt): ");
printBytes(iv, AES_BLOCK_SIZE);
error = wc_AesSetKey(&aesEncrypt, key, (word32)strlen((char *)key), iv, AES_ENCRYPTION);
if (error){
printf("\nEncrypt set key failed with error: %d\n", error);
}
printf("\nIV after SetKey(Encrypt): ");
printBytes(iv, AES_BLOCK_SIZE);
printf("\n aesEncrypt.reg contents: ");
printBytes((byte *) aesEncrypt.reg, AES_BLOCK_SIZE);
error = wc_AesSetKey(&aesDecrypt, key, (word32)strlen((char *)key), iv, AES_DECRYPTION);
if (error){
printf("\nDecrypt set key failed with error: %d\n", error);
}
printf("\nIV after SetKey(Decrypt): ");
printBytes(iv, AES_BLOCK_SIZE);
printf("\n aesDecrypt.reg contents: ");
printBytes((byte *) aesDecrypt.reg, AES_BLOCK_SIZE);
byte plain[] = "AAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
size_t plainLength = sizeof(plain);
size_t paddedLength = padLength(plainLength);
byte padded[paddedLength];
byte padding = (byte)(paddedLength-plainLength);
memcpy(padded, plain, plainLength);
for (size_t i=plainLength; i<paddedLength; ++i){
padded[i]=padding;
}
byte cipher[paddedLength];
error = wc_AesCbcEncrypt(&aesEncrypt, cipher, padded, (word32)paddedLength);
if (error){
printf("\nEncryption failed with error: %d\n", error);
}
byte plain2[paddedLength];
error = wc_AesCbcDecrypt(&aesDecrypt, plain2, cipher, (word32)paddedLength);
if (error){
printf("\nDecryption failed with error: %d\n", error);
}
printf("\nPlain1: ");
printBytes(plain,sizeof(plain));
printf("\n%s\nPadded: ",plain);
printBytes(padded,paddedLength);
printf("\nCipher: ");
printBytes(cipher, paddedLength);
printf("\nPlain2: ");
printBytes(plain2, unpadLength(plain2, paddedLength));
printf("\n%s\n",plain2);
return 0;
}
When I run that code, I get the following output:
IV before SetKey(Encrypt): 31 32 33 34 35 36 37 38 39 30 61 62 63 64 65 66
IV after SetKey(Encrypt): 31 32 33 34 00 00 00 00 39 30 61 62 63 64 65 66
aesEncrypt.reg contents: 31 32 33 34 00 00 00 00 39 30 61 62 63 64 65 66
IV after SetKey(Decrypt): 31 32 33 34 00 00 00 00 39 30 61 62 63 64 65 66
aesDecrypt.reg contents: 31 32 33 34 00 00 00 00 39 30 61 62 63 64 65 66
Plain1: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 00
AAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
Padded: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 00 05 05 05 05 05
Cipher: 8A D4 F6 7D 53 E1 FA 88 36 9C 83 00 D8 A5 1A 60 43 AB 87 03 FE E6 1B C0 44 DF CD 71 18 D8 D7 93 C9 E5 66 48 C9 16 12 AF 07 A7 43 AF 98 95 2D 62 AA 44 FA 04 96 CE E1 73 F1 04 30 B7 CC A9 59 75
Plain2: 41 41 41 41 74 77 76 79 41 41 41 41 41 41 41 41 41 41 41 41 74 77 76 79 42 42 42 42 42 42 42 42 42 42 42 42 77 74 75 7A 42 42 42 42 42 42 42 42 42 42 42 42 77 74 75 7A 42 42 00
AAAAtwvyAAAAAAAAAAAAtwvyBBBBBBBBBBBBwtuzBBBBBBBBBBBBwtuzBB
When I moved things around so the decrypt struct gets configured before the encrypt chunk and ran it again I got:
IV before SetKey(Decrypt): 31 32 33 34 35 36 37 38 39 30 61 62 63 64 65 66
IV after SetKey(Decrypt): 31 32 33 34 35 36 37 38 39 30 61 62 63 64 65 66
aesDecrypt.reg contents: 31 32 33 34 35 36 37 38 39 30 61 62 63 64 65 66
IV after SetKey(Encrypt): 31 32 33 34 00 00 00 00 39 30 61 62 63 64 65 66
aesEncrypt.reg contents: 31 32 33 34 00 00 00 00 39 30 61 62 63 64 65 66
Plain1: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 00
AAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
Padded: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 00 05 05 05 05 05
Cipher: D2 08 09 0A AB 5B 27 D4 B4 17 4D 55 BD EE 45 44 40 4C F7 92 D1 D2 7D B4 FD 9D 84 DF 67 F4 9E E6 89 60 8E 63 84 8F 72 F3 1E 46 48 8D C0 D1 DF A5 1D BC CC AA 99 EA 5F B3 DA A8 93 8C 43 05 32 9B
Plain2: 41 41 41 41 74 77 76 79 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 00
AAAAtwvyAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
So... AesSetKey is zeroing the second word of the IV if the last argument is AES_ENCRYPTION. Any ideas why this is happening or what I should do differently?