00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "rsync.h"
00023
00024
00025
00026
00027
00028
00029 static struct mdfour *m;
00030
00031 #define MASK32 (0xffffffff)
00032
00033 #define F(X,Y,Z) ((((X)&(Y)) | ((~(X))&(Z))))
00034 #define G(X,Y,Z) ((((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z))))
00035 #define H(X,Y,Z) (((X)^(Y)^(Z)))
00036 #define lshift(x,s) (((((x)<<(s))&MASK32) | (((x)>>(32-(s)))&MASK32)))
00037
00038 #define ROUND1(a,b,c,d,k,s) a = lshift((a + F(b,c,d) + M[k])&MASK32, s)
00039 #define ROUND2(a,b,c,d,k,s) a = lshift((a + G(b,c,d) + M[k] + 0x5A827999)&MASK32,s)
00040 #define ROUND3(a,b,c,d,k,s) a = lshift((a + H(b,c,d) + M[k] + 0x6ED9EBA1)&MASK32,s)
00041
00042
00043 static void mdfour64(uint32 *M)
00044 {
00045 uint32 AA, BB, CC, DD;
00046 uint32 A,B,C,D;
00047
00048 A = m->A; B = m->B; C = m->C; D = m->D;
00049 AA = A; BB = B; CC = C; DD = D;
00050
00051 ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
00052 ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19);
00053 ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
00054 ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19);
00055 ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
00056 ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19);
00057 ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);
00058 ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19);
00059
00060
00061 ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5);
00062 ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13);
00063 ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);
00064 ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13);
00065 ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
00066 ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13);
00067 ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
00068 ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13);
00069
00070 ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9);
00071 ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15);
00072 ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
00073 ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15);
00074 ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
00075 ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15);
00076 ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);
00077 ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15);
00078
00079 A += AA; B += BB;
00080 C += CC; D += DD;
00081
00082 A &= MASK32; B &= MASK32;
00083 C &= MASK32; D &= MASK32;
00084
00085 m->A = A; m->B = B; m->C = C; m->D = D;
00086 }
00087
00088 static void copy64(uint32 *M, unsigned char *in)
00089 {
00090 int i;
00091
00092 for (i=0;i<16;i++)
00093 M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
00094 (in[i*4+1]<<8) | (in[i*4+0]<<0);
00095 }
00096
00097 static void copy4(unsigned char *out,uint32 x)
00098 {
00099 out[0] = x&0xFF;
00100 out[1] = (x>>8)&0xFF;
00101 out[2] = (x>>16)&0xFF;
00102 out[3] = (x>>24)&0xFF;
00103 }
00104
00105 void mdfour_begin(struct mdfour *md)
00106 {
00107 md->A = 0x67452301;
00108 md->B = 0xefcdab89;
00109 md->C = 0x98badcfe;
00110 md->D = 0x10325476;
00111 md->totalN = 0;
00112 }
00113
00114
00115 static void mdfour_tail(unsigned char *in, int n)
00116 {
00117 unsigned char buf[128];
00118 uint32 M[16];
00119 uint32 b;
00120
00121 m->totalN += n;
00122
00123 b = m->totalN * 8;
00124
00125 memset(buf, 0, 128);
00126 if (n) memcpy(buf, in, n);
00127 buf[n] = 0x80;
00128
00129 if (n <= 55) {
00130 copy4(buf+56, b);
00131 copy64(M, buf);
00132 mdfour64(M);
00133 } else {
00134 copy4(buf+120, b);
00135 copy64(M, buf);
00136 mdfour64(M);
00137 copy64(M, buf+64);
00138 mdfour64(M);
00139 }
00140 }
00141
00142 void mdfour_update(struct mdfour *md, unsigned char *in, int n)
00143 {
00144 uint32 M[16];
00145
00146 if (n == 0) mdfour_tail(in, n);
00147
00148 m = md;
00149
00150 while (n >= 64) {
00151 copy64(M, in);
00152 mdfour64(M);
00153 in += 64;
00154 n -= 64;
00155 m->totalN += 64;
00156 }
00157
00158 if (n) mdfour_tail(in, n);
00159 }
00160
00161
00162 void mdfour_result(struct mdfour *md, unsigned char *out)
00163 {
00164 m = md;
00165
00166 copy4(out, m->A);
00167 copy4(out+4, m->B);
00168 copy4(out+8, m->C);
00169 copy4(out+12, m->D);
00170 }
00171
00172
00173 void mdfour(unsigned char *out, unsigned char *in, int n)
00174 {
00175 struct mdfour md;
00176 mdfour_begin(&md);
00177 mdfour_update(&md, in, n);
00178 mdfour_result(&md, out);
00179 }
00180
00181 #ifdef TEST_MDFOUR
00182 static void file_checksum1(char *fname)
00183 {
00184 int fd, i;
00185 struct mdfour md;
00186 unsigned char buf[64*1024], sum[16];
00187
00188 fd = open(fname,O_RDONLY);
00189 if (fd == -1) {
00190 perror("fname");
00191 exit(1);
00192 }
00193
00194 mdfour_begin(&md);
00195
00196 while (1) {
00197 int n = read(fd, buf, sizeof(buf));
00198 if (n <= 0) break;
00199 mdfour_update(&md, buf, n);
00200 }
00201
00202 close(fd);
00203
00204 mdfour_result(&md, sum);
00205
00206 for (i=0;i<16;i++)
00207 printf("%02X", sum[i]);
00208 printf("\n");
00209 }
00210
00211 #if 0
00212 #include "../md4.h"
00213
00214 static void file_checksum2(char *fname)
00215 {
00216 int fd, i;
00217 MDstruct md;
00218 unsigned char buf[64], sum[16];
00219
00220 fd = open(fname,O_RDONLY);
00221 if (fd == -1) {
00222 perror("fname");
00223 exit(1);
00224 }
00225
00226 MDbegin(&md);
00227
00228 while (1) {
00229 int n = read(fd, buf, sizeof(buf));
00230 if (n <= 0) break;
00231 MDupdate(&md, buf, n*8);
00232 }
00233
00234 if (!md.done) {
00235 MDupdate(&md, buf, 0);
00236 }
00237
00238 close(fd);
00239
00240 memcpy(sum, md.buffer, 16);
00241
00242 for (i=0;i<16;i++)
00243 printf("%02X", sum[i]);
00244 printf("\n");
00245 }
00246 #endif
00247
00248 int main(int argc, char *argv[])
00249 {
00250 file_checksum1(argv[1]);
00251 #if 0
00252 file_checksum2(argv[1]);
00253 #endif
00254 return 0;
00255 }
00256 #endif