[c] implemented cfich_aes_cbc.c

This commit is contained in:
Afonso Franco 2024-02-22 22:22:18 +00:00
parent c5b05e25ef
commit 68d5728ab4
Signed by: afonso
SSH key fingerprint: SHA256:JiuxZNdA5bRWXPMUJChI0AQ75yC+cXY4xM0IaVwEVys

View file

@ -0,0 +1,206 @@
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void setup(char *key_file) {
FILE *f = fopen(key_file, "wb");
if (f == NULL) {
printf("Error opening file\n");
return;
}
unsigned char key_bytes[32];
if (RAND_bytes(key_bytes, 32) != 1) {
printf("Error generating random bytes\n");
fclose(f);
return;
}
if (fwrite(key_bytes, 1, 32, f) != 32) {
printf("Error writing to file\n");
}
fclose(f);
}
int aes(const char *input_file, const char *output_file, const char *key_file, int enc) {
int BUF_SIZE = 1024;
int cipher_block_size = EVP_CIPHER_block_size(EVP_aes_256_cbc());
int input_size = BUF_SIZE;
int output_size = input_size + (cipher_block_size - 1);
int u_len = 0,f_len = 0;
unsigned char input_buf[input_size], output_buf[output_size];
FILE *finput = fopen(input_file, "rb");
if (finput == NULL) {
printf("Error opening input file\n");
return 1;
}
// Open output file
FILE *foutput = fopen(output_file, "wb");
if (foutput == NULL) {
printf("Error opening output file\n");
fclose(finput);
return 1;
}
FILE *fkey = fopen(key_file, "rb");
if (fkey == NULL) {
printf("Error opening key file\n");
return 1;
}
unsigned char key_bytes[32];
if (fread(key_bytes, 1, 32, fkey) != 32) {
printf("Error reading key from file\n");
fclose(fkey);
return 1;
}
fclose(fkey);
EVP_CIPHER_CTX *ctx = NULL;
if (!(ctx = EVP_CIPHER_CTX_new())) {
printf("Error creating context\n");
fclose(finput);
fclose(foutput);
return 1;
}
// If enc is 1, then we are encrypting, else we are decrypting
// If we are encrypting, we need to generate an IV
// If we are decrypting, we need to read the IV from the file
unsigned char iv[16];
if (enc) {
if (RAND_bytes(iv, 16) != 1) {
printf("Error generating IV\n");
return 1;
}
if (fwrite(iv, 1, 16, foutput) != 16) {
printf("Error writing IV to file\n");
return 1;
}
} else {
if (fread(iv, 1, 16, finput) != 16) {
printf("Error reading IV from file\n");
return 1;
}
}
if (EVP_CipherInit_ex(ctx, EVP_aes_256_cbc(), NULL, key_bytes, iv, enc) != 1) {
fprintf(stderr, "ERROR: EVP_CipherInit_ex failed. OpenSSL error: %s\n",
ERR_error_string(ERR_get_error(), NULL));
EVP_CIPHER_CTX_free(ctx);
return 1;
}
int read_size, len;
while ((read_size = fread(input_buf, 1, BUF_SIZE, finput)) > 0) {
printf("Read %d bytes, passing through CipherUpdate...\n", read_size);
if (EVP_CipherUpdate(ctx, output_buf, &len, input_buf, read_size) != 1) {
fprintf(stderr, "ERROR: EVP_CipherUpdate failed. OpenSSL error: %s\n",
ERR_error_string(ERR_get_error(), NULL));
fclose(finput);
fclose(foutput);
return 1;
}
printf("\tGot back %d bytes from CipherUpdate...\n", len);
printf("Writing %d bytes to %s...\n", len, output_file);
if (fwrite(output_buf, 1, len, foutput) != len) {
printf("Error writing to output file\n");
return 1;
}
printf("\tWrote %d bytes\n", len);
u_len += len;
}
if (read_size == -1) {
fprintf(stderr, "ERROR: Reading from the file %s failed.\n", input_file);
}
if (EVP_CipherFinal_ex(ctx, output_buf, &f_len) != 1) {
fprintf(stderr, "ERROR: EVP_CipherFinal_ex failed. OpenSSL error: %s\n",
ERR_error_string(ERR_get_error(), NULL));
fclose(finput);
fclose(foutput);
return 1;
}
printf("u_len: %d, f_len: %d\n", u_len, f_len);
if (f_len) {
printf("Writing final %d bytes to %s...\n", f_len, output_file);
if (fwrite(output_buf, 1, f_len, foutput) != f_len) {
printf("Error writing to output file\n");
fclose(finput);
fclose(foutput);
return 1;
}
}
printf("\tWrote last %d bytes\n", f_len);
fclose(finput);
fclose(foutput);
return 0;
}
int encrypt(char *input_file, char *key_file) {
char *output_file = malloc(strlen(input_file) + 5);
strcpy(output_file, input_file);
strcat(output_file, ".enc");
aes(input_file, output_file, key_file,1);
return 0;
}
int decrypt(char *input_file, char *key_file) {
char *output_file = malloc(strlen(input_file) + 5);
strcpy(output_file, input_file);
strcat(output_file, ".dec");
aes(input_file, output_file, key_file,0);
return 0;
}
int main(int argc, char *argv[]) {
if (argc < 3) {
fprintf(stderr, "Usage: %s {setup|enc|dec} [file_path] [key_file_path]\n", argv[0]);
return 1;
}
char *mode = argv[1];
char *file_path = argv[2];
char *key_file_path = NULL;
if (strcmp(mode, "setup") == 0) {
if (argc != 3) {
fprintf(stderr, "Usage: %s setup [key_file_path]\n", argv[0]);
return 1;
}
key_file_path = file_path;
setup(key_file_path);
} else if (strcmp(mode, "enc") == 0 || strcmp(mode, "dec") == 0) {
if (argc != 4) {
fprintf(stderr,
"Usage: %s {enc|dec} [file_path] "
"[key_file_path]\n",
argv[0]);
return 1;
}
file_path = argv[2];
key_file_path = argv[3];
if (strcmp(mode, "enc") == 0)
encrypt(file_path, key_file_path);
else
decrypt(file_path, key_file_path);
} else {
fprintf(stderr, "Invalid mode. Use 'setup', 'enc', or 'dec'.\n");
return 1;
}
return 0;
}