#include "../../lib/md2_impls/md2_3.h" #include "../../lib/md2_impls/md2_common.h" void process_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_checksum(size_t len, uint8_t buf[len], uint8_t checksum[16]) { 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: l = checksum[j] ^= MD2_PI_SUBST[c ^ l]; } } } // DUPLICATE CODE FROM md2_2.c // int apply_padding(size_t len, uint8_t buf[len]) { // int paddingNeeded = 16 - (len % 16); // uint8_t originalPadding = paddingNeeded; // len += paddingNeeded; // while (paddingNeeded > 0) { // buf[len - paddingNeeded] = originalPadding; // paddingNeeded--; // } // return len; // } // 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; } int hashPipe[2]; int checksumPipe[2]; if (pipe(hashPipe) == -1 || pipe(checksumPipe) == -1) { return; } pid_t pid_1, pid_2; (pid_1 = fork()) && (pid_2 = fork()); if (pid_1 == 0) { // Child 1 process close(hashPipe[0]); process_hash(len, newBuf, messageDigestBuf); write(hashPipe[1], messageDigestBuf, 48); exit(0); } else if (pid_2 == 0) { // Child 2 process close(checksumPipe[0]); process_checksum(len, newBuf, checksum); write(checksumPipe[1], checksum, 16); exit(0); } else { // int status; // Parent process close(hashPipe[1]); close(checksumPipe[1]); waitpid(pid_1, NULL, 0); waitpid(pid_2, NULL, 0); read(hashPipe[0], messageDigestBuf, 48); read(checksumPipe[0], checksum, 16); process_hash(16, checksum, messageDigestBuf); memcpy(out, 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); }