I am trying to use the TinyAES Library to encrypt and decrypt some data. The data is:
unsigned char Plaintext[] = {
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x6C, 0x61, 0x6E, 0x65, 0x20, 0x74, 0x65,
0x78, 0x74, 0x20, 0x73, 0x74, 0x69, 0x6E, 0x67, 0x2C, 0x20, 0x77, 0x65, 0x27, 0x6C, 0x6C, 0x20,
0x74, 0x72, 0x79, 0x20, 0x74, 0x6F, 0x20, 0x65, 0x6E, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2E, 0x2E,
0x2E, 0x20, 0x6C, 0x65, 0x74, 0x73, 0x20, 0x68, 0x6F, 0x70, 0x65, 0x20, 0x65, 0x76, 0x65, 0x72,
0x79, 0x74, 0x68, 0x69, 0x67, 0x6E, 0x20, 0x67, 0x6F, 0x20, 0x77, 0x65, 0x6C, 0x6C, 0x20, 0x3A,
0x29, 0x00 };
The string is this is plain text sting, we'll try to encrypt... lets hope everythign go well :)
In the below code int main()
performs the encryption and decryption all in one step. The function PaddBuffer
is to padd the data to a multiple of 16.
int main() {
// INITIALIZATION
// Struct needed for tiny-AES library
struct AES_ctx ctx;
BYTE pKey[KEYSIZE]; // KEYSIZE is 32
BYTE pIv[IVSIZE]; // IVSIZE is 16
srand(time(NULL)); // The seed to generate the key
GenerateRandomBytes(pKey, KEYSIZE); // Generating the key bytes
srand(time(NULL) ^ pKey[0]); // The seed to generate the iv (using the first byte from the key to add more spice)
GenerateRandomBytes(pIv, IVSIZE); // Generating the IV
//Print plaintext
PrintHexData("Plaintext", Data, sizeof(Data));
// Initilizing the Tiny-AES Library
AES_init_ctx_iv(&ctx, pKey, pIv);
// Initializing padding variables if required
PBYTE PaddedBuffer = NULL;
SIZE_T PAddedSize = NULL;
// ENCRYPTION
// Check if padding required
if (sizeof(Data) % 16 != 0){
PaddBuffer(Data, sizeof(Data), &PaddedBuffer, &PAddedSize);
// Encrypting the padded buffer instead
AES_CBC_encrypt_buffer(&ctx, PaddedBuffer, PAddedSize);
PrintHexData("CipherText", PaddedBuffer, PAddedSize);
}
else {
// No padding is required, encrypt Data directly
AES_CBC_encrypt_buffer(&ctx, Data, sizeof(Data));
PrintHexData("CipherText", Data, sizeof(Data));
}
// DECRYPTION
//Check if we need to decrypt the PaddedBuffer or the Data
if (PaddedBuffer != NULL) {
AES_CBC_decrypt_buffer(&ctx, PaddedBuffer, PAddedSize);
PrintHexData("Plaintext", PaddedBuffer, PAddedSize);
}
else {
AES_CBC_decrypt_buffer(&ctx, Data, sizeof(Data));
PrintHexData("Plaintext", Data, sizeof(Data));
}
The problem is the output. The initial Data is above, the encrypted data is:
unsigned char CipherText[] = {
0x9A, 0x13, 0xC2, 0xA6, 0x60, 0x2F, 0xEC, 0xAF, 0x50, 0xEC, 0x5A, 0x79, 0x40, 0xE6, 0xFF, 0xFA,
0xBD, 0x55, 0x1E, 0x1C, 0x3A, 0xD2, 0x87, 0x87, 0x24, 0x78, 0x48, 0x07, 0x33, 0x64, 0xB3, 0x18,
0x72, 0x60, 0x74, 0xB2, 0xBD, 0x84, 0x79, 0x91, 0x0D, 0xC0, 0x35, 0xA9, 0x65, 0x37, 0x53, 0x67,
0x94, 0xEC, 0xB9, 0x10, 0xC4, 0x84, 0xA5, 0xDA, 0x6E, 0x74, 0x67, 0x75, 0xA5, 0x32, 0xFE, 0x42,
0xB5, 0x3B, 0xE2, 0xF7, 0xCE, 0x90, 0xB0, 0x43, 0x85, 0xB5, 0x2A, 0x40, 0xF3, 0x0A, 0x67, 0x9C,
0x1D, 0x8F, 0xDA, 0xE5, 0xEB, 0xDC, 0x60, 0xD3, 0xAB, 0x66, 0xC4, 0xF2, 0x60, 0x60, 0x62, 0xC6 };
but the Decrypted data is:
unsigned char Plaintext[] = {
0xC9, 0x80, 0xB8, 0xE3, 0xBD, 0x5E, 0xEC, 0xF3, 0x88, 0x25, 0xA6, 0x0B, 0x3C, 0x13, 0xCA, 0x98,
0x78, 0x74, 0x20, 0x73, 0x74, 0x69, 0x6E, 0x67, 0x2C, 0x20, 0x77, 0x65, 0x27, 0x6C, 0x6C, 0x20,
0x74, 0x72, 0x79, 0x20, 0x74, 0x6F, 0x20, 0x65, 0x6E, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2E, 0x2E,
0x2E, 0x20, 0x6C, 0x65, 0x74, 0x73, 0x20, 0x68, 0x6F, 0x70, 0x65, 0x20, 0x65, 0x76, 0x65, 0x72,
0x79, 0x74, 0x68, 0x69, 0x67, 0x6E, 0x20, 0x67, 0x6F, 0x20, 0x77, 0x65, 0x6C, 0x6C, 0x20, 0x3A,
0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Note that the first 16 bytes are different but then the rest is the same. If I printf
the decrypted data, again the first 16 characters are gibberish but the rest decrypts fine:
╔Ç╕π╜^∞≤ê%ª♂<‼╩ÿxt sting, we'll try to encrypt... lets hope everythign go well :)
I can't understand what is going on. The encryption works fine and encrypts all the data. The decryption obviously works in some part, or else it wouldn't decrypt everything from the 17th byte onward. But why are the first 16 bytes wrong?
tiny-AES-c updates the context’s IV after performing CBC encryption so that you can encrypt more data:
/* store Iv in ctx for next call */ memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
You need to reset the IV back to the original before decryption.
AES_ctx_set_iv(&ctx, pIv);
// DECRYPTION