diff --git a/TPs/TP03/compile_commands.json b/TPs/TP03/compile_commands.json new file mode 100644 index 0000000..469619e --- /dev/null +++ b/TPs/TP03/compile_commands.json @@ -0,0 +1,17 @@ +[ + { + "arguments": [ + "/usr/bin/gcc", + "-c", + "-Wall", + "-O2", + "-I/opt/homebrew/opt/openssl@3.2/include", + "-o", + "pbenc_aes_ctr_hmac", + "pbenc_aes_ctr_hmac.c" + ], + "directory": "/Users/afonso/projects/University/4ano/2sem/ES/2324-G05/TPs/TP03", + "file": "/Users/afonso/projects/University/4ano/2sem/ES/2324-G05/TPs/TP03/pbenc_aes_ctr_hmac.c", + "output": "/Users/afonso/projects/University/4ano/2sem/ES/2324-G05/TPs/TP03/pbenc_aes_ctr_hmac" + } +] diff --git a/TPs/TP03/pbenc_aes_ctr_hmac b/TPs/TP03/pbenc_aes_ctr_hmac new file mode 100755 index 0000000..cb20297 Binary files /dev/null and b/TPs/TP03/pbenc_aes_ctr_hmac differ diff --git a/TPs/TP03/pbenc_aes_ctr_hmac.c b/TPs/TP03/pbenc_aes_ctr_hmac.c index dc03ee6..79e823e 100644 --- a/TPs/TP03/pbenc_aes_ctr_hmac.c +++ b/TPs/TP03/pbenc_aes_ctr_hmac.c @@ -19,7 +19,7 @@ int aes_ctr(const char *input_file, const char *output_file, const unsigned char int input_size = BUF_SIZE; int output_size = input_size + (cipher_block_size - 1); - int u_len = 0, f_len = 0; + int f_len = 0; unsigned char input_buf[input_size], output_buf[output_size]; @@ -45,30 +45,44 @@ int aes_ctr(const char *input_file, const char *output_file, const unsigned char 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}; + EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL); + if (!mac) { + fprintf(stderr, "Error creating HMAC\n"); + fclose(finput); + fclose(foutput); + return 1; + } - // 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; - // } + 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; + } + + // Set parameters for HMAC algorithm + OSSL_PARAM params[2], *p = params; + const EVP_MD *md = EVP_sha256(); + *p++ = OSSL_PARAM_construct_utf8_string("digest", (char *)EVP_MD_name(md), 0); + *p = OSSL_PARAM_construct_end(); + + unsigned char *hmac = malloc(32); + unsigned char *mac_input; + if (enc) { + mac_input = output_buf; + } else { + mac_input = input_buf; + } + + fseek(finput, 0, SEEK_END); + long file_size = ftell(finput); + rewind(finput); + if (!enc) { + // Remove the size of the SALT, IV and HMAC from the file size + fseek(finput, 32, SEEK_SET); + file_size -= 64; + } // If enc is 1, then we are encrypting, else we are decrypting // If we are encrypting, we need to generate an IV @@ -86,6 +100,7 @@ int aes_ctr(const char *input_file, const char *output_file, const unsigned char } 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; } @@ -102,7 +117,7 @@ int aes_ctr(const char *input_file, const char *output_file, const unsigned char return 1; } - if (EVP_MAC_init(hctx, key, 32, NULL) != 1) { + if (EVP_MAC_init(hctx, key, 32, params) != 1) { fprintf(stderr, "ERROR: EVP_MAC_init failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL)); fclose(finput); @@ -110,10 +125,15 @@ int aes_ctr(const char *input_file, const char *output_file, const unsigned char 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); + int len; + while (file_size > 0) { + if (file_size < BUF_SIZE) { + BUF_SIZE = file_size; + } + size_t read_size = fread(input_buf, 1, BUF_SIZE, finput); + if (read_size == 0) { + break; + } 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)); @@ -121,17 +141,18 @@ int aes_ctr(const char *input_file, const char *output_file, const unsigned char fclose(foutput); return 1; } - printf("\tGot back %d bytes from CipherUpdate...\n", len); - printf("Writing %d bytes to %s...\n", len, output_file); + if (EVP_MAC_update(hctx, mac_input, read_size) != 1) { + fprintf(stderr, "ERROR: EVP_MAC_update failed. OpenSSL error: %s\n", + ERR_error_string(ERR_get_error(), NULL)); + fclose(finput); + fclose(foutput); + return 1; + } 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); + file_size -= read_size; } if (EVP_CipherFinal_ex(ctx, output_buf, &f_len) != 1) { @@ -141,10 +162,22 @@ int aes_ctr(const char *input_file, const char *output_file, const unsigned char fclose(foutput); return 1; } - printf("u_len: %d, f_len: %d\n", u_len, f_len); + size_t m_len = 0; + if (EVP_MAC_final(hctx, hmac, &m_len, 32) != 1) { + fprintf(stderr, "ERROR: EVP_MAC_final failed. OpenSSL error: %s\n", + ERR_error_string(ERR_get_error(), NULL)); + fclose(finput); + fclose(foutput); + return 1; + } + if (m_len != 32) { + fprintf(stderr, "ERROR: HMAC length is not 32\n"); + fclose(finput); + fclose(foutput); + return 1; + } 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); @@ -152,7 +185,32 @@ int aes_ctr(const char *input_file, const char *output_file, const unsigned char return 1; } } - printf("\tWrote last %d bytes\n", f_len); + if (enc) { + if (fwrite(hmac, 1, m_len, foutput) != m_len) { + fprintf(stderr, "Error writing HMAC to file\n"); + fclose(finput); + fclose(foutput); + return 1; + } + } else { + unsigned char *hmac2 = malloc(32); + if (fread(hmac2, 1, 32, finput) != 32) { + fprintf(stderr, "Error reading HMAC from file\n"); + fclose(finput); + fclose(foutput); + return 1; + } + int cmp = memcmp(hmac, hmac2, 32); + if (cmp == 0) { + printf("HMACs match\n"); + } else { + fprintf(stderr, "HMACs do not match\n"); + fclose(finput); + fclose(foutput); + return 1; + } + } + fclose(finput); fclose(foutput); @@ -160,7 +218,7 @@ int aes_ctr(const char *input_file, const char *output_file, const unsigned char } int encrypt(char *input_file, const char *passphrase) { - unsigned char key[KEY_SIZE]; + unsigned char key[KEY_SIZE * 2]; unsigned char salt[SALT_SIZE]; // Derive key from passphrase using PBKDF2 char *output_file = malloc(strlen(input_file) + 5); @@ -184,8 +242,9 @@ int encrypt(char *input_file, const char *passphrase) { } fclose(foutput); + int pass_len = strlen(passphrase); // Derive key from passphrase using PBKDF2 - if (PKCS5_PBKDF2_HMAC(passphrase, strlen(passphrase), salt, SALT_SIZE, ITERATIONS, EVP_sha256(), + if (PKCS5_PBKDF2_HMAC(passphrase, pass_len, salt, SALT_SIZE, ITERATIONS, EVP_sha256(), KEY_SIZE * 2, key) != 1) { fprintf(stderr, "Error deriving key from passphrase\n"); return 1; @@ -268,6 +327,7 @@ int main(int argc, char *argv[]) { return 1; } enableEcho(); + putchar('\n'); passphrase[strcspn(passphrase, "\n")] = '\0'; // Remove trailing newline int suc = 0; if (strcmp(mode, "enc") == 0) { diff --git a/TPs/TP03/plaintext b/TPs/TP03/plaintext new file mode 100644 index 0000000..a9c64a9 --- /dev/null +++ b/TPs/TP03/plaintext @@ -0,0 +1,42 @@ +This was a triumph. +I'm making a note here: HUGE SUCCESS. +It's hard to overstate my satisfaction. +Aperture Science +We do what we must because we can. +For the good of all of us +Except the ones who are dead. +But there's no sense crying over every mistake +You just keep on trying till you run out of cake +And the science gets done and you make a neat gun +For the people who are still alive. +I'm not even angry. +I'm being so sincere right now. +Even though you broke my heart and killed me. +And tore me to pieces. +And threw every piece into a fire. +As they burned it hurt because +I was so happy for you! +Now these points of data make a beautiful line +And we're out of beta, we're releasing on time. +So I'm GLaD. I got burned. +Think of all the things we learned +For the people who are still alive. +Go ahead and leave me. +I think I prefer to stay inside. +Maybe you'll find someone else to help you. +Maybe Black Mesa +THAT WAS A JOKE. Haha. FAT CHANCE. +Anyway, this cake is great. +It's so delicious and moist. +Look at me still talking when there's science to do. +When I look out there, it makes me GLaD I'm not you. +I've experiments to run, there is research to be done +On the people who are still alive +And believe me I am still alive. +I'm doing science and I'm still alive. +I feel FANTASTIC and I'm still alive. +While you're dying I'll be still alive. +And when you're dead I will be still alive. +Still alive +Still alive +Still alive diff --git a/TPs/TP03/tokefile.toml b/TPs/TP03/tokefile.toml new file mode 100644 index 0000000..dfcb7ed --- /dev/null +++ b/TPs/TP03/tokefile.toml @@ -0,0 +1,15 @@ +[vars] +CC="!which gcc" +CFLAGS="-Wall -O2 -I/opt/homebrew/opt/openssl@3.2/include -L/opt/homebrew/opt/openssl@3.2/lib" +LDFLAGS="-lssl -lcrypto" + +[targets.build] +wildcards=["!ls -1 *.c","!ls -1 *.c | sed -e 's/\\.c$//'"] +cmd="${CC} ${CFLAGS} ${LDFLAGS} @@ -o @@" + +[targets.debug] +vars.CC="clang" +vars.CFLAGS="-Wall -O0 -g -fsanitize=address -g -I/opt/homebrew/opt/openssl@3.2/include -L/opt/homebrew/opt/openssl@3.2/lib" +wildcards=["!ls -1 *.c","!ls -1 *.c | sed -e 's/\\.c$//'"] +cmd="${CC} ${CFLAGS} ${LDFLAGS} @@ -o @@" +