AES (aes-ige-128, aes-ige-192, aes-ige-256) encryption/decryption with openssl C

aes, c, openssl

Solution

The error message says it all.

aes_ige.c(88): OpenSSL internal error, assertion failed: (length%AES_BLOCK_SIZE) == 0

This is basically a run-time-check (assertion) that fails due to invalid input provided to the function `AES_ige_encrypt()` present in the source at line 88 of aes_ige.c.

OPENSSL_assert((length%AES_BLOCK_SIZE) == 0);

The assertion basically checks if `length` (the 3rd parameter passed to the function) is an integral multiple of `AES_BLOCK_SIZE`. If yes, the execution continues, otherwise the program halts and prints warning about the assertion having failed.

So ensure that the size of the data being passed to `AES_ige_encrypt()` is a multiple of `AES_BLOCK_SIZE`.

If size of the data is not an integral multiple, then append `NUL` bytes to it to make the total size the nearest multiple of `AES_BLOCK_SIZE`.

Also, always pass the "integral-multiple-of-`AES_BLOCK_SIZE`" value as the `length` parameter to `AES_ige_encrypt()`.

Problem

Recently I finally (with help of stackoverflow's user, @WhozCraig) got to work AES in CBC mode. Now, I would like to do exact same thing but with AES IGE. I took a look at `openssl-1.0.1e/test/igetest.c` and tried to build my own test. But once again, I have a problem with inputs and outputs proper sizes. Everything else is good, because I copied it from my previous code: AES (aes-cbc-128, aes-cbc-192, aes-cbc-256) encryption/decryption with openssl C. Now, when I pass an inputs length which is less than 32, it says: ``` Give a key length [only 128 or 192 or 256!]: 256 Give an input's length: 3 aes_ige.c(88): OpenSSL internal error, assertion failed: (length%AES_BLOCK_SIZE) == 0 (core dumped) ``` But when the lenght is bigger than 32, Im also not so sure if its all ok: ``` Give a key length [only 128 or 192 or 256!]: 256 Give an input's length: 48 original: 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 encrypt: A4 1F C4 E8 42 5E E5 62 1A B6 C1 47 D2 2F 8D 98 D0 0B 32 77 4E 36 84 25 15 5B BA 60 EA A9 64 D2 53 D1 98 78 83 21 90 90 74 44 C7 AA 3E AD 9B 26 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 decrypt: 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 ``` Heres the code: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/aes.h> #include <openssl/rand.h> // a simple hex-print routine. could be modified to print 16 bytes-per-line static void hex_print(const void* pv, size_t len) { const unsigned char * p = (const unsigned char*)pv; if (NULL == pv) printf("NULL"); else { size_t i = 0; for (; i<len;++i) printf("%02X ", *p++); } printf("\n"); } // main entrypoint int main(int argc, char **argv) { int keylength; printf("Give a key length [only 128 or 192 or 256!]:\n"); scanf("%d", &keylength); /* generate a key with a given length */ unsigned char aes_key[keylength/8]; memset(aes_key, 0, keylength/8); if (!RAND_bytes(aes_key, keylength/8)) exit(-1); size_t inputslength = 0; printf("Give an input's length:\n"); scanf("%lu", &inputslength); /* generate input with a given length */ unsigned char aes_input[inputslength]; memset(aes_input, 'X', inputslength); const size_t ivsize = AES_BLOCK_SIZE*2; /* init vector */ unsigned char iv_enc[ivsize], iv_dec[ivsize]; RAND_bytes(iv_enc, ivsize); memcpy(iv_dec, iv_enc, ivsize); // buffers for encryption and decryption const size_t encslength = (inputslength/AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE;//((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; unsigned char enc_out[encslength]; unsigned char dec_out[inputslength]; memset(enc_out, 0, sizeof(enc_out)); memset(dec_out, 0, sizeof(dec_out)); AES_KEY enc_key, dec_key; AES_set_encrypt_key(aes_key, keylength, &enc_key); AES_set_decrypt_key(aes_key, keylength, &dec_key); AES_ige_encrypt(aes_input, enc_out, inputslength, &enc_key, iv_enc, AES_ENCRYPT); AES_ige_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT); printf("original:\t"); hex_print(aes_input, sizeof(aes_input)); printf("encrypt:\t"); hex_print(enc_out, sizeof(enc_out)); printf("decrypt:\t"); hex_print(dec_out, sizeof(dec_out)); return 0; } ``` FINALLY! Got it working (hope so).But I would be veeery grateful if someone can say, that this code below is 100% good ;) ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/aes.h> #include <openssl/rand.h> // a simple hex-print routine. could be modified to print 16 bytes-per-line static void hex_print(const void* pv, size_t len) { const unsigned char * p = (const unsigned char*)pv; if (NULL == pv) printf("NULL"); else { size_t i = 0; for (; i<len;++i) printf("%02X ", *p++); } printf("\n"); } // main entrypoint int main(int argc, char **argv) { int keylength = 256; //printf("Give a key length [only 128 or 192 or 256!]:\n"); //scanf("%d", &keylength); /* generate a key with a given length */ unsigned char aes_key[keylength/8]; memset(aes_key, 0, keylength/8); if (!RAND_bytes(aes_key, keylength/8)) exit(-1); size_t inputslength = 0; printf("Give an input's length:\n"); scanf("%lu", &inputslength); /* generate input with a given length */ unsigned char aes_input[inputslength]; memset(aes_input, 'X', inputslength); const size_t ivsize = AES_BLOCK_SIZE*2; /* init vector */ unsigned char iv_enc[ivsize], iv_dec[ivsize]; RAND_bytes(iv_enc, ivsize); memcpy(iv_dec, iv_enc, ivsize); // buffers for encryption and decryption const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; unsigned char enc_out[encslength]; unsigned char dec_out[inputslength]; memset(enc_out, 0, sizeof(enc_out)); memset(dec_out, 0, sizeof(dec_out)); // so i can do with this aes-cbc-128 aes-cbc-192 aes-cbc-256 AES_KEY enc_key, dec_key; AES_set_encrypt_key(aes_key, keylength, &enc_key); AES_ige_encrypt(aes_input, enc_out, encslength, &enc_key, iv_enc, AES_ENCRYPT); AES_set_decrypt_key(aes_key, keylength, &dec_key); AES_ige_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT); printf("original:\t"); hex_print(aes_input, sizeof(aes_input)); printf("encrypt:\t"); hex_print(enc_out, sizeof(enc_out)); printf("decrypt:\t"); hex_print(dec_out, sizeof(dec_out)); return 0; } ``` I only changed this: `AES_ige_encrypt(aes_input, enc_out, **inputslength**, &enc_key, iv_enc, AES_ENCRYPT);` into that: `AES_ige_encrypt(aes_input, enc_out, **encslength**, &enc_key, iv_enc, AES_ENCRYPT);` is it correct? EDIT No.2 ;) Ok guys, did another example, with your advices added some padding to the input. Hope its ok now? ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/aes.h> #include <openssl/rand.h> // a simple hex-print routine. could be modified to print 16 bytes-per-line static void hex_print(const void* pv, size_t len) { const unsigned char * p = (const unsigned char*)pv; if (NULL == pv) printf("NULL"); else { size_t i = 0; for (; i<len;++i) printf("%02X ", *p++); } printf("\n"); } // main entrypoint int main(int argc, char **argv) { int keylength = 256; //printf("Give a key length [only 128 or 192 or 256!]:\n"); //scanf("%d", &keylength); /* generate a key with a given length */ unsigned char aes_key[keylength/8]; memset(aes_key, 0, keylength/8); if (!RAND_bytes(aes_key, keylength/8)) exit(-1); size_t inputslength = 0; printf("Give an input's length:\n"); scanf("%lu", &inputslength); /* generate input with a given length */ unsigned char aes_input[inputslength]; memset(aes_input, 'X', inputslength); const size_t ivsize = AES_BLOCK_SIZE*2; /* init vector */ unsigned char iv_enc[ivsize], iv_dec[ivsize]; RAND_bytes(iv_enc, ivsize); memcpy(iv_dec, iv_enc, ivsize); // buffers for encryption and decryption const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; unsigned char paddedinput[encslength]; memset(paddedinput, 0, encslength); memcpy(paddedinput, aes_input, inputslength); unsigned char enc_out[encslength]; unsigned char dec_out[inputslength]; memset(enc_out, 0, sizeof(enc_out)); memset(dec_out, 0, sizeof(dec_out)); AES_KEY enc_key, dec_key; AES_set_encrypt_key(aes_key, keylength, &enc_key); AES_ige_encrypt(paddedinput, enc_out, encslength, &enc_key, iv_enc, AES_ENCRYPT); AES_set_decrypt_key(aes_key, keylength, &dec_key); AES_ige_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT); printf("original:\t"); hex_print(aes_input, sizeof(aes_input)); printf("encrypt:\t"); hex_print(enc_out, sizeof(enc_out)); printf("decrypt:\t"); hex_print(dec_out, sizeof(dec_out)); return 0; } ```

Original source

Related problems