[quake3] md5.c is not 64 bit-safe.

Tony J. White tjw at webteam.net
Wed Apr 26 11:11:40 EDT 2006


On Wed, Apr 26, 2006 at 03:45:16PM +0200, Thilo Schulz wrote:
>    /* Append length in bits and transform */
>     ((unsigned long int *) ctx->in)[14] = ctx->bits[0];
>     ((unsigned long int *) ctx->in)[15] = ctx->bits[1];
> 
> In GCC sizeof(long int) is 8 bytes on 64 bit platforms but only 4 bytes on 32 
> bit platforms.

Sorry.

Could someone with a 64-bit platform please test the attached patch for md5.c?

I used the same uint32 defines from md4.c so I assume it works for determining
that type on all build targets.

-Tony


-- 
-------------- next part --------------
Index: code/qcommon/md5.c
===================================================================
--- code/qcommon/md5.c	(revision 726)
+++ code/qcommon/md5.c	(working copy)
@@ -17,9 +17,17 @@
 #include "q_shared.h"
 #include "qcommon.h"
 
+#ifndef int32
+#define int32 int
+#endif
+
+#ifndef uint32
+#define uint32 unsigned int32
+#endif 
+
 typedef struct MD5Context {
-	unsigned long int buf[4];
-	unsigned long int bits[2];
+	uint32 buf[4];
+	uint32 bits[2];
 	unsigned char in[64];
 } MD5_CTX;
 
@@ -33,12 +41,12 @@
 	 */
 	static void byteReverse(unsigned char *buf, unsigned longs)
 	{
-	    unsigned long int t;
+	    uint32 t;
 	    do {
-		t = (unsigned long int)
+		t = (uint32)
 			((unsigned) buf[3] << 8 | buf[2]) << 16 |
 			((unsigned) buf[1] << 8 | buf[0]);
-		*(unsigned long int *) buf = t;
+		*(uint32 *) buf = t;
 		buf += 4;
 	    } while (--longs);
 	}
@@ -75,10 +83,10 @@
  * reflect the addition of 16 longwords of new data.  MD5Update blocks
  * the data and converts bytes into longwords for this routine.
  */
-static void MD5Transform(unsigned long int buf[4],
-	unsigned long int const in[16])
+static void MD5Transform(uint32 buf[4],
+	uint32 const in[16])
 {
-    register unsigned long int a, b, c, d;
+    register uint32 a, b, c, d;
 
     a = buf[0];
     b = buf[1];
@@ -166,12 +174,12 @@
 static void MD5Update(struct MD5Context *ctx, unsigned char const *buf,
 	unsigned len)
 {
-    register unsigned long int t;
+    register uint32 t;
 
     /* Update bitcount */
 
     t = ctx->bits[0];
-    if ((ctx->bits[0] = t + ((unsigned long int) len << 3)) < t)
+    if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
 	ctx->bits[1]++;		/* Carry from low to high */
     ctx->bits[1] += len >> 29;
 
@@ -189,7 +197,7 @@
 	}
 	memcpy(p, buf, t);
 	byteReverse(ctx->in, 16);
-	MD5Transform(ctx->buf, (unsigned long int *) ctx->in);
+	MD5Transform(ctx->buf, (uint32 *) ctx->in);
 	buf += t;
 	len -= t;
     }
@@ -198,7 +206,7 @@
     while (len >= 64) {
 	memcpy(ctx->in, buf, 64);
 	byteReverse(ctx->in, 16);
-	MD5Transform(ctx->buf, (unsigned long int *) ctx->in);
+	MD5Transform(ctx->buf, (uint32 *) ctx->in);
 	buf += 64;
 	len -= 64;
     }
@@ -215,7 +223,7 @@
  */
 static void MD5Final(struct MD5Context *ctx, unsigned char *digest)
 {
-    unsigned long int count;
+    uint32 count;
     unsigned char *p;
 
     /* Compute number of bytes mod 64 */
@@ -234,7 +242,7 @@
 	/* Two lots of padding:  Pad the first block to 64 bytes */
 	memset(p, 0, count);
 	byteReverse(ctx->in, 16);
-	MD5Transform(ctx->buf, (unsigned long int *) ctx->in);
+	MD5Transform(ctx->buf, (uint32 *) ctx->in);
 
 	/* Now fill the next block with 56 bytes */
 	memset(ctx->in, 0, 56);
@@ -245,10 +253,10 @@
     byteReverse(ctx->in, 14);
 
     /* Append length in bits and transform */
-    ((unsigned long int *) ctx->in)[14] = ctx->bits[0];
-    ((unsigned long int *) ctx->in)[15] = ctx->bits[1];
+    ((uint32 *) ctx->in)[14] = ctx->bits[0];
+    ((uint32 *) ctx->in)[15] = ctx->bits[1];
 
-    MD5Transform(ctx->buf, (unsigned long int *) ctx->in);
+    MD5Transform(ctx->buf, (uint32 *) ctx->in);
     byteReverse((unsigned char *) ctx->buf, 4);
     
     if (digest!=NULL)
Index: code/client/cl_main.c
===================================================================
--- code/client/cl_main.c	(revision 726)
+++ code/client/cl_main.c	(working copy)
@@ -2549,8 +2549,7 @@
 	Cvar_Set( "cl_running", "1" );
 
 	CL_GenerateQKey();	
-//	Uncomment this once md5.c has been made 64 bit-safe.
-//	Cvar_Get("cl_guid", Com_MD5File(QKEY_FILE, 0), CVAR_USERINFO | CVAR_ROM);
+	Cvar_Get("cl_guid", Com_MD5File(QKEY_FILE, 0), CVAR_USERINFO | CVAR_ROM);
 
 	Com_Printf( "----- Client Initialization Complete -----\n" );
 }


More information about the quake3 mailing list