cencryptionaes

Using TinyAES to encrypt a decrypt data returns a strange result


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?


Solution

  • 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