clang format and init tp03

This commit is contained in:
Tiago Sousa 2024-02-27 12:01:18 +00:00
parent 6ad30e2340
commit 053e94abbc
Signed by: tiago
SSH key fingerprint: SHA256:odOD9vln9U7qNe1R8o3UCbE3jkQCkr5/q5mgd5hwua0
2 changed files with 293 additions and 0 deletions

9
.clang-format Normal file
View file

@ -0,0 +1,9 @@
BasedOnStyle: LLVM
UseTab: Always
IndentWidth: 4
TabWidth: 4
BreakBeforeBraces: Attach
ColumnLimit: 100
PenaltyReturnTypeOnItsOwnLine: 1000000
AlwaysBreakAfterDefinitionReturnType: None
SeparateDefinitionBlocks: Always

View file

@ -0,0 +1,284 @@
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/params.h>
#include <openssl/rand.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#define KEY_SIZE 32
#define SALT_SIZE 16
#define ITERATIONS 80000
int aes_ctr(const char *input_file, const char *output_file, const unsigned char *key, int enc) {
int BUF_SIZE = 1024;
int cipher_block_size = EVP_CIPHER_block_size(EVP_aes_256_ctr());
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) {
fprintf(stderr, "Error opening input file\n");
return 1;
}
// Open output file
FILE *foutput = fopen(output_file, "ab");
if (foutput == NULL) {
fprintf(stderr, "Error opening output file\n");
fclose(finput);
return 1;
}
EVP_CIPHER_CTX *ctx = NULL;
if (!(ctx = EVP_CIPHER_CTX_new())) {
fprintf(stderr, "Error creating context\n");
fclose(finput);
fclose(foutput);
return 1;
}
// EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
// if (!mac) {
// fprintf(stderr, "Error creating HMAC\n");
// fclose(finput);
// fclose(foutput);
// return 1;
// }
//
// EVP_MAC_CTX *hctx = NULL;
// if (!(hctx = EVP_MAC_CTX_new(mac))) {
// fprintf(stderr, "Error creating HMAC context\n");
// fclose(finput);
// fclose(foutput);
// return 1;
// }
// const OSSL_PARAM params[] = {OSSL_PARAM_UTF8_STRING(OSSL_MAC, "SHA256", 0), OSSL_PARAM_END};
// Set the digest type to SHA256
// if (EVP_MAC_CTX_set_params(hctx, EVP_sha256()) != 1) {
// fprintf(stderr, "Error setting HMAC digest type\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) {
fprintf(stderr, "Error generating IV\n");
return 1;
}
if (fwrite(iv, 1, 16, foutput) != 16) {
fprintf(stderr, "Error writing IV to file\n");
return 1;
}
} else {
// Seek forward by 16 bytes to ignore the salt
if (fseek(finput, 16, SEEK_SET) != 0) {
fprintf(stderr, "Error seeking to IV position in input file\n");
return 1;
}
if (fread(iv, 1, 16, finput) != 16) {
fprintf(stderr, "Error reading IV from file\n");
return 1;
}
}
if (EVP_CipherInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, 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;
}
if (EVP_MAC_init(hctx, key, 32, NULL) != 1) {
fprintf(stderr, "ERROR: EVP_MAC_init failed. OpenSSL error: %s\n",
ERR_error_string(ERR_get_error(), NULL));
fclose(finput);
fclose(foutput);
return 1;
}
int read_size, len;
unsigned char *hmac = (unsigned char *)malloc(32);
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) {
fprintf(stderr, "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) {
fprintf(stderr, "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, const char *passphrase) {
unsigned char key[KEY_SIZE];
unsigned char salt[SALT_SIZE];
// Derive key from passphrase using PBKDF2
char *output_file = malloc(strlen(input_file) + 5);
strcpy(output_file, input_file);
strcat(output_file, ".enc");
if (RAND_bytes(salt, SALT_SIZE) != 1) {
fprintf(stderr, "Error generating salt\n");
return 1;
}
// Write salt to output file
FILE *foutput = fopen(output_file, "wb");
if (foutput == NULL) {
fprintf(stderr, "Error opening output file\n");
return 1;
}
if (fwrite(salt, 1, 16, foutput) != 16) {
fprintf(stderr, "Error writing salt to file\n");
fclose(foutput);
return 1;
}
fclose(foutput);
// Derive key from passphrase using PBKDF2
if (PKCS5_PBKDF2_HMAC(passphrase, strlen(passphrase), salt, SALT_SIZE, ITERATIONS, EVP_sha256(),
KEY_SIZE * 2, key) != 1) {
fprintf(stderr, "Error deriving key from passphrase\n");
return 1;
}
aes_ctr(input_file, output_file, key, 1);
return 0;
}
int decrypt(char *input_file, const char *passphrase) {
unsigned char key[KEY_SIZE];
unsigned char salt[SALT_SIZE];
// Derive key from passphrase using PBKDF2
char *output_file = malloc(strlen(input_file) + 5);
strcpy(output_file, input_file);
strcat(output_file, ".dec");
// Read salt from input file
FILE *finput = fopen(input_file, "rb");
if (finput == NULL) {
fprintf(stderr, "Error opening input file\n");
return 1;
}
if (fread(salt, 1, 16, finput) != 16) {
fprintf(stderr, "Error reading salt from file\n");
fclose(finput);
return 1;
}
fclose(finput);
// Derive key from passphrase using PBKDF2
if (PKCS5_PBKDF2_HMAC(passphrase, strlen(passphrase), salt, SALT_SIZE, ITERATIONS, EVP_sha256(),
KEY_SIZE, key) != 1) {
fprintf(stderr, "Error deriving key from passphrase\n");
return 1;
}
aes_ctr(input_file, output_file, key, 0);
return 0;
}
void disableEcho() {
struct termios oldTermios, newTermios;
tcgetattr(0, &oldTermios);
newTermios = oldTermios;
newTermios.c_lflag &= ~(ECHO);
tcsetattr(0, TCSANOW, &newTermios);
}
void enableEcho() {
struct termios oldTermios;
tcgetattr(0, &oldTermios);
oldTermios.c_lflag |= ECHO;
tcsetattr(0, TCSANOW, &oldTermios);
}
int main(int argc, char *argv[]) {
if (argc < 3) {
fprintf(stderr, "Usage: %s {enc|dec} [file_path]\n", argv[0]);
return 1;
}
char *mode = argv[1];
char *input_file = argv[2];
if (!(strcmp(mode, "enc") == 0 || strcmp(mode, "dec") == 0)) {
fprintf(stderr, "Invalid mode. Use 'enc' or 'dec'.\n");
}
if (argc != 3) {
fprintf(stderr, "Usage: %s {enc|dec} [file_path]\n", argv[0]);
return 1;
}
input_file = argv[2];
char passphrase[256]; // Assuming maximum passphrase length of 255 characters
printf("Enter passphrase: ");
disableEcho();
if (fgets(passphrase, sizeof(passphrase), stdin) == NULL) {
fprintf(stderr, "Error reading passphrase from stdin\n");
return 1;
}
enableEcho();
passphrase[strcspn(passphrase, "\n")] = '\0'; // Remove trailing newline
int suc = 0;
if (strcmp(mode, "enc") == 0) {
suc = encrypt(input_file, passphrase);
} else {
suc = decrypt(input_file, passphrase);
}
if (suc == 0) {
printf("Operation completed successfully\n");
} else {
printf("Operation failed\n");
}
return 0;
}