Im new to OpenSSL, Can anybody give me a hint in how to initialize AES CTR mode from a C file. I know this is the method´s signature but I am having problems with the parameters, there´s not many documentation neither a clear example how to make a simple encryption. I would appreciate if somebody could exemplify a call to this method. Thanks in advance!
void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
const unsigned long length, const AES_KEY *key,
unsigned char ivec[AES_BLOCK_SIZE],
unsigned char ecount_buf[AES_BLOCK_SIZE],
unsigned int *num);
Hi Caf I really appreciate your quick answer it has been really useful, and defenetly the best example I have found on the web. I am trying to open a file with undetermined length, encrypt it and write another file with the ciphertext generated, then open the ciphered file and recover the plaintext. I need to use a file of a considerable amount of MB cause I would like to benchmark the performance of the CPU. However Im still having a problem while decrypting. Somehow when decrypting a considerable txt files (1504KB)it wont decrypt it complete, and I get half of it in plaintext and the other half still ciphered. I think this might be related to the size of the iv or the way I am calling the counter. Here is what I have so far:
#include <openssl/aes.h>
#include <stdio.h>
#include <string.h>
struct ctr_state {
unsigned char ivec[16];
unsigned int num;
unsigned char ecount[16];
};
FILE *fp;
FILE *rp;
FILE *op;
size_t count;
char * buffer;
AES_KEY key;
int bytes_read, bytes_written;
unsigned char indata[AES_BLOCK_SIZE];
unsigned char outdata[AES_BLOCK_SIZE];
unsigned char ckey[] = "thiskeyisverybad"; // It is 128bits though..
unsigned char iv[8] = {0};//This should be generated by RAND_Bytes I will take into consideration your previous post
struct ctr_state state;
int init_ctr(struct ctr_state *state, const unsigned char iv[8]){
state->num = 0;
memset(state->ecount, 0, 16);
memset(state->ivec + 8, 0, 8);
memcpy(state->ivec, iv, 8);
}
void encrypt(){
//Opening files where text plain text is read and ciphertext stored
fp=fopen("input.txt","a+b");
op=fopen("output.txt","w");
if (fp==NULL) {fputs ("File error",stderr); exit (1);}
if (op==NULL) {fputs ("File error",stderr); exit (1);}
//Initializing the encryption KEY
AES_set_encrypt_key(ckey, 128, &key);
//Encrypting Blocks of 16 bytes and writing the output.txt with ciphertext
while (1) {
init_ctr(&state, iv); //Counter call
bytes_read = fread(indata, 1, AES_BLOCK_SIZE, fp);
AES_ctr128_encrypt(indata, outdata, bytes_read, &key, state.ivec, state.ecount, &state.num);
bytes_written = fwrite(outdata, 1, bytes_read, op);
if (bytes_read < AES_BLOCK_SIZE)
break;
}
fclose (fp);
fclose (op);
free (buffer);
}
void decrypt(){
//Opening files where text cipher text is read and the plaintext recovered
rp=fopen("recovered.txt","w");
op=fopen("output.txt","a+b");
if (rp==NULL) {fputs ("File error",stderr); exit (1);}
if (op==NULL) {fputs ("File error",stderr); exit (1);}
//Initializing the encryption KEY
AES_set_encrypt_key(ckey, 128, &key);
//Encrypting Blocks of 16 bytes and writing the output.txt with ciphertext
while (1) {
init_ctr(&state, iv);//Counter call
bytes_read = fread(indata, 1, AES_BLOCK_SIZE, op);
AES_ctr128_encrypt(indata, outdata, bytes_read, &key, state.ivec, state.ecount, &state.num);
bytes_written = fwrite(outdata, 1, bytes_read, rp);
if (bytes_read < AES_BLOCK_SIZE)
break;
}
fclose (rp);
fclose (op);
free (buffer);
}
int main(int argc, char *argv[]){
encrypt();
//decrypt();
system("PAUSE");
return 0;
}
Each encrypt and decrypt function are called in different runs so everything is initialized always with the same values. Thanks again for the hints you can provide me in advance & Regards!!!
init_ctr()
call outside of thewhile()
loops in both encryption and decryption.indata
andoutdata
also don't have to be ofAES_BLOCK_SIZE
length - they can be considerably larger. – CountessAES_encrypt
and friends. That's a software-only implementation, so you will not enjoy hardware support, like AES-NI. You should be usingEVP_*
functions. See EVP Symmetric Encryption and Decryption on the OpenSSL wiki. In fact, you should probably be using authenticated encryption because it provides both confidentiality and authenticity. See EVP Authenticated Encryption and Decryption on the OpenSSL wiki. – PanchoEVP_*
functions, then the ciphers of interest areEVP_aes_128_ctr
,EVP_aes_192_ctr
andEVP_aes_256_ctr
. – Pancho