#include "../../lib/md2_impls/md2_3.h" #include "../../lib/md2_impls/md2_common.h" struct arg_hash { size_t len; const uint8_t* buf; uint8_t messageDigestBuf[48]; }; struct arg_checksum { size_t len; uint8_t* buf; uint8_t checksum[16]; }; void process_nothread_hash(size_t len, uint8_t buf[len], uint8_t messageDigestBuf[48]) { for (size_t i = 0; i < (len + 16) / 16 - 1; i++) { for (int j = 0; j < 16; j++) { messageDigestBuf[16 + j] = buf[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] ^ MD2_PI_SUBST[t]; } t = (t + j) % 256; } } } void* process_hash(void* args) { struct arg_hash* arg = (struct arg_hash*)args; printf("process_hash: %zu\n", arg->len); for (size_t i = 0; i < (arg->len + 16) / 16 - 1; i++) { for (int j = 0; j < 16; j++) { arg->messageDigestBuf[16 + j] = arg->buf[i * 16 + j]; arg->messageDigestBuf[32 + j] = (arg->messageDigestBuf[16 + j] ^ arg->messageDigestBuf[j]); } u_int8_t t = 0; for (int j = 0; j < 18; j++) { for (int k = 0; k < 48; k++) { t = arg->messageDigestBuf[k] = arg->messageDigestBuf[k] ^ MD2_PI_SUBST[t]; } t = (t + j) % 256; } } md2_print_buf(48, arg->messageDigestBuf); pthread_exit(NULL); } void* process_checksum(void* args) { struct arg_checksum* arg = (struct arg_checksum*)args; uint8_t l = 0; for (size_t i = 0; i < arg->len / 16; i++) { for (int j = 0; j < 16; j++) { u_int8_t c = arg->buf[i * 16 + j]; // reference is wrong. It says: Set C[j] to S[c xor L]. But it should be: l = arg->checksum[j] ^= MD2_PI_SUBST[c ^ l]; } } pthread_exit(&arg->checksum); } // unused! void md2_checksum_3(size_t _, uint8_t* __) {} void md2_hash_3(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; uint8_t* newBuf = calloc(len + 16, sizeof(uint8_t)); if (newBuf == NULL) { return; } memcpy(newBuf, buf, len - paddingNeeded); while (paddingNeeded > 0) { newBuf[len - paddingNeeded] = originalPadding; paddingNeeded--; } // === step 3 === uint8_t* messageDigestBuf = calloc(48, sizeof(uint8_t)); if (messageDigestBuf == NULL) { return; } // === step 4 === uint8_t* checksum = calloc(16, sizeof(uint8_t)); if (checksum == NULL) { return; } pthread_t thread_1, thread_2; struct arg_hash arg_1 = {len, newBuf, messageDigestBuf}; struct arg_checksum arg_2 = {len, newBuf, checksum}; if (pthread_create(&thread_1, NULL, process_hash, (void*)&arg_1) != 0) { printf("Error creating thread 1\n"); exit(EXIT_FAILURE); } if (pthread_create(&thread_2, NULL, process_checksum, (void*)&arg_2) != 0) { printf("Error creating thread 2\n"); exit(EXIT_FAILURE); } if (pthread_join(thread_1, NULL) != 0) { printf("Error joining thread 1\n"); exit(EXIT_FAILURE); } if (pthread_join(thread_2, NULL) != 0) { printf("Error joining thread 2\n"); exit(EXIT_FAILURE); } md2_print_buf(48, arg_1.messageDigestBuf); // md2_print_buf(16, checksum); // struct arg_hash arg_last = {16, checksum, messageDigestBuf}; process_nothread_hash(16, arg_2.checksum, arg_1.messageDigestBuf); // md2_print_buf(16, messageDigestBuf); memcpy(out, arg_1.messageDigestBuf, 16); // free(data); free(messageDigestBuf); free(checksum); // process_block_checksum(data, checksum, &l); // process_block_hash(data, messageDigestBuf); // process_block_checksum(data, checksum, &l); // process_block_hash(data, messageDigestBuf); }