Optional openssl support for MD4 pre-transfer checksums (but, sadly, not transfer...
authorWayne Davison <wayne@opencoder.net>
Sat, 23 May 2020 19:26:06 +0000 (12:26 -0700)
committerWayne Davison <wayne@opencoder.net>
Sat, 23 May 2020 19:30:58 +0000 (12:30 -0700)
NEWS
checksum.c
configure.ac

diff --git a/NEWS b/NEWS
index 599995096b38559706925e517daa42a8e4b1c58b..ecd469ff929570a43077279844695cc0b65256a0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -39,11 +39,11 @@ Changes since 3.1.3:
   ENHANCEMENTS:
 
     - Various checksum enhancements, including the optional use of openssl's
-      MD5 checksum algorithms, x86_64 optimizations for the rolling checksum,
-      x86_64 optimizations for the (non-openssl) MD5 checksum, the addition of
-      xxhash checksum support, and a simple checksum negotation heuristic that
-      will ensure that it is easier to add new checksum algorithms in the
-      future.  Currently the x86_64 optimizations require the use of the
+      MD4 & MD5 checksum algorithms, some x86_64 optimizations for the rolling
+      checksum, some x86_64 optimizations for the (non-openssl) MD5 checksum,
+      the addition of xxhash checksum support, and a simple checksum negotation
+      heuristic that ensures that it is easier to add new checksum algorithms
+      in the future.  Currently the x86_64 optimizations require the use of the
       --enable-simd flag to configure, but they will probably be enabled by
       default in the near future.
 
index 7c4c855cdf3262a6711205131d836db2914763d0..596a31adffd780434bb8907b895042b7274ca48c 100644 (file)
@@ -31,6 +31,7 @@
 #include "xxhash.h"
 #endif
 #ifdef USE_OPENSSL
+#include "openssl/md4.h"
 #include "openssl/md5.h"
 #endif
 
@@ -121,7 +122,7 @@ static const char *checksum_name(int num)
        if (num < CSUM_MD4)
                return "MD4";
 
-       return "UNKNOWN";
+       return "UNKNOWN"; /* IMPOSSIBLE */
 }
 
 void parse_checksum_choice(int final_call)
@@ -315,6 +316,9 @@ uint32 get_checksum1(char *buf1, int32 len)
 void get_checksum2(char *buf, int32 len, char *sum)
 {
        md_context m;
+#if 0 /* #ifdef USE_OPENSSL */
+       MD4_CTX m4;
+#endif
        MD5_CTX m5;
 
        switch (xfersum_type) {
@@ -338,6 +342,19 @@ void get_checksum2(char *buf, int32 len, char *sum)
                break;
          }
          case CSUM_MD4:
+#if 0 /* #ifdef USE_OPENSSL -- this doesn't match the old checksums. */
+         {
+               MD4_Init(&m4);
+               if (checksum_seed) {
+                       uchar seedbuf[4];
+                       SIVALu(seedbuf, 0, checksum_seed);
+                       MD4_Update(&m4, seedbuf, 4);
+               }
+               MD4_Update(&m4, (uchar *)buf, len);
+               MD4_Final((uchar *)sum, &m4);
+               break;
+         }
+#endif
          case CSUM_MD4_OLD:
          case CSUM_MD4_BUSTED:
          case CSUM_MD4_ARCHAIC: {
@@ -392,6 +409,9 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
        struct map_struct *buf;
        OFF_T i, len = st_p->st_size;
        md_context m;
+#ifdef USE_OPENSSL
+       MD4_CTX m4;
+#endif
        MD5_CTX m5;
        int32 remainder;
        int fd;
@@ -408,10 +428,8 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
          case CSUM_MD5:
                MD5_Init(&m5);
 
-               for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
-                       MD5_Update(&m5, (uchar *)map_ptr(buf, i, CSUM_CHUNK),
-                                  CSUM_CHUNK);
-               }
+               for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK)
+                       MD5_Update(&m5, (uchar *)map_ptr(buf, i, CSUM_CHUNK), CSUM_CHUNK);
 
                remainder = (int32)(len - i);
                if (remainder > 0)
