.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
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);
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);
}
* 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
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! */
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";
#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)
void get_checksum2(char *buf, int32 len, char *sum)
{
- int32 i;
- static char *buf1;
- static int32 len1;
- struct mdfour m;
-
- if (len > len1) {
- if (buf1)
- free(buf1);
- buf1 = new_array(char, len+4);
- len1 = len;
- if (!buf1)
- out_of_memory("get_checksum2");
- }
-
- 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));
+ md_context m;
+
+ 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_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)
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);
+ }
- /* 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);
+ remainder = (int32)(len - i);
+ if (remainder > 0)
+ md5_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
- mdfour_result(&m, (uchar *)sum);
+ 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);
+ }
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);
}
**/
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;
}
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;
}
#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);
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)
/* 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;
}
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);
--- /dev/null
+/*
+ * 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
* 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
*
* It assumes that a int is at least 32 bits long. */
-static struct mdfour *m;
+static md_context *m;
#define MASK32 (0xffffffff)
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;
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;
out[3] = (x>>24)&0xFF;
}
-void mdfour_begin(struct mdfour *md)
+void mdfour_begin(md_context *md)
{
md->A = 0x67452301;
md->B = 0xefcdab89;
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
* 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 {
* 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);
}
}
-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
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) {
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);
mdfour_result(&md, sum);
- for (i=0;i<16;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++)
+ for (i = 0; i < MD4_DIGEST_LEN; 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
+++ /dev/null
-/*
- * 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);
--- /dev/null
+/* 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);
**/
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;
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;
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");
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",
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;
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;
}
#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
#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))
(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"