00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <string.h>
00033 #include "md4.h"
00034
00035 static struct mdfour *m;
00036
00037 #define F(X,Y,Z) (((X)&(Y)) | ((~(X))&(Z)))
00038 #define G(X,Y,Z) (((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z)))
00039 #define H(X,Y,Z) ((X)^(Y)^(Z))
00040 #ifdef LARGE_INT32
00041 #define lshift(x,s) ((((x)<<(s))&0xFFFFFFFF) | (((x)>>(32-(s)))&0xFFFFFFFF))
00042 #else
00043 #define lshift(x,s) (((x)<<(s)) | ((x)>>(32-(s))))
00044 #endif
00045
00046 #define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
00047 #define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + 0x5A827999,s)
00048 #define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + 0x6ED9EBA1,s)
00049
00050
00051 static void mdfour64 (uint32_t *M)
00052 {
00053 int j;
00054 uint32_t AA, BB, CC, DD;
00055 uint32_t X[16];
00056 uint32_t A, B, C, D;
00057
00058 for (j = 0; j < 16; j++)
00059 X[j] = M[j];
00060
00061 A = m->A; B = m->B; C = m->C; D = m->D;
00062 AA = A; BB = B; CC = C; DD = D;
00063
00064 ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
00065 ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19);
00066 ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
00067 ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19);
00068 ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
00069 ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19);
00070 ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);
00071 ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19);
00072
00073 ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5);
00074 ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13);
00075 ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);
00076 ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13);
00077 ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
00078 ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13);
00079 ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
00080 ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13);
00081
00082 ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9);
00083 ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15);
00084 ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
00085 ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15);
00086 ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
00087 ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15);
00088 ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);
00089 ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15);
00090
00091 A += AA; B += BB; C += CC; D += DD;
00092
00093 #ifdef LARGE_INT32
00094 A &= 0xFFFFFFFF; B &= 0xFFFFFFFF;
00095 C &= 0xFFFFFFFF; D &= 0xFFFFFFFF;
00096 #endif
00097
00098 for (j = 0; j < 16; j++)
00099 X[j] = 0;
00100
00101 m->A = A; m->B = B; m->C = C; m->D = D;
00102 }
00103
00104 static void copy64 (uint32_t *M, const unsigned char *in)
00105 {
00106 int i;
00107
00108 for (i = 0; i < 16; i++)
00109 M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) | (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
00110 }
00111
00112 static void copy4 (unsigned char *out, uint32_t x)
00113 {
00114 out[0] = x&0xFF;
00115 out[1] = (x>>8)&0xFF;
00116 out[2] = (x>>16)&0xFF;
00117 out[3] = (x>>24)&0xFF;
00118 }
00119
00120 static void mdfour_begin (struct mdfour *md)
00121 {
00122 md->A = 0x67452301;
00123 md->B = 0xefcdab89;
00124 md->C = 0x98badcfe;
00125 md->D = 0x10325476;
00126 md->totalN = 0;
00127 }
00128
00129
00130 static void mdfour_tail (const unsigned char *in, int n)
00131 {
00132 unsigned char buf[128];
00133 uint32_t M[16];
00134 uint32_t b;
00135
00136 m->totalN += n;
00137
00138 b = m->totalN * 8;
00139
00140 memset(buf, 0, 128);
00141 if (n)
00142 memcpy(buf, in, n);
00143 buf[n] = 0x80;
00144
00145 if (n <= 55) {
00146 copy4(buf + 56, b);
00147 copy64(M, buf);
00148 mdfour64(M);
00149 } else {
00150 copy4(buf + 120, b);
00151 copy64(M, buf);
00152 mdfour64(M);
00153 copy64(M, buf + 64);
00154 mdfour64(M);
00155 }
00156 }
00157
00158 static void mdfour_update (struct mdfour *md, const unsigned char *in, int n)
00159 {
00160 uint32_t M[16];
00161
00168 m = md;
00169
00170 while (n >= 64) {
00171 copy64(M, in);
00172 mdfour64(M);
00173 in += 64;
00174 n -= 64;
00175 m->totalN += 64;
00176 }
00177
00178 mdfour_tail(in, n);
00179 }
00180
00181
00182 static void mdfour_result (struct mdfour *md, unsigned char *out)
00183 {
00184 m = md;
00185
00186 copy4(out, m->A);
00187 copy4(out + 4, m->B);
00188 copy4(out + 8, m->C);
00189 copy4(out + 12, m->D);
00190 }
00191
00192
00193 static void mdfour (unsigned char *out, const unsigned char *in, int n)
00194 {
00195 struct mdfour md;
00196 mdfour_begin(&md);
00197 mdfour_update(&md, in, n);
00198 mdfour_result(&md, out);
00199 }
00200
00208 unsigned Com_BlockChecksum (const void *buffer, int length)
00209 {
00210 int digest[4];
00211 unsigned val;
00212
00213 mdfour((unsigned char *) digest, (const unsigned char *) buffer, length);
00214
00215 val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3];
00216
00217 return val;
00218 }