From c05daa0f536fd2e6cb635bb04ee74dc4715820cd Mon Sep 17 00:00:00 2001 From: afonsofrancof Date: Thu, 22 Feb 2024 01:02:01 +0000 Subject: [PATCH] [c] implemented cfich_chacha20.c --- TPs/TP02/c/src/cfich_chacha20.c | 308 ++++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 TPs/TP02/c/src/cfich_chacha20.c diff --git a/TPs/TP02/c/src/cfich_chacha20.c b/TPs/TP02/c/src/cfich_chacha20.c new file mode 100644 index 0000000..0dacc5c --- /dev/null +++ b/TPs/TP02/c/src/cfich_chacha20.c @@ -0,0 +1,308 @@ +#include +#include +#include +#include + +void setup(char *key_file) { + FILE *f = fopen(key_file, "wb"); + if (f == NULL) { + printf("Error opening file\n"); + goto close; + } + + unsigned char key_bytes[32]; + if (RAND_bytes(key_bytes, 32) != 1) { + printf("Error generating random bytes\n"); + goto close; + } + + if (fwrite(key_bytes, 1, 32, f) != 32) { + printf("Error writing to file\n"); + goto close; + } + + goto close; +close: + fclose(f); +} + +int encrypt(char *input_file, char *key_file) { + FILE *fkey = fopen(key_file, "rb"); + FILE *finput = fopen(input_file, "rb"); + // Create output file + char *output_file = malloc(strlen(input_file) + 5); + output_file = strcpy(output_file, input_file); + output_file = strcat(output_file, ".enc"); + FILE *foutput = fopen(output_file, "wb"); + + if (fkey == NULL) { + printf("Error opening key file\n"); + return 1; + } + if (finput == NULL) { + printf("Error opening input file\n"); + return 1; + } + if (foutput == NULL) { + printf("Error opening output 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); + fclose(finput); + fclose(foutput); + return 1; + } + + // Determining file size + fseek(finput, 0, SEEK_END); + unsigned long fsize = ftell(finput); + rewind(finput); + + unsigned char *plaintext = malloc(fsize * sizeof(unsigned char)); + if (plaintext == NULL) { + printf("Error allocating memory\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + return 1; + } + + if (fread(plaintext, 1, fsize, finput) != fsize) { + printf("Error reading file\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + free(plaintext); + return 1; + } + + unsigned char nonce[16]; + if (RAND_bytes(nonce, 16) != 1) { + printf("Error generating nonce\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + free(plaintext); + return 1; + } + + // Encrypt the plaintext using chacha20 + unsigned char ciphertext[fsize]; + EVP_CIPHER_CTX *ctx; + if (!(ctx = EVP_CIPHER_CTX_new())) { + printf("Error creating context\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + free(plaintext); + return 1; + } + + if (EVP_EncryptInit_ex(ctx, EVP_chacha20(), NULL, key_bytes, nonce) != 1) { + printf("Error initializing encryption\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + free(plaintext); + return 1; + } + + int len; + if (EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, sizeof(plaintext)) != 1) { + printf("Error encrypting\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + free(plaintext); + return 1; + } + + if (EVP_EncryptFinal_ex(ctx, ciphertext + len, &len) != 1) { + printf("Error finalizing encryption\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + free(plaintext); + return 1; + } + + // Add the nonce to the beginning of the file + char *nonce_and_ciphertext = malloc(16 + fsize); + nonce_and_ciphertext = memcpy(nonce_and_ciphertext, nonce, 16); + nonce_and_ciphertext = memcpy(nonce_and_ciphertext + 16, ciphertext, fsize); + + if (fwrite(nonce_and_ciphertext, 1, 16 + fsize, foutput) != (16 + fsize)) { + printf("Error writing to output file\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + free(plaintext); + free(nonce_and_ciphertext); + return 1; + } + + fclose(fkey); + fclose(finput); + fclose(foutput); + free(plaintext); + free(nonce_and_ciphertext); + return 0; +} + +int decrypt(char *input_file, char *key_file) { + FILE *fkey = fopen(key_file, "rb"); + FILE *finput = fopen(input_file, "rb"); + // Create output file + char *output_file = malloc(strlen(input_file) + 5); + output_file = strcpy(output_file, input_file); + output_file = strcat(output_file, ".dec"); + FILE *foutput = fopen(output_file, "wb"); + + if (fkey == NULL) { + printf("Error opening key file\n"); + return 1; + } + if (finput == NULL) { + printf("Error opening input file\n"); + return 1; + } + if (foutput == NULL) { + printf("Error opening output 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); + fclose(finput); + fclose(foutput); + return 1; + } + + // Determining file size + fseek(finput, 0, SEEK_END); + unsigned long fsize = ftell(finput); + rewind(finput); + + unsigned char *nounce_and_ciphertext = malloc(fsize * sizeof(unsigned char)); + if (nounce_and_ciphertext == NULL) { + printf("Error allocating memory\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + return 1; + } + + if (fread(nounce_and_ciphertext, 1, fsize, finput) != fsize) { + printf("Error reading file\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + free(nounce_and_ciphertext); + return 1; + } + + unsigned char nonce[16]; + memcpy(nonce, nounce_and_ciphertext, 16); + unsigned char *ciphertext = malloc((fsize * sizeof(unsigned char)) - 16); + memcpy(ciphertext, nounce_and_ciphertext + 16, fsize - 16); + + // Decrypt the ciphertext using chacha20 + unsigned char plaintext[fsize - 16]; + EVP_CIPHER_CTX *ctx; + if (!(ctx = EVP_CIPHER_CTX_new())) { + printf("Error creating context\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + free(nounce_and_ciphertext); + return 1; + } + + if (EVP_DecryptInit_ex(ctx, EVP_chacha20(), NULL, key_bytes, nonce) != 1) { + printf("Error initializing decryption\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + free(nounce_and_ciphertext); + return 1; + } + + int len; + if (EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, fsize - 16) != 1) { + printf("Error decrypting\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + free(nounce_and_ciphertext); + return 1; + } + + if (EVP_DecryptFinal_ex(ctx, plaintext + len, &len) != 1) { + printf("Error finalizing decryption\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + free(nounce_and_ciphertext); + return 1; + } + + if (fwrite(plaintext, 1, fsize - 16, foutput) != (fsize - 16)) { + printf("Error writing to output file\n"); + fclose(fkey); + fclose(finput); + fclose(foutput); + free(nounce_and_ciphertext); + return 1; + } + + fclose(fkey); + fclose(finput); + fclose(foutput); + free(nounce_and_ciphertext); + 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; +}