X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/03e2d0e329575f0ca6f7843e9ceae1cd5341902b..0f78b81511be65d8fe21af1e6ac674f9e80ac29d:/lib/mdfour.c diff --git a/lib/mdfour.c b/lib/mdfour.c index 0a059dcd..d231a3ed 100644 --- a/lib/mdfour.c +++ b/lib/mdfour.c @@ -1,57 +1,51 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. - a implementation of MD4 designed for use in the SMB authentication protocol - Copyright (C) Andrew Tridgell 1997-1998. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ + * Unix SMB/Netbios implementation. + * Version 1.9. + * An implementation of MD4 designed for use in the SMB authentication protocol. + * + * Copyright (C) 1997-1998 Andrew Tridgell + * Copyright (C) 2005 Wayne Davison + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ #include "rsync.h" /* NOTE: This code makes no attempt to be fast! - - It assumes that a int is at least 32 bits long -*/ + * + * It assumes that a int is at least 32 bits long. */ static struct mdfour *m; -#define F(X,Y,Z) (((X)&(Y)) | ((~(X))&(Z))) -#define G(X,Y,Z) (((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z))) -#define H(X,Y,Z) ((X)^(Y)^(Z)) -#ifdef LARGE_INT32 -#define lshift(x,s) ((((x)<<(s))&0xFFFFFFFF) | (((x)>>(32-(s)))&0xFFFFFFFF)) -#else -#define lshift(x,s) (((x)<<(s)) | ((x)>>(32-(s)))) -#endif +#define MASK32 (0xffffffff) + +#define F(X,Y,Z) ((((X)&(Y)) | ((~(X))&(Z)))) +#define G(X,Y,Z) ((((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z)))) +#define H(X,Y,Z) (((X)^(Y)^(Z))) +#define lshift(x,s) (((((x)<<(s))&MASK32) | (((x)>>(32-(s)))&MASK32))) -#define ROUND1(a,b,c,d,k,s) a = lshift((uint32)(a + F(b,c,d) + X[k]), s) -#define ROUND2(a,b,c,d,k,s) a = lshift((uint32)(a + G(b,c,d) + X[k] + 0x5A827999),s) -#define ROUND3(a,b,c,d,k,s) a = lshift((uint32)(a + H(b,c,d) + X[k] + 0x6ED9EBA1),s) +#define ROUND1(a,b,c,d,k,s) a = lshift((a + F(b,c,d) + M[k])&MASK32, s) +#define ROUND2(a,b,c,d,k,s) a = lshift((a + G(b,c,d) + M[k] + 0x5A827999)&MASK32,s) +#define ROUND3(a,b,c,d,k,s) a = lshift((a + H(b,c,d) + M[k] + 0x6ED9EBA1)&MASK32,s) /* this applies md4 to 64 byte chunks */ static void mdfour64(uint32 *M) { - int j; uint32 AA, BB, CC, DD; - uint32 X[16]; uint32 A,B,C,D; - for (j=0;j<16;j++) - X[j] = M[j]; - A = m->A; B = m->B; C = m->C; D = m->D; AA = A; BB = B; CC = C; DD = D; @@ -64,6 +58,7 @@ static void mdfour64(uint32 *M) ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7); ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19); + ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5); ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13); ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5); @@ -82,15 +77,11 @@ static void mdfour64(uint32 *M) ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9); ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15); - A += AA; B += BB; C += CC; D += DD; + A += AA; B += BB; + C += CC; D += DD; -#ifdef LARGE_INT32 - A &= 0xFFFFFFFF; B &= 0xFFFFFFFF; - C &= 0xFFFFFFFF; D &= 0xFFFFFFFF; -#endif - - for (j=0;j<16;j++) - X[j] = 0; + A &= MASK32; B &= MASK32; + C &= MASK32; D &= MASK32; m->A = A; m->B = B; m->C = C; m->D = D; } @@ -119,29 +110,53 @@ void mdfour_begin(struct mdfour *md) md->C = 0x98badcfe; md->D = 0x10325476; md->totalN = 0; + md->totalN2 = 0; } -static void mdfour_tail(unsigned char *in, int n) +static void mdfour_tail(unsigned char *in, uint32 n) { unsigned char buf[128]; uint32 M[16]; - uint32 b; - - m->totalN += n; - - b = m->totalN * 8; + extern int protocol_version; + + /* + * Count total number of bits, modulo 2^64 + */ + m->totalN += n << 3; + if (m->totalN < (n << 3)) { + m->totalN2++; + } + m->totalN2 += n >> 29; memset(buf, 0, 128); if (n) memcpy(buf, in, n); buf[n] = 0x80; if (n <= 55) { - copy4(buf+56, b); + copy4(buf+56, m->totalN); + /* + * Prior to protocol version 27 only the number of bits + * modulo 2^32 was included. MD4 requires the number + * of bits modulo 2^64, which was fixed starting with + * protocol version 27. + */ + if (protocol_version >= 27) { + copy4(buf+60, m->totalN2); + } copy64(M, buf); mdfour64(M); } else { - copy4(buf+120, b); + copy4(buf+120, m->totalN); + /* + * Prior to protocol version 27 only the number of bits + * modulo 2^32 was included. MD4 requires the number + * of bits modulo 2^64, which was fixed starting with + * protocol version 27. + */ + if (protocol_version >= 27) { + copy4(buf+124, m->totalN2); + } copy64(M, buf); mdfour64(M); copy64(M, buf+64); @@ -149,20 +164,23 @@ static void mdfour_tail(unsigned char *in, int n) } } -void mdfour_update(struct mdfour *md, unsigned char *in, int n) +void mdfour_update(struct mdfour *md, unsigned char *in, uint32 n) { uint32 M[16]; - if (n == 0) mdfour_tail(in, n); - m = md; + if (n == 0) mdfour_tail(in, n); + while (n >= 64) { copy64(M, in); mdfour64(M); in += 64; n -= 64; - m->totalN += 64; + m->totalN += 64 << 3; + if (m->totalN < 64 << 3) { + m->totalN2++; + } } if (n) mdfour_tail(in, n); @@ -189,9 +207,11 @@ void mdfour(unsigned char *out, unsigned char *in, int n) } #ifdef TEST_MDFOUR +int protocol_version = 28; + static void file_checksum1(char *fname) { - int fd, i; + int fd, i, was_multiple_of_64 = 1; struct mdfour md; unsigned char buf[64*1024], sum[16]; @@ -205,9 +225,13 @@ static void file_checksum1(char *fname) while (1) { int n = read(fd, buf, sizeof(buf)); - if (n <= 0) break; + if (n <= 0) + break; + was_multiple_of_64 = !(n % 64); mdfour_update(&md, buf, n); } + if (was_multiple_of_64 && protocol_version >= 27) + mdfour_update(&md, buf, 0); close(fd);