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
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 17:34:47.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,11 +530,11 @@ 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;
@@ -582,13 +583,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 +616,20 @@ 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;
+		p = __md5_to64(p,l,4);
 	}
 	l = final[11];
-	__md5_to64(p,l,2); p += 2;
+	p = __md5_to64(p,l,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