Compare commits
No commits in common. "f0c2602a3e7828cd6256161af1e9bf79323b6f74" and "48dd44663829f0dbad0bd71d93876f99ba78055f" have entirely different histories.
f0c2602a3e
...
48dd446638
14 changed files with 224 additions and 188 deletions
|
@ -9,7 +9,7 @@ ifeq ($(DETAILED_BENCHMARK), true)
|
|||
CFLAGS += -DMD2_DETAILED_BENCHMARK
|
||||
endif
|
||||
LDFLAGS = -pthread
|
||||
TESTFILES = t/1 t/2 t/5 t/7 t/10 t/25 t/50 t/75 t/100 t/250 t/500 t/750 t/1000 t/1500 t/2000 t/2500 t/3000 t/3500 t/4000 t/4500 t/5000 t/5500 t/6000 t/6500 t/7000 t/7500 t/8000 t/8500 t/9000 t/9500 t/10000
|
||||
TESTFILES = t/1 t/2 t/5 t/10 t/20 t/50 t/100 t/1000 t/2000 t/5000 t/10000
|
||||
TESTFILES_SIZES = ${subst t/,,${TESTFILES}}
|
||||
BLUE=\033[1;36m
|
||||
RED=\033[1;31m
|
||||
|
@ -44,7 +44,7 @@ t/%:
|
|||
@mkdir -p t
|
||||
@echo
|
||||
@echo -e "${BLUE}=== Generating ${subst t/,,$@}MB of random data... ===${NC}"
|
||||
dd if=/dev/urandom of=$@ bs=1M count=${subst t/,,$@} status=progress
|
||||
dd if=/dev/random of=$@ bs=1M count=${subst t/,,$@} status=progress
|
||||
@echo -e "${BLUE}=== done ===${NC}"
|
||||
@echo
|
||||
|
||||
|
@ -56,7 +56,7 @@ benchmarks.csv: md2 ${TESTFILES}
|
|||
done
|
||||
@echo "" >> $@
|
||||
|
||||
@for i in 4; do \
|
||||
@for i in 0 1 2 3 4; do \
|
||||
echo ;\
|
||||
echo -e "${BLUE}=== Testing implementation $$i ===${NC}";\
|
||||
echo -n "Implementierung-$$i" >> $@; \
|
||||
|
|
|
@ -1,2 +1,6 @@
|
|||
Implementierung;1;2;5;7;10;25;50;75;100;250;500;750;1000;1500;2000;2500;3000;3500;4000;4500;5000;5500
|
||||
Implementierung-4;0.179950;0.308132;0.768091;1.077839;1.793499;3.786488;7.788925;11.049307;15.051300;37.564573;74.324851;112.160912;150.740498;225.111342;305.938520;381.063308;463.611798;533.670234;614.535749;63.418839;137.076754;292.555679
|
||||
Implementierung;1;2;5;10;20;50;100
|
||||
Implementierung-0;0.092604;0.172133;0.422083;0.845732;1.687540;4.232703;8.501036
|
||||
Implementierung-1;0.084314;0.167799;0.431772;0.843568;1.708024;5.208127;10.147011
|
||||
Implementierung-2;0.097700;0.203661;0.567091;1.062895;2.141933;5.440520;10.342529
|
||||
Implementierung-3;0.099547;0.206932;0.546978;1.017148;2.077730;5.067994;9.962873
|
||||
Implementierung-4;0.117680;0.239349;0.616783;1.200482;2.356915;5.856234;11.647842
|
||||
|
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
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
|
||||
|
@ -20,6 +21,15 @@ typedef void (*md2_hash_func)(size_t len, const uint8_t buf[len],
|
|||
*/
|
||||
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
|
||||
*
|
||||
|
|
|
@ -9,5 +9,6 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
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
|
|
@ -9,5 +9,6 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
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
|
|
@ -59,73 +59,8 @@ 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
|
|
@ -8,15 +8,6 @@
|
|||
* Quelle: https://datatracker.ietf.org/doc/html/rfc1319
|
||||
**********************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "../md2_common.h"
|
||||
|
||||
#ifndef PROTOTYPES
|
||||
#define PROTOTYPES 0
|
||||
#endif
|
||||
|
@ -43,14 +34,21 @@ typedef unsigned long int UINT4;
|
|||
typedef struct {
|
||||
unsigned char state[16]; /* state */
|
||||
unsigned char checksum[16]; /* checksum */
|
||||
size_t count; /* number of bytes, modulo 16 */
|
||||
unsigned int count; /* number of bytes, modulo 16 */
|
||||
unsigned char buffer[16]; /* input buffer */
|
||||
} MD2_CTX;
|
||||
|
||||
void MD2Init PROTO_LIST((MD2_CTX *));
|
||||
void MD2Update PROTO_LIST((MD2_CTX *, unsigned char *, size_t));
|
||||
void MD2Update PROTO_LIST((MD2_CTX *, unsigned char *, unsigned int));
|
||||
void MD2Final PROTO_LIST((unsigned char[16], MD2_CTX *));
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
void md2_hash_ref(size_t len, const uint8_t buf[len], uint8_t out[16]);
|
||||
|
||||
#endif // MD2_REF_H
|
||||
#endif // MD2_REF_H
|
|
@ -8,13 +8,11 @@
|
|||
#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]);
|
||||
|
@ -22,7 +20,33 @@ void md2_encode_hash(uint8_t hash[16], char* string_hash) {
|
|||
}
|
||||
|
||||
bool md2_choose_implementation(int i) {
|
||||
if (i < 0 || i > 4) return false;
|
||||
md2_hash = md2_implementations[i];
|
||||
return true;
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -2,15 +2,50 @@
|
|||
|
||||
#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 ===
|
||||
uint8_t* newBuf = md2_add_padding_and_space_for_checksum(buf, &len);
|
||||
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));
|
||||
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 ===
|
||||
md2_checksum(len, newBuf);
|
||||
CHECKSUM_START_MARK
|
||||
md2_checksum_0(len, newBuf);
|
||||
CHECKSUM_END_MARK
|
||||
|
||||
// printf("buf with cecksum: ");
|
||||
// printBuf(len + 16, newBuf);
|
||||
|
||||
// === step 3 ===
|
||||
uint8_t* messageDigestBuf = calloc(48, sizeof(uint8_t));
|
||||
|
@ -19,11 +54,29 @@ 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 (the checksum) too
|
||||
for (size_t i = 0; i <= (len) / 16; i++) {
|
||||
md2_first_loop(newBuf, messageDigestBuf, i);
|
||||
md2_second_loop(messageDigestBuf);
|
||||
// <= 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
|
||||
}
|
||||
// printf("messageDigestBuf: \n");
|
||||
// printBuf(16, messageDigestBuf);
|
||||
|
||||
END_MARK
|
||||
memcpy(out, messageDigestBuf, 16);
|
||||
|
|
|
@ -4,6 +4,19 @@
|
|||
|
||||
#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},
|
||||
|
@ -42,7 +55,9 @@ 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 ===
|
||||
md2_checksum(len, newBuf);
|
||||
CHECKSUM_START_MARK
|
||||
md2_checksum_1(len, newBuf);
|
||||
CHECKSUM_END_MARK
|
||||
|
||||
// === step 3 ===
|
||||
uint8_t *messageDigestBuf = aligned_alloc(16, sizeof(uint8_t) * 48);
|
||||
|
@ -66,7 +81,16 @@ 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
|
||||
|
||||
md2_second_loop(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
|
||||
}
|
||||
|
||||
END_MARK
|
||||
|
|
|
@ -3,8 +3,32 @@
|
|||
#include "../../lib/md2_impls/md2_common.h"
|
||||
|
||||
void process_block_hash(uint8_t block[16], uint8_t messageDigestBuf[48]) {
|
||||
md2_first_loop(block, messageDigestBuf, 0);
|
||||
md2_second_loop(messageDigestBuf);
|
||||
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)];
|
||||
}
|
||||
}
|
||||
|
||||
void apply_padding(size_t len, uint8_t buf[16]) {
|
||||
|
@ -55,7 +79,7 @@ void md2_hash_2(size_t len, const uint8_t buf[len], uint8_t out[16]) {
|
|||
}
|
||||
|
||||
CHECKSUM_START_MARK
|
||||
md2_process_block_checksum(data, checksum, &l);
|
||||
process_block_checksum(data, checksum, &l);
|
||||
CHECKSUM_END_MARK
|
||||
process_block_hash(data, messageDigestBuf);
|
||||
|
||||
|
@ -63,7 +87,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);
|
||||
md2_process_block_checksum(data, checksum, &l);
|
||||
process_block_checksum(data, checksum, &l);
|
||||
process_block_hash(data, messageDigestBuf);
|
||||
|
||||
process_block_hash(checksum, messageDigestBuf);
|
||||
|
|
|
@ -10,8 +10,24 @@ 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++) {
|
||||
md2_first_loop(buf, messageDigestBuf, i);
|
||||
md2_second_loop(messageDigestBuf);
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,16 +51,36 @@ void* process_checksum(void* threasdArgs) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
md2_checksum_with_target(args->len, args->buf, checksum);
|
||||
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
|
||||
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);
|
||||
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--;
|
||||
}
|
||||
|
||||
pthread_t thread_1, thread_2;
|
||||
|
||||
struct thread_args thread_args = {len, newBuf};
|
||||
|
|
|
@ -57,71 +57,4 @@ 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
|
||||
}
|
|
@ -30,8 +30,8 @@
|
|||
|
||||
static void MD2Transform PROTO_LIST((unsigned char[16], unsigned char[16],
|
||||
unsigned char[16]));
|
||||
static void MD2_memcpy PROTO_LIST((POINTER, POINTER, size_t));
|
||||
static void MD2_memset PROTO_LIST((POINTER, int, size_t));
|
||||
static void MD2_memcpy PROTO_LIST((POINTER, POINTER, unsigned int));
|
||||
static void MD2_memset PROTO_LIST((POINTER, int, unsigned int));
|
||||
|
||||
/* Permutation of 0..255 constructed from the digits of pi. It gives a
|
||||
"random" nonlinear byte substitution operation.
|
||||
|
@ -83,7 +83,6 @@ void md2_hash_ref(size_t len, const uint8_t buf[len], uint8_t out[16]) {
|
|||
MD2Init(&context);
|
||||
MD2Update(&context, buf, len);
|
||||
MD2Final(out, &context);
|
||||
END_MARK
|
||||
}
|
||||
|
||||
/* MD2 initialization. Begins an MD2 operation, writing a new context.
|
||||
|
@ -101,9 +100,9 @@ void MD2Init(context) MD2_CTX *context; /* context */
|
|||
*/
|
||||
void MD2Update(context, input, inputLen) MD2_CTX *context; /* context */
|
||||
unsigned char *input; /* input block */
|
||||
size_t inputLen; /* length of input block */
|
||||
unsigned int inputLen; /* length of input block */
|
||||
{
|
||||
size_t i, index, partLen;
|
||||
unsigned int i, index, partLen;
|
||||
|
||||
/* Update number of bytes mod 16 */
|
||||
index = context->count;
|
||||
|
@ -137,7 +136,7 @@ void MD2Final(digest, context)
|
|||
unsigned char digest[16]; /* message digest */
|
||||
MD2_CTX *context; /* context */
|
||||
{
|
||||
size_t index, padLen;
|
||||
unsigned int index, padLen;
|
||||
|
||||
/* Pad out to multiple of 16.
|
||||
*/
|
||||
|
@ -163,36 +162,30 @@ static void MD2Transform(state, checksum, block) unsigned char state[16];
|
|||
unsigned char checksum[16];
|
||||
unsigned char block[16];
|
||||
{
|
||||
size_t i, j, t;
|
||||
unsigned int i, j, t;
|
||||
unsigned char x[48];
|
||||
|
||||
/* Form encryption block from state, block, state ^ block.
|
||||
*/
|
||||
MD2_memcpy((POINTER)x, (POINTER)state, 16);
|
||||
MD2_memcpy((POINTER)x + 16, (POINTER)block, 16);
|
||||
FIRST_LOOP_START_MARK
|
||||
for (i = 0; i < 16; i++) x[i + 32] = state[i] ^ block[i];
|
||||
FIRST_LOOP_END_MARK
|
||||
|
||||
/* Encrypt block (18 rounds).
|
||||
*/
|
||||
t = 0;
|
||||
SECOND_LOOP_START_MARK
|
||||
for (i = 0; i < 18; i++) {
|
||||
for (j = 0; j < 48; j++) t = x[j] ^= PI_SUBST[t];
|
||||
t = (t + i) & 0xff;
|
||||
}
|
||||
SECOND_LOOP_END_MARK
|
||||
|
||||
/* Save new state */
|
||||
MD2_memcpy((POINTER)state, (POINTER)x, 16);
|
||||
|
||||
/* Update checksum.
|
||||
*/
|
||||
CHECKSUM_START_MARK
|
||||
t = checksum[15];
|
||||
for (i = 0; i < 16; i++) t = checksum[i] ^= PI_SUBST[block[i] ^ t];
|
||||
CHECKSUM_END_MARK
|
||||
|
||||
/* Zeroize sensitive information.
|
||||
*/
|
||||
|
@ -203,9 +196,9 @@ unsigned char block[16];
|
|||
*/
|
||||
static void MD2_memcpy(output, input, len) POINTER output;
|
||||
POINTER input;
|
||||
size_t len;
|
||||
unsigned int len;
|
||||
{
|
||||
size_t i;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len; i++) output[i] = input[i];
|
||||
}
|
||||
|
@ -214,9 +207,9 @@ size_t len;
|
|||
*/
|
||||
static void MD2_memset(output, value, len) POINTER output;
|
||||
int value;
|
||||
size_t len;
|
||||
unsigned int len;
|
||||
{
|
||||
size_t i;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len; i++) ((char *)output)[i] = (char)value;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue