From 60b46c9687313d5361992412446e963d497aaa31 Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Wed, 29 Jun 2022 11:40:12 +0200 Subject: [PATCH 01/15] Chore add makefile --- Implementierung/.gitignore | 1 - Implementierung/Makefile | 262 +++++++++++++++++++++++++++++++++++++ 2 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 Implementierung/Makefile diff --git a/Implementierung/.gitignore b/Implementierung/.gitignore index a811ad3..a8b5368 100644 --- a/Implementierung/.gitignore +++ b/Implementierung/.gitignore @@ -1,4 +1,3 @@ -Makefile cmake_install.cmake CMakeCache.txt md2 diff --git a/Implementierung/Makefile b/Implementierung/Makefile new file mode 100644 index 0000000..76e6023 --- /dev/null +++ b/Implementierung/Makefile @@ -0,0 +1,262 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.23 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +# Allow only one "make -f Makefile2" at a time, but pass parallelism. +.NOTPARALLEL: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/dorian/Documents/git/UNI/era/team199/Implementierung + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/dorian/Documents/git/UNI/era/team199/Implementierung + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..." + /usr/bin/ccmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# The main all target +all: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/dorian/Documents/git/UNI/era/team199/Implementierung/CMakeFiles /home/dorian/Documents/git/UNI/era/team199/Implementierung//CMakeFiles/progress.marks + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all + $(CMAKE_COMMAND) -E cmake_progress_start /home/dorian/Documents/git/UNI/era/team199/Implementierung/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +#============================================================================= +# Target rules for targets named md2 + +# Build rule for target. +md2: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 md2 +.PHONY : md2 + +# fast build rule for target. +md2/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/build +.PHONY : md2/fast + +src/helper.o: src/helper.c.o +.PHONY : src/helper.o + +# target to build an object file +src/helper.c.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/helper.c.o +.PHONY : src/helper.c.o + +src/helper.i: src/helper.c.i +.PHONY : src/helper.i + +# target to preprocess a source file +src/helper.c.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/helper.c.i +.PHONY : src/helper.c.i + +src/helper.s: src/helper.c.s +.PHONY : src/helper.s + +# target to generate assembly for a file +src/helper.c.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/helper.c.s +.PHONY : src/helper.c.s + +src/io.o: src/io.c.o +.PHONY : src/io.o + +# target to build an object file +src/io.c.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/io.c.o +.PHONY : src/io.c.o + +src/io.i: src/io.c.i +.PHONY : src/io.i + +# target to preprocess a source file +src/io.c.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/io.c.i +.PHONY : src/io.c.i + +src/io.s: src/io.c.s +.PHONY : src/io.s + +# target to generate assembly for a file +src/io.c.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/io.c.s +.PHONY : src/io.c.s + +src/main.o: src/main.c.o +.PHONY : src/main.o + +# target to build an object file +src/main.c.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/main.c.o +.PHONY : src/main.c.o + +src/main.i: src/main.c.i +.PHONY : src/main.i + +# target to preprocess a source file +src/main.c.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/main.c.i +.PHONY : src/main.c.i + +src/main.s: src/main.c.s +.PHONY : src/main.s + +# target to generate assembly for a file +src/main.c.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/main.c.s +.PHONY : src/main.c.s + +src/md2.o: src/md2.c.o +.PHONY : src/md2.o + +# target to build an object file +src/md2.c.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/md2.c.o +.PHONY : src/md2.c.o + +src/md2.i: src/md2.c.i +.PHONY : src/md2.i + +# target to preprocess a source file +src/md2.c.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/md2.c.i +.PHONY : src/md2.c.i + +src/md2.s: src/md2.c.s +.PHONY : src/md2.s + +# target to generate assembly for a file +src/md2.c.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/md2.c.s +.PHONY : src/md2.c.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... rebuild_cache" + @echo "... md2" + @echo "... src/helper.o" + @echo "... src/helper.i" + @echo "... src/helper.s" + @echo "... src/io.o" + @echo "... src/io.i" + @echo "... src/io.s" + @echo "... src/main.o" + @echo "... src/main.i" + @echo "... src/main.s" + @echo "... src/md2.o" + @echo "... src/md2.i" + @echo "... src/md2.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + From e1623f8f29a29008d67183b537ab6d329e7581e9 Mon Sep 17 00:00:00 2001 From: Thomas Florian Date: Wed, 29 Jun 2022 12:37:45 +0200 Subject: [PATCH 02/15] feat: init Ausarbeitung --- Ausarbeitung/Ausarbeitung.pdf | Bin 0 -> 67759 bytes Ausarbeitung/Ausarbeitung.tex | 8 ++++---- 2 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 Ausarbeitung/Ausarbeitung.pdf diff --git a/Ausarbeitung/Ausarbeitung.pdf b/Ausarbeitung/Ausarbeitung.pdf new file mode 100644 index 0000000000000000000000000000000000000000..09e03186994e56ccb4d0598d8c2df378ce57f271 GIT binary patch literal 67759 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 yPy<0hmewT6em}J*U| Date: Wed, 29 Jun 2022 14:47:58 +0200 Subject: [PATCH 03/15] Chore: don't use cmake --- .gitignore | 1 - .vscode/extensions.json | 3 +- .vscode/settings.json | 1 - Implementierung/.gitignore | 6 +- Implementierung/.gitkeep | 0 Implementierung/CMakeLists.txt | 19 --- Implementierung/Makefile | 272 +++------------------------------ 7 files changed, 24 insertions(+), 278 deletions(-) delete mode 100644 .gitignore delete mode 100644 Implementierung/.gitkeep delete mode 100644 Implementierung/CMakeLists.txt 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/settings.json b/.vscode/settings.json index fc00b84..f97fffe 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,4 @@ "helper.h": "c" }, "editor.formatOnSave": true, - "cmake.sourceDirectory": "${workspaceFolder}/Implementierung" } diff --git a/Implementierung/.gitignore b/Implementierung/.gitignore index a8b5368..91f3d4d 100644 --- a/Implementierung/.gitignore +++ b/Implementierung/.gitignore @@ -1,4 +1,2 @@ -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 index 76e6023..9283a29 100644 --- a/Implementierung/Makefile +++ b/Implementierung/Makefile @@ -1,262 +1,32 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 3.23 -# Default target executed when no arguments are given to make. -default_target: all -.PHONY : default_target -# Allow only one "make -f Makefile2" at a time, but pass parallelism. -.NOTPARALLEL: +SRC = src/main.c src/helper.c src/io.c src/md2.c +OBJ = ${subst src,build,${SRC:.c=.o}} +CC = gcc +CFLAGS = -Ilib +LDFLAGS = -#============================================================================= -# Special targets provided by cmake. +all: md2 -# Disable implicit rules so canonical targets will work. -.SUFFIXES: - -# Disable VCS-based implicit rules. -% : %,v - -# Disable VCS-based implicit rules. -% : RCS/% - -# Disable VCS-based implicit rules. -% : RCS/%,v - -# Disable VCS-based implicit rules. -% : SCCS/s.% - -# Disable VCS-based implicit rules. -% : s.% - -.SUFFIXES: .hpux_make_needs_suffix_list - -# Command-line flag to silence nested $(MAKE). -$(VERBOSE)MAKESILENT = -s - -#Suppress display of executed commands. -$(VERBOSE).SILENT: - -# A target that is always out of date. -cmake_force: -.PHONY : cmake_force - -#============================================================================= -# Set environment variables for the build. - -# The shell in which to execute make rules. -SHELL = /bin/sh - -# The CMake executable. -CMAKE_COMMAND = /usr/bin/cmake - -# The command to remove a file. -RM = /usr/bin/cmake -E rm -f - -# Escaping for special characters. -EQUALS = = - -# The top-level source directory on which CMake was run. -CMAKE_SOURCE_DIR = /home/dorian/Documents/git/UNI/era/team199/Implementierung - -# The top-level build directory on which CMake was run. -CMAKE_BINARY_DIR = /home/dorian/Documents/git/UNI/era/team199/Implementierung - -#============================================================================= -# Targets provided globally by CMake. - -# Special rule for the target edit_cache -edit_cache: - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..." - /usr/bin/ccmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) -.PHONY : edit_cache - -# Special rule for the target edit_cache -edit_cache/fast: edit_cache -.PHONY : edit_cache/fast - -# Special rule for the target rebuild_cache -rebuild_cache: - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." - /usr/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) -.PHONY : rebuild_cache - -# Special rule for the target rebuild_cache -rebuild_cache/fast: rebuild_cache -.PHONY : rebuild_cache/fast - -# The main all target -all: cmake_check_build_system - $(CMAKE_COMMAND) -E cmake_progress_start /home/dorian/Documents/git/UNI/era/team199/Implementierung/CMakeFiles /home/dorian/Documents/git/UNI/era/team199/Implementierung//CMakeFiles/progress.marks - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all - $(CMAKE_COMMAND) -E cmake_progress_start /home/dorian/Documents/git/UNI/era/team199/Implementierung/CMakeFiles 0 -.PHONY : all - -# The main clean target clean: - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 clean -.PHONY : clean + rm -f md2 $(OBJ) -# The main clean target -clean/fast: clean -.PHONY : clean/fast - -# Prepare targets for installation. -preinstall: all - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall -.PHONY : preinstall - -# Prepare targets for installation. -preinstall/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall -.PHONY : preinstall/fast - -# clear depends -depend: - $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 -.PHONY : depend - -#============================================================================= -# Target rules for targets named md2 - -# Build rule for target. -md2: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 md2 -.PHONY : md2 - -# fast build rule for target. -md2/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/build -.PHONY : md2/fast - -src/helper.o: src/helper.c.o -.PHONY : src/helper.o - -# target to build an object file -src/helper.c.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/helper.c.o -.PHONY : src/helper.c.o - -src/helper.i: src/helper.c.i -.PHONY : src/helper.i - -# target to preprocess a source file -src/helper.c.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/helper.c.i -.PHONY : src/helper.c.i - -src/helper.s: src/helper.c.s -.PHONY : src/helper.s - -# target to generate assembly for a file -src/helper.c.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/helper.c.s -.PHONY : src/helper.c.s - -src/io.o: src/io.c.o -.PHONY : src/io.o - -# target to build an object file -src/io.c.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/io.c.o -.PHONY : src/io.c.o - -src/io.i: src/io.c.i -.PHONY : src/io.i - -# target to preprocess a source file -src/io.c.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/io.c.i -.PHONY : src/io.c.i - -src/io.s: src/io.c.s -.PHONY : src/io.s - -# target to generate assembly for a file -src/io.c.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/io.c.s -.PHONY : src/io.c.s - -src/main.o: src/main.c.o -.PHONY : src/main.o - -# target to build an object file -src/main.c.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/main.c.o -.PHONY : src/main.c.o - -src/main.i: src/main.c.i -.PHONY : src/main.i - -# target to preprocess a source file -src/main.c.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/main.c.i -.PHONY : src/main.c.i - -src/main.s: src/main.c.s -.PHONY : src/main.s - -# target to generate assembly for a file -src/main.c.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/main.c.s -.PHONY : src/main.c.s - -src/md2.o: src/md2.c.o -.PHONY : src/md2.o - -# target to build an object file -src/md2.c.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/md2.c.o -.PHONY : src/md2.c.o - -src/md2.i: src/md2.c.i -.PHONY : src/md2.i - -# target to preprocess a source file -src/md2.c.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/md2.c.i -.PHONY : src/md2.c.i - -src/md2.s: src/md2.c.s -.PHONY : src/md2.s - -# target to generate assembly for a file -src/md2.c.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/md2.dir/build.make CMakeFiles/md2.dir/src/md2.c.s -.PHONY : src/md2.c.s - -# Help Target help: - @echo "The following are some of the valid targets for this Makefile:" - @echo "... all (the default if no target is provided)" - @echo "... clean" - @echo "... depend" - @echo "... edit_cache" - @echo "... rebuild_cache" - @echo "... md2" - @echo "... src/helper.o" - @echo "... src/helper.i" - @echo "... src/helper.s" - @echo "... src/io.o" - @echo "... src/io.i" - @echo "... src/io.s" - @echo "... src/main.o" - @echo "... src/main.i" - @echo "... src/main.s" - @echo "... src/md2.o" - @echo "... src/md2.i" - @echo "... src/md2.s" -.PHONY : 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 $@ $< -#============================================================================= -# Special targets to cleanup operation of make. - -# Special rule to run CMake to check the build system integrity. -# No rule that depends on this can have commands that come from listfiles -# because they might be regenerated. -cmake_check_build_system: - $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 -.PHONY : cmake_check_build_system +md2: ${OBJ} + ${CC} -o $@ $(OBJ) ${LDFLAGS} +.PHONY: all clean help \ No newline at end of file From eeb416461003d7f707f0f9c4d127bdd22f64b3f6 Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Wed, 29 Jun 2022 15:41:56 +0200 Subject: [PATCH 04/15] Feat: Step1 padding --- Implementierung/lib/md2.h | 3 +++ Implementierung/src/main.c | 3 +++ Implementierung/src/md2.c | 31 +++++++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/Implementierung/lib/md2.h b/Implementierung/lib/md2.h index 3880bb7..2fb47f7 100644 --- a/Implementierung/lib/md2.h +++ b/Implementierung/lib/md2.h @@ -2,6 +2,9 @@ #define MD2_H #include +#include +#include +#include #include /** diff --git a/Implementierung/src/main.c b/Implementierung/src/main.c index db1527a..dac7b80 100644 --- a/Implementierung/src/main.c +++ b/Implementierung/src/main.c @@ -20,5 +20,8 @@ int main(int argc, char** argv) { "benchmark cycles: %d\n", c.filename, c.implementationToUse, c.doBenchmark, c.benchmarkingCycles); + uint8_t out[16]; + md2_hash(3, "abc", out); + return 0; } diff --git a/Implementierung/src/md2.c b/Implementierung/src/md2.c index 1f30e8d..1bcc23a 100644 --- a/Implementierung/src/md2.c +++ b/Implementierung/src/md2.c @@ -1,8 +1,35 @@ -#include "io.h" +#include "../lib/md2.h" // The file "testfile" should lead to this hash: // fc982e558db259f298b43cd4c1241c66 +void printBuf(size_t len, uint8_t buf[len]) { + for (int i = 0; i < len; i++) { + printf("'%lx',", buf[i]); + } + printf("\n"); +} + void md2_checksum(size_t len, uint8_t* buf) {} -void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) {} \ No newline at end of file +void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { + // add padding + int paddingNeeded = 16 - (len % 16); + uint8_t originalPadding = paddingNeeded; + len += paddingNeeded; + + printf("len: %d\n", len); + + uint8_t* newBuf = malloc(len); + memcpy(newBuf, buf, len - paddingNeeded); + newBuf[4] = 'f'; + + while (paddingNeeded > 0) { + newBuf[len - paddingNeeded] = originalPadding; + paddingNeeded--; + } + + printBuf(len, newBuf); + + free(newBuf); +} \ No newline at end of file From 3940ee3a21d1cdf289cafdeb1c92dd35cd10e097 Mon Sep 17 00:00:00 2001 From: Thomas Florian Date: Wed, 29 Jun 2022 15:53:46 +0200 Subject: [PATCH 05/15] feat: implement step 2: checksum --- Implementierung/src/md2.c | 40 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/Implementierung/src/md2.c b/Implementierung/src/md2.c index 1bcc23a..1b3e0a3 100644 --- a/Implementierung/src/md2.c +++ b/Implementierung/src/md2.c @@ -3,6 +3,27 @@ // The file "testfile" should lead to this hash: // fc982e558db259f298b43cd4c1241c66 +// 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 printBuf(size_t len, uint8_t buf[len]) { for (int i = 0; i < len; i++) { printf("'%lx',", buf[i]); @@ -10,7 +31,17 @@ void printBuf(size_t len, uint8_t buf[len]) { printf("\n"); } -void md2_checksum(size_t len, uint8_t* buf) {} +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]; + buf[len + j] = PI_SUBST[c ^ l]; + l = buf[len + j]; + } + } +} void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { // add padding @@ -20,7 +51,7 @@ void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { printf("len: %d\n", len); - uint8_t* newBuf = malloc(len); + uint8_t* newBuf = malloc(len + 16); // 16 = Checksum memcpy(newBuf, buf, len - paddingNeeded); newBuf[4] = 'f'; @@ -28,8 +59,11 @@ void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { newBuf[len - paddingNeeded] = originalPadding; paddingNeeded--; } - printBuf(len, newBuf); + md2_checksum(len, newBuf); + + printBuf(len + 16, newBuf); + free(newBuf); } \ No newline at end of file From 76a685d1b7f63b9c3afeb935c0574d5ef7a4ed28 Mon Sep 17 00:00:00 2001 From: Thomas Florian Date: Wed, 29 Jun 2022 16:07:05 +0200 Subject: [PATCH 06/15] feat: implement step 3 & 4 --- Implementierung/src/md2.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Implementierung/src/md2.c b/Implementierung/src/md2.c index 1b3e0a3..bd21615 100644 --- a/Implementierung/src/md2.c +++ b/Implementierung/src/md2.c @@ -51,7 +51,7 @@ void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { printf("len: %d\n", len); - uint8_t* newBuf = malloc(len + 16); // 16 = Checksum + uint8_t* newBuf = calloc(len + 16, sizeof(uint8_t)); // +16 = Checksum memcpy(newBuf, buf, len - paddingNeeded); newBuf[4] = 'f'; @@ -65,5 +65,28 @@ void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { printBuf(len + 16, newBuf); + // implement step 3 + u_int8_t messageDigestBuf = calloc(48, sizeof(uint8_t)); + + for (int i = 0; i <= len / 16; i++) { // <= because we need to hash the last block too + for (int j = 0; j < 16; j++) { + messageDigestBuf[16 + j] = newBuf[i * 16 + j]; + messageDigestBuf[32 + j] = (newBuf[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); + + + free(messageDigestBuf); free(newBuf); } \ No newline at end of file From 0d3771c7192ffc76fe915f434cad49efd1d92c8c Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Wed, 29 Jun 2022 16:12:09 +0200 Subject: [PATCH 07/15] Feat: implement 5 --- Implementierung/src/main.c | 8 +++++++- Implementierung/src/md2.c | 42 ++++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/Implementierung/src/main.c b/Implementierung/src/main.c index dac7b80..1db108d 100644 --- a/Implementierung/src/main.c +++ b/Implementierung/src/main.c @@ -21,7 +21,13 @@ int main(int argc, char** argv) { c.filename, c.implementationToUse, c.doBenchmark, c.benchmarkingCycles); uint8_t out[16]; - md2_hash(3, "abc", out); + md2_hash(0, "", out); + + printf("Hash: "); + for (int i = 0; i < 16; i++) { + printf("%02x", out[i]); + } + printf("\n"); return 0; } diff --git a/Implementierung/src/md2.c b/Implementierung/src/md2.c index bd21615..dc74837 100644 --- a/Implementierung/src/md2.c +++ b/Implementierung/src/md2.c @@ -5,24 +5,24 @@ // 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}; + 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 printBuf(size_t len, uint8_t buf[len]) { for (int i = 0; i < len; i++) { @@ -66,9 +66,10 @@ void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { printBuf(len + 16, newBuf); // implement step 3 - u_int8_t messageDigestBuf = calloc(48, sizeof(uint8_t)); + u_int8_t* messageDigestBuf = calloc(48, sizeof(uint8_t)); - for (int i = 0; i <= len / 16; i++) { // <= because we need to hash the last block too + for (int i = 0; i <= len / 16; + i++) { // <= because we need to hash the last block too for (int j = 0; j < 16; j++) { messageDigestBuf[16 + j] = newBuf[i * 16 + j]; messageDigestBuf[32 + j] = (newBuf[16 + j] ^ messageDigestBuf[j]); @@ -86,6 +87,7 @@ void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { printf("messageDigestBuf: \n"); printBuf(16, messageDigestBuf); + memcpy(out, messageDigestBuf, 16); free(messageDigestBuf); free(newBuf); From 9194475153c0916f00e89e3892aed5fab243a3a5 Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Wed, 29 Jun 2022 18:29:26 +0200 Subject: [PATCH 08/15] fix: everything --- Implementierung/src/main.c | 2 +- Implementierung/src/md2.c | 34 +++++++++++++++++++--------------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/Implementierung/src/main.c b/Implementierung/src/main.c index 1db108d..3f458a3 100644 --- a/Implementierung/src/main.c +++ b/Implementierung/src/main.c @@ -21,7 +21,7 @@ int main(int argc, char** argv) { c.filename, c.implementationToUse, c.doBenchmark, c.benchmarkingCycles); uint8_t out[16]; - md2_hash(0, "", out); + md2_hash(3, "abc", out); printf("Hash: "); for (int i = 0; i < 16; i++) { diff --git a/Implementierung/src/md2.c b/Implementierung/src/md2.c index dc74837..f0ac6bf 100644 --- a/Implementierung/src/md2.c +++ b/Implementierung/src/md2.c @@ -26,7 +26,7 @@ static unsigned char PI_SUBST[256] = { void printBuf(size_t len, uint8_t buf[len]) { for (int i = 0; i < len; i++) { - printf("'%lx',", buf[i]); + printf("'%02x',", buf[i]); } printf("\n"); } @@ -37,42 +37,46 @@ void md2_checksum(size_t len, uint8_t* buf) { for (int i = 0; i < len / 16; i++) { for (int j = 0; j < 16; j++) { u_int8_t c = buf[i * 16 + j]; - buf[len + j] = PI_SUBST[c ^ l]; - l = buf[len + j]; + l = buf[len + j] = PI_SUBST[c ^ l]; } } } void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { - // add padding + // === step 1 === int paddingNeeded = 16 - (len % 16); uint8_t originalPadding = paddingNeeded; len += paddingNeeded; printf("len: %d\n", len); - uint8_t* newBuf = calloc(len + 16, sizeof(uint8_t)); // +16 = Checksum + // +16 for the checksum + uint8_t* newBuf = calloc(len + 16, sizeof(uint8_t)); memcpy(newBuf, buf, len - paddingNeeded); - newBuf[4] = 'f'; while (paddingNeeded > 0) { newBuf[len - paddingNeeded] = originalPadding; paddingNeeded--; } - printBuf(len, newBuf); - - md2_checksum(len, newBuf); - + printf("buf with padding: "); printBuf(len + 16, newBuf); - // implement step 3 - u_int8_t* messageDigestBuf = calloc(48, sizeof(uint8_t)); + // === step 2 === + md2_checksum(len, newBuf); - for (int i = 0; i <= len / 16; - i++) { // <= because we need to hash the last block too + 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] = (newBuf[16 + j] ^ messageDigestBuf[j]); + messageDigestBuf[32 + j] = + (messageDigestBuf[16 + j] ^ messageDigestBuf[j]); } u_int8_t t = 0; From 331ed1750ff6d306ce0405b3422168d21d24c3b6 Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Wed, 29 Jun 2022 19:03:12 +0200 Subject: [PATCH 09/15] Feat: Add tests --- .vscode/settings.json | 11 +++++-- Implementierung/lib/io.h | 2 +- Implementierung/lib/md2.h | 2 ++ Implementierung/src/io.c | 2 +- Implementierung/src/main.c | 60 ++++++++++++++++++++++++++++++++++---- Implementierung/src/md2.c | 20 ++++++++----- 6 files changed, 81 insertions(+), 16 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index f97fffe..fcad2d4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,14 @@ "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" }, - "editor.formatOnSave": true, + "editor.formatOnSave": true } diff --git a/Implementierung/lib/io.h b/Implementierung/lib/io.h index 2ed8134..80cfcda 100644 --- a/Implementierung/lib/io.h +++ b/Implementierung/lib/io.h @@ -14,6 +14,6 @@ * @param size a pointer where the size of the result should be stored * @return the raw data */ -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 2fb47f7..5fd07d3 100644 --- a/Implementierung/lib/md2.h +++ b/Implementierung/lib/md2.h @@ -25,4 +25,6 @@ void md2_hash(size_t len, const uint8_t buf[], uint8_t out[16]); */ void md2_checksum(size_t len, uint8_t* buf); +void encodeHash(uint8_t hash[16], char* stringHash); + #endif // MD2_H \ No newline at end of file diff --git a/Implementierung/src/io.c b/Implementierung/src/io.c index ee415ce..83d1ba6 100644 --- a/Implementierung/src/io.c +++ b/Implementierung/src/io.c @@ -1,6 +1,6 @@ #include "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"); diff --git a/Implementierung/src/main.c b/Implementierung/src/main.c index 3f458a3..bdfb3d8 100644 --- a/Implementierung/src/main.c +++ b/Implementierung/src/main.c @@ -1,7 +1,52 @@ +#include + #include "helper.h" #include "io.h" #include "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; enum argumentParseResult result = parseArguments(argc, argv, &c); @@ -20,14 +65,19 @@ 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); + uint8_t out[16]; - md2_hash(3, "abc", out); + const char* test = "abcdefghijklmnopqrstuvwxyz"; + len = strlen(test); + md2_hash(len, test, out); printf("Hash: "); - for (int i = 0; i < 16; i++) { - printf("%02x", out[i]); - } - printf("\n"); + const char hash[16]; + encodeHash(out, &hash); + printf("%s\n", hash);*/ return 0; } diff --git a/Implementierung/src/md2.c b/Implementierung/src/md2.c index f0ac6bf..03e0b79 100644 --- a/Implementierung/src/md2.c +++ b/Implementierung/src/md2.c @@ -48,7 +48,7 @@ void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { uint8_t originalPadding = paddingNeeded; len += paddingNeeded; - printf("len: %d\n", len); + // printf("len: %d\n", len); // +16 for the checksum uint8_t* newBuf = calloc(len + 16, sizeof(uint8_t)); @@ -58,14 +58,14 @@ void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { newBuf[len - paddingNeeded] = originalPadding; paddingNeeded--; } - printf("buf with padding: "); - printBuf(len + 16, newBuf); + // printf("buf with padding: "); + // printBuf(len + 16, newBuf); // === step 2 === md2_checksum(len, newBuf); - printf("buf with cecksum: "); - printBuf(len + 16, newBuf); + // printf("buf with cecksum: "); + // printBuf(len + 16, newBuf); // === step 3 === uint8_t* messageDigestBuf = calloc(48, sizeof(uint8_t)); @@ -88,11 +88,17 @@ void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { t = (t + j) % 256; } } - printf("messageDigestBuf: \n"); - printBuf(16, messageDigestBuf); + // 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 From 9133601088f5fe10923178677287644f66fa78f3 Mon Sep 17 00:00:00 2001 From: Thomas Florian Date: Wed, 29 Jun 2022 19:10:43 +0200 Subject: [PATCH 10/15] fix: error in reference --- Implementierung/src/md2.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/Implementierung/src/md2.c b/Implementierung/src/md2.c index 03e0b79..04b3764 100644 --- a/Implementierung/src/md2.c +++ b/Implementierung/src/md2.c @@ -5,23 +5,23 @@ // 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, + 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 printBuf(size_t len, uint8_t buf[len]) { @@ -37,7 +37,8 @@ void md2_checksum(size_t len, uint8_t* buf) { for (int i = 0; i < len / 16; i++) { for (int j = 0; j < 16; j++) { u_int8_t c = buf[i * 16 + j]; - l = buf[len + j] = PI_SUBST[c ^ l]; + // 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]; } } } @@ -54,6 +55,8 @@ void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { 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--; From 9f91eb39625e1e87fb026bff81a1029f3377b144 Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Wed, 29 Jun 2022 20:54:41 +0200 Subject: [PATCH 11/15] Fix: File reading --- .vscode/settings.json | 3 ++- Implementierung/lib/io.h | 4 +++- Implementierung/src/io.c | 20 ++++++++++---------- Implementierung/src/main.c | 22 +++++++++++++--------- Implementierung/src/md2.c | 36 ++++++++++++++++++------------------ 5 files changed, 46 insertions(+), 39 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index fcad2d4..e8e7420 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,7 +9,8 @@ "optional": "c", "string_view": "c", "system_error": "c", - "variant": "c" + "variant": "c", + "array": "c" }, "editor.formatOnSave": true } diff --git a/Implementierung/lib/io.h b/Implementierung/lib/io.h index 80cfcda..da5e511 100644 --- a/Implementierung/lib/io.h +++ b/Implementierung/lib/io.h @@ -2,6 +2,7 @@ #define IO_H #include +#include #include #include #include @@ -11,9 +12,10 @@ * @brief reads a file at a path * * @param path the filepath + * @param data where to store the pointer to the data * @param size a pointer where the size of the result should be stored * @return the raw data */ -uint8_t* read_file(const char* path, size_t* size); +bool read_file(const char* path, uint8_t** data, size_t* size); #endif // IO_H \ No newline at end of file diff --git a/Implementierung/src/io.c b/Implementierung/src/io.c index 83d1ba6..f289907 100644 --- a/Implementierung/src/io.c +++ b/Implementierung/src/io.c @@ -1,13 +1,13 @@ #include "io.h" -uint8_t* read_file(const char* path, size_t* size) { +bool read_file(const char* path, uint8_t** data, 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; + return false; } struct stat statOfFile; @@ -15,28 +15,28 @@ uint8_t* read_file(const char* path, size_t* size) { if (status == -1) { printf("Fstat error: %d\n", errno); fclose(f); - return NULL; + return false; }; if ((statOfFile.st_mode & S_IFMT) != S_IFREG) { printf("File is not a regular file!\n"); fclose(f); - return NULL; + return false; } - uint8_t* data = malloc(statOfFile.st_size); + (*data) = malloc(statOfFile.st_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); + fread((*data), statOfFile.st_blksize, statOfFile.st_blocks, 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); - return NULL; + return false; } fclose(f); - (*size) = bytesRead; - return data; + (*size) = statOfFile.st_size; + return true; } \ No newline at end of file diff --git a/Implementierung/src/main.c b/Implementierung/src/main.c index bdfb3d8..5193421 100644 --- a/Implementierung/src/main.c +++ b/Implementierung/src/main.c @@ -65,19 +65,23 @@ 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); + // runTests(); + size_t len; + uint8_t* data; + if (!read_file(c.filename, &data, &len)) { + printf("Error reading file %s!", c.filename); + return EXIT_FAILURE; + } + printf("File read with size: %zu\n", len); + printf("\n"); uint8_t out[16]; - const char* test = "abcdefghijklmnopqrstuvwxyz"; - len = strlen(test); - md2_hash(len, test, out); + md2_hash(len, data, out); printf("Hash: "); - const char hash[16]; - encodeHash(out, &hash); - printf("%s\n", hash);*/ + char hash[16]; + encodeHash(out, hash); + printf("%s\n", hash); return 0; } diff --git a/Implementierung/src/md2.c b/Implementierung/src/md2.c index 04b3764..fcb11b8 100644 --- a/Implementierung/src/md2.c +++ b/Implementierung/src/md2.c @@ -5,23 +5,23 @@ // 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, + 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 printBuf(size_t len, uint8_t buf[len]) { @@ -55,7 +55,7 @@ void md2_hash(size_t len, const uint8_t buf[len], uint8_t out[16]) { uint8_t* newBuf = calloc(len + 16, sizeof(uint8_t)); memcpy(newBuf, buf, len - paddingNeeded); - printBuf(len + 16, newBuf); + // printBuf(len + 16, newBuf); while (paddingNeeded > 0) { newBuf[len - paddingNeeded] = originalPadding; From 387e7aad348a37a3048118a179ed7e88e19cb36e Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Wed, 29 Jun 2022 21:29:15 +0200 Subject: [PATCH 12/15] Chore: Configure debugging in vscode --- .vscode/launch.json | 29 +++++++++++++++++++++++++++++ .vscode/settings.json | 13 ++++++++++--- .vscode/tasks.json | 4 ++-- Implementierung/Makefile | 2 +- Implementierung/lib/io.h | 2 ++ Implementierung/src/helper.c | 2 +- Implementierung/src/io.c | 2 +- Implementierung/src/main.c | 6 +++--- 8 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 .vscode/launch.json 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 e8e7420..57c9e18 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,14 @@ "string_view": "c", "system_error": "c", "variant": "c", - "array": "c" + "array": "c", + "md2.h": "c", + "io.h": "c" }, - "editor.formatOnSave": true -} + "editor.formatOnSave": true, + "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/Implementierung/Makefile b/Implementierung/Makefile index 9283a29..d678b32 100644 --- a/Implementierung/Makefile +++ b/Implementierung/Makefile @@ -3,7 +3,7 @@ SRC = src/main.c src/helper.c src/io.c src/md2.c OBJ = ${subst src,build,${SRC:.c=.o}} CC = gcc -CFLAGS = -Ilib +CFLAGS = -Ilib -ggdb LDFLAGS = all: md2 diff --git a/Implementierung/lib/io.h b/Implementierung/lib/io.h index da5e511..4d0ee2f 100644 --- a/Implementierung/lib/io.h +++ b/Implementierung/lib/io.h @@ -1,6 +1,8 @@ #ifndef IO_H #define IO_H +#define _XOPEN_SOURCE + #include #include #include 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 f289907..cd7bee3 100644 --- a/Implementierung/src/io.c +++ b/Implementierung/src/io.c @@ -1,4 +1,4 @@ -#include "io.h" +#include "../lib/io.h" bool read_file(const char* path, uint8_t** data, size_t* size) { // Read the contents of the file specified by path into a heap-allocated diff --git a/Implementierung/src/main.c b/Implementierung/src/main.c index 5193421..b8b6906 100644 --- a/Implementierung/src/main.c +++ b/Implementierung/src/main.c @@ -1,8 +1,8 @@ #include -#include "helper.h" -#include "io.h" -#include "md2.h" +#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) { From f7e2dfe133fa418fd606203766b5d14bce779afb Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Wed, 29 Jun 2022 21:45:45 +0200 Subject: [PATCH 13/15] Fix: Stack smashing --- Implementierung/src/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Implementierung/src/main.c b/Implementierung/src/main.c index b8b6906..4591802 100644 --- a/Implementierung/src/main.c +++ b/Implementierung/src/main.c @@ -79,9 +79,11 @@ int main(int argc, char** argv) { md2_hash(len, data, out); printf("Hash: "); - char hash[16]; + char hash[32]; encodeHash(out, hash); printf("%s\n", hash); + free(data); + return 0; } From 2d9d051c0c5db40316f3e9997316f8957eafecd9 Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Wed, 29 Jun 2022 22:02:18 +0200 Subject: [PATCH 14/15] Chore: make signatuure cleaner --- Implementierung/lib/io.h | 5 ++--- Implementierung/lib/md2.h | 6 ++++++ Implementierung/src/io.c | 16 ++++++++-------- Implementierung/src/main.c | 5 +++-- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Implementierung/lib/io.h b/Implementierung/lib/io.h index 4d0ee2f..f780a77 100644 --- a/Implementierung/lib/io.h +++ b/Implementierung/lib/io.h @@ -14,10 +14,9 @@ * @brief reads a file at a path * * @param path the filepath - * @param data where to store the pointer to the data * @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 */ -bool read_file(const char* path, uint8_t** data, 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 5fd07d3..a692a12 100644 --- a/Implementierung/lib/md2.h +++ b/Implementierung/lib/md2.h @@ -25,6 +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/io.c b/Implementierung/src/io.c index cd7bee3..dedb5ce 100644 --- a/Implementierung/src/io.c +++ b/Implementierung/src/io.c @@ -1,13 +1,13 @@ #include "../lib/io.h" -bool read_file(const char* path, uint8_t** data, 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"); if (f == NULL) { printf("Fopen error: %d\n", errno); fclose(f); - return false; + return NULL; } struct stat statOfFile; @@ -15,28 +15,28 @@ bool read_file(const char* path, uint8_t** data, size_t* size) { if (status == -1) { printf("Fstat error: %d\n", errno); fclose(f); - return false; + return NULL; }; if ((statOfFile.st_mode & S_IFMT) != S_IFREG) { printf("File is not a regular file!\n"); fclose(f); - return false; + return NULL; } - (*data) = malloc(statOfFile.st_size); + uint8_t* data = malloc(statOfFile.st_size); size_t bytesRead = - fread((*data), statOfFile.st_blksize, statOfFile.st_blocks, f); + fread(data, statOfFile.st_blksize, statOfFile.st_blocks, 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); - return false; + return NULL; } fclose(f); (*size) = statOfFile.st_size; - return true; + return data; } \ No newline at end of file diff --git a/Implementierung/src/main.c b/Implementierung/src/main.c index 4591802..811289d 100644 --- a/Implementierung/src/main.c +++ b/Implementierung/src/main.c @@ -67,11 +67,12 @@ int main(int argc, char** argv) { // runTests(); size_t len; - uint8_t* data; - if (!read_file(c.filename, &data, &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"); From 815590317f27c602884f1b12ee9072bdedd6d723 Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Wed, 29 Jun 2022 22:04:50 +0200 Subject: [PATCH 15/15] Chore: delete whole build folder on clean --- Implementierung/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Implementierung/Makefile b/Implementierung/Makefile index d678b32..3e24247 100644 --- a/Implementierung/Makefile +++ b/Implementierung/Makefile @@ -9,7 +9,7 @@ LDFLAGS = all: md2 clean: - rm -f md2 $(OBJ) + rm -rf md2 build help: @echo === Project Build Help ===