Index: lib/libcrypt/crypt-md5.c =================================================================== --- lib/libcrypt/crypt-md5.c +++ lib/libcrypt/crypt-md5.c @@ -43,20 +43,22 @@ * UNIX password */ +#define MAGIC_LEN 3 + int crypt_md5(const char *pw, const char *salt, char *buffer) { - MD5_CTX ctx,ctx1; + MD5_CTX ctx, ctx1; unsigned long l; - int sl, pl; - u_int i; + size_t pl, sl; + size_t i; u_char final[MD5_SIZE]; const char *ep; - static const char *magic = "$1$"; + static const char magic[] = "$1$"; /* If the salt starts with the magic string, skip that. */ - if (!strncmp(salt, magic, strlen(magic))) - salt += strlen(magic); + if (!strncmp(salt, magic, MAGIC_LEN)) + salt += MAGIC_LEN; /* It stops at the first '$', max 8 chars */ for (ep = salt; *ep && *ep != '$' && ep < salt + 8; ep++) @@ -68,37 +70,40 @@ MD5Init(&ctx); /* The password first, since that is what is most unknown */ - MD5Update(&ctx, (const u_char *)pw, strlen(pw)); + MD5Update(&ctx, (const u_char *)pw, (pl = strlen(pw))); /* Then our magic string */ - MD5Update(&ctx, (const u_char *)magic, strlen(magic)); + MD5Update(&ctx, (const u_char *)magic, MAGIC_LEN); /* Then the raw salt */ - MD5Update(&ctx, (const u_char *)salt, (u_int)sl); + MD5Update(&ctx, (const u_char *)salt, sl); /* Then just as many characters of the MD5(pw,salt,pw) */ MD5Init(&ctx1); - MD5Update(&ctx1, (const u_char *)pw, strlen(pw)); - MD5Update(&ctx1, (const u_char *)salt, (u_int)sl); - MD5Update(&ctx1, (const u_char *)pw, strlen(pw)); + MD5Update(&ctx1, (const u_char *)pw, pl); + MD5Update(&ctx1, (const u_char *)salt, sl); + MD5Update(&ctx1, (const u_char *)pw, pl); MD5Final(final, &ctx1); - for(pl = (int)strlen(pw); pl > 0; pl -= MD5_SIZE) - MD5Update(&ctx, (const u_char *)final, - (u_int)(pl > MD5_SIZE ? MD5_SIZE : pl)); + + for (i = pl / MD5_SIZE; i; --i) // pl >> 4 + MD5Update(&ctx, (const u_char *)final, MD5_SIZE); + + if ((i = pl % MD5_SIZE) != 0) // pl & 15 + MD5Update(&ctx, (const u_char *)final, i); /* Don't leave anything around in vm they could use. */ memset(final, 0, sizeof(final)); /* Then something really weird... */ - for (i = strlen(pw); i; i >>= 1) - if(i & 1) - MD5Update(&ctx, (const u_char *)final, 1); + for (i = pl; i; i >>= 1) + if (i & 1) + MD5Update(&ctx, (const u_char *)final, 1); else - MD5Update(&ctx, (const u_char *)pw, 1); + MD5Update(&ctx, (const u_char *)pw, 1); /* Now make the output string */ buffer = stpcpy(buffer, magic); - buffer = stpncpy(buffer, salt, (u_int)sl); + buffer = stpncpy(buffer, salt, sl); *buffer++ = '$'; MD5Final(final, &ctx); @@ -108,42 +113,48 @@ * 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 u_char *)pw, strlen(pw)); + if (i & 1) + MD5Update(&ctx1, (const u_char *)pw, pl); else MD5Update(&ctx1, (const u_char *)final, MD5_SIZE); - if(i % 3) - MD5Update(&ctx1, (const u_char *)salt, (u_int)sl); + if (i % 3) + MD5Update(&ctx1, (const u_char *)salt, sl); - if(i % 7) - MD5Update(&ctx1, (const u_char *)pw, strlen(pw)); + if (i % 7) + MD5Update(&ctx1, (const u_char *)pw, pl); - if(i & 1) + if (i & 1) MD5Update(&ctx1, (const u_char *)final, MD5_SIZE); else - MD5Update(&ctx1, (const u_char *)pw, strlen(pw)); + MD5Update(&ctx1, (const u_char *)pw, pl); MD5Final(final, &ctx1); } - l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; - _crypt_to64(buffer, l, 4); buffer += 4; - l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; - _crypt_to64(buffer, l, 4); buffer += 4; - l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; - _crypt_to64(buffer, l, 4); buffer += 4; - l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; - _crypt_to64(buffer, l, 4); buffer += 4; - l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; - _crypt_to64(buffer, l, 4); buffer += 4; + l = (final[0] << 16) | (final[6] << 8) | final[12]; + _crypt_to64(buffer, l, 4); + buffer += 4; + l = (final[1] << 16) | (final[7] << 8) | final[13]; + _crypt_to64(buffer, l, 4); + buffer += 4; + l = (final[2] << 16) | (final[8] << 8) | final[14]; + _crypt_to64(buffer, l, 4); + buffer += 4; + l = (final[3] << 16) | (final[9] << 8) | final[15]; + _crypt_to64(buffer, l, 4); + buffer += 4; + l = (final[4] << 16) | (final[10] << 8) | final[5]; + _crypt_to64(buffer, l, 4); + buffer += 4; l = final[11]; - _crypt_to64(buffer, l, 2); buffer += 2; + _crypt_to64(buffer, l, 2); + buffer += 2; *buffer = '\0'; /* Don't leave anything around in vm they could use. */ - memset(final, 0, sizeof(final)); + memset_s(final, sizeof(final), 0, sizeof(final)); return (0); } Index: lib/libcrypt/crypt-nthash.c =================================================================== --- lib/libcrypt/crypt-nthash.c +++ lib/libcrypt/crypt-nthash.c @@ -52,7 +52,7 @@ crypt_nthash(const char *pw, const char *salt __unused, char *buffer) { size_t unipwLen; - int i; + u_int i; static const char hexconvtab[] = "0123456789abcdef"; static const char *magic = "$3$"; u_int16_t unipw[128]; @@ -60,7 +60,7 @@ const char *s; MD4_CTX ctx; - bzero(unipw, sizeof(unipw)); + memset(unipw, 0, sizeof(unipw)); /* convert to unicode (thanx Archie) */ unipwLen = 0; for (s = pw; unipwLen < sizeof(unipw) / 2 && *s; s++) Index: lib/libcrypt/crypt-sha256.c =================================================================== --- lib/libcrypt/crypt-sha256.c +++ lib/libcrypt/crypt-sha256.c @@ -183,21 +183,21 @@ SHA256_Init(&ctx); /* Add key or last result. */ - if ((cnt & 1) != 0) + if (cnt & 1) SHA256_Update(&ctx, p_bytes, key_len); else SHA256_Update(&ctx, alt_result, 32); /* Add salt for numbers not divisible by 3. */ - if (cnt % 3 != 0) + if (cnt % 3) SHA256_Update(&ctx, s_bytes, salt_len); /* Add key for numbers not divisible by 7. */ - if (cnt % 7 != 0) + if (cnt % 7) SHA256_Update(&ctx, p_bytes, key_len); /* Add key or last result. */ - if ((cnt & 1) != 0) + if (cnt & 1) SHA256_Update(&ctx, alt_result, 32); else SHA256_Update(&ctx, p_bytes, key_len); Index: lib/libcrypt/crypt-sha512.c =================================================================== --- lib/libcrypt/crypt-sha512.c +++ lib/libcrypt/crypt-sha512.c @@ -131,8 +131,8 @@ /* Take the binary representation of the length of the key and for * every 1 add the alternate sum, for every 0 the key. */ - for (cnt = key_len; cnt > 0; cnt >>= 1) - if ((cnt & 1) != 0) + for (cnt = key_len; cnt; cnt >>= 1) + if (cnt & 1) SHA512_Update(&ctx, alt_result, 64); else SHA512_Update(&ctx, key, key_len); @@ -144,7 +144,7 @@ SHA512_Init(&alt_ctx); /* For every character in the password add the entire password. */ - for (cnt = 0; cnt < key_len; ++cnt) + for (cnt = key_len; cnt; --cnt) SHA512_Update(&alt_ctx, key, key_len); /* Finish the digest. */ @@ -162,7 +162,7 @@ SHA512_Init(&alt_ctx); /* For every character in the password add the entire password. */ - for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt) + for (cnt = 16 + alt_result[0]; cnt; --cnt) SHA512_Update(&alt_ctx, salt, salt_len); /* Finish the digest. */ @@ -178,26 +178,26 @@ /* Repeatedly run the collected hash value through SHA512 to burn CPU * cycles. */ - for (cnt = 0; cnt < rounds; ++cnt) { + for (cnt = rounds; cnt; --cnt) { /* New context. */ SHA512_Init(&ctx); /* Add key or last result. */ - if ((cnt & 1) != 0) + if (cnt & 1) SHA512_Update(&ctx, p_bytes, key_len); else SHA512_Update(&ctx, alt_result, 64); /* Add salt for numbers not divisible by 3. */ - if (cnt % 3 != 0) + if (cnt % 3) SHA512_Update(&ctx, s_bytes, salt_len); /* Add key for numbers not divisible by 7. */ - if (cnt % 7 != 0) + if (cnt % 7) SHA512_Update(&ctx, p_bytes, key_len); /* Add key or last result. */ - if ((cnt & 1) != 0) + if (cnt & 1) SHA512_Update(&ctx, alt_result, 64); else SHA512_Update(&ctx, p_bytes, key_len); Index: lib/libcrypt/crypt.c =================================================================== --- lib/libcrypt/crypt.c +++ lib/libcrypt/crypt.c @@ -111,7 +111,7 @@ const struct crypt_format *cf; int (*func)(const char *, const char *, char *); #ifdef HAS_DES - int len; + size_t len; #endif for (cf = crypt_formats; cf->name != NULL; ++cf)