diff --git a/.gitignore b/.gitignore deleted file mode 100644 index c795b05..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 420dda6..5a9a397 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,5 @@ { "recommendations": [ - "ms-vscode.cpptools", - "twxs.cmake" + "ms-vscode.cpptools" ] } \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..78b164e --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,29 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "cppdbg", + "request": "launch", + "name": "C/C++: gcc debug active file", + "program": "${workspaceFolder}/Implementierung/md2", + "args": [ + "${workspaceFolder}/Implementierung/testfile" + ], + "cwd": "${workspaceFolder}", + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "C/C++: gcc build active file", + "miDebuggerPath": "/usr/bin/gdb" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index fc00b84..57c9e18 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,8 +2,22 @@ "C_Cpp.clang_format_fallbackStyle": "Google", "files.associations": { "functional": "c", - "helper.h": "c" + "helper.h": "c", + "string": "c", + "vector": "c", + "memory": "c", + "optional": "c", + "string_view": "c", + "system_error": "c", + "variant": "c", + "array": "c", + "md2.h": "c", + "io.h": "c" }, "editor.formatOnSave": true, - "cmake.sourceDirectory": "${workspaceFolder}/Implementierung" -} + "C_Cpp.default.includePath": [ + "./lib", + "./Implementierung/lib", + "../lib" + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 08d9005..dde10c3 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -7,9 +7,9 @@ "args": [ "-fdiagnostics-color=always", "-g", - "${file}", + "${fileDirname}/*.c", "-o", - "${fileDirname}/${fileBasenameNoExtension}" + "${fileDirname}/../md2" ], "options": { "cwd": "${fileDirname}" diff --git a/Ausarbeitung/Ausarbeitung.pdf b/Ausarbeitung/Ausarbeitung.pdf new file mode 100644 index 0000000..09e0318 Binary files /dev/null and b/Ausarbeitung/Ausarbeitung.pdf differ diff --git a/Ausarbeitung/Ausarbeitung.tex b/Ausarbeitung/Ausarbeitung.tex index 0089c45..a07bb11 100644 --- a/Ausarbeitung/Ausarbeitung.tex +++ b/Ausarbeitung/Ausarbeitung.tex @@ -4,10 +4,10 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% TODO: Ersetzen Sie in den folgenden Zeilen die entsprechenden -Texte- %% mit den richtigen Werten. -\newcommand{\theGroup}{IhreGruppennummer} % Beispiel: 42 -\newcommand{\theNumber}{IhreProjektnummer} % Beispiel: A123 -\author{Vorname1 Nachname1 \and Vorname2 Nachname2 \and Vorname3 Nachname3} -\date{AktuellesSemester} % Beispiel: Wintersemester 2019/20 +\newcommand{\theGroup}{199} % Beispiel: 42 +\newcommand{\theNumber}{A505} % Beispiel: A123 +\author{Dorian Zedler \and Finn Dröge \and Thomas Florian} +\date{Sommersemester 2022} % Beispiel: Wintersemester 2019/20 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Diese Zeile bitte -nicht- aendern. diff --git a/Implementierung/.gitignore b/Implementierung/.gitignore index a811ad3..91f3d4d 100644 --- a/Implementierung/.gitignore +++ b/Implementierung/.gitignore @@ -1,5 +1,2 @@ -Makefile -cmake_install.cmake -CMakeCache.txt -md2 -CMakeFiles \ No newline at end of file +build +md2 \ No newline at end of file diff --git a/Implementierung/.gitkeep b/Implementierung/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/Implementierung/CMakeLists.txt b/Implementierung/CMakeLists.txt deleted file mode 100644 index e312b0e..0000000 --- a/Implementierung/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -cmake_minimum_required(VERSION 3.0.0) - -# here we specify that the project is C language only, so the default -# C compiler on the system will be used -project(md2 C) -add_executable(md2 "") - -set(SOURCE_FILES - src/main.c - src/helper.c - src/io.c - src/md2.c -) - -target_sources(md2 PRIVATE ${SOURCE_FILES}) - -target_include_directories(md2 PUBLIC - lib -) \ No newline at end of file diff --git a/Implementierung/Makefile b/Implementierung/Makefile new file mode 100644 index 0000000..3e24247 --- /dev/null +++ b/Implementierung/Makefile @@ -0,0 +1,32 @@ + + +SRC = src/main.c src/helper.c src/io.c src/md2.c +OBJ = ${subst src,build,${SRC:.c=.o}} +CC = gcc +CFLAGS = -Ilib -ggdb +LDFLAGS = + +all: md2 + +clean: + rm -rf md2 build + +help: + @echo === Project Build Help === + @echo + @echo Available targets: + @echo - all: build everything + @echo - clean: clean distfiles + @echo - help: show this help + +build: + mkdir build + +build/%.o: src/%.c + @mkdir -p build + ${CC} -c ${CFLAGS} -o $@ $< + +md2: ${OBJ} + ${CC} -o $@ $(OBJ) ${LDFLAGS} + +.PHONY: all clean help \ No newline at end of file diff --git a/Implementierung/lib/io.h b/Implementierung/lib/io.h index 2ed8134..f780a77 100644 --- a/Implementierung/lib/io.h +++ b/Implementierung/lib/io.h @@ -1,7 +1,10 @@ #ifndef IO_H #define IO_H +#define _XOPEN_SOURCE + #include +#include #include #include #include @@ -12,8 +15,8 @@ * * @param path the filepath * @param size a pointer where the size of the result should be stored - * @return the raw data + * @return pointer to the raw data or NULL on errors */ -static uint8_t* read_file(const char* path, size_t* size); +uint8_t* read_file(const char* path, size_t* size); #endif // IO_H \ No newline at end of file diff --git a/Implementierung/lib/md2.h b/Implementierung/lib/md2.h index 3880bb7..a692a12 100644 --- a/Implementierung/lib/md2.h +++ b/Implementierung/lib/md2.h @@ -2,6 +2,9 @@ #define MD2_H #include +#include +#include +#include #include /** @@ -22,4 +25,12 @@ void md2_hash(size_t len, const uint8_t buf[], uint8_t out[16]); */ void md2_checksum(size_t len, uint8_t* buf); +/** + * @brief Takes a uint8_t array and converts it into a string + * + * @param hash the array containing the hash + * @param stringHash pointer to store the string, has to have 32 bytes space + */ +void encodeHash(uint8_t hash[16], char* stringHash); + #endif // MD2_H \ No newline at end of file diff --git a/Implementierung/src/helper.c b/Implementierung/src/helper.c index fa3043b..f809aa5 100644 --- a/Implementierung/src/helper.c +++ b/Implementierung/src/helper.c @@ -1,4 +1,4 @@ -#include "helper.h" +#include "../lib/helper.h" int stringToInt(char *string) { char *leftover = ""; diff --git a/Implementierung/src/io.c b/Implementierung/src/io.c index ee415ce..dedb5ce 100644 --- a/Implementierung/src/io.c +++ b/Implementierung/src/io.c @@ -1,6 +1,6 @@ -#include "io.h" +#include "../lib/io.h" -static uint8_t* read_file(const char* path, size_t* size) { +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"); @@ -28,7 +28,7 @@ static uint8_t* read_file(const char* path, size_t* size) { size_t bytesRead = fread(data, statOfFile.st_blksize, statOfFile.st_blocks, f); - // Or: size_t bytesRead = fread(data, sizeof(char), statOfFile.st_size, f); + // size_t bytesRead = fread(data, sizeof(uint8_t), statOfFile.st_size, f); if (bytesRead != 0 && !feof(f)) { printf("Error reading file!\n"); fclose(f); @@ -37,6 +37,6 @@ static uint8_t* read_file(const char* path, size_t* size) { fclose(f); - (*size) = bytesRead; + (*size) = statOfFile.st_size; return data; } \ No newline at end of file diff --git a/Implementierung/src/main.c b/Implementierung/src/main.c index db1527a..811289d 100644 --- a/Implementierung/src/main.c +++ b/Implementierung/src/main.c @@ -1,6 +1,51 @@ -#include "helper.h" -#include "io.h" -#include "md2.h" +#include + +#include "../lib/helper.h" +#include "../lib/io.h" +#include "../lib/md2.h" + +// Returns true when val is approx. equal to exp. +static bool runTest(const char* message, const char* expectedHash) { + uint8_t out[16]; + md2_hash(strlen(message), message, out); + + char hash[32]; + encodeHash(out, hash); + + bool ok = !strcmp(hash, expectedHash); + printf("%s: md2(%s) %s == %s\n", "not ok" + (4 * ok), message, hash, + expectedHash); + return ok; +} + +unsigned runTests(void) { + unsigned failed = 0; + // Note: cases with n<2 are not tested here. + failed += !runTest("", "8350e5a3e24c153df2275c9f80692773"); + failed += !runTest("a", "32ec01ec4a6dac72c0ab96fb34c0b5d1"); + failed += !runTest("abc", "da853b0d3f88d99b30283a69e6ded6bb"); + failed += !runTest("message digest", "ab4f496bfb2a530b219ff33031fe06b0"); + failed += !runTest("jebdjcslfhwfdig", "e1b69085c6f6e36cb8fe8d98ed3f2c35"); + failed += !runTest("0123456789abcde", "d95629645108a20ab4d70e8545e0723b"); + failed += !runTest("0123456789abcdef", "12c8dfa285f14e1af8c5254e7092d0d3"); + failed += !runTest("0123456789abcdefg", "e4d0efded5ef7b6843a5ba47e1171347"); + failed += !runTest("abcdefghijklmnopqrstuvwxyz", + "4e8ddff3650292ab5a4108c3aa47940b"); + failed += + !runTest("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "da33def2a42df13975352846c30338cd"); + failed += !runTest( + "123456789012345678901234567890123456789012345678901234567890123456789012" + "34567890", + "d5976f79d83d3a0dc9806c3c66f3efd8"); + + if (failed) + printf("%u tests FAILED\n", failed); + else + printf("All tests PASSED\n"); + + return failed; +} int main(int argc, char** argv) { struct configuration c; @@ -20,5 +65,26 @@ int main(int argc, char** argv) { "benchmark cycles: %d\n", c.filename, c.implementationToUse, c.doBenchmark, c.benchmarkingCycles); + // runTests(); + size_t len; + uint8_t* data = read_file(c.filename, &len); + if (data == NULL) { + printf("Error reading file %s!", c.filename); + return EXIT_FAILURE; + } + + printf("File read with size: %zu\n", len); + printf("\n"); + + uint8_t out[16]; + md2_hash(len, data, out); + + printf("Hash: "); + char hash[32]; + encodeHash(out, hash); + printf("%s\n", hash); + + free(data); + return 0; } diff --git a/Implementierung/src/md2.c b/Implementierung/src/md2.c index 1f30e8d..fcb11b8 100644 --- a/Implementierung/src/md2.c +++ b/Implementierung/src/md2.c @@ -1,8 +1,107 @@ -#include "io.h" +#include "../lib/md2.h" // The file "testfile" should lead to this hash: // fc982e558db259f298b43cd4c1241c66 -void md2_checksum(size_t len, uint8_t* buf) {} +// Source: https://datatracker.ietf.org/doc/html/rfc1319 +static unsigned char PI_SUBST[256] = { + 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, + 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 76, + 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 138, + 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 245, 142, + 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, 148, 194, 16, + 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, 39, 53, 62, + 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, 181, 209, 215, + 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, 150, 164, 125, 182, + 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, 112, 89, 100, 113, 135, + 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, 96, 37, 173, 174, 176, + 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, 85, 71, 163, 35, 221, + 81, 175, 58, 195, 92, 249, 206, 186, 197, 234, 38, 44, 83, 13, 110, + 133, 40, 132, 9, 211, 223, 205, 244, 65, 129, 77, 82, 106, 220, 55, + 200, 108, 193, 171, 250, 36, 225, 123, 8, 12, 189, 177, 74, 120, 136, + 149, 139, 227, 99, 232, 109, 233, 203, 213, 254, 59, 0, 29, 57, 242, + 239, 183, 14, 102, 88, 208, 228, 166, 119, 114, 248, 235, 117, 75, 10, + 49, 68, 80, 180, 143, 237, 31, 26, 219, 153, 141, 51, 159, 17, 131, + 20}; -void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) {} \ No newline at end of file +void printBuf(size_t len, uint8_t buf[len]) { + for (int i = 0; i < len; i++) { + printf("'%02x',", buf[i]); + } + printf("\n"); +} + +void md2_checksum(size_t len, uint8_t* buf) { + uint8_t l = 0; + + for (int i = 0; i < len / 16; i++) { + for (int j = 0; j < 16; j++) { + u_int8_t c = buf[i * 16 + j]; + // reference is wrong. It says: Set C[j] to S[c xor L]. But it should be: + l = buf[len + j] ^= PI_SUBST[c ^ l]; + } + } +} + +void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { + // === step 1 === + 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 + 16, sizeof(uint8_t)); + memcpy(newBuf, buf, len - paddingNeeded); + + // printBuf(len + 16, newBuf); + + while (paddingNeeded > 0) { + newBuf[len - paddingNeeded] = originalPadding; + paddingNeeded--; + } + // printf("buf with padding: "); + // printBuf(len + 16, newBuf); + + // === step 2 === + md2_checksum(len, newBuf); + + // printf("buf with cecksum: "); + // printBuf(len + 16, newBuf); + + // === step 3 === + uint8_t* messageDigestBuf = calloc(48, sizeof(uint8_t)); + + // === step 4 === + // <= because we need to hash the last block too + for (int i = 0; i <= (len + 16) / 16 - 1; i++) { + for (int j = 0; j < 16; j++) { + messageDigestBuf[16 + j] = newBuf[i * 16 + j]; + messageDigestBuf[32 + j] = + (messageDigestBuf[16 + j] ^ messageDigestBuf[j]); + } + + u_int8_t t = 0; + + for (int j = 0; j < 18; j++) { + for (int k = 0; k < 48; k++) { + t = messageDigestBuf[k] = messageDigestBuf[k] ^ PI_SUBST[t]; + } + t = (t + j) % 256; + } + } + // printf("messageDigestBuf: \n"); + // printBuf(16, messageDigestBuf); + + memcpy(out, messageDigestBuf, 16); + + free(messageDigestBuf); + free(newBuf); +} + +void encodeHash(uint8_t hash[16], char* stringHash) { + for (int i = 0; i < 16; i++) { + sprintf(stringHash + (2 * i), "%02x", hash[i]); + } +} \ No newline at end of file