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

Tony J. White tjw at webteam.net
Wed Apr 26 12:20:23 EDT 2006


On Wed, Apr 26, 2006 at 05:35:52PM +0200, Erik Auerswald wrote:
> In the file server/sv_rankings.c uint32_t is used, so maybe this could
> be used instead since an int might be larger than 4 bytes (which is
> checked in qcommon/md4.c).

As long as it's used once already, it won't be my fault if it's
undefined for someone, right? :)

> Replacing every "unsigned long int" by "uint32_t" in qcommon/md5.c
> compiles on linux/x86 (32bit), I can't check any other platform. I did
> _not_ check every integer type in that file for size assumptions, so a
> simple search and replace might not be enough.

Yeah, uint32_t seems like the way to go.  I've compared md5.c with the one
from the asterisk project (which apperantly has good 64-bit support) and
it's equivalent.

http://www.asterisk.org/doxygen/md5_8c-source.html 

Attached patch uses uint32_t as well as some other variable-typing changes
taken from the asterisk version.

-Tony

-------------- next part --------------
Index: code/qcommon/md5.c
===================================================================
--- code/qcommon/md5.c	(revision 726)
+++ code/qcommon/md5.c	(working copy)
@@ -18,8 +18,8 @@
 #include "qcommon.h"
 
 typedef struct MD5Context {
-	unsigned long int buf[4];
-	unsigned long int bits[2];
+	uint32_t buf[4];
+	uint32_t bits[2];
 	unsigned char in[64];
 } MD5_CTX;
 
@@ -33,12 +33,12 @@
 	 */
 	static void byteReverse(unsigned char *buf, unsigned longs)
 	{
-	    unsigned long int t;
+	    uint32_t t;
 	    do {
-		t = (unsigned long int)
+		t = (uint32_t)
 			((unsigned) buf[3] << 8 | buf[2]) << 16 |
 			((unsigned) buf[1] << 8 | buf[0]);
-		*(unsigned long int *) buf = t;
+		*(uint32_t *) buf = t;
 		buf += 4;
 	    } while (--longs);
 	}
@@ -75,10 +75,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_t buf[4],
+	uint32_t const in[16])
 {
-    register unsigned long int a, b, c, d;
+    register uint32_t a, b, c, d;
 
     a = buf[0];
     b = buf[1];
@@ -166,12 +166,12 @@
 static void MD5Update(struct MD5Context *ctx, unsigned char const *buf,
 	unsigned len)
 {
-    register unsigned long int t;
+    uint32_t t;
 
     /* Update bitcount */
 
     t = ctx->bits[0];
-    if ((ctx->bits[0] = t + ((unsigned long int) len << 3)) < t)
+    if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
 	ctx->bits[1]++;		/* Carry from low to high */
     ctx->bits[1] += len >> 29;
 
@@ -189,7 +189,7 @@
 	}
 	memcpy(p, buf, t);
 	byteReverse(ctx->in, 16);
-	MD5Transform(ctx->buf, (unsigned long int *) ctx->in);
+	MD5Transform(ctx->buf, (uint32_t *) ctx->in);
 	buf += t;
 	len -= t;
     }
@@ -198,7 +198,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_t *) ctx->in);
 	buf += 64;
 	len -= 64;
     }
@@ -215,7 +215,7 @@
  */
 static void MD5Final(struct MD5Context *ctx, unsigned char *digest)
 {
-    unsigned long int count;
+    unsigned count;
     unsigned char *p;
 
     /* Compute number of bytes mod 64 */
@@ -234,7 +234,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_t *) ctx->in);
 
 	/* Now fill the next block with 56 bytes */
 	memset(ctx->in, 0, 56);
@@ -245,15 +245,15 @@
     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_t *) ctx->in)[14] = ctx->bits[0];
+    ((uint32_t *) ctx->in)[15] = ctx->bits[1];
 
-    MD5Transform(ctx->buf, (unsigned long int *) ctx->in);
+    MD5Transform(ctx->buf, (uint32_t *) ctx->in);
     byteReverse((unsigned char *) ctx->buf, 4);
     
     if (digest!=NULL)
 	    memcpy(digest, ctx->buf, 16);
-    //memset(ctx, 0, sizeof(ctx));	/* In case it's sensitive */
+    memset(ctx, 0, sizeof(ctx));	/* In case it's sensitive */
 }
 
 
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