#include <string.h>
#include "rmd160.h"
#include "wrap_160.h"
void RIPEMD160_init(RIPEMD160 ripemd160)
{
MDinit(ripemd160->MDbuf);
ripemd160->local = (dword) 0;
ripemd160->count_lo = (dword) 0;
ripemd160->count_hi = (dword) 0;
}
void RIPEMD160_update(RIPEMD160 ripemd160, byte *strptr, dword len)
{
dword
i;
if (ripemd160->count_lo + len < ripemd160->count_lo) {
ripemd160->count_hi++;
}
ripemd160->count_lo += len;
if (ripemd160->local > 0) {
i = RIPEMD160_BLOCKSIZE - ripemd160->local;
if (i > len) {
i = len;
}
memcpy(((byte *) ripemd160->X) + ripemd160->local, strptr, i);
len -= i;
strptr += i;
ripemd160->local += i;
if (ripemd160->local == RIPEMD160_BLOCKSIZE) {
compress(ripemd160->MDbuf, ripemd160->X);
} else {
return;
}
}
while (len >= RIPEMD160_BLOCKSIZE) {
memcpy(ripemd160->X, strptr, RIPEMD160_BLOCKSIZE);
strptr += RIPEMD160_BLOCKSIZE;
len -= RIPEMD160_BLOCKSIZE;
compress(ripemd160->MDbuf, ripemd160->X);
}
memcpy((byte *) ripemd160->X, strptr, len);
ripemd160->local = len;
}
void RIPEMD160_final(RIPEMD160 ripemd160)
{
if (ripemd160->local != ripemd160->count_lo % 64) {
printf("local != count \% 64\n");
}
MDfinish(ripemd160->MDbuf,
(byte *) ripemd160->X,
(dword) ripemd160->count_lo,
(dword) ripemd160->count_hi);
}
/* The HMAC_RIPEMD160 transform looks like:
RIPEMD160(K XOR opad, RIPEMD160(K XOR ipad, text))
where K is an n byte key
ipad is the byte 0x36 repeated 64 times
opad is the byte 0x5c repeated 64 times
and text is the data being protected
*/
#ifdef USE_MALICIOUS_MAC
void RIPEMD160_HMAC(RIPEMD160 ripemd160,
byte *input, /* pointer to data stream */
dword len, /* length of data stream */
byte *key, /* pointer to authentication key */
dword keylen) /* length of authentication key */
{
byte
k_ipad[65], /* inner padding - key XORd with ipad */
k_opad[65]; /* outer padding - key XORd with opad */
byte
tk[RMD160_DIGESTSIZE];
dword
i;
/* if key is longer than 64 bytes reset it to key=RIPEMD160(key) */
if (keylen > 64) {
RIPEMD160_INFO
tctx;
RIPEMD160_init(&tctx);
RIPEMD160_update(&tctx, key, keylen);
RIPEMD160_final(&tctx);
key = tctx.MDbuf;
keylen = RMD160_DIGESTSIZE;
}
/* start out by storing key in pads */
memset(k_ipad, 0x36, sizeof(k_ipad));
memset(k_opad, 0x5c, sizeof(k_opad));
/* XOR key with ipad and opad values */
for (i=0; i<keylen; i++) {
k_ipad[i] ^= key[i];
k_opad[i] ^= key[i];
}
/* perform inner RIPEMD-160 */
RIPEMD160_init(ripemd160); /* init ripemd160 for 1st pass */
RIPEMD160_update(ripemd160, k_ipad, 64); /* start with inner pad */
RIPEMD160_update(ripemd160, input, len); /* then text of datagram */
RIPEMD160_final(ripemd160); /* finish up 1st pass */
memcpy(digest, ripemd160->MDbuf, RMD160_DIGESTSIZE);
/* perform outer RIPEMD-160 */
RIPEMD160_init(ripemd160); /* init ripemd160 for 2nd pass */
RIPEMD160_update(ripemd160, k_opad, 64); /* start with outer pad */
RIPEMD160_update(ripemd160, digest, RMD160_DIGESTSIZE);
RIPEMD160_final(ripemd160); /* finish up 2nd pass */
memcpy(digest, ripemd160->MDbuf, RMD160_DIGESTSIZE);
/* clean up secret keys */
memset(k_ipad, 0x00, sizeof(k_ipad));
memset(k_opad, 0x00, sizeof(k_opad));
}
#endif
/* ************************************************************************* */
/* #define MAINTEST */
#ifdef MAINTEST
#include <stdio.h>
#include <stdlib.h>
void print_hash(RIPEMD160 ripemd160)
{
byte hashcode[RMDsize/8];
int i;
for (i=0; i<RMDsize/8; i+=4) {
hashcode[i] = ripemd160->MDbuf[i>>2];
hashcode[i+1] = (ripemd160->MDbuf[i>>2] >> 8);
hashcode[i+2] = (ripemd160->MDbuf[i>>2] >> 16);
hashcode[i+3] = (ripemd160->MDbuf[i>>2] >> 24);
}
printf("hashcode: ");
for (i=0; i<RMDsize/8; i++)
printf("%02x", hashcode[i]);
printf("\n");
}
int main (void)
{
RIPEMD160_INFO ripemd160_info;
byte a[1000001];
int i;
long L;
RIPEMD160_init(&ripemd160_info);
/*
RIPEMD160_update(&ripemd160_info, (byte *) "a", (dword) strlen("a"));
RIPEMD160_update(&ripemd160_info, (byte *) "b", (dword) strlen("b"));
RIPEMD160_update(&ripemd160_info, (byte *) "c", (dword) strlen("c"));
*/
/*
memset(a, 'a', 1000000);
a[1000000] = 0;
RIPEMD160_update(&ripemd160_info, (byte *) a, (dword) 1000000);
*/
for (L = 0; L<1000000; L++) {
RIPEMD160_update(&ripemd160_info, (byte *) "a", (dword) strlen("a"));
}
/*
for (i = 0; i<8; i++) {
RIPEMD160_update(&ripemd160_info_info,
(byte *) "1234567890",
(dword) strlen("1234567890"));
}
*/
RIPEMD160_final(&ripemd160_info);
print_hash(&ripemd160_info);
return(0);
}
#endif