summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-01-28 21:49:42 -0800
committerH. Peter Anvin <hpa@zytor.com>2008-01-28 21:49:42 -0800
commit5e98b2f1caefd9b6a26d95a91c14474c6880ea39 (patch)
tree2e02bb386f60f0cb895a42956d61d9ec8927479b
parent5a8e4fc8351b5d40bc05ad99d88a2355337dd899 (diff)
downloadsyslinux-5e98b2f1caefd9b6a26d95a91c14474c6880ea39.tar.gz
menu: clean up and fix MD5 password code
MD5 password code would append the encrypted password to a previous password, with the result that it would never match after picking a wrong password. Fix.
-rw-r--r--com32/libutil/crypt-md5.c111
-rw-r--r--com32/libutil/md5.c3
2 files changed, 61 insertions, 53 deletions
diff --git a/com32/libutil/crypt-md5.c b/com32/libutil/crypt-md5.c
index c5034432..751c3d26 100644
--- a/com32/libutil/crypt-md5.c
+++ b/com32/libutil/crypt-md5.c
@@ -32,16 +32,17 @@
* UNIX password
*/
-static char itoa64[] = /* 0 ... 63 => ascii - 64 */
- "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-static void
+static char *
_crypt_to64(char *s, uint32_t v, int n)
{
+ static const char itoa64[64] = "./0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
while (--n >= 0) {
*s++ = itoa64[v&0x3f];
v >>= 6;
}
+ return s;
}
char *
@@ -52,59 +53,65 @@ crypt_md5(const char *pw, const char *salt)
int sl, pl;
uint32_t i;
uint8_t final[MD5_SIZE];
- static const char *sp, *ep;
- static char passwd[120], *p;
- static const char *magic = "$1$";
+ const char *sp;
+ static char passwd[120]; /* Output buffer */
+ static const char magic[] = "$1$";
+ char *p;
+ const int magic_len = sizeof magic - 1;
+ int pwlen = strlen(pw);
/* Refine the Salt first */
sp = salt;
/* If it starts with the magic string, then skip that */
- if(!strncmp(sp, magic, strlen(magic)))
- sp += strlen(magic);
-
- /* It stops at the first '$', max 8 chars */
- for(ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++)
- continue;
+ if (!strncmp(sp, magic, magic_len))
+ sp += magic_len;
- /* get the length of the true salt */
- sl = ep - sp;
+ /* Compute the salt length:
+ it stops at the first '$', max 8 chars */
+ for (sl = 0; sl < 8 && sp[sl] && sp[sl] != '$'; sl++)
+ ;
MD5Init(&ctx);
/* The password first, since that is what is most unknown */
- MD5Update(&ctx, (const uint8_t *)pw, strlen(pw));
+ MD5Update(&ctx, pw, pwlen);
/* Then our magic string */
- MD5Update(&ctx, (const uint8_t *)magic, strlen(magic));
+ MD5Update(&ctx, magic, magic_len);
/* Then the raw salt */
- MD5Update(&ctx, (const uint8_t *)sp, (uint32_t)sl);
+ MD5Update(&ctx, sp, sl);
/* Then just as many characters of the MD5(pw,salt,pw) */
MD5Init(&ctx1);
- MD5Update(&ctx1, (const uint8_t *)pw, strlen(pw));
- MD5Update(&ctx1, (const uint8_t *)sp, (uint32_t)sl);
- MD5Update(&ctx1, (const uint8_t *)pw, strlen(pw));
+ MD5Update(&ctx1, pw, pwlen);
+ MD5Update(&ctx1, sp, sl);
+ MD5Update(&ctx1, pw, pwlen);
MD5Final(final, &ctx1);
- for(pl = (int)strlen(pw); pl > 0; pl -= MD5_SIZE)
- MD5Update(&ctx, (const uint8_t *)final,
- (uint32_t)(pl > MD5_SIZE ? MD5_SIZE : pl));
+ for (pl = pwlen; pl > 0; pl -= MD5_SIZE)
+ MD5Update(&ctx, final, pl > MD5_SIZE ? MD5_SIZE : pl);
/* Don't leave anything around in vm they could use. */
- memset(final, 0, sizeof(final));
+ memset(final, 0, sizeof final);
/* Then something really weird... */
- for (i = strlen(pw); i; i >>= 1)
- if(i & 1)
- MD5Update(&ctx, (const uint8_t *)final, 1);
+ for (i = pwlen; i; i >>= 1)
+ if (i & 1)
+ MD5Update(&ctx, final, 1);
else
- MD5Update(&ctx, (const uint8_t *)pw, 1);
+ MD5Update(&ctx, pw, 1);
/* Now make the output string */
- strcpy(passwd, magic);
- strncat(passwd, sp, (uint32_t)sl);
- strcat(passwd, "$");
+ p = passwd;
+
+ memcpy(p, magic, magic_len);
+ p += magic_len;
+
+ memcpy(p, sp, sl);
+ p += sl;
+
+ *p++ = '$';
MD5Final(final, &ctx);
@@ -113,46 +120,44 @@ crypt_md5(const char *pw, const char *salt)
* On a 60 Mhz Pentium this takes 34 msec, so you would
* need 30 seconds to build a 1000 entry dictionary...
*/
- for(i = 0; i < 1000; i++) {
+ for (i = 0; i < 1000; i++) {
MD5Init(&ctx1);
if(i & 1)
- MD5Update(&ctx1, (const uint8_t *)pw, strlen(pw));
+ MD5Update(&ctx1, pw, pwlen);
else
- MD5Update(&ctx1, (const uint8_t *)final, MD5_SIZE);
+ MD5Update(&ctx1, final, MD5_SIZE);
if(i % 3)
- MD5Update(&ctx1, (const uint8_t *)sp, (uint32_t)sl);
+ MD5Update(&ctx1, sp, sl);
if(i % 7)
- MD5Update(&ctx1, (const uint8_t *)pw, strlen(pw));
+ MD5Update(&ctx1, pw, pwlen);
if(i & 1)
- MD5Update(&ctx1, (const uint8_t *)final, MD5_SIZE);
+ MD5Update(&ctx1, final, MD5_SIZE);
else
- MD5Update(&ctx1, (const uint8_t *)pw, strlen(pw));
+ MD5Update(&ctx1, pw, pwlen);
MD5Final(final, &ctx1);
}
- p = passwd + strlen(passwd);
-
l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];
- _crypt_to64(p, l, 4); p += 4;
+ p = _crypt_to64(p, l, 4);
l = (final[ 1]<<16) | (final[ 7]<<8) | final[13];
- _crypt_to64(p, l, 4); p += 4;
+ p = _crypt_to64(p, l, 4);
l = (final[ 2]<<16) | (final[ 8]<<8) | final[14];
- _crypt_to64(p, l, 4); p += 4;
+ p = _crypt_to64(p, l, 4);
l = (final[ 3]<<16) | (final[ 9]<<8) | final[15];
- _crypt_to64(p, l, 4); p += 4;
+ p = _crypt_to64(p, l, 4);
l = (final[ 4]<<16) | (final[10]<<8) | final[ 5];
- _crypt_to64(p, l, 4); p += 4;
+ p = _crypt_to64(p, l, 4);
l = final[11];
- _crypt_to64(p, l, 2); p += 2;
+ p = _crypt_to64(p, l, 2);
*p = '\0';
/* Don't leave anything around in vm they could use. */
- memset(final, 0, sizeof(final));
+ memset(final, 0, sizeof final);
- return (passwd);
+ return passwd;
}
#ifdef TEST
@@ -160,8 +165,12 @@ crypt_md5(const char *pw, const char *salt)
int main(int argc, char *argv[])
{
- puts(crypt_md5(argv[1], argv[2]));
- return 0;
+ int i;
+
+ for (i = 2; i < argc; i += 2) {
+ puts(crypt_md5(argv[i], argv[i-1]));
+ }
+ return 0;
}
#endif
diff --git a/com32/libutil/md5.c b/com32/libutil/md5.c
index 0e53db39..0a2c3dca 100644
--- a/com32/libutil/md5.c
+++ b/com32/libutil/md5.c
@@ -80,7 +80,6 @@ static unsigned char PADDING[64] = {
void
MD5Init (MD5_CTX *context)
{
-
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants. */
@@ -90,7 +89,7 @@ MD5Init (MD5_CTX *context)
context->state[3] = 0x10325476;
}
-/*
+/*
* MD5 block update operation. Continues an MD5 message-digest
* operation, processing another message block, and updating the
* context.