On Friday 13 June 2008 19:30, Peter Kjellerstedt wrote:
> > -----Original Message-----
> > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
> > Behalf Of Denys Vlasenko
> > Sent: den 13 juni 2008 17:46
> > To: [email protected]
> > Subject: Re: [PATCH] use 36 byte buffer in md5 instead of 120, shrink
> > code
> >
> > On Friday 13 June 2008 17:45, Denys Vlasenko wrote:
> > > md5 crypt stores result in the form $1$xxx$yyyyyyyyy<NUL>
> > >
> > > where xxx is salt (up to 8 chars) and yyy is hash
> > > (22 chars). Using 120 bytes buffer for it is excessive.
> > >
> > > The patch also replaces e.g. strcat(passwd,"$")
> > > which writes $ between xxx and yyyy above with one-byte store,
> > > which is shorter.
> > >
> > > __md5_to64 is made to return advanced pointer, eliminating
> > > the need to do it at call sites.
> > >
> > > Size:
> > >
> > >     text           data     bss     dec     hex filename
> > > -   1905              0     120    2025     7e9 libcrypt/md5.o
> > > +   1879              0      36    1915     77b libcrypt/md5.o
> > >
> > > Run tested:
> > >   TEST_EXEC crypt/ crypt
> > >   TEST_DIFF crypt/ crypt.out crypt.out.good
> > >   TEST_EXEC crypt/ md5c-test
> > >   TEST_EXEC crypt/ crypt_glibc
> > >   TEST_DIFF crypt/ crypt_glibc.out crypt.out.good
> > >   TEST_EXEC crypt/ md5c-test_glibc
> > >
> > > Please review.
> >
> > Now even with patch actually attached.
> > --
> > vda
> 
> You changed the type of the second argument to __md5_to64() from
> unsigned long to unsigned, but in __md5_crypt() you are still
> passing it l (stupid variable name) which is unsigned long.

Good eyes, I didn't think about chasing that variable's type.
It didn't materially affect generated code, but being consistent
is better.

Anyway, unsigned long->unsigned was intended. unsigned long can be
64 bit wide, we don't need that. 32 bits is enough here (24 actually).

In this patch, I fix it, and also move "unsigned l" into
much smaller scope. Helps next reader/editor to see it.
--
vda


diff -d -urpN -U5 uClibc.9/libcrypt/md5.c uClibc.a/libcrypt/md5.c
--- uClibc.9/libcrypt/md5.c	2008-06-12 13:05:19.000000000 +0200
+++ uClibc.a/libcrypt/md5.c	2008-06-13 21:58:46.000000000 +0200
@@ -512,16 +512,17 @@ static void __md5_Transform (u_int32_t s
 	/* Zeroize sensitive information. */
 	memset ((void *)x, 0, sizeof (x));
 }
 
 
-static void __md5_to64( char *s, unsigned long v, int n)
+static char *__md5_to64(char *s, unsigned v, int n)
 {
 	while (--n >= 0) {
 		*s++ = __md5_itoa64[v&0x3f];
 		v >>= 6;
 	}
+	return s;
 }
 
 /*
  * UNIX password
  *
@@ -529,18 +530,17 @@ static void __md5_to64( char *s, unsigne
  */
 
 char *__md5_crypt(const unsigned char *pw, const unsigned char *salt)
 {
 	/* Static stuff */
-	static char passwd[120];
+	static char passwd[36];
 
 	const unsigned char *sp, *ep;
 	char *p;
 	unsigned char	final[17];	/* final[16] exists only to aid in looping */
 	int sl,pl,i,pw_len;
 	struct MD5Context ctx,ctx1;
-	unsigned long l;
 
 	/* Refine the Salt first */
 	sp = salt;
 
 	/* If it starts with the magic string, then skip that */
@@ -582,13 +582,15 @@ char *__md5_crypt(const unsigned char *p
 	for (i = pw_len; i ; i >>= 1) {
 		__md5_Update(&ctx, ((i&1) ? final : (const unsigned char *) pw), 1);
 	}
 
 	/* Now make the output string */
-	strcpy(passwd,__md5__magic);
-	strncat(passwd,sp,sl);
-	strcat(passwd,"$");
+	passwd[0] = '$'; /* __md5__magic */
+	passwd[1] = '1';
+	passwd[2] = '$';
+	strncpy(passwd + 3, (char*)sp, sl);
+	passwd[sl + 3] = '$';
 
 	__md5_Final(final,&ctx);
 
 	/*
 	 * and now, just to make sure things don't run too fast
@@ -613,19 +615,19 @@ char *__md5_crypt(const unsigned char *p
 		else
 			__md5_Update(&ctx1,pw,pw_len);
 		__md5_Final(final,&ctx1);
 	}
 
-	p = passwd + strlen(passwd);
+	p = passwd + sl + 4; /* 12 bytes max (sl is up to 8 bytes) */
 
+	/* Add 5*4+2 = 22 bytes of hash, + NUL byte. */
 	final[16] = final[5];
 	for ( i=0 ; i < 5 ; i++ ) {
-		l = (final[i]<<16) | (final[i+6]<<8) | final[i+12];
-		__md5_to64(p,l,4); p += 4;
+		unsigned l = (final[i]<<16) | (final[i+6]<<8) | final[i+12];
+		p = __md5_to64(p,l,4);
 	}
-	l = final[11];
-	__md5_to64(p,l,2); p += 2;
+	p = __md5_to64(p,final[11],2);
 	*p = '\0';
 
 	/* Don't leave anything around in vm they could use. */
 	memset(final,0,sizeof final);
 
_______________________________________________
uClibc mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/uclibc

Reply via email to