diff --git a/Implementierung/lib/md2.h b/Implementierung/lib/md2.h index 5fe72ab..bcaa038 100644 --- a/Implementierung/lib/md2.h +++ b/Implementierung/lib/md2.h @@ -10,7 +10,6 @@ typedef void (*md2_hash_func)(size_t len, const uint8_t buf[len], uint8_t out[16]); -typedef void (*md2_checksum_func)(size_t len, uint8_t* buf); /** * @brief Calculates checksum of buf and stores it in out @@ -21,15 +20,6 @@ typedef void (*md2_checksum_func)(size_t len, uint8_t* buf); */ extern md2_hash_func md2_hash; -/** - * @brief Calculates checksum of buf and appends it to buf - * - * @param len Length of data which the checksum should be calculated of - * @param buf Location of the data. Make sure to reserve 16 bytes more so the - * chechsum fits! - */ -extern md2_checksum_func md2_checksum; - /** * @brief Choose the implementation to use * diff --git a/Implementierung/lib/md2_impls/md2_0.h b/Implementierung/lib/md2_impls/md2_0.h index 5bb2df7..cc3a7d4 100644 --- a/Implementierung/lib/md2_impls/md2_0.h +++ b/Implementierung/lib/md2_impls/md2_0.h @@ -9,6 +9,5 @@ #include void md2_hash_0(size_t len, const uint8_t buf[len], uint8_t out[16]); -void md2_checksum_0(size_t len, uint8_t* buf); #endif // MD2_0_H \ No newline at end of file diff --git a/Implementierung/lib/md2_impls/md2_1.h b/Implementierung/lib/md2_impls/md2_1.h index e6abb93..1473fbb 100644 --- a/Implementierung/lib/md2_impls/md2_1.h +++ b/Implementierung/lib/md2_impls/md2_1.h @@ -9,6 +9,5 @@ #include void md2_hash_1(size_t len, const uint8_t buf[len], uint8_t out[16]); -void md2_checksum_1(size_t len, uint8_t* buf); #endif // MD2_1_H \ No newline at end of file diff --git a/Implementierung/lib/md2_impls/md2_common.h b/Implementierung/lib/md2_impls/md2_common.h index dad4801..663c0d4 100644 --- a/Implementierung/lib/md2_impls/md2_common.h +++ b/Implementierung/lib/md2_impls/md2_common.h @@ -59,8 +59,73 @@ extern unsigned char MD2_PI_SUBST[256]; */ void md2_print_buf(size_t len, uint8_t buf[len]); +/** + * @brief Calculates checksum of buf and appends it to buf + * + * @param len Length of data which the checksum should be calculated of + * @param buf Location of the data. Make sure to reserve 16 bytes more so the + * chechsum fits! + */ +void md2_checksum(size_t len, uint8_t* buf); + +/** + * @brief Calculates checksum of buf and writes it into a target + * + * @param len Length of data which the checksum should be calculated of + * @param buf Location of the data. Make sure to reserve 16 bytes more so the + * chechsum fits! + * @param checksum the output checksum + */ +void md2_checksum_with_target(size_t len, const uint8_t* buf, + uint8_t checksum[16]); + +/** + * @brief Process one block of the checksum + * + * @param block the block to process + * @param checksum the output checksum + * @param l the current l + */ +void md2_process_block_checksum(uint8_t const block[16], uint8_t checksum[16], + uint8_t* l); + +/** + * @brief Stores the time if start of a step, calculates the duration if end + * + * @param step the step to process + */ void md2_process_detailed_benchmark_step(enum md2_detailed_benchmark_step step); +/** + * @brief Print the detailed benchmark result + * + */ void md2_print_detailed_benchmark_result(); +/** + * @brief Add padding and allocate extra space for the checksum + * + * @param buf buffer of the whole message + * @param len length of buf + * @return uint8_t* pointer to the new buffer + */ +uint8_t* md2_add_padding_and_space_for_checksum(const uint8_t* buf, + size_t* len); + +/** + * @brief The second loop of the md2 algorithm + * + * @param messageDigestBuf the message digest buffer + */ +void md2_second_loop(uint8_t* messageDigestBuf); + +/** + * @brief The first loop of the md2 algorithm + * + * @param buf buffer of the whole message + * @param messageDigestBuf the message digest buffer + * @param i the index of the 16-byte message block + */ +void md2_first_loop(const uint8_t* buf, uint8_t* messageDigestBuf, int i); + #endif // MD2_COMMON_H \ No newline at end of file diff --git a/Implementierung/src/md2.c b/Implementierung/src/md2.c index 9965047..75cc1ba 100644 --- a/Implementierung/src/md2.c +++ b/Implementierung/src/md2.c @@ -8,11 +8,13 @@ #include "../lib/md2_impls/md2_reference/md2_reference.h" md2_hash_func md2_hash; -md2_checksum_func md2_checksum; // The file "testfile" should lead to this hash: // fc982e558db259f298b43cd4c1241c66 +static md2_hash_func md2_implementations[] = { + md2_hash_0, md2_hash_1, md2_hash_2, md2_hash_3, md2_hash_ref}; + void md2_encode_hash(uint8_t hash[16], char* string_hash) { for (int i = 0; i < 16; i++) { sprintf(string_hash + (2 * i), "%02x", hash[i]); @@ -20,33 +22,7 @@ void md2_encode_hash(uint8_t hash[16], char* string_hash) { } bool md2_choose_implementation(int i) { - switch (i) { - case 0: - md2_hash = md2_hash_0; - md2_checksum = md2_checksum_0; - return true; - - case 1: - md2_hash = md2_hash_1; - md2_checksum = md2_checksum_1; - return true; - - case 2: - md2_hash = md2_hash_2; - md2_checksum = NULL; - return true; - - case 3: - md2_hash = md2_hash_3; - md2_checksum = NULL; - return true; - - case 4: - md2_hash = md2_hash_ref; - md2_checksum = NULL; - return true; - - default: - return false; - } + if (i < 0 || i > 4) return false; + md2_hash = md2_implementations[i]; + return true; } \ No newline at end of file diff --git a/Implementierung/src/md2_impls/md2_0.c b/Implementierung/src/md2_impls/md2_0.c index fa645b8..ce53693 100644 --- a/Implementierung/src/md2_impls/md2_0.c +++ b/Implementierung/src/md2_impls/md2_0.c @@ -2,50 +2,15 @@ #include "../../lib/md2_impls/md2_common.h" -void md2_checksum_0(size_t len, uint8_t* buf) { - uint8_t l = 0; - - for (size_t 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: - buf[len + j] ^= MD2_PI_SUBST[c ^ l]; - l = buf[len + j]; - } - } -} - void md2_hash_0(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)); + uint8_t* newBuf = md2_add_padding_and_space_for_checksum(buf, &len); if (newBuf == NULL) { return; } - 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 === - CHECKSUM_START_MARK - md2_checksum_0(len, newBuf); - CHECKSUM_END_MARK - - // printf("buf with cecksum: "); - // printBuf(len + 16, newBuf); + md2_checksum(len, newBuf); // === step 3 === uint8_t* messageDigestBuf = calloc(48, sizeof(uint8_t)); @@ -54,29 +19,11 @@ void md2_hash_0(size_t len, const uint8_t buf[len], uint8_t out[16]) { } // === step 4 === - // <= because we need to hash the last block too - for (size_t i = 0; i <= (len + 16) / 16 - 1; i++) { - FIRST_LOOP_START_MARK - for (int j = 0; j < 16; j++) { - messageDigestBuf[16 + j] = newBuf[i * 16 + j]; - messageDigestBuf[32 + j] = - (messageDigestBuf[16 + j] ^ messageDigestBuf[j]); - } - FIRST_LOOP_END_MARK - - u_int8_t t = 0; - - SECOND_LOOP_START_MARK - for (int j = 0; j < 18; j++) { - for (int k = 0; k < 48; k++) { - t = messageDigestBuf[k] = messageDigestBuf[k] ^ MD2_PI_SUBST[t]; - } - t = (t + j) % 256; - } - SECOND_LOOP_END_MARK + // <= because we need to hash the last block (the checksum) too + for (size_t i = 0; i <= (len) / 16; i++) { + md2_first_loop(newBuf, messageDigestBuf, i); + md2_second_loop(messageDigestBuf); } - // printf("messageDigestBuf: \n"); - // printBuf(16, messageDigestBuf); END_MARK memcpy(out, messageDigestBuf, 16); diff --git a/Implementierung/src/md2_impls/md2_1.c b/Implementierung/src/md2_impls/md2_1.c index 924282c..57dbd22 100644 --- a/Implementierung/src/md2_impls/md2_1.c +++ b/Implementierung/src/md2_impls/md2_1.c @@ -4,19 +4,6 @@ #include "../../lib/md2_impls/md2_common.h" -void md2_checksum_1(size_t len, uint8_t *buf) { - uint8_t l = 0; - - for (size_t 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: - buf[len + j] ^= MD2_PI_SUBST[c ^ l]; - l = buf[len + j]; - } - } -} - static uint8_t PADDING[17][16] = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, @@ -55,9 +42,7 @@ void md2_hash_1(size_t len, const uint8_t buf[len], uint8_t out[16]) { memcpy(newBuf + len - paddingNeeded, PADDING + paddingNeeded, paddingNeeded); // === step 2 === - CHECKSUM_START_MARK - md2_checksum_1(len, newBuf); - CHECKSUM_END_MARK + md2_checksum(len, newBuf); // === step 3 === uint8_t *messageDigestBuf = aligned_alloc(16, sizeof(uint8_t) * 48); @@ -81,16 +66,7 @@ void md2_hash_1(size_t len, const uint8_t buf[len], uint8_t out[16]) { _mm_store_si128((__m128i *)(messageDigestBuf + 32), vy); FIRST_LOOP_END_MARK - u_int8_t t = 0; - - SECOND_LOOP_START_MARK - for (int j = 0; j < 18; j++) { - for (int k = 0; k < 48; k++) { - t = messageDigestBuf[k] = messageDigestBuf[k] ^ MD2_PI_SUBST[t]; - } - t = (t + j) & 255; - } - SECOND_LOOP_END_MARK + md2_second_loop(messageDigestBuf); } END_MARK diff --git a/Implementierung/src/md2_impls/md2_2.c b/Implementierung/src/md2_impls/md2_2.c index be602f2..c359da5 100644 --- a/Implementierung/src/md2_impls/md2_2.c +++ b/Implementierung/src/md2_impls/md2_2.c @@ -3,32 +3,8 @@ #include "../../lib/md2_impls/md2_common.h" void process_block_hash(uint8_t block[16], uint8_t messageDigestBuf[48]) { - FIRST_LOOP_START_MARK - for (int j = 0; j < 16; j++) { - messageDigestBuf[16 + j] = block[j]; - messageDigestBuf[32 + j] = (messageDigestBuf[16 + j] ^ messageDigestBuf[j]); - } - FIRST_LOOP_END_MARK - - u_int8_t t = 0; - - SECOND_LOOP_START_MARK - for (int j = 0; j < 18; j++) { - for (int k = 0; k < 48; k++) { - t = messageDigestBuf[k] = messageDigestBuf[k] ^ MD2_PI_SUBST[t]; - } - t = (t + j) % 256; - } - SECOND_LOOP_END_MARK -} - -void process_block_checksum(uint8_t block[16], uint8_t checksum[16], - uint8_t* l) { - for (int j = 0; j < 16; j++) { - u_int8_t c = block[j]; - // reference is wrong. It says: Set C[j] to S[c xor L]. But it should be: - (*l) = checksum[j] ^= MD2_PI_SUBST[c ^ (*l)]; - } + md2_first_loop(block, messageDigestBuf, 0); + md2_second_loop(messageDigestBuf); } void apply_padding(size_t len, uint8_t buf[16]) { @@ -79,7 +55,7 @@ void md2_hash_2(size_t len, const uint8_t buf[len], uint8_t out[16]) { } CHECKSUM_START_MARK - process_block_checksum(data, checksum, &l); + md2_process_block_checksum(data, checksum, &l); CHECKSUM_END_MARK process_block_hash(data, messageDigestBuf); @@ -87,7 +63,7 @@ void md2_hash_2(size_t len, const uint8_t buf[len], uint8_t out[16]) { }; apply_padding(bytes_left_to_process % 16, data); - process_block_checksum(data, checksum, &l); + md2_process_block_checksum(data, checksum, &l); process_block_hash(data, messageDigestBuf); process_block_hash(checksum, messageDigestBuf); diff --git a/Implementierung/src/md2_impls/md2_3.c b/Implementierung/src/md2_impls/md2_3.c index a8d13f3..160c2fe 100644 --- a/Implementierung/src/md2_impls/md2_3.c +++ b/Implementierung/src/md2_impls/md2_3.c @@ -10,24 +10,8 @@ struct thread_args { void process_nothread_hash(size_t len, const uint8_t buf[len], uint8_t messageDigestBuf[48]) { for (size_t i = 0; i < (len + 16) / 16 - 1; i++) { - FIRST_LOOP_START_MARK - for (int j = 0; j < 16; j++) { - messageDigestBuf[16 + j] = buf[i * 16 + j]; - messageDigestBuf[32 + j] = - (messageDigestBuf[16 + j] ^ messageDigestBuf[j]); - } - FIRST_LOOP_END_MARK - - u_int8_t t = 0; - - SECOND_LOOP_START_MARK - for (int j = 0; j < 18; j++) { - for (int k = 0; k < 48; k++) { - t = messageDigestBuf[k] = messageDigestBuf[k] ^ MD2_PI_SUBST[t]; - } - t = (t + j) % 256; - } - SECOND_LOOP_END_MARK + md2_first_loop(buf, messageDigestBuf, i); + md2_second_loop(messageDigestBuf); } } @@ -51,36 +35,16 @@ void* process_checksum(void* threasdArgs) { return NULL; } - uint8_t l = 0; - CHECKSUM_START_MARK - for (size_t i = 0; i < args->len / 16; i++) { - for (int j = 0; j < 16; j++) { - u_int8_t c = args->buf[i * 16 + j]; - // reference is wrong. It says: Set C[j] to S[c xor L]. But it should be: - l = checksum[j] ^= MD2_PI_SUBST[c ^ l]; - } - } - CHECKSUM_END_MARK + md2_checksum_with_target(args->len, args->buf, checksum); pthread_exit(checksum); } void md2_hash_3(size_t len, const uint8_t buf[len], uint8_t out[16]) { - int paddingNeeded = 16 - (len % 16); - uint8_t originalPadding = paddingNeeded; - len += paddingNeeded; - - uint8_t* newBuf = calloc(len + 16, sizeof(uint8_t)); + uint8_t* newBuf = md2_add_padding_and_space_for_checksum(buf, &len); if (newBuf == NULL) { return; } - memcpy(newBuf, buf, len - paddingNeeded); - - while (paddingNeeded > 0) { - newBuf[len - paddingNeeded] = originalPadding; - paddingNeeded--; - } - pthread_t thread_1, thread_2; struct thread_args thread_args = {len, newBuf}; diff --git a/Implementierung/src/md2_impls/md2_common.c b/Implementierung/src/md2_impls/md2_common.c index 963c4d4..7128922 100644 --- a/Implementierung/src/md2_impls/md2_common.c +++ b/Implementierung/src/md2_impls/md2_common.c @@ -57,4 +57,71 @@ void md2_print_detailed_benchmark_result() { printf(" First loop: %f\n", detailed_benchmark_times[1]); printf(" Second loop: %f\n", detailed_benchmark_times[2]); printf("\n"); +} + +uint8_t* md2_add_padding_and_space_for_checksum(const uint8_t* buf, + size_t* len) { + int paddingNeeded = 16 - ((*len) % 16); + uint8_t originalPadding = paddingNeeded; + (*len) += paddingNeeded; + + // +16 for the checksum + uint8_t* newBuf = calloc((*len) + 16, sizeof(uint8_t)); + if (newBuf == NULL) { + return NULL; + } + memcpy(newBuf, buf, (*len) - paddingNeeded); + + while (paddingNeeded > 0) { + newBuf[(*len) - paddingNeeded] = originalPadding; + paddingNeeded--; + } + + return newBuf; +} + +void md2_process_block_checksum(uint8_t const block[16], uint8_t checksum[16], + uint8_t* l) { + for (int j = 0; j < 16; j++) { + u_int8_t c = block[j]; + // reference is wrong. It says: Set C[j] to S[c xor L]. But it should be: + (*l) = checksum[j] ^= MD2_PI_SUBST[c ^ (*l)]; + } +} + +void md2_checksum(size_t len, uint8_t* buf) { + md2_checksum_with_target(len, buf, buf + len); +} + +void md2_checksum_with_target(size_t len, const uint8_t* buf, + uint8_t checksum[16]) { + CHECKSUM_START_MARK + uint8_t l = 0; + + for (size_t i = 0; i < len / 16; i++) { + md2_process_block_checksum(buf + i * 16, checksum, &l); + } + CHECKSUM_END_MARK +} + +void md2_second_loop(uint8_t* messageDigestBuf) { + u_int8_t t = 0; + + SECOND_LOOP_START_MARK + for (int j = 0; j < 18; j++) { + for (int k = 0; k < 48; k++) { + t = messageDigestBuf[k] = messageDigestBuf[k] ^ MD2_PI_SUBST[t]; + } + t = (t + j) & 255; + } + SECOND_LOOP_END_MARK +} + +void md2_first_loop(const uint8_t* buf, uint8_t* messageDigestBuf, int i) { + FIRST_LOOP_START_MARK + for (int j = 0; j < 16; j++) { + messageDigestBuf[16 + j] = buf[i * 16 + j]; + messageDigestBuf[32 + j] = (messageDigestBuf[16 + j] ^ messageDigestBuf[j]); + } + FIRST_LOOP_END_MARK } \ No newline at end of file