I am trying to implement ecb encryption/decryption using OpenSSL. At present all the setup process seems to return success codes however when it comes to the final decryption it fails.
I have checked the input and key size to make sure they are both divisible by 16 and I have checked a number of other threads and this man page to try and find examples of how to do this properly.
This question seems to have the exact same problem however implementing the suggestions did not rectify the issue.
At present the function is returning 0 which indicates decryption failed however I can not identify what is causing the failure.
Code:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int b64invs[] = { 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58,
59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, 51 };
int b64_decode(const char *bytes, unsigned char *out, size_t *outlen) {
size_t len;
size_t i;
size_t j;
int v;
if (bytes == NULL)
return 1;
len = strlen(bytes);
size_t b64_decoded_size = 9;
b64_decoded_size = len / 4 * 3;
for (i=len; i-->0; ) {
if (bytes[i] == '=') {
b64_decoded_size--;
} else {
break;
}
}
if (*outlen < b64_decoded_size || len % 4 != 0 || out == NULL) {
*outlen = b64_decoded_size;
return 2;
} else {
*outlen = b64_decoded_size;
}
for (i=0; i<len; i++) {
bool invalid_char = true;
if (bytes[i] >= '0' && bytes[i] <= '9')
invalid_char = false;
else if (bytes[i] >= 'A' && bytes[i] <= 'Z')
invalid_char = false;
else if (bytes[i] >= 'a' && bytes[i] <= 'z')
invalid_char = false;
else if (bytes[i] == '+' || bytes[i] == '/' || bytes[i] == '=')
invalid_char = false;
if (invalid_char == true)
return 3;
}
for (i=0, j=0; i<len; i+=4, j+=3) {
v = b64invs[bytes[i]-43];
v = (v << 6) | b64invs[bytes[i+1]-43];
v = bytes[i+2]=='=' ? v << 6 : (v << 6) | b64invs[bytes[i+2]-43];
v = bytes[i+3]=='=' ? v << 6 : (v << 6) | b64invs[bytes[i+3]-43];
out[j] = (v >> 16) & 0xFF;
if (bytes[i+2] != '=')
out[j+1] = (v >> 8) & 0xFF;
if (bytes[i+3] != '=')
out[j+2] = v & 0xFF;
}
return 0;
}
int main () {
//Lyrics to yellow submarine, padded with spaces to make length 1200.
unsigned char cipher_text[] = "kG/VjeOGoBnNfTnWm2zRI/Tr6bmqtbN7bOpbcL4ZIUegmblOVZECN9U6Na13W/2r0IPsgIgkhbhJTHVh39O9iS8BE8maJVxXko6h6QOWjHXE5o+EcWxbwdpA0usHv8RR+RZzAaNEpFmWWUoVr6egmdnAyWV1gd0VLiRZhB1/swfU5gpwQ0PzcUXcnkbJB0sXvfDAVt9WPvvRA6L2+r22NdHnZztHfwe/cIvhJqMHhK2LAUQnV4y1lmT0xhUbybtcQng5uVXFf1oHrDk/Wa+eMqGh+S9byjDa5X815wj0nI01rd5xjJZK+5Cybm9YrUG6mO5Oh/e0b+hJrBOcSbsm+lRuPI6JfyBaXvw2O/HedLyr7iGg1TM2NCF3eb5iYDCDXK+avahsn71WOQC7Vaxt/XY2+sjI3fMndNkFSj+0ruKm69aeTnNJAEsNiIM1+xWlZOhKg52wIhL3n6DpdIfSAsjfNY/ijK+uszvRUZzMBqFwR9mIUyKM0m9UJryjKIz1St1KbiILeMZjb0neW32N9LiUxOKkp2OhQ8vm4BZiUFPQYeWn1JYqjCxRVwQw8jqqsO0/J+4GPGCXV8YWgFlyZCT/eNQh3M4wy3oMXQcamxEnK1YfbTpfxWaaMM8vQzjwb3caeyJtE3xX4iy80Ln1hNHxOeUXI6W0UfJZTzzbM7HJacaeTi4xFPOdEqy8BQpfojfZ+JD8Na6k1yaeb4mJRZOpRrSsWpA24rK5a2m4FCX/f4aA1T+5zejHBqfUnIWopibiWLS+irtXOfzJewhKVFpzi8Xkm1DNxQmXsfu93Cplt2YPlKuU+wzuCBguESgWFohVZIiW8gjBqba4MNcsaNEhwSlQmEhbMwN+VKpbf/5D1bhccyxgw35TwLA6AZrMTrZweY+lnXf81zSeWcRn2hQQbm/lbkrJ+YUgV2o3ewer1n2vrv3xwjCxjHGnfVUj6k5lJXPuRsJX/ehf9MtEBb7P6seErlaOkHuaSrutaGcjBXVEie7kZItqGECox5Sh5ig47bkKO0xe181NAVJF2pJkKpV9g19EWqLINOMRGYIuCaG5dlIf5hbnTPNnOk23z7WBUs3QF/DpAIp6w3mS3AELAgXXAWgN8m3xXu6yV+Y14g7sMYjFdxcTbQbD4w8U04X3ip1EZwB77PRJtG4/ONknBCJ6lO3J7kd2YnM0aiAWeIYmDRK3R3r7mJy9z3Ex7efxiyDOwbXPSbcVtpfN76UVQBPkFgCQRHAgmfUpaxpjGK/YgDd3nGONZJiB38A+HpnqcRznTf4szPvgKNM9l4kK8Q3/XfMJXMeXY8qve0fEqvCvtMNFQ+GKFrWnjzbv038ycC6QZKLTae/x1k0NQvGPNqRF82NZvb+mc+cozY/mzeOqOnq+4Kp3qeQPO1C97Dnr89eRTo8UG4r7kdNGKaGh+S9byjDa5X815wj0nI2Yjq8gtmgtw6HQ/1nZBUKOtNT/utkpPaBz+UpZB3pMnqsicBV2iRXas2BpMrhtCHJGUEBVkKjE9X2sy6cqCV3C6YUL7nlJeXRpUEwaktT04wMDjDXsAG8m0SG2lJY3e2IJCxCAisCtDCsmagO0cfhV";
unsigned char key[] = "YELLOW SUBMARINE";
size_t cipher_bytes_len = 0;
size_t cipher_text_len = strlen((const char *)cipher_text);
b64_decode((const char *)cipher_text, NULL, &cipher_bytes_len);
unsigned char cipher_bytes[cipher_bytes_len];
b64_decode((const char *)cipher_text, cipher_bytes, &cipher_bytes_len);
printf("cipher_text_len = %ldn", cipher_text_len);
printf("cipher_bytes_len = %ldn", cipher_bytes_len);
EVP_CIPHER_CTX *ctx;
int len;
unsigned char plain[1584];
if(!(ctx = EVP_CIPHER_CTX_new()))
return 4;
if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL))
return 5;
if(1 != EVP_DecryptUpdate(ctx, plain, &len, cipher_text, cipher_text_len))
return 6;
int plain_len = len;
printf("len = %dn", len);
printf("EVP_DecryptFinal_ex(ctx, plain + len, &len) = %dn", EVP_DecryptFinal_ex(ctx, plain + plain_len, &len));
EVP_CIPHER_CTX_free(ctx);
return 0;
}
The build command for this is:
gcc main.c -lcrypto
DavidT is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.