[c] implemented cfich_chacha20.c
This commit is contained in:
parent
2495981b72
commit
c05daa0f53
1 changed files with 308 additions and 0 deletions
308
TPs/TP02/c/src/cfich_chacha20.c
Normal file
308
TPs/TP02/c/src/cfich_chacha20.c
Normal file
|
@ -0,0 +1,308 @@
|
|||
#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");
|
||||
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;
|
||||
}
|
Loading…
Reference in a new issue