1 (edited by LordCapybara 2016-04-26 20:28:08)

Topic: Bug using AES in ECB mode

I am using OpenSSL in a Desktop software and WolfCrypt in its embedded counterpart. For this project I must use AES in ECB mode, even though I know ECB is not the most secure mode of operation for AES. According to http://www.yassl.com/forums/topic411-aes-ecb.html, WolfCrypt supports ECB mode, even though it is not properly documented.

I could encode and decode data in OpenSSL without a problem, but I could not do so in WolfCrypt. It seems wolfCrypt is buggy in ECB mode with 192 and 256 bits-long keys (but it seems to work with 128 bits-long keys). I noticed this behavior using the following code. This code encrypts a chunk of data, decrypts it and compares the results with the original data. If the data match, a success message is displayed. Only 128 bits-long keys seem to yield correct results.

I tested this code in VS 2013 (Windows 7) using WolfSSL 3.8.0.

Am I doing something wrong here or is WolfCrypt really buggy?

#include <stdlib.h>
#include <stdio.h>

#include <wolfssl/wolfcrypt/aes.h>
                                
#define POINTER_TO_INDEX(v, i)  ( &( ( v )[ i ] ) )
#define BITS_TO_BYTES(x)        ( ( x ) / 8 )

#define MAX_KEY_BITS            ( 256 )
#define MAX_KEY_LENGTH          BITS_TO_BYTES( MAX_KEY_BITS )
#define DATA_LENGTH             ( 768 )

byte aes_key[MAX_KEY_LENGTH];
byte aes_iv[MAX_KEY_LENGTH];

byte original_data[DATA_LENGTH];
byte encrypted_data[DATA_LENGTH];
byte decrypted_data[DATA_LENGTH];

Aes aes_encrypt;
Aes aes_decrypt;

void wait_before_exit(void)
{
    printf("\nPress 'q' to quit.\n");
    while (1)
    {
        char c = getchar();
        if (c == 'q' || c == 'Q') return;
    }
}

int main(int argc, char* argv[])
{
    int actual_key_length = 0;
    printf("Choose key length:\n ( A ) 128 bits\n ( B ) 192 bits\n ( C ) 256 bits\n");
    while (actual_key_length == 0)
    {
        char c = getchar();
        switch (c)
        {
            case 'A': case 'a':
                actual_key_length = BITS_TO_BYTES(128);
                break;
            case 'B': case 'b':
                actual_key_length = BITS_TO_BYTES(192);
                break;
            case 'C': case 'c':
                actual_key_length = BITS_TO_BYTES(256);
                break;
        }
    }

    // generate aes_key and aes_iv.
    for (int i = 0; i < actual_key_length; i++)
    {
        aes_key[i] = (byte)rand();
        aes_iv[i] = (byte)rand();
    }

    // initialize AES engines.
    if (wc_AesSetKeyDirect(&aes_encrypt, (const byte *)aes_key, actual_key_length, (const byte *)aes_iv, AES_ENCRYPTION))
    {
        printf("Cannot create AES engine for encryption.\n");
        wait_before_exit();
        return 0;
    }
    if (wc_AesSetKeyDirect(&aes_decrypt, (const byte *)aes_key, actual_key_length, (const byte *)aes_iv, AES_DECRYPTION))
    {
        printf("Cannot create AES engine for decryption.\n");
        wait_before_exit();
        return 0;
    }

    // generate original data.
    for (int i = 0; i < DATA_LENGTH; i++)
        original_data[i] = (byte)rand();

    // encrypt data.
    for (int i = 0; i < DATA_LENGTH; i += actual_key_length)
        wc_AesEncryptDirect(&aes_encrypt, POINTER_TO_INDEX(encrypted_data, i), (const byte*)POINTER_TO_INDEX(original_data, i));

    // decrypt data.
    for (int i = 0; i < DATA_LENGTH; i += actual_key_length)
        wc_AesDecryptDirect(&aes_decrypt, POINTER_TO_INDEX(decrypted_data, i), (const byte*)POINTER_TO_INDEX(encrypted_data, i));

    // check data.
    for (int i = 0; i < DATA_LENGTH; i++)
        if (original_data[i] != decrypted_data[i])
        {
            printf("Data mismatch at index %i: original value was %i but decrypted value is %i.\n", i, original_data[i], decrypted_data[i]);
            wait_before_exit();
            return 0;
        }

    printf("Decrypted data matches original data.\n");
    wait_before_exit();
    return 0;
}

Share

Re: Bug using AES in ECB mode

Hi LordCapybara,

With AES used in ECB mode it is only going to encrypt and decrypt one AES block at a time. This would be 16 bytes, the trouble here is that the for loop in your code jumps by 24 bytes or 32 bytes with key size 192 and 256. Changing the loop to do a block at a time fixed the issue.

A suggestion outside of the AES encrypt/decryption is to include the same preprocessor defines from wolfSSL compilation.

Can you tell me some about the reason behind using ECB mode and the project being worked on? For multiple blocks like this, ECB mode is not as secure as other modes available.

Regards,
Jacob

Share