diff --git a/Implementierung/lib/io.h b/Implementierung/lib/io.h index f780a77..6887f25 100644 --- a/Implementierung/lib/io.h +++ b/Implementierung/lib/io.h @@ -10,6 +10,17 @@ #include #include +/** + * @brief Open a file and load its stats + * + * @param path the filepath + * @param file where the pointer of the file handle should be stored + * @param file_stat pointer to a stat struct + * @return true it worked + * @return false there was an error + */ +bool open_file(const char* path, FILE** file, struct stat* file_stat); + /** * @brief reads a file at a path * diff --git a/Implementierung/lib/md2_impls/md2_2.h b/Implementierung/lib/md2_impls/md2_2.h index 3e6ff3f..4e64689 100644 --- a/Implementierung/lib/md2_impls/md2_2.h +++ b/Implementierung/lib/md2_impls/md2_2.h @@ -8,6 +8,8 @@ #include #include +#include "../io.h" + /** * @brief This implementation loads the file in bits and not at once * diff --git a/Implementierung/src/io.c b/Implementierung/src/io.c index dedb5ce..4983811 100644 --- a/Implementierung/src/io.c +++ b/Implementierung/src/io.c @@ -1,26 +1,35 @@ #include "../lib/io.h" +bool open_file(const char* path, FILE** file, struct stat* file_stat) { + (*file) = fopen(path, "r"); + if ((*file) == NULL) { + printf("Fopen error: %d\n", errno); + fclose((*file)); + return false; + } + + int status = fstat(fileno((*file)), file_stat); + if (status == -1) { + printf("Fstat error: %d\n", errno); + fclose((*file)); + return false; + }; + + if ((file_stat->st_mode & S_IFMT) != S_IFREG) { + printf("File is not a regular file!\n"); + fclose((*file)); + return false; + } + + return true; +} + uint8_t* read_file(const char* path, size_t* size) { // Read the contents of the file specified by path into a heap-allocated // buffer and return a pointer to that buffer. - FILE* f = fopen(path, "r"); - if (f == NULL) { - printf("Fopen error: %d\n", errno); - fclose(f); - return NULL; - } - + FILE* f; struct stat statOfFile; - int status = fstat(fileno(f), &statOfFile); - if (status == -1) { - printf("Fstat error: %d\n", errno); - fclose(f); - return NULL; - }; - - if ((statOfFile.st_mode & S_IFMT) != S_IFREG) { - printf("File is not a regular file!\n"); - fclose(f); + if (!open_file(path, &f, &statOfFile)) { return NULL; } diff --git a/Implementierung/src/main.c b/Implementierung/src/main.c index 9bdb675..08d26de 100644 --- a/Implementierung/src/main.c +++ b/Implementierung/src/main.c @@ -62,6 +62,38 @@ unsigned runTests(struct configuration* c) { return failed; } +bool calculate_hash(struct configuration c, char* hash) { + size_t len; + uint8_t* data; + + if (c.implementationToUse != 2) { + data = read_file(c.filename, &len); + } else { + data = (uint8_t*)c.filename; + len = 0; + } + + if (data == NULL) { + printf("Error reading file %s!", c.filename); + return false; + } + + uint8_t out[16]; + if (c.doBenchmark) { + double duration = + run_benchmark(c.benchmarkingCycles, md2_hash, len, data, out); + printf("Running %d cycles took %f seconds\n", c.benchmarkingCycles, + duration); + } else { + md2_hash(len, data, out); + } + + md2_encode_hash(out, hash); + + if (c.implementationToUse != 2) free(data); + return true; +} + int main(int argc, char** argv) { struct configuration c; enum argumentParseResult result = parseArguments(argc, argv, &c); @@ -87,33 +119,21 @@ int main(int argc, char** argv) { "benchmark cycles: %d\n", c.implementationToUse, c.doBenchmark, c.benchmarkingCycles); + if (c.runTests && c.implementationToUse == 2) { + fprintf(stderr, "Cannot run tests on implementation 2!"); + return EXIT_FAILURE; + } + if (c.runTests) { printf("Running tests...\n\n"); return runTests(&c); } printf("Hashing file %s...\n\n", c.filename); - size_t len; - uint8_t* data = read_file(c.filename, &len); - if (data == NULL) { - printf("Error reading file %s!", c.filename); - return EXIT_FAILURE; - } - uint8_t out[16]; char hash[32]; - if (c.doBenchmark) { - double duration = - run_benchmark(c.benchmarkingCycles, md2_hash, len, data, out); - printf("Running %d cycles took %f seconds\n", c.benchmarkingCycles, - duration); - } else { - md2_hash(len, data, out); - } - md2_encode_hash(out, hash); + calculate_hash(c, hash); printf("Hash: %s\n", hash); - free(data); - return 0; } diff --git a/Implementierung/src/md2_impls/md2_2.c b/Implementierung/src/md2_impls/md2_2.c index 1fac14a..f8d54d8 100644 --- a/Implementierung/src/md2_impls/md2_2.c +++ b/Implementierung/src/md2_impls/md2_2.c @@ -27,30 +27,26 @@ void process_block_checksum(uint8_t block[16], uint8_t checksum[16], } } -// unused! -void md2_checksum_2(size_t, uint8_t*) {} - -void md2_hash_2(size_t len, const uint8_t buf[len], uint8_t out[16]) { - // === step 1 === +void apply_padding(size_t len, uint8_t buf[16]) { int paddingNeeded = 16 - (len % 16); uint8_t originalPadding = paddingNeeded; len += paddingNeeded; - // printf("len: %d\n", len); - - // +16 for the checksum - uint8_t* newBuf = calloc(len, sizeof(uint8_t)); - // TODO: null check - memcpy(newBuf, buf, len - paddingNeeded); - - // printBuf(len + 16, newBuf); - while (paddingNeeded > 0) { - newBuf[len - paddingNeeded] = originalPadding; + buf[len - paddingNeeded] = originalPadding; paddingNeeded--; } - // printf("buf with padding: "); - // printBuf(len + 16, newBuf); + printf("buf with padding: "); + md2_print_buf(len, buf); +} + +// unused! +void md2_checksum_2(size_t, uint8_t*) {} + +void md2_hash_2(size_t len, const uint8_t buf[len], uint8_t out[16]) { + FILE* file; + struct stat file_stat; + open_file((char*)buf, &file, &file_stat); // === step 3 === uint8_t* messageDigestBuf = calloc(48, sizeof(uint8_t)); @@ -59,16 +55,33 @@ void md2_hash_2(size_t len, const uint8_t buf[len], uint8_t out[16]) { uint8_t l = 0; uint8_t* checksum = calloc(16, sizeof(uint8_t)); - for (size_t i = 0; i < len / 16; i++) { - process_block_checksum(newBuf + (i * 16), checksum, &l); - process_block_hash(newBuf + (i * 16), messageDigestBuf); - } + uint8_t* data = malloc(16); + size_t bytes_left_to_read = file_stat.st_size; + size_t bytes_left_to_process = 0; + + while (bytes_left_to_read != 0) { + bytes_left_to_process = bytes_left_to_read >= 16 ? 16 : bytes_left_to_read; + + fread(data, 1, bytes_left_to_process, file); + if (ferror(file) || feof(file)) { + fprintf(stderr, "Error reading the file!"); + return; + } + + process_block_checksum(data, checksum, &l); + process_block_hash(data, messageDigestBuf); + + bytes_left_to_read -= bytes_left_to_process; + }; + + apply_padding(bytes_left_to_process % 16, data); + process_block_checksum(data, checksum, &l); + process_block_hash(data, messageDigestBuf); process_block_hash(checksum, messageDigestBuf); - memcpy(out, messageDigestBuf, 16); - free(newBuf); + free(data); free(messageDigestBuf); free(checksum); }