Protocol 30 now uses MD5 checksums instead of MD4.

This commit is contained in:
Wayne Davison committed 2007-03-18 06:00:53 +00:00
1 parent 1a515b494b
commit a0456b9c46
13 files changed
+524 -227

No files matched your search

+1 -1
View File
@@ -27,7 +27,7 @@ VERSION=@VERSION@
.SUFFIXES: .c .o
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h smb_acls.h lib/pool_alloc.h
LIBOBJ=lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o \
LIBOBJ=lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o lib/md5.o \
lib/permstring.o lib/pool_alloc.o lib/sysacls.o @LIBOBJS@
ZLIBOBJ=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o
+11 -9
View File
@@ -57,8 +57,9 @@ void base64_encode(const char *buf, int len, char *out, int pad)
static void gen_challenge(const char *addr, char *challenge)
{
char input[32];
char md4_out[MD4_SUM_LENGTH];
char digest[MAX_DIGEST_LEN];
struct timeval tv;
int len;
memset(input, 0, sizeof input);
@@ -70,9 +71,9 @@ static void gen_challenge(const char *addr, char *challenge)
sum_init(0);
sum_update(input, sizeof input);
sum_end(md4_out);
len = sum_end(digest);
base64_encode(md4_out, MD4_SUM_LENGTH, challenge, 0);
base64_encode(digest, len, challenge, 0);
}
@@ -205,14 +206,15 @@ static const char *getpassf(const char *filename)
* and the challenge string and return it base64-encoded. */
static void generate_hash(const char *in, const char *challenge, char *out)
{
char buf[MD4_SUM_LENGTH];
char buf[MAX_DIGEST_LEN];
int len;
sum_init(0);
sum_update(in, strlen(in));
sum_update(challenge, strlen(challenge));
sum_end(buf);
len = sum_end(buf);
base64_encode(buf, MD4_SUM_LENGTH, out, 0);
base64_encode(buf, len, out, 0);
}
/* Possibly negotiate authentication with the client. Use "leader" to
@@ -225,10 +227,10 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
const char *addr, const char *leader)
{
char *users = lp_auth_users(module);
char challenge[MD4_SUM_LENGTH*2];
char challenge[MAX_DIGEST_LEN*2];
char line[BIGPATHBUFLEN];
char secret[512];
char pass2[MD4_SUM_LENGTH*2];
char pass2[MAX_DIGEST_LEN*2];
char *tok, *pass;
/* if no auth list then allow anyone in! */
@@ -289,7 +291,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
void auth_client(int fd, const char *user, const char *challenge)
{
const char *pass;
char pass2[MD4_SUM_LENGTH*2];
char pass2[MAX_DIGEST_LEN*2];
if (!user || !*user)
user = "nobody";
+105 -67
View File
@@ -21,13 +21,11 @@
#include "rsync.h"
int csum_length = SHORT_SUM_LENGTH; /* initial value */
#define CSUM_CHUNK 64
extern int checksum_seed;
extern int protocol_version;
int csum_length = SHORT_SUM_LENGTH; /* initial value */
/*
a simple 32 bit checksum that can be upadted from either end
(inspired by Mark Adler's Adler-32 checksum)
@@ -53,54 +51,64 @@ uint32 get_checksum1(char *buf1, int32 len)
void get_checksum2(char *buf, int32 len, char *sum)
{
int32 i;
static char *buf1;
static int32 len1;
struct mdfour m;
md_context m;
if (len > len1) {
if (buf1)
free(buf1);
buf1 = new_array(char, len+4);
len1 = len;
if (!buf1)
out_of_memory("get_checksum2");
if (protocol_version >= 30) {
uchar seedbuf[4];
md5_begin(&m);
if (checksum_seed) {
SIVAL(seedbuf, 0, checksum_seed);
md5_update(&m, seedbuf, 4);
}
md5_update(&m, (uchar *)buf, len);
md5_result(&m, (uchar *)sum);
} else {
int32 i;
static char *buf1;
static int32 len1;
mdfour_begin(&m);
if (len > len1) {
if (buf1)
free(buf1);
buf1 = new_array(char, len+4);
len1 = len;
if (!buf1)
out_of_memory("get_checksum2");
}
memcpy(buf1, buf, len);
if (checksum_seed) {
SIVAL(buf1,len,checksum_seed);
len += 4;
}
for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK)
mdfour_update(&m, (uchar *)(buf1+i), CSUM_CHUNK);
/*
* Prior to version 27 an incorrect MD4 checksum was computed
* by failing to call mdfour_tail() for block sizes that
* are multiples of 64. This is fixed by calling mdfour_update()
* even when there are no more bytes.
*/
if (len - i > 0 || protocol_version >= 27)
mdfour_update(&m, (uchar *)(buf1+i), len-i);
mdfour_result(&m, (uchar *)sum);
}
mdfour_begin(&m);
memcpy(buf1,buf,len);
if (checksum_seed) {
SIVAL(buf1,len,checksum_seed);
len += 4;
}
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
mdfour_update(&m, (uchar *)(buf1+i), CSUM_CHUNK);
}
/*
* Prior to version 27 an incorrect MD4 checksum was computed
* by failing to call mdfour_tail() for block sizes that
* are multiples of 64. This is fixed by calling mdfour_update()
* even when there are no more bytes.
*/
if (len - i > 0 || protocol_version >= 27) {
mdfour_update(&m, (uchar *)(buf1+i), (len-i));
}
mdfour_result(&m, (uchar *)sum);
}
void file_checksum(char *fname,char *sum,OFF_T size)
void file_checksum(char *fname, char *sum, OFF_T size)
{
struct map_struct *buf;
OFF_T i, len = size;
struct mdfour m;
md_context m;
int32 remainder;
int fd;
memset(sum,0,MD4_SUM_LENGTH);
memset(sum, 0, MAX_DIGEST_LEN);
fd = do_open(fname, O_RDONLY, 0);
if (fd == -1)
@@ -108,37 +116,55 @@ void file_checksum(char *fname,char *sum,OFF_T size)
buf = map_file(fd, size, MAX_MAP_SIZE, CSUM_CHUNK);
mdfour_begin(&m);
if (protocol_version >= 30) {
md5_begin(&m);
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
mdfour_update(&m, (uchar *)map_ptr(buf, i, CSUM_CHUNK),
CSUM_CHUNK);
for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
md5_update(&m, (uchar *)map_ptr(buf, i, CSUM_CHUNK),
CSUM_CHUNK);
}
remainder = (int32)(len - i);
if (remainder > 0)
md5_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
md5_result(&m, (uchar *)sum);
} else {
mdfour_begin(&m);
for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
mdfour_update(&m, (uchar *)map_ptr(buf, i, CSUM_CHUNK),
CSUM_CHUNK);
}
/* Prior to version 27 an incorrect MD4 checksum was computed
* by failing to call mdfour_tail() for block sizes that
* are multiples of 64. This is fixed by calling mdfour_update()
* even when there are no more bytes. */
remainder = (int32)(len - i);
if (remainder > 0 || protocol_version >= 27)
mdfour_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
mdfour_result(&m, (uchar *)sum);
}
/* Prior to version 27 an incorrect MD4 checksum was computed
* by failing to call mdfour_tail() for block sizes that
* are multiples of 64. This is fixed by calling mdfour_update()
* even when there are no more bytes. */
remainder = (int32)(len - i);
if (remainder > 0 || protocol_version >= 27)
mdfour_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
mdfour_result(&m, (uchar *)sum);
close(fd);
unmap_file(buf);
}
static int32 sumresidue;
static char sumrbuf[CSUM_CHUNK];
static struct mdfour md;
static md_context md;
void sum_init(int seed)
{
char s[4];
mdfour_begin(&md);
sumresidue = 0;
if (protocol_version >= 30)
md5_begin(&md);
else {
mdfour_begin(&md);
sumresidue = 0;
}
SIVAL(s, 0, seed);
sum_update(s, 4);
}
@@ -153,16 +179,21 @@ void sum_init(int seed)
**/
void sum_update(const char *p, int32 len)
{
if (protocol_version >= 30) {
md5_update(&md, (uchar *)p, len);
return;
}
if (len + sumresidue < CSUM_CHUNK) {
memcpy(sumrbuf + sumresidue, p, len);
memcpy(md.buffer + sumresidue, p, len);
sumresidue += len;
return;
}
if (sumresidue) {
int32 i = CSUM_CHUNK - sumresidue;
memcpy(sumrbuf + sumresidue, p, i);
mdfour_update(&md, (uchar *)sumrbuf, CSUM_CHUNK);
memcpy(md.buffer + sumresidue, p, i);
mdfour_update(&md, (uchar *)md.buffer, CSUM_CHUNK);
len -= i;
p += i;
}
@@ -175,13 +206,20 @@ void sum_update(const char *p, int32 len)
sumresidue = len;
if (sumresidue)
memcpy(sumrbuf, p, sumresidue);
memcpy(md.buffer, p, sumresidue);
}
void sum_end(char *sum)
int sum_end(char *sum)
{
if (protocol_version >= 30) {
md5_result(&md, (uchar *)sum);
return MD5_DIGEST_LEN;
}
if (sumresidue || protocol_version >= 27)
mdfour_update(&md, (uchar *)sumrbuf, sumresidue);
mdfour_update(&md, (uchar *)md.buffer, sumresidue);
mdfour_result(&md, (uchar *)sum);
return MD4_DIGEST_LEN;
}
+5 -3
View File
@@ -85,9 +85,9 @@ static dev_t tmp_rdev;
#ifdef SUPPORT_HARD_LINKS
static int64 tmp_dev, tmp_ino;
#endif
static char tmp_sum[MD4_SUM_LENGTH];
static char tmp_sum[MAX_DIGEST_LEN];
static char empty_sum[MD4_SUM_LENGTH];
static char empty_sum[MAX_DIGEST_LEN];
static int flist_count_offset; /* for --delete --progress */
static void clean_flist(struct file_list *flist, int strip_root, int no_dups);
@@ -99,7 +99,9 @@ void init_flist(void)
rprintf(FINFO, "FILE_STRUCT_LEN=%d, EXTRA_LEN=%d\n",
(int)FILE_STRUCT_LEN, (int)EXTRA_LEN);
}
checksum_len = protocol_version < 21 ? 2 : MD4_SUM_LENGTH;
checksum_len = protocol_version < 21 ? 2
: protocol_version < 30 ? MD4_DIGEST_LEN
: MD5_DIGEST_LEN;
}
static int show_filelist_p(void)
+1 -1
View File
@@ -598,7 +598,7 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
/* if always checksum is set then we use the checksum instead
of the file time to determine whether to sync */
if (always_checksum > 0 && S_ISREG(st->st_mode)) {
char sum[MD4_SUM_LENGTH];
char sum[MAX_DIGEST_LEN];
file_checksum(fn, sum, st->st_size);
return memcmp(sum, F_SUM(file), checksum_len) == 0;
}
+1 -1
View File
@@ -1159,7 +1159,7 @@ void read_sum_head(int f, struct sum_struct *sum)
exit_cleanup(RERR_PROTOCOL);
}
sum->s2length = protocol_version < 27 ? csum_length : (int)read_int(f);
if (sum->s2length < 0 || sum->s2length > MD4_SUM_LENGTH) {
if (sum->s2length < 0 || sum->s2length > MAX_DIGEST_LEN) {
rprintf(FERROR, "Invalid checksum length %d [%s]\n",
sum->s2length, who_am_i());
exit_cleanup(RERR_PROTOCOL);
+305
View File
@@ -0,0 +1,305 @@
/*
* RFC 1321 compliant MD5 implementation
*
* Copyright (C) 2001-2003 Christophe Devine
*
* 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.,
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "rsync.h"
void md5_begin(md_context *ctx)
{
ctx->A = 0x67452301;
ctx->B = 0xEFCDAB89;
ctx->C = 0x98BADCFE;
ctx->D = 0x10325476;
ctx->totalN = ctx->totalN2 = 0;
}
static void md5_process(md_context *ctx, const uchar data[CSUM_CHUNK])
{
uint32 X[16], A, B, C, D;
A = ctx->A;
B = ctx->B;
C = ctx->C;
D = ctx->D;
X[0] = IVAL(data, 0);
X[1] = IVAL(data, 4);
X[2] = IVAL(data, 8);
X[3] = IVAL(data, 12);
X[4] = IVAL(data, 16);
X[5] = IVAL(data, 20);
X[6] = IVAL(data, 24);
X[7] = IVAL(data, 28);
X[8] = IVAL(data, 32);
X[9] = IVAL(data, 36);
X[10] = IVAL(data, 40);
X[11] = IVAL(data, 44);
X[12] = IVAL(data, 48);
X[13] = IVAL(data, 52);
X[14] = IVAL(data, 56);
X[15] = IVAL(data, 60);
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define P(a,b,c,d,k,s,t) a += F(b,c,d) + X[k] + t, a = S(a,s) + b
#define F(x,y,z) (z ^ (x & (y ^ z)))
P(A, B, C, D, 0, 7, 0xD76AA478);
P(D, A, B, C, 1, 12, 0xE8C7B756);
P(C, D, A, B, 2, 17, 0x242070DB);
P(B, C, D, A, 3, 22, 0xC1BDCEEE);
P(A, B, C, D, 4, 7, 0xF57C0FAF);
P(D, A, B, C, 5, 12, 0x4787C62A);
P(C, D, A, B, 6, 17, 0xA8304613);
P(B, C, D, A, 7, 22, 0xFD469501);
P(A, B, C, D, 8, 7, 0x698098D8);
P(D, A, B, C, 9, 12, 0x8B44F7AF);
P(C, D, A, B, 10, 17, 0xFFFF5BB1);
P(B, C, D, A, 11, 22, 0x895CD7BE);
P(A, B, C, D, 12, 7, 0x6B901122);
P(D, A, B, C, 13, 12, 0xFD987193);
P(C, D, A, B, 14, 17, 0xA679438E);
P(B, C, D, A, 15, 22, 0x49B40821);
#undef F
#define F(x,y,z) (y ^ (z & (x ^ y)))
P(A, B, C, D, 1, 5, 0xF61E2562);
P(D, A, B, C, 6, 9, 0xC040B340);
P(C, D, A, B, 11, 14, 0x265E5A51);
P(B, C, D, A, 0, 20, 0xE9B6C7AA);
P(A, B, C, D, 5, 5, 0xD62F105D);
P(D, A, B, C, 10, 9, 0x02441453);
P(C, D, A, B, 15, 14, 0xD8A1E681);
P(B, C, D, A, 4, 20, 0xE7D3FBC8);
P(A, B, C, D, 9, 5, 0x21E1CDE6);
P(D, A, B, C, 14, 9, 0xC33707D6);
P(C, D, A, B, 3, 14, 0xF4D50D87);
P(B, C, D, A, 8, 20, 0x455A14ED);
P(A, B, C, D, 13, 5, 0xA9E3E905);
P(D, A, B, C, 2, 9, 0xFCEFA3F8);
P(C, D, A, B, 7, 14, 0x676F02D9);
P(B, C, D, A, 12, 20, 0x8D2A4C8A);
#undef F
#define F(x,y,z) (x ^ y ^ z)
P(A, B, C, D, 5, 4, 0xFFFA3942);
P(D, A, B, C, 8, 11, 0x8771F681);
P(C, D, A, B, 11, 16, 0x6D9D6122);
P(B, C, D, A, 14, 23, 0xFDE5380C);
P(A, B, C, D, 1, 4, 0xA4BEEA44);
P(D, A, B, C, 4, 11, 0x4BDECFA9);
P(C, D, A, B, 7, 16, 0xF6BB4B60);
P(B, C, D, A, 10, 23, 0xBEBFBC70);
P(A, B, C, D, 13, 4, 0x289B7EC6);
P(D, A, B, C, 0, 11, 0xEAA127FA);
P(C, D, A, B, 3, 16, 0xD4EF3085);
P(B, C, D, A, 6, 23, 0x04881D05);
P(A, B, C, D, 9, 4, 0xD9D4D039);
P(D, A, B, C, 12, 11, 0xE6DB99E5);
P(C, D, A, B, 15, 16, 0x1FA27CF8);
P(B, C, D, A, 2, 23, 0xC4AC5665);
#undef F
#define F(x,y,z) (y ^ (x | ~z))
P(A, B, C, D, 0, 6, 0xF4292244);
P(D, A, B, C, 7, 10, 0x432AFF97);
P(C, D, A, B, 14, 15, 0xAB9423A7);
P(B, C, D, A, 5, 21, 0xFC93A039);
P(A, B, C, D, 12, 6, 0x655B59C3);
P(D, A, B, C, 3, 10, 0x8F0CCC92);
P(C, D, A, B, 10, 15, 0xFFEFF47D);
P(B, C, D, A, 1, 21, 0x85845DD1);
P(A, B, C, D, 8, 6, 0x6FA87E4F);
P(D, A, B, C, 15, 10, 0xFE2CE6E0);
P(C, D, A, B, 6, 15, 0xA3014314);
P(B, C, D, A, 13, 21, 0x4E0811A1);
P(A, B, C, D, 4, 6, 0xF7537E82);
P(D, A, B, C, 11, 10, 0xBD3AF235);
P(C, D, A, B, 2, 15, 0x2AD7D2BB);
P(B, C, D, A, 9, 21, 0xEB86D391);
#undef F
ctx->A += A;
ctx->B += B;
ctx->C += C;
ctx->D += D;
}
void md5_update(md_context *ctx, const uchar *input, uint32 length)
{
uint32 left, fill;
if (!length)
return;
left = ctx->totalN & 0x3F;
fill = CSUM_CHUNK - left;
ctx->totalN += length;
ctx->totalN &= 0xFFFFFFFF;
if (ctx->totalN < length)
ctx->totalN2++;
if (left && length >= fill) {
memcpy(ctx->buffer + left, input, fill);
md5_process(ctx, ctx->buffer);
length -= fill;
input += fill;
left = 0;
}
while (length >= CSUM_CHUNK) {
md5_process(ctx, input);
length -= CSUM_CHUNK;
input += CSUM_CHUNK;
}
if (length)
memcpy(ctx->buffer + left, input, length);
}
static uchar md5_padding[CSUM_CHUNK] = { 0x80 };
void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN])
{
uint32 last, padn;
uint32 high, low;
uchar msglen[8];
high = (ctx->totalN >> 29)
| (ctx->totalN2 << 3);
low = (ctx->totalN << 3);
SIVAL(msglen, 0, low);
SIVAL(msglen, 4, high);
last = ctx->totalN & 0x3F;
padn = last < 56 ? 56 - last : 120 - last;
md5_update(ctx, md5_padding, padn);
md5_update(ctx, msglen, 8);
SIVAL(digest, 0, ctx->A);
SIVAL(digest, 4, ctx->B);
SIVAL(digest, 8, ctx->C);
SIVAL(digest, 12, ctx->D);
}
void get_md5(uchar *out, const uchar *input, int n)
{
md_context ctx;
md5_begin(&ctx);
md5_update(&ctx, input, n);
md5_result(&ctx, out);
}
#ifdef TEST_MD5
#include <stdlib.h>
#include <stdio.h>
/*
* those are the standard RFC 1321 test vectors
*/
static struct {
char *str, *md5;
} tests[] = {
{ "",
"d41d8cd98f00b204e9800998ecf8427e" },
{ "a",
"0cc175b9c0f1b6a831c399e269772661" },
{ "abc",
"900150983cd24fb0d6963f7d28e17f72" },
{ "message digest",
"f96b697d7cb7938d525a2f31aaf161d0" },
{ "abcdefghijklmnopqrstuvwxyz",
"c3fcd3d76192e4007dfb496cca67e13b" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"d174ab98d277d9f5a5611c2c9f419d9f" },
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
"57edf4a22be3c955ac49da2e2107b67a" },
{ NULL, NULL }
};
int main(int argc, char *argv[])
{
FILE *f;
int i, j;
char output[33];
md_context ctx;
uchar buf[1000];
uchar md5sum[MD5_DIGEST_LEN];
if (argc < 2) {
printf("\nMD5 Validation Tests:\n\n");
for (i = 0; tests[i].str; i++) {
char *str = tests[i].str;
char *chk = tests[i].md5;
printf(" Test %d ", i + 1);
get_md5(md5sum, str, strlen(str));
for (j = 0; j < MD5_DIGEST_LEN; j++)
sprintf(output + j * 2, "%02x", md5sum[j]);
if (memcmp(output, chk, 32)) {
printf("failed!\n");
return 1;
}
printf("passed.\n");
}
printf("\n");
return 0;
}
while (--argc) {
if (!(f = fopen(*++argv, "rb"))) {
perror("fopen");
return 1;
}
md5_begin(&ctx);
while ((i = fread(buf, 1, sizeof buf, f)) > 0)
md5_update(&ctx, buf, i);
md5_result(&ctx, md5sum);
for (j = 0; j < MD5_DIGEST_LEN; j++)
printf("%02x", md5sum[j]);
printf(" %s\n", *argv);
}
return 0;
}
#endif
+54 -97
View File
@@ -4,7 +4,7 @@
* An implementation of MD4 designed for use in the SMB authentication protocol.
*
* Copyright (C) 1997-1998 Andrew Tridgell
* Copyright (C) 2005 Wayne Davison
* Copyright (C) 2005-2007 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
@@ -27,7 +27,7 @@
*
* It assumes that a int is at least 32 bits long. */
static struct mdfour *m;
static md_context *m;
#define MASK32 (0xffffffff)
@@ -49,32 +49,31 @@ static void mdfour64(uint32 *M)
A = m->A; B = m->B; C = m->C; D = m->D;
AA = A; BB = B; CC = C; DD = D;
ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19);
ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19);
ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19);
ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);
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(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);
ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);
ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13);
ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13);
ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13);
ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9);
ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15);
ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15);
ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15);
ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);
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;
@@ -86,16 +85,17 @@ static void mdfour64(uint32 *M)
m->A = A; m->B = B; m->C = C; m->D = D;
}
static void copy64(uint32 *M, unsigned char *in)
static void copy64(uint32 *M, const uchar *in)
{
int i;
for (i=0;i<16;i++)
M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
(in[i*4+1]<<8) | (in[i*4+0]<<0);
for (i = 0; i < MD4_DIGEST_LEN; i++) {
M[i] = (in[i*4+3] << 24) | (in[i*4+2] << 16)
| (in[i*4+1] << 8) | (in[i*4+0] << 0);
}
}
static void copy4(unsigned char *out,uint32 x)
static void copy4(uchar *out,uint32 x)
{
out[0] = x&0xFF;
out[1] = (x>>8)&0xFF;
@@ -103,7 +103,7 @@ static void copy4(unsigned char *out,uint32 x)
out[3] = (x>>24)&0xFF;
}
void mdfour_begin(struct mdfour *md)
void mdfour_begin(md_context *md)
{
md->A = 0x67452301;
md->B = 0xefcdab89;
@@ -113,27 +113,26 @@ void mdfour_begin(struct mdfour *md)
md->totalN2 = 0;
}
static void mdfour_tail(unsigned char *in, uint32 n)
static void mdfour_tail(const uchar *in, uint32 length)
{
unsigned char buf[128];
uchar buf[128];
uint32 M[16];
extern int protocol_version;
/*
* Count total number of bits, modulo 2^64
*/
m->totalN += n << 3;
if (m->totalN < (n << 3)) {
m->totalN += length << 3;
if (m->totalN < (length << 3))
m->totalN2++;
}
m->totalN2 += n >> 29;
m->totalN2 += length >> 29;
memset(buf, 0, 128);
if (n) memcpy(buf, in, n);
buf[n] = 0x80;
if (length)
memcpy(buf, in, length);
buf[length] = 0x80;
if (n <= 55) {
if (length <= 55) {
copy4(buf+56, m->totalN);
/*
* Prior to protocol version 27 only the number of bits
@@ -141,9 +140,8 @@ static void mdfour_tail(unsigned char *in, uint32 n)
* of bits modulo 2^64, which was fixed starting with
* protocol version 27.
*/
if (protocol_version >= 27) {
if (protocol_version >= 27)
copy4(buf+60, m->totalN2);
}
copy64(M, buf);
mdfour64(M);
} else {
@@ -154,9 +152,8 @@ static void mdfour_tail(unsigned char *in, uint32 n)
* of bits modulo 2^64, which was fixed starting with
* protocol version 27.
*/
if (protocol_version >= 27) {
if (protocol_version >= 27)
copy4(buf+124, m->totalN2);
}
copy64(M, buf);
mdfour64(M);
copy64(M, buf+64);
@@ -164,46 +161,45 @@ static void mdfour_tail(unsigned char *in, uint32 n)
}
}
void mdfour_update(struct mdfour *md, unsigned char *in, uint32 n)
void mdfour_update(md_context *md, const uchar *in, uint32 length)
{
uint32 M[16];
m = md;
if (n == 0) mdfour_tail(in, n);
if (length == 0)
mdfour_tail(in, length);
while (n >= 64) {
while (length >= 64) {
copy64(M, in);
mdfour64(M);
in += 64;
n -= 64;
length -= 64;
m->totalN += 64 << 3;
if (m->totalN < 64 << 3) {
if (m->totalN < 64 << 3)
m->totalN2++;
}
}
if (n) mdfour_tail(in, n);
if (length)
mdfour_tail(in, length);
}
void mdfour_result(struct mdfour *md, unsigned char *out)
void mdfour_result(md_context *md, uchar digest[MD4_DIGEST_LEN])
{
m = md;
copy4(out, m->A);
copy4(out+4, m->B);
copy4(out+8, m->C);
copy4(out+12, m->D);
copy4(digest, m->A);
copy4(digest+4, m->B);
copy4(digest+8, m->C);
copy4(digest+12, m->D);
}
void mdfour(unsigned char *out, unsigned char *in, int n)
void mdfour(uchar digest[MD4_DIGEST_LEN], uchar *in, int length)
{
struct mdfour md;
md_context md;
mdfour_begin(&md);
mdfour_update(&md, in, n);
mdfour_result(&md, out);
mdfour_update(&md, in, length);
mdfour_result(&md, digest);
}
#ifdef TEST_MDFOUR
@@ -212,8 +208,8 @@ int protocol_version = 28;
static void file_checksum1(char *fname)
{
int fd, i, was_multiple_of_64 = 1;
struct mdfour md;
unsigned char buf[64*1024], sum[16];
md_context md;
uchar buf[64*1024], sum[MD4_DIGEST_LEN];
fd = open(fname,O_RDONLY);
if (fd == -1) {
@@ -224,7 +220,7 @@ static void file_checksum1(char *fname)
mdfour_begin(&md);
while (1) {
int n = read(fd, buf, sizeof(buf));
int n = read(fd, buf, sizeof buf);
if (n <= 0)
break;
was_multiple_of_64 = !(n % 64);
@@ -237,54 +233,15 @@ static void file_checksum1(char *fname)
mdfour_result(&md, sum);
for (i=0;i<16;i++)
for (i = 0; i < MD4_DIGEST_LEN; i++)
printf("%02X", sum[i]);
printf("\n");
}
#if 0
#include "../md4.h"
static void file_checksum2(char *fname)
{
int fd, i;
MDstruct md;
unsigned char buf[64], sum[16];
fd = open(fname,O_RDONLY);
if (fd == -1) {
perror("fname");
exit(1);
}
MDbegin(&md);
while (1) {
int n = read(fd, buf, sizeof(buf));
if (n <= 0) break;
MDupdate(&md, buf, n*8);
}
if (!md.done) {
MDupdate(&md, buf, 0);
}
close(fd);
memcpy(sum, md.buffer, 16);
for (i=0;i<16;i++)
printf("%02X", sum[i]);
printf("\n");
}
#endif
int main(int argc, char *argv[])
{
file_checksum1(argv[1]);
#if 0
file_checksum2(argv[1]);
#endif
while (--argc)
file_checksum1(*++argv);
return 0;
}
#endif
-32
View File
@@ -1,32 +0,0 @@
/*
* 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
*
* 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.,
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
struct mdfour {
uint32 A, B, C, D;
uint32 totalN; /* bit count, lower 32 bits */
uint32 totalN2; /* bit count, upper 32 bits */
};
void mdfour_begin(struct mdfour *md);
void mdfour_update(struct mdfour *md, unsigned char *in, uint32 n);
void mdfour_result(struct mdfour *md, unsigned char *out);
void mdfour(unsigned char *out, unsigned char *in, int n);
+26
View File
@@ -0,0 +1,26 @@
/* The include file for both the MD4 and MD5 routines. */
#define MD4_DIGEST_LEN 16
#define MD5_DIGEST_LEN 16
#define MAX_DIGEST_LEN MD5_DIGEST_LEN
#define CSUM_CHUNK 64
typedef struct {
uint32 A, B, C, D;
uint32 totalN; /* bit count, lower 32 bits */
uint32 totalN2; /* bit count, upper 32 bits */
uchar buffer[CSUM_CHUNK];
} md_context;
void mdfour_begin(md_context *md);
void mdfour_update(md_context *md, const uchar *in, uint32 length);
void mdfour_result(md_context *md, uchar digest[MD4_DIGEST_LEN]);
void get_mdfour(uchar digest[MD4_DIGEST_LEN], const uchar *in, int length);
void md5_begin(md_context *ctx);
void md5_update(md_context *ctx, const uchar *input, uint32 length);
void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN]);
void get_md5(uchar digest[MD5_DIGEST_LEN], const uchar *input, int n);
+7 -6
View File
@@ -303,7 +303,8 @@ static void hash_search(int f,struct sum_struct *s,
**/
void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
{
char file_sum[MD4_SUM_LENGTH];
char file_sum[MAX_DIGEST_LEN];
int sum_len;
last_match = 0;
false_alarms = 0;
@@ -323,10 +324,10 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
last_match = j;
}
if (last_match < s->flength) {
int32 len = (int32)(s->flength - last_match);
int32 n = (int32)(s->flength - last_match);
if (buf && do_progress)
show_progress(last_match, buf->file_size);
sum_update(map_ptr(buf, last_match, len), len);
sum_update(map_ptr(buf, last_match, n), n);
last_match = s->flength;
}
s->count = 0;
@@ -338,7 +339,7 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
if (verbose > 2)
rprintf(FINFO,"built hash table\n");
hash_search(f,s,buf,len);
hash_search(f, s, buf, len);
if (verbose > 2)
rprintf(FINFO,"done hash search\n");
@@ -350,14 +351,14 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
matched(f, s, buf, len, -1);
}
sum_end(file_sum);
sum_len = sum_end(file_sum);
/* If we had a read error, send a bad checksum. */
if (buf && buf->status != 0)
file_sum[0]++;
if (verbose > 2)
rprintf(FINFO,"sending file_sum\n");
write_buf(f,file_sum,MD4_SUM_LENGTH);
write_buf(f, file_sum, sum_len);
if (verbose > 2)
rprintf(FINFO, "false_alarms=%d hash_hits=%d matches=%d\n",
+6 -6
View File
@@ -125,11 +125,11 @@ int get_tmpname(char *fnametmp, char *fname)
static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
char *fname, int fd, OFF_T total_size)
{
static char file_sum1[MD4_SUM_LENGTH];
static char file_sum2[MD4_SUM_LENGTH];
static char file_sum1[MAX_DIGEST_LEN];
static char file_sum2[MAX_DIGEST_LEN];
struct map_struct *mapbuf;
struct sum_struct sum;
int32 len;
int32 len, sum_len;
OFF_T offset = 0;
OFF_T offset2;
char *data;
@@ -257,15 +257,15 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
exit_cleanup(RERR_FILEIO);
}
sum_end(file_sum1);
sum_len = sum_end(file_sum1);
if (mapbuf)
unmap_file(mapbuf);
read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
read_buf(f_in, file_sum2, sum_len);
if (verbose > 2)
rprintf(FINFO,"got file_sum\n");
if (fd != -1 && memcmp(file_sum1, file_sum2, MD4_SUM_LENGTH) != 0)
if (fd != -1 && memcmp(file_sum1, file_sum2, sum_len) != 0)
return 0;
return 1;
}
+2 -4
View File
@@ -517,8 +517,6 @@ struct idev_node {
#define MAXHOSTNAMELEN 256
#endif
/* the length of the md4 checksum */
#define MD4_SUM_LENGTH 16
#define SUM_LENGTH 16
#define SHORT_SUM_LENGTH 2
#define BLOCKSUM_BIAS 10
@@ -575,7 +573,7 @@ extern int preserve_acls;
#define FILE_STRUCT_LEN (offsetof(struct file_struct, basename))
#define EXTRA_LEN (sizeof (union file_extras))
#define PTR_EXTRA_LEN ((sizeof (char *) + EXTRA_LEN - 1) / EXTRA_LEN)
#define SUM_EXTRA_CNT ((MD4_SUM_LENGTH + EXTRA_LEN - 1) / EXTRA_LEN)
#define SUM_EXTRA_CNT ((MAX_DIGEST_LEN + EXTRA_LEN - 1) / EXTRA_LEN)
#define REQ_EXTRA(f,ndx) ((union file_extras*)(f) - (ndx))
#define OPT_EXTRA(f,bump) ((union file_extras*)(f) - file_extra_cnt - 1 - (bump))
@@ -772,7 +770,7 @@ typedef struct {
(type*)expand_item_list(lp, sizeof (type), #type, incr)
#include "byteorder.h"
#include "lib/mdfour.h"
#include "lib/mdigest.h"
#include "lib/wildmatch.h"
#include "lib/permstring.h"
#include "lib/addrinfo.h"