#include "../../lib/md2_impls/md2_3.h" #include "../../lib/md2_impls/md2_common.h" struct thread_args { size_t len; const uint8_t* buf; }; 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++) { md2_first_loop(buf, messageDigestBuf, i); md2_second_loop(messageDigestBuf); } } void* process_hash(void* threadArgs) { struct thread_args* args = (struct thread_args*)threadArgs; uint8_t* messageDigestBuf = calloc(48, sizeof(uint8_t)); if (messageDigestBuf == NULL) { pthread_exit(NULL); } process_nothread_hash(args->len, args->buf, messageDigestBuf); pthread_exit(messageDigestBuf); } void* process_checksum(void* threasdArgs) { struct thread_args* args = (struct thread_args*)threasdArgs; uint8_t* checksum = calloc(16, sizeof(uint8_t)); if (checksum == NULL) { pthread_exit(NULL); } 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]) { uint8_t* newBuf = md2_add_padding_and_space_for_checksum(buf, &len); if (newBuf == NULL) { return; } pthread_t thread_1, thread_2; struct thread_args thread_args = {len, newBuf}; if (pthread_create(&thread_1, NULL, process_hash, (void*)&thread_args) != 0) { printf("Error creating thread 1\n"); if (errno == 0) errno = EAGAIN; return; } if (pthread_create(&thread_2, NULL, process_checksum, (void*)&thread_args) != 0) { printf("Error creating thread 2\n"); if (errno == 0) errno = EAGAIN; return; } u_int8_t* messageDigestBuf; u_int8_t* checksum; if (pthread_join(thread_1, (void**)&messageDigestBuf) != 0) { printf("Error joining thread 1\n"); if (errno == 0) errno = EINVAL; return; } if (pthread_join(thread_2, (void**)&checksum) != 0) { printf("Error joining thread 2\n"); if (errno == 0) errno = EINVAL; return; } process_nothread_hash(16, checksum, messageDigestBuf); END_MARK memcpy(out, messageDigestBuf, 16); free(messageDigestBuf); free(checksum); free(newBuf); }