xref: /illumos-gate/usr/src/grub/grub-0.97/stage2/md5.c (revision 1b8adde7)
17c478bd9Sstevel@tonic-gate /* md5.c - an implementation of the MD5 algorithm and MD5 crypt */
27c478bd9Sstevel@tonic-gate /*
37c478bd9Sstevel@tonic-gate  *  GRUB  --  GRand Unified Bootloader
47c478bd9Sstevel@tonic-gate  *  Copyright (C) 2000, 2001  Free Software Foundation, Inc.
57c478bd9Sstevel@tonic-gate  *
67c478bd9Sstevel@tonic-gate  *  This program is free software; you can redistribute it and/or modify
77c478bd9Sstevel@tonic-gate  *  it under the terms of the GNU General Public License as published by
87c478bd9Sstevel@tonic-gate  *  the Free Software Foundation; either version 2 of the License, or
97c478bd9Sstevel@tonic-gate  *  (at your option) any later version.
107c478bd9Sstevel@tonic-gate  *
117c478bd9Sstevel@tonic-gate  *  This program is distributed in the hope that it will be useful,
127c478bd9Sstevel@tonic-gate  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
137c478bd9Sstevel@tonic-gate  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
147c478bd9Sstevel@tonic-gate  *  GNU General Public License for more details.
157c478bd9Sstevel@tonic-gate  *
167c478bd9Sstevel@tonic-gate  *  You should have received a copy of the GNU General Public License
177c478bd9Sstevel@tonic-gate  *  along with this program; if not, write to the Free Software
187c478bd9Sstevel@tonic-gate  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
197c478bd9Sstevel@tonic-gate  */
207c478bd9Sstevel@tonic-gate 
217c478bd9Sstevel@tonic-gate /* See RFC 1321 for a description of the MD5 algorithm.
227c478bd9Sstevel@tonic-gate  */
237c478bd9Sstevel@tonic-gate 
247c478bd9Sstevel@tonic-gate #include <md5.h>
257c478bd9Sstevel@tonic-gate #ifndef TEST
267c478bd9Sstevel@tonic-gate # include <shared.h>
277c478bd9Sstevel@tonic-gate #endif
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #ifdef TEST
307c478bd9Sstevel@tonic-gate # include <string.h>
317c478bd9Sstevel@tonic-gate # define USE_MD5_PASSWORDS
327c478bd9Sstevel@tonic-gate # define USE_MD5
337c478bd9Sstevel@tonic-gate #endif
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #ifdef USE_MD5_PASSWORDS
367c478bd9Sstevel@tonic-gate # define USE_MD5
377c478bd9Sstevel@tonic-gate #endif
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #ifdef USE_MD5
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #define cpu_to_le32(x) (x)
427c478bd9Sstevel@tonic-gate #define le32_to_cpu(x) cpu_to_le32(x)
437c478bd9Sstevel@tonic-gate typedef unsigned int UINT4;
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate /* F, G, H and I are basic MD5 functions.
467c478bd9Sstevel@tonic-gate  */
477c478bd9Sstevel@tonic-gate #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
487c478bd9Sstevel@tonic-gate #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
497c478bd9Sstevel@tonic-gate #define H(x, y, z) ((x) ^ (y) ^ (z))
507c478bd9Sstevel@tonic-gate #define I(x, y, z) ((y) ^ ((x) | (~z)))
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate /* ROTATE_LEFT rotates x left n bits.
537c478bd9Sstevel@tonic-gate  */
547c478bd9Sstevel@tonic-gate #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x >> (32 - (n)))))
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate static UINT4 initstate[4] =
577c478bd9Sstevel@tonic-gate {
587c478bd9Sstevel@tonic-gate   0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
597c478bd9Sstevel@tonic-gate };
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate static char s1[4] = {  7, 12, 17, 22 };
627c478bd9Sstevel@tonic-gate static char s2[4] = {  5,  9, 14, 20 };
637c478bd9Sstevel@tonic-gate static char s3[4] = {  4, 11, 16, 23 };
647c478bd9Sstevel@tonic-gate static char s4[4] = {  6, 10, 15, 21 };
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate static UINT4 T[64] =
677c478bd9Sstevel@tonic-gate {
687c478bd9Sstevel@tonic-gate   0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
697c478bd9Sstevel@tonic-gate   0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
707c478bd9Sstevel@tonic-gate   0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
717c478bd9Sstevel@tonic-gate   0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
727c478bd9Sstevel@tonic-gate   0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
737c478bd9Sstevel@tonic-gate   0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
747c478bd9Sstevel@tonic-gate   0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
757c478bd9Sstevel@tonic-gate   0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
767c478bd9Sstevel@tonic-gate   0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
777c478bd9Sstevel@tonic-gate   0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
787c478bd9Sstevel@tonic-gate   0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
797c478bd9Sstevel@tonic-gate   0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
807c478bd9Sstevel@tonic-gate   0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
817c478bd9Sstevel@tonic-gate   0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
827c478bd9Sstevel@tonic-gate   0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
837c478bd9Sstevel@tonic-gate   0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
847c478bd9Sstevel@tonic-gate };
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate static const char *b64t =
877c478bd9Sstevel@tonic-gate "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate static UINT4 state[4];
907c478bd9Sstevel@tonic-gate static unsigned int length;
917c478bd9Sstevel@tonic-gate static unsigned char buffer[64];
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate static void
md5_transform(const unsigned char block[64])947c478bd9Sstevel@tonic-gate md5_transform (const unsigned char block[64])
957c478bd9Sstevel@tonic-gate {
967c478bd9Sstevel@tonic-gate   int i, j;
977c478bd9Sstevel@tonic-gate   UINT4 a,b,c,d,tmp;
987c478bd9Sstevel@tonic-gate   const UINT4 *x = (UINT4 *) block;
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate   a = state[0];
1017c478bd9Sstevel@tonic-gate   b = state[1];
1027c478bd9Sstevel@tonic-gate   c = state[2];
1037c478bd9Sstevel@tonic-gate   d = state[3];
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate   /* Round 1 */
1067c478bd9Sstevel@tonic-gate   for (i = 0; i < 16; i++)
1077c478bd9Sstevel@tonic-gate     {
1087c478bd9Sstevel@tonic-gate       tmp = a + F (b, c, d) + le32_to_cpu (x[i]) + T[i];
1097c478bd9Sstevel@tonic-gate       tmp = ROTATE_LEFT (tmp, s1[i & 3]);
1107c478bd9Sstevel@tonic-gate       tmp += b;
1117c478bd9Sstevel@tonic-gate       a = d; d = c; c = b; b = tmp;
1127c478bd9Sstevel@tonic-gate     }
1137c478bd9Sstevel@tonic-gate   /* Round 2 */
1147c478bd9Sstevel@tonic-gate   for (i = 0, j = 1; i < 16; i++, j += 5)
1157c478bd9Sstevel@tonic-gate     {
1167c478bd9Sstevel@tonic-gate       tmp = a + G (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+16];
1177c478bd9Sstevel@tonic-gate       tmp = ROTATE_LEFT (tmp, s2[i & 3]);
1187c478bd9Sstevel@tonic-gate       tmp += b;
1197c478bd9Sstevel@tonic-gate       a = d; d = c; c = b; b = tmp;
1207c478bd9Sstevel@tonic-gate     }
1217c478bd9Sstevel@tonic-gate   /* Round 3 */
1227c478bd9Sstevel@tonic-gate   for (i = 0, j = 5; i < 16; i++, j += 3)
1237c478bd9Sstevel@tonic-gate     {
1247c478bd9Sstevel@tonic-gate       tmp = a + H (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+32];
1257c478bd9Sstevel@tonic-gate       tmp = ROTATE_LEFT (tmp, s3[i & 3]);
1267c478bd9Sstevel@tonic-gate       tmp += b;
1277c478bd9Sstevel@tonic-gate       a = d; d = c; c = b; b = tmp;
1287c478bd9Sstevel@tonic-gate     }
1297c478bd9Sstevel@tonic-gate   /* Round 4 */
1307c478bd9Sstevel@tonic-gate   for (i = 0, j = 0; i < 16; i++, j += 7)
1317c478bd9Sstevel@tonic-gate     {
1327c478bd9Sstevel@tonic-gate       tmp = a + I (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+48];
1337c478bd9Sstevel@tonic-gate       tmp = ROTATE_LEFT (tmp, s4[i & 3]);
1347c478bd9Sstevel@tonic-gate       tmp += b;
1357c478bd9Sstevel@tonic-gate       a = d; d = c; c = b; b = tmp;
1367c478bd9Sstevel@tonic-gate     }
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate   state[0] += a;
1397c478bd9Sstevel@tonic-gate   state[1] += b;
1407c478bd9Sstevel@tonic-gate   state[2] += c;
1417c478bd9Sstevel@tonic-gate   state[3] += d;
1427c478bd9Sstevel@tonic-gate }
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate static void
md5_init(void)1457c478bd9Sstevel@tonic-gate md5_init(void)
1467c478bd9Sstevel@tonic-gate {
1477c478bd9Sstevel@tonic-gate   memcpy ((char *) state, (char *) initstate, sizeof (initstate));
1487c478bd9Sstevel@tonic-gate   length = 0;
1497c478bd9Sstevel@tonic-gate }
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate static void
md5_update(const char * input,int inputlen)1527c478bd9Sstevel@tonic-gate md5_update (const char *input, int inputlen)
1537c478bd9Sstevel@tonic-gate {
1547c478bd9Sstevel@tonic-gate   int buflen = length & 63;
1557c478bd9Sstevel@tonic-gate   length += inputlen;
1567c478bd9Sstevel@tonic-gate   if (buflen + inputlen < 64)
1577c478bd9Sstevel@tonic-gate     {
1587c478bd9Sstevel@tonic-gate       memcpy (buffer + buflen, input, inputlen);
1597c478bd9Sstevel@tonic-gate       buflen += inputlen;
1607c478bd9Sstevel@tonic-gate       return;
1617c478bd9Sstevel@tonic-gate     }
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate   memcpy (buffer + buflen, input, 64 - buflen);
1647c478bd9Sstevel@tonic-gate   md5_transform (buffer);
1657c478bd9Sstevel@tonic-gate   input += 64 - buflen;
1667c478bd9Sstevel@tonic-gate   inputlen -= 64 - buflen;
1677c478bd9Sstevel@tonic-gate   while (inputlen >= 64)
1687c478bd9Sstevel@tonic-gate     {
1697c478bd9Sstevel@tonic-gate       md5_transform (input);
1707c478bd9Sstevel@tonic-gate       input += 64;
1717c478bd9Sstevel@tonic-gate       inputlen -= 64;
1727c478bd9Sstevel@tonic-gate     }
1737c478bd9Sstevel@tonic-gate   memcpy (buffer, input, inputlen);
1747c478bd9Sstevel@tonic-gate   buflen = inputlen;
1757c478bd9Sstevel@tonic-gate }
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate static unsigned char *
md5_final()1787c478bd9Sstevel@tonic-gate md5_final()
1797c478bd9Sstevel@tonic-gate {
1807c478bd9Sstevel@tonic-gate   int i, buflen = length & 63;
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate   buffer[buflen++] = 0x80;
1837c478bd9Sstevel@tonic-gate   memset (buffer+buflen, 0, 64 - buflen);
1847c478bd9Sstevel@tonic-gate   if (buflen > 56)
1857c478bd9Sstevel@tonic-gate     {
1867c478bd9Sstevel@tonic-gate       md5_transform (buffer);
1877c478bd9Sstevel@tonic-gate       memset (buffer, 0, 64);
1887c478bd9Sstevel@tonic-gate       buflen = 0;
1897c478bd9Sstevel@tonic-gate     }
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate   *(UINT4 *) (buffer + 56) = cpu_to_le32 (8 * length);
1927c478bd9Sstevel@tonic-gate   *(UINT4 *) (buffer + 60) = 0;
1937c478bd9Sstevel@tonic-gate   md5_transform (buffer);
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate   for (i = 0; i < 4; i++)
1967c478bd9Sstevel@tonic-gate     state[i] = cpu_to_le32 (state[i]);
1977c478bd9Sstevel@tonic-gate   return (unsigned char *) state;
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate #ifdef USE_MD5_PASSWORDS
2017c478bd9Sstevel@tonic-gate /* If CHECK is true, check a password for correctness. Returns 0
2027c478bd9Sstevel@tonic-gate    if password was correct, and a value != 0 for error, similarly
2037c478bd9Sstevel@tonic-gate    to strcmp.
2047c478bd9Sstevel@tonic-gate    If CHECK is false, crypt KEY and save the result in CRYPTED.
2057c478bd9Sstevel@tonic-gate    CRYPTED must have a salt.  */
2067c478bd9Sstevel@tonic-gate int
md5_password(const char * key,char * crypted,int check)2077c478bd9Sstevel@tonic-gate md5_password (const char *key, char *crypted, int check)
2087c478bd9Sstevel@tonic-gate {
2097c478bd9Sstevel@tonic-gate   int keylen = strlen (key);
2107c478bd9Sstevel@tonic-gate   char *salt = crypted + 3; /* skip $1$ header */
2117c478bd9Sstevel@tonic-gate   char *p;
2127c478bd9Sstevel@tonic-gate   int saltlen;
2137c478bd9Sstevel@tonic-gate   int i, n;
2147c478bd9Sstevel@tonic-gate   unsigned char alt_result[16];
2157c478bd9Sstevel@tonic-gate   unsigned char *digest;
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate   if (check)
2187c478bd9Sstevel@tonic-gate     {
2197c478bd9Sstevel@tonic-gate       /* If our crypted password isn't 3 chars, then it can't be md5
2207c478bd9Sstevel@tonic-gate 	 crypted. So, they don't match.  */
2217c478bd9Sstevel@tonic-gate       if (strlen(crypted) <= 3)
2227c478bd9Sstevel@tonic-gate 	return 1;
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate       saltlen = strstr (salt, "$") - salt;
2257c478bd9Sstevel@tonic-gate     }
2267c478bd9Sstevel@tonic-gate   else
2277c478bd9Sstevel@tonic-gate     {
2287c478bd9Sstevel@tonic-gate       char *end = strstr (salt, "$");
2297c478bd9Sstevel@tonic-gate       if (end && end - salt < 8)
2307c478bd9Sstevel@tonic-gate 	saltlen = end - salt;
2317c478bd9Sstevel@tonic-gate       else
2327c478bd9Sstevel@tonic-gate 	saltlen = 8;
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate       salt[saltlen] = '$';
2357c478bd9Sstevel@tonic-gate     }
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate   md5_init ();
2387c478bd9Sstevel@tonic-gate   md5_update (key, keylen);
2397c478bd9Sstevel@tonic-gate   md5_update (salt, saltlen);
2407c478bd9Sstevel@tonic-gate   md5_update (key, keylen);
2417c478bd9Sstevel@tonic-gate   digest = md5_final ();
2427c478bd9Sstevel@tonic-gate   memcpy (alt_result, digest, 16);
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate   memcpy ((char *) state, (char *) initstate, sizeof (initstate));
2457c478bd9Sstevel@tonic-gate   length = 0;
2467c478bd9Sstevel@tonic-gate   md5_update (key, keylen);
2477c478bd9Sstevel@tonic-gate   md5_update (crypted, 3 + saltlen); /* include the $1$ header */
2487c478bd9Sstevel@tonic-gate   for (i = keylen; i > 16; i -= 16)
2497c478bd9Sstevel@tonic-gate     md5_update (alt_result, 16);
2507c478bd9Sstevel@tonic-gate   md5_update (alt_result, i);
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate   for (i = keylen; i > 0; i >>= 1)
2537c478bd9Sstevel@tonic-gate     md5_update (key + ((i & 1) ? keylen : 0), 1);
2547c478bd9Sstevel@tonic-gate   digest = md5_final ();
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate   for (i = 0; i < 1000; i++)
2577c478bd9Sstevel@tonic-gate     {
2587c478bd9Sstevel@tonic-gate       memcpy (alt_result, digest, 16);
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate       memcpy ((char *) state, (char *) initstate, sizeof (initstate));
2617c478bd9Sstevel@tonic-gate       length = 0;
2627c478bd9Sstevel@tonic-gate       if ((i & 1) != 0)
2637c478bd9Sstevel@tonic-gate 	md5_update (key, keylen);
2647c478bd9Sstevel@tonic-gate       else
2657c478bd9Sstevel@tonic-gate 	md5_update (alt_result, 16);
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate       if (i % 3 != 0)
2687c478bd9Sstevel@tonic-gate 	md5_update (salt, saltlen);
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate       if (i % 7 != 0)
2717c478bd9Sstevel@tonic-gate 	md5_update (key, keylen);
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate       if ((i & 1) != 0)
2747c478bd9Sstevel@tonic-gate 	md5_update (alt_result, 16);
2757c478bd9Sstevel@tonic-gate       else
2767c478bd9Sstevel@tonic-gate 	md5_update (key, keylen);
2777c478bd9Sstevel@tonic-gate       digest = md5_final ();
2787c478bd9Sstevel@tonic-gate     }
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate   p = salt + saltlen + 1;
2817c478bd9Sstevel@tonic-gate   for (i = 0; i < 5; i++)
2827c478bd9Sstevel@tonic-gate     {
2837c478bd9Sstevel@tonic-gate       unsigned int w =
2847c478bd9Sstevel@tonic-gate 	digest[i == 4 ? 5 : 12+i] | (digest[6+i] << 8) | (digest[i] << 16);
2857c478bd9Sstevel@tonic-gate       for (n = 4; n-- > 0;)
2867c478bd9Sstevel@tonic-gate 	{
2877c478bd9Sstevel@tonic-gate 	  if (check)
2887c478bd9Sstevel@tonic-gate 	    {
2897c478bd9Sstevel@tonic-gate 	      if (*p++ != b64t[w & 0x3f])
2907c478bd9Sstevel@tonic-gate 		return 1;
2917c478bd9Sstevel@tonic-gate 	    }
2927c478bd9Sstevel@tonic-gate 	  else
2937c478bd9Sstevel@tonic-gate 	    {
2947c478bd9Sstevel@tonic-gate 	      *p++ = b64t[w & 0x3f];
2957c478bd9Sstevel@tonic-gate 	    }
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 	  w >>= 6;
2987c478bd9Sstevel@tonic-gate 	}
2997c478bd9Sstevel@tonic-gate     }
3007c478bd9Sstevel@tonic-gate   {
3017c478bd9Sstevel@tonic-gate     unsigned int w = digest[11];
3027c478bd9Sstevel@tonic-gate     for (n = 2; n-- > 0;)
3037c478bd9Sstevel@tonic-gate       {
3047c478bd9Sstevel@tonic-gate 	if (check)
3057c478bd9Sstevel@tonic-gate 	  {
3067c478bd9Sstevel@tonic-gate 	    if (*p++ != b64t[w & 0x3f])
3077c478bd9Sstevel@tonic-gate 	      return 1;
3087c478bd9Sstevel@tonic-gate 	  }
3097c478bd9Sstevel@tonic-gate 	else
3107c478bd9Sstevel@tonic-gate 	  {
3117c478bd9Sstevel@tonic-gate 	    *p++ = b64t[w & 0x3f];
3127c478bd9Sstevel@tonic-gate 	  }
3137c478bd9Sstevel@tonic-gate 
3147c478bd9Sstevel@tonic-gate 	w >>= 6;
3157c478bd9Sstevel@tonic-gate       }
3167c478bd9Sstevel@tonic-gate   }
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate   if (! check)
3197c478bd9Sstevel@tonic-gate     *p = '\0';
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate   return *p;
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate #endif
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate #ifdef TEST
3267c478bd9Sstevel@tonic-gate static char *
md5(const char * input)3277c478bd9Sstevel@tonic-gate md5 (const char *input)
3287c478bd9Sstevel@tonic-gate {
3297c478bd9Sstevel@tonic-gate   memcpy ((char *) state, (char *) initstate, sizeof (initstate));
3307c478bd9Sstevel@tonic-gate   length = 0;
3317c478bd9Sstevel@tonic-gate   md5_update (input, strlen (input));
3327c478bd9Sstevel@tonic-gate   return md5_final ();
3337c478bd9Sstevel@tonic-gate }
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate static void
test(char * buffer,char * expected)3367c478bd9Sstevel@tonic-gate test (char *buffer, char *expected)
3377c478bd9Sstevel@tonic-gate {
3387c478bd9Sstevel@tonic-gate   char result[16 * 3 +1];
3397c478bd9Sstevel@tonic-gate   unsigned char* digest = md5 (buffer);
3407c478bd9Sstevel@tonic-gate   int i;
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate   for (i=0; i < 16; i++)
3437c478bd9Sstevel@tonic-gate     sprintf (result+2*i, "%02x", digest[i]);
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate   if (strcmp (result, expected))
3467c478bd9Sstevel@tonic-gate     printf ("MD5(%s) failed: %s\n", buffer, result);
3477c478bd9Sstevel@tonic-gate   else
3487c478bd9Sstevel@tonic-gate     printf ("MD5(%s) OK\n", buffer);
3497c478bd9Sstevel@tonic-gate }
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate int
main(void)3527c478bd9Sstevel@tonic-gate main (void)
3537c478bd9Sstevel@tonic-gate {
3547c478bd9Sstevel@tonic-gate   test ("", "d41d8cd98f00b204e9800998ecf8427e");
3557c478bd9Sstevel@tonic-gate   test ("a", "0cc175b9c0f1b6a831c399e269772661");
3567c478bd9Sstevel@tonic-gate   test ("abc", "900150983cd24fb0d6963f7d28e17f72");
3577c478bd9Sstevel@tonic-gate   test ("message digest", "f96b697d7cb7938d525a2f31aaf161d0");
3587c478bd9Sstevel@tonic-gate   test ("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b");
3597c478bd9Sstevel@tonic-gate   test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
3607c478bd9Sstevel@tonic-gate 	"d174ab98d277d9f5a5611c2c9f419d9f");
3617c478bd9Sstevel@tonic-gate   test ("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
3627c478bd9Sstevel@tonic-gate 	"57edf4a22be3c955ac49da2e2107b67a");
3637c478bd9Sstevel@tonic-gate   test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz3456",
3647c478bd9Sstevel@tonic-gate 	"6831fa90115bb9a54fbcd4f9fee0b5c4");
3657c478bd9Sstevel@tonic-gate   test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz345",
3667c478bd9Sstevel@tonic-gate 	"bc40505cc94a43b7ff3e2ac027325233");
3677c478bd9Sstevel@tonic-gate   test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz34567",
3687c478bd9Sstevel@tonic-gate 	"fa94b73a6f072a0239b52acacfbcf9fa");
3697c478bd9Sstevel@tonic-gate   test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz345678901234",
3707c478bd9Sstevel@tonic-gate 	"bd201eae17f29568927414fa326f1267");
3717c478bd9Sstevel@tonic-gate   test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz34567890123",
3727c478bd9Sstevel@tonic-gate 	"80063db1e6b70a2e91eac903f0e46b85");
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate   if (check_md5_password ("Hello world!",
3757c478bd9Sstevel@tonic-gate 			  "$1$saltstri$YMyguxXMBpd2TEZ.vS/3q1"))
3767c478bd9Sstevel@tonic-gate     printf ("Password differs\n");
3777c478bd9Sstevel@tonic-gate   else
3787c478bd9Sstevel@tonic-gate     printf ("Password OK\n");
3797c478bd9Sstevel@tonic-gate   return 0;
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate #endif
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate #endif
384