@@ -420,14 +438,26 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
                MD5_Final((uchar *)sum, &m5);
                break;
          case CSUM_MD4:
+#ifdef USE_OPENSSL
+               MD4_Init(&m4);
+
+               for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK)
+                       MD4_Update(&m4, (uchar *)map_ptr(buf, i, CSUM_CHUNK), CSUM_CHUNK);
+
+               remainder = (int32)(len - i);
+               if (remainder > 0)
+                       MD4_Update(&m4, (uchar *)map_ptr(buf, i, remainder), remainder);
+
+               MD4_Final((uchar *)sum, &m4);
+               break;
+#endif
          case CSUM_MD4_OLD:
          case CSUM_MD4_BUSTED:
          case CSUM_MD4_ARCHAIC:
                mdfour_begin(&m);
 
-               for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
+               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
@@ -478,6 +508,9 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
 
 static int32 sumresidue;
 static md_context md;
+#ifdef USE_OPENSSL
+static MD4_CTX m4;
+#endif
 static MD5_CTX m5;
 static int cursum_type;
 #ifdef SUPPORT_XXHASH
@@ -497,8 +530,12 @@ void sum_init(int csum_type, int seed)
                MD5_Init(&m5);
                break;
          case CSUM_MD4:
+#ifdef USE_OPENSSL
+               MD4_Init(&m4);
+#else
                mdfour_begin(&md);
                sumresidue = 0;
+#endif
                break;
          case CSUM_MD4_OLD:
          case CSUM_MD4_BUSTED:
@@ -543,6 +580,10 @@ void sum_update(const char *p, int32 len)
                MD5_Update(&m5, (uchar *)p, len);
                break;
          case CSUM_MD4:
+#ifdef USE_OPENSSL
+               MD4_Update(&m4, (uchar *)p, len);
+               break;
+#endif
          case CSUM_MD4_OLD:
          case CSUM_MD4_BUSTED:
          case CSUM_MD4_ARCHAIC:
@@ -596,6 +637,10 @@ int sum_end(char *sum)
                MD5_Final((uchar *)sum, &m5);
                break;
          case CSUM_MD4:
+#ifdef USE_OPENSSL
+               MD4_Final((uchar *)sum, &m4);
+               break;
+#endif
          case CSUM_MD4_OLD:
                mdfour_update(&md, (uchar *)md.buffer, sumresidue);
                mdfour_result(&md, (uchar *)sum);
index 77b1827822349778c4305af789b90329d8ace785..427959f38b0fad7f04dcc5be1dfaae09d22f9fe4 100644 (file)
@@ -381,7 +381,7 @@ AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h \
     netdb.h malloc.h float.h limits.h iconv.h libcharset.h langinfo.h \
     sys/acl.h acl/libacl.h attr/xattr.h sys/xattr.h sys/extattr.h \
     popt.h popt/popt.h linux/falloc.h netinet/in_systm.h netinet/ip.h \
-    zlib.h xxhash.h openssl/md5.h)
+    zlib.h xxhash.h openssl/md4.h openssl/md5.h)
 AC_HEADER_MAJOR_FIXED
 
 AC_MSG_CHECKING([whether to enable use of openssl crypto library])
@@ -389,7 +389,7 @@ AC_ARG_ENABLE([openssl],
        AS_HELP_STRING([--disable-openssl],[disable openssl crypto library]))
 AH_TEMPLATE([USE_OPENSSL],
 [Undefine if you do not want to use openssl crypto library.  By default this is defined.])
-if test x"$enable_openssl" != x"no" && test x"$ac_cv_header_openssl_md5_h" = x"yes"; then
+if test x"$enable_openssl" != x"no" && test x"$ac_cv_header_openssl_md4_h" = x"yes" && test x"$ac_cv_header_openssl_md5_h" = x"yes"; then
     AC_MSG_RESULT(yes)
     AC_SEARCH_LIBS(MD5_Init, crypto)
     AC_DEFINE(USE_OPENSSL)