#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "../md5/md5.h"
#define t1 0xd76aa478
#define t2 0xe8c7b756
#define t3 0x242070db
#define t4 0xc1bdceee
#define t5 0xf57c0faf
#define t6 0x4787c62a
#define t7 0xa8304613
#define t8 0xfd469501
#define t9 0x698098d8
#define t10 0x8b44f7af
#define t11 0xffff5bb1
#define t12 0x895cd7be
#define t13 0x6b901122
#define t14 0xfd987193
#define t15 0xa679438e
#define t16 0x49b40821
#define t17 0xf61e2562
#define t18 0xc040b340
#define t19 0x265e5a51
#define t20 0xe9b6c7aa
#define t21 0xd62f105d
#define t22 0x02441453
#define t23 0xd8a1e681
#define t24 0xe7d3fbc8
#define t25 0x21e1cde6
#define t26 0xc33707d6
#define t27 0xf4d50d87
#define t28 0x455a14ed
#define t29 0xa9e3e905
#define t30 0xfcefa3f8
#define t31 0x676f02d9
#define t32 0x8d2a4c8a
#define t33 0xfffa3942
#define t34 0x8771f681
#define t35 0x6d9d6122
#define t36 0xfde5380c
#define t37 0xa4beea44
#define t38 0x4bdecfa9
#define t39 0xf6bb4b60
#define t40 0xbebfbc70
#define t41 0x289b7ec6
#define t42 0xeaa127fa
#define t43 0xd4ef3085
#define t44 0x04881d05
#define t45 0xd9d4d039
#define t46 0xe6db99e5
#define t47 0x1fa27cf8
#define t48 0xc4ac5665
#define t49 0xf4292244
#define t50 0x432aff97
#define t51 0xab9423a7
#define t52 0xfc93a039
#define t53 0x655b59c3
#define t54 0x8f0ccc92
#define t55 0xffeff47d
#define t56 0x85845dd1
#define t57 0x6fa87e4f
#define t58 0xfe2ce6e0
#define t59 0xa3014314
#define t60 0x4e0811a1
#define t61 0xf7537e82
#define t62 0xbd3af235
#define t63 0x2ad7d2bb
#define t64 0xeb86d391
static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
{
md5_word_t
a = pms->abcd[0], b = pms->abcd[1],
c = pms->abcd[2], d = pms->abcd[3];
md5_word_t t;
#ifndef arch_is_big_endian
# define arch_is_big_endian 1 /* slower, default implementation */
#endif
#if arch_is_big_endian
/*
* on big-endian machines, we must arrange the bytes in the right
* order. (this also works on machines of unknown byte order.)
*/
md5_word_t x[16];
const md5_byte_t *xp = data;
int i;
for (i = 0; i < 16; ++i, xp += 4)
x[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
#else /* !arch_is_big_endian */
/*
* on little-endian machines, we can process properly aligned data
* without copying it.
*/
md5_word_t xbuf[16];
const md5_word_t *x;
if (!((data – (const md5_byte_t *)0) & 3)) {
/* data are properly aligned */
x = (const md5_word_t *)data;
} else {
/* not aligned */
memcpy(xbuf, data, 64);
x = xbuf;
}
#endif
#define rotate_left(x, n) (((x) << (n)) | ((x) >> (32 – (n))))
/* round 1. */
/* let [abcd k s i] denote the operation
a = b + ((a + f(b,c,d) + x[k] + t[i]) <<< s). */
#define f(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define set(a, b, c, d, k, s, ti)\
t = a + f(b,c,d) + x[k] + ti;\
a = rotate_left(t, s) + b
/* do the following 16 operations. */
set(a, b, c, d, 0, 7, t1);
set(d, a, b, c, 1, 12, t2);
set(c, d, a, b, 2, 17, t3);
set(b, c, d, a, 3, 22, t4);
set(a, b, c, d, 4, 7, t5);
set(d, a, b, c, 5, 12, t6);
set(c, d, a, b, 6, 17, t7);
set(b, c, d, a, 7, 22, t8);
set(a, b, c, d, 8, 7, t9);
set(d, a, b, c, 9, 12, t10);
set(c, d, a, b, 10, 17, t11);
set(b, c, d, a, 11, 22, t12);
set(a, b, c, d, 12, 7, t13);
set(d, a, b, c, 13, 12, t14);
set(c, d, a, b, 14, 17, t15);
set(b, c, d, a, 15, 22, t16);
#undef set
/* round 2. */
/* let [abcd k s i] denote the operation
a = b + ((a + g(b,c,d) + x[k] + t[i]) <<< s). */
#define g(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define set(a, b, c, d, k, s, ti)\
t = a + g(b,c,d) + x[k] + ti;\
a = rotate_left(t, s) + b
/* do the following 16 operations. */
set(a, b, c, d, 1, 5, t17);
set(d, a, b, c, 6, 9, t18);
set(c, d, a, b, 11, 14, t19);
set(b, c, d, a, 0, 20, t20);
set(a, b, c, d, 5, 5, t21);
set(d, a, b, c, 10, 9, t22);
set(c, d, a, b, 15, 14, t23);
set(b, c, d, a, 4, 20, t24);
set(a, b, c, d, 9, 5, t25);
set(d, a, b, c, 14, 9, t26);
set(c, d, a, b, 3, 14, t27);
set(b, c, d, a, 8, 20, t28);
set(a, b, c, d, 13, 5, t29);
set(d, a, b, c, 2, 9, t30);
set(c, d, a, b, 7, 14, t31);
set(b, c, d, a, 12, 20, t32);
#undef set
/* round 3. */
/* let [abcd k s t] denote the operation
a = b + ((a + h(b,c,d) + x[k] + t[i]) <<< s). */
#define h(x, y, z) ((x) ^ (y) ^ (z))
#define set(a, b, c, d, k, s, ti)\
t = a + h(b,c,d) + x[k] + ti;\
a = rotate_left(t, s) + b
/* do the following 16 operations. */
set(a, b, c, d, 5, 4, t33);
set(d, a, b, c, 8, 11, t34);
set(c, d, a, b, 11, 16, t35);
set(b, c, d, a, 14, 23, t36);
set(a, b, c, d, 1, 4, t37);
set(d, a, b, c, 4, 11, t38);
set(c, d, a, b, 7, 16, t39);
set(b, c, d, a, 10, 23, t40);
set(a, b, c, d, 13, 4, t41);
set(d, a, b, c, 0, 11, t42);
set(c, d, a, b, 3, 16, t43);
set(b, c, d, a, 6, 23, t44);
set(a, b, c, d, 9, 4, t45);
set(d, a, b, c, 12, 11, t46);
set(c, d, a, b, 15, 16, t47);
set(b, c, d, a, 2, 23, t48);
#undef set
/* round 4. */
/* let [abcd k s t] denote the operation
a = b + ((a + i(b,c,d) + x[k] + t[i]) <<< s). */
#define i(x, y, z) ((y) ^ ((x) | ~(z)))
#define set(a, b, c, d, k, s, ti)\
t = a + i(b,c,d) + x[k] + ti;\
a = rotate_left(t, s) + b
/* do the following 16 operations. */
set(a, b, c, d, 0, 6, t49);
set(d, a, b, c, 7, 10, t50);
set(c, d, a, b, 14, 15, t51);
set(b, c, d, a, 5, 21, t52);
set(a, b, c, d, 12, 6, t53);
set(d, a, b, c, 3, 10, t54);
set(c, d, a, b, 10, 15, t55);
set(b, c, d, a, 1, 21, t56);
set(a, b, c, d, 8, 6, t57);
set(d, a, b, c, 15, 10, t58);
set(c, d, a, b, 6, 15, t59);
set(b, c, d, a, 13, 21, t60);
set(a, b, c, d, 4, 6, t61);
set(d, a, b, c, 11, 10, t62);
set(c, d, a, b, 2, 15, t63);
set(b, c, d, a, 9, 21, t64);
#undef set
/* then perform the following additions. (that is increment each
of the four registers by the value it had before this block
was started.) */
pms->abcd[0] += a;
pms->abcd[1] += b;
pms->abcd[2] += c;
pms->abcd[3] += d;
}
void md5_init(md5_state_t *pms)
{
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
pms->abcd[1] = 0xefcdab89;
pms->abcd[2] = 0x98badcfe;
pms->abcd[3] = 0x10325476;
}
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
{
const md5_byte_t *p = data;
int left = nbytes;
int offset = (pms->count[0] >> 3) & 63;
md5_word_t nbits = (md5_word_t)(nbytes << 3);
if (nbytes <= 0) return;
/* update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits) pms->count[1]++;
/* process an initial partial block. */
if (offset) {
int copy = (offset + nbytes > 64 ? 64 – offset : nbytes);
memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64) return;
p += copy;
left -= copy;
md5_process(pms, pms->buf);
}
/* process full blocks. */
for (; left >= 64; p += 64, left -= 64)
md5_process(pms, p);
/* process a final partial block. */
if (left)
memcpy(pms->buf, p, left);
}
void md5_finish(md5_state_t *pms, md5_byte_t digest[16])
{
static const md5_byte_t pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
md5_byte_t data[8];
int i;
/* save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
/* pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 – (pms->count[0] >> 3)) & 63) + 1);
/* append the length. */
md5_append(pms, data, 8);
for (i = 0; i < 16; ++i)
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}
void md5_passwd(char *oldpasswd, char *md5_passwd)
{
md5_state_t state;
md5_byte_t digest[16];
int di;
md5_init(&state);
md5_append(&state, (const md5_byte_t *)oldpasswd, strlen(oldpasswd));
md5_finish(&state, digest);
sprintf(md5_passwd,"\0");
for(di=0; di<16; di++)
sprintf(md5_passwd,"%s%02x",md5_passwd,digest[di]);
}
main(int argc, char **argv)
{
char md5p[33];
if (argc<1 || argc>2 ) perror("error param");
md5_passwd(argv[1], md5p);
printf("pass=%s, md5pass=%s\n", argv[1], md5p);
}
