"Fossies" - the Fresh Open Source Software Archive

Member "scanssh-2.1/md5.c" (31 Mar 2004, 9106 Bytes) of package /linux/privat/old/scanssh-2.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "md5.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * This code implements the MD5 message-digest algorithm.
    3  * The algorithm is due to Ron Rivest.  This code was
    4  * written by Colin Plumb in 1993, no copyright is claimed.
    5  * This code is in the public domain; do with it what you wish.
    6  *
    7  * Equivalent code is available from RSA Data Security, Inc.
    8  * This code has been tested against that, and is equivalent,
    9  * except that you don't need to include two pages of legalese
   10  * with every copy.
   11  *
   12  * To compute the message digest of a chunk of bytes, declare an
   13  * MD5Context structure, pass it to MD5Init, call MD5Update as
   14  * needed on buffers full of bytes, and then call MD5Final, which
   15  * will fill a supplied 16-byte array with the digest.
   16  */
   17 
   18 /* This code was modified in 1997 by Jim Kingdon of Cyclic Software to
   19    not require an integer type which is exactly 32 bits.  This work
   20    draws on the changes for the same purpose by Tatu Ylonen
   21    <ylo@cs.hut.fi> as part of SSH, but since I didn't actually use
   22    that code, there is no copyright issue.  I hereby disclaim
   23    copyright in any changes I have made; this code remains in the
   24    public domain.  */
   25 
   26 #include <sys/types.h>
   27 
   28 #ifdef HAVE_CONFIG_H
   29 #include "config.h"
   30 #endif
   31 
   32 #include "md5.h"
   33 
   34 /* Little-endian byte-swapping routines.  Note that these do not
   35    depend on the size of datatypes such as uint32, nor do they require
   36    us to detect the endianness of the machine we are running on.  It
   37    is possible they should be macros for speed, but I would be
   38    surprised if they were a performance bottleneck for MD5.  */
   39 
   40 static uint32
   41 getu32 (addr)
   42      const unsigned char *addr;
   43 {
   44     return (((((unsigned long)addr[3] << 8) | addr[2]) << 8)
   45         | addr[1]) << 8 | addr[0];
   46 }
   47 
   48 static void
   49 putu32 (data, addr)
   50      uint32 data;
   51      unsigned char *addr;
   52 {
   53     addr[0] = (unsigned char)data;
   54     addr[1] = (unsigned char)(data >> 8);
   55     addr[2] = (unsigned char)(data >> 16);
   56     addr[3] = (unsigned char)(data >> 24);
   57 }
   58 
   59 /*
   60  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
   61  * initialization constants.
   62  */
   63 void
   64 MD5Init(ctx)
   65      struct MD5Context *ctx;
   66 {
   67     ctx->buf[0] = 0x67452301;
   68     ctx->buf[1] = 0xefcdab89;
   69     ctx->buf[2] = 0x98badcfe;
   70     ctx->buf[3] = 0x10325476;
   71 
   72     ctx->bits[0] = 0;
   73     ctx->bits[1] = 0;
   74 }
   75 
   76 /*
   77  * Update context to reflect the concatenation of another buffer full
   78  * of bytes.
   79  */
   80 void
   81 MD5Update(ctx, buf, len)
   82      struct MD5Context *ctx;
   83      unsigned char const *buf;
   84      unsigned len;
   85 {
   86     uint32 t;
   87 
   88     /* Update bitcount */
   89 
   90     t = ctx->bits[0];
   91     if ((ctx->bits[0] = (t + ((uint32)len << 3)) & 0xffffffff) < t)
   92         ctx->bits[1]++; /* Carry from low to high */
   93     ctx->bits[1] += len >> 29;
   94 
   95     t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
   96 
   97     /* Handle any leading odd-sized chunks */
   98 
   99     if ( t ) {
  100         unsigned char *p = ctx->in + t;
  101 
  102         t = 64-t;
  103         if (len < t) {
  104             memcpy(p, buf, len);
  105             return;
  106         }
  107         memcpy(p, buf, t);
  108         MD5Transform(ctx->buf, ctx->in);
  109         buf += t;
  110         len -= t;
  111     }
  112 
  113     /* Process data in 64-byte chunks */
  114 
  115     while (len >= 64) {
  116         memcpy(ctx->in, buf, 64);
  117         MD5Transform(ctx->buf, ctx->in);
  118         buf += 64;
  119         len -= 64;
  120     }
  121 
  122     /* Handle any remaining bytes of data. */
  123 
  124     memcpy(ctx->in, buf, len);
  125 }
  126 
  127 /*
  128  * Final wrapup - pad to 64-byte boundary with the bit pattern 
  129  * 1 0* (64-bit count of bits processed, MSB-first)
  130  */
  131 void
  132 MD5Final(digest, ctx)
  133      unsigned char digest[16];
  134      struct MD5Context *ctx;
  135 {
  136     unsigned count;
  137     unsigned char *p;
  138 
  139     /* Compute number of bytes mod 64 */
  140     count = (ctx->bits[0] >> 3) & 0x3F;
  141 
  142     /* Set the first char of padding to 0x80.  This is safe since there is
  143        always at least one byte free */
  144     p = ctx->in + count;
  145     *p++ = 0x80;
  146 
  147     /* Bytes of padding needed to make 64 bytes */
  148     count = 64 - 1 - count;
  149 
  150     /* Pad out to 56 mod 64 */
  151     if (count < 8) {
  152         /* Two lots of padding:  Pad the first block to 64 bytes */
  153         memset(p, 0, count);
  154         MD5Transform(ctx->buf, ctx->in);
  155 
  156         /* Now fill the next block with 56 bytes */
  157         memset(ctx->in, 0, 56);
  158     } else {
  159         /* Pad block to 56 bytes */
  160         memset(p, 0, count-8);
  161     }
  162 
  163     /* Append length in bits and transform */
  164     putu32(ctx->bits[0], ctx->in + 56);
  165     putu32(ctx->bits[1], ctx->in + 60);
  166 
  167     MD5Transform(ctx->buf, ctx->in);
  168     putu32(ctx->buf[0], digest);
  169     putu32(ctx->buf[1], digest + 4);
  170     putu32(ctx->buf[2], digest + 8);
  171     putu32(ctx->buf[3], digest + 12);
  172     memset(ctx, 0, sizeof(ctx));    /* In case it's sensitive */
  173 }
  174 
  175 #ifndef ASM_MD5
  176 
  177 /* The four core functions - F1 is optimized somewhat */
  178 
  179 /* #define F1(x, y, z) (x & y | ~x & z) */
  180 #define F1(x, y, z) (z ^ (x & (y ^ z)))
  181 #define F2(x, y, z) F1(z, x, y)
  182 #define F3(x, y, z) (x ^ y ^ z)
  183 #define F4(x, y, z) (y ^ (x | ~z))
  184 
  185 /* This is the central step in the MD5 algorithm. */
  186 #define MD5STEP(f, w, x, y, z, data, s) \
  187     ( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
  188 
  189 /*
  190  * The core of the MD5 algorithm, this alters an existing MD5 hash to
  191  * reflect the addition of 16 longwords of new data.  MD5Update blocks
  192  * the data and converts bytes into longwords for this routine.
  193  */
  194 void
  195 MD5Transform(buf, inraw)
  196      uint32 buf[4];
  197      const unsigned char inraw[64];
  198 {
  199     register uint32 a, b, c, d;
  200     uint32 in[16];
  201     int i;
  202 
  203     for (i = 0; i < 16; ++i)
  204         in[i] = getu32 (inraw + 4 * i);
  205 
  206     a = buf[0];
  207     b = buf[1];
  208     c = buf[2];
  209     d = buf[3];
  210 
  211     MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
  212     MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
  213     MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
  214     MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
  215     MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
  216     MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
  217     MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
  218     MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
  219     MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
  220     MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
  221     MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
  222     MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
  223     MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
  224     MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
  225     MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
  226     MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
  227 
  228     MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
  229     MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
  230     MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
  231     MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
  232     MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
  233     MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
  234     MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
  235     MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
  236     MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
  237     MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
  238     MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
  239     MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
  240     MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
  241     MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
  242     MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
  243     MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
  244 
  245     MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
  246     MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
  247     MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
  248     MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
  249     MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
  250     MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
  251     MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
  252     MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
  253     MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
  254     MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
  255     MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
  256     MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
  257     MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
  258     MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
  259     MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
  260     MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
  261 
  262     MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
  263     MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
  264     MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
  265     MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
  266     MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
  267     MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
  268     MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
  269     MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
  270     MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
  271     MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
  272     MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
  273     MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
  274     MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
  275     MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
  276     MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
  277     MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
  278 
  279     buf[0] += a;
  280     buf[1] += b;
  281     buf[2] += c;
  282     buf[3] += d;
  283 }
  284 #endif
  285 
  286 #ifdef TEST
  287 /* Simple test program.  Can use it to manually run the tests from
  288    RFC1321 for example.  */
  289 #include <stdio.h>
  290 
  291 int
  292 main (int argc, char **argv)
  293 {
  294     struct MD5Context context;
  295     unsigned char checksum[16];
  296     int i;
  297     int j;
  298 
  299     if (argc < 2)
  300     {
  301         fprintf (stderr, "usage: %s string-to-hash\n", argv[0]);
  302         exit (1);
  303     }
  304     for (j = 1; j < argc; ++j)
  305     {
  306         printf ("MD5 (\"%s\") = ", argv[j]);
  307         MD5Init (&context);
  308         MD5Update (&context, argv[j], strlen (argv[j]));
  309         MD5Final (checksum, &context);
  310         for (i = 0; i < 16; i++)
  311         {
  312             printf ("%02x", (unsigned int) checksum[i]);
  313         }
  314         printf ("\n");
  315     }
  316     return 0;
  317 }
  318 #endif /* TEST */