Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:26

0001 /*
0002   Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
0003 
0004   This software is provided 'as-is', without any express or implied
0005   warranty.  In no event will the authors be held liable for any damages
0006   arising from the use of this software.
0007 
0008   Permission is granted to anyone to use this software for any purpose,
0009   including commercial applications, and to alter it and redistribute it
0010   freely, subject to the following restrictions:
0011 
0012   1. The origin of this software must not be misrepresented; you must not
0013      claim that you wrote the original software. If you use this software
0014      in a product, an acknowledgment in the product documentation would be
0015      appreciated but is not required.
0016   2. Altered source versions must be plainly marked as such, and must not be
0017      misrepresented as being the original software.
0018   3. This notice may not be removed or altered from any source distribution.
0019 
0020   L. Peter Deutsch
0021   ghost@aladdin.com
0022 
0023  */
0024 /* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
0025 /*
0026   Independent implementation of MD5 (RFC 1321).
0027 
0028   This code implements the MD5 Algorithm defined in RFC 1321, whose
0029   text is available at
0030     http://www.ietf.org/rfc/rfc1321.txt
0031   The code is derived from the text of the RFC, including the test suite
0032   (section A.5) but excluding the rest of Appendix A.  It does not include
0033   any code or documentation that is identified in the RFC as being
0034   copyrighted.
0035 
0036   The original and principal author of md5.c is L. Peter Deutsch
0037   <ghost@aladdin.com>.  Other authors are noted in the change history
0038   that follows (in reverse chronological order):
0039 
0040   2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
0041     either statically or dynamically; added missing #include <string.h>
0042     in library.
0043   2002-03-11 lpd Corrected argument list for main(), and added int return
0044     type, in test program and T value program.
0045   2002-02-21 lpd Added missing #include <stdio.h> in test program.
0046   2000-07-03 lpd Patched to eliminate warnings about "constant is
0047     unsigned in ANSI C, signed in traditional"; made test program
0048     self-checking.
0049   1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
0050   1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
0051   1999-05-03 lpd Original version.
0052  */
0053 
0054 #include "md5.h"
0055 #include <string.h>
0056 
0057 #undef BYTE_ORDER   /* 1 = big-endian, -1 = little-endian, 0 = unknown */
0058 #ifdef ARCH_IS_BIG_ENDIAN
0059 #  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
0060 #else
0061 #  define BYTE_ORDER 0
0062 #endif
0063 
0064 #define T_MASK ((md5_word_t)~0)
0065 #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
0066 #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
0067 #define T3    0x242070db
0068 #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
0069 #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
0070 #define T6    0x4787c62a
0071 #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
0072 #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
0073 #define T9    0x698098d8
0074 #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
0075 #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
0076 #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
0077 #define T13    0x6b901122
0078 #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
0079 #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
0080 #define T16    0x49b40821
0081 #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
0082 #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
0083 #define T19    0x265e5a51
0084 #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
0085 #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
0086 #define T22    0x02441453
0087 #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
0088 #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
0089 #define T25    0x21e1cde6
0090 #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
0091 #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
0092 #define T28    0x455a14ed
0093 #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
0094 #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
0095 #define T31    0x676f02d9
0096 #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
0097 #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
0098 #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
0099 #define T35    0x6d9d6122
0100 #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
0101 #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
0102 #define T38    0x4bdecfa9
0103 #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
0104 #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
0105 #define T41    0x289b7ec6
0106 #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
0107 #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
0108 #define T44    0x04881d05
0109 #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
0110 #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
0111 #define T47    0x1fa27cf8
0112 #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
0113 #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
0114 #define T50    0x432aff97
0115 #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
0116 #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
0117 #define T53    0x655b59c3
0118 #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
0119 #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
0120 #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
0121 #define T57    0x6fa87e4f
0122 #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
0123 #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
0124 #define T60    0x4e0811a1
0125 #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
0126 #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
0127 #define T63    0x2ad7d2bb
0128 #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
0129 
0130 
0131 static void
0132 md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
0133 {
0134     md5_word_t
0135     a = pms->abcd[0], b = pms->abcd[1],
0136     c = pms->abcd[2], d = pms->abcd[3];
0137     md5_word_t t;
0138 #if BYTE_ORDER > 0
0139     /* Define storage only for big-endian CPUs. */
0140     md5_word_t X[16];
0141 #else
0142     /* Define storage for little-endian or both types of CPUs. */
0143     md5_word_t xbuf[16];
0144     const md5_word_t *X;
0145 #endif
0146 
0147     {
0148 #if BYTE_ORDER == 0
0149     /*
0150      * Determine dynamically whether this is a big-endian or
0151      * little-endian machine, since we can use a more efficient
0152      * algorithm on the latter.
0153      */
0154     static const int w = 1;
0155 
0156     if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
0157 #endif
0158 #if BYTE_ORDER <= 0     /* little-endian */
0159     {
0160         /*
0161          * On little-endian machines, we can process properly aligned
0162          * data without copying it.
0163          */
0164         if (!((data - (const md5_byte_t *)0) & 3)) {
0165         /* data are properly aligned */
0166         X = (const md5_word_t *)data;
0167         } else {
0168         /* not aligned */
0169         memcpy(xbuf, data, 64);
0170         X = xbuf;
0171         }
0172     }
0173 #endif
0174 #if BYTE_ORDER == 0
0175     else            /* dynamic big-endian */
0176 #endif
0177 #if BYTE_ORDER >= 0     /* big-endian */
0178     {
0179         /*
0180          * On big-endian machines, we must arrange the bytes in the
0181          * right order.
0182          */
0183         const md5_byte_t *xp = data;
0184         int i;
0185 
0186 #  if BYTE_ORDER == 0
0187         X = xbuf;       /* (dynamic only) */
0188 #  else
0189 #    define xbuf X      /* (static only) */
0190 #  endif
0191         for (i = 0; i < 16; ++i, xp += 4)
0192         xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
0193     }
0194 #endif
0195     }
0196 
0197 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
0198 
0199     /* Round 1. */
0200     /* Let [abcd k s i] denote the operation
0201        a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
0202 #define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
0203 #define SET(a, b, c, d, k, s, Ti)\
0204   t = a + F(b,c,d) + X[k] + Ti;\
0205   a = ROTATE_LEFT(t, s) + b
0206     /* Do the following 16 operations. */
0207     SET(a, b, c, d,  0,  7,  T1);
0208     SET(d, a, b, c,  1, 12,  T2);
0209     SET(c, d, a, b,  2, 17,  T3);
0210     SET(b, c, d, a,  3, 22,  T4);
0211     SET(a, b, c, d,  4,  7,  T5);
0212     SET(d, a, b, c,  5, 12,  T6);
0213     SET(c, d, a, b,  6, 17,  T7);
0214     SET(b, c, d, a,  7, 22,  T8);
0215     SET(a, b, c, d,  8,  7,  T9);
0216     SET(d, a, b, c,  9, 12, T10);
0217     SET(c, d, a, b, 10, 17, T11);
0218     SET(b, c, d, a, 11, 22, T12);
0219     SET(a, b, c, d, 12,  7, T13);
0220     SET(d, a, b, c, 13, 12, T14);
0221     SET(c, d, a, b, 14, 17, T15);
0222     SET(b, c, d, a, 15, 22, T16);
0223 #undef SET
0224 
0225      /* Round 2. */
0226      /* Let [abcd k s i] denote the operation
0227           a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
0228 #define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
0229 #define SET(a, b, c, d, k, s, Ti)\
0230   t = a + G(b,c,d) + X[k] + Ti;\
0231   a = ROTATE_LEFT(t, s) + b
0232      /* Do the following 16 operations. */
0233     SET(a, b, c, d,  1,  5, T17);
0234     SET(d, a, b, c,  6,  9, T18);
0235     SET(c, d, a, b, 11, 14, T19);
0236     SET(b, c, d, a,  0, 20, T20);
0237     SET(a, b, c, d,  5,  5, T21);
0238     SET(d, a, b, c, 10,  9, T22);
0239     SET(c, d, a, b, 15, 14, T23);
0240     SET(b, c, d, a,  4, 20, T24);
0241     SET(a, b, c, d,  9,  5, T25);
0242     SET(d, a, b, c, 14,  9, T26);
0243     SET(c, d, a, b,  3, 14, T27);
0244     SET(b, c, d, a,  8, 20, T28);
0245     SET(a, b, c, d, 13,  5, T29);
0246     SET(d, a, b, c,  2,  9, T30);
0247     SET(c, d, a, b,  7, 14, T31);
0248     SET(b, c, d, a, 12, 20, T32);
0249 #undef SET
0250 
0251      /* Round 3. */
0252      /* Let [abcd k s t] denote the operation
0253           a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
0254 #define H(x, y, z) ((x) ^ (y) ^ (z))
0255 #define SET(a, b, c, d, k, s, Ti)\
0256   t = a + H(b,c,d) + X[k] + Ti;\
0257   a = ROTATE_LEFT(t, s) + b
0258      /* Do the following 16 operations. */
0259     SET(a, b, c, d,  5,  4, T33);
0260     SET(d, a, b, c,  8, 11, T34);
0261     SET(c, d, a, b, 11, 16, T35);
0262     SET(b, c, d, a, 14, 23, T36);
0263     SET(a, b, c, d,  1,  4, T37);
0264     SET(d, a, b, c,  4, 11, T38);
0265     SET(c, d, a, b,  7, 16, T39);
0266     SET(b, c, d, a, 10, 23, T40);
0267     SET(a, b, c, d, 13,  4, T41);
0268     SET(d, a, b, c,  0, 11, T42);
0269     SET(c, d, a, b,  3, 16, T43);
0270     SET(b, c, d, a,  6, 23, T44);
0271     SET(a, b, c, d,  9,  4, T45);
0272     SET(d, a, b, c, 12, 11, T46);
0273     SET(c, d, a, b, 15, 16, T47);
0274     SET(b, c, d, a,  2, 23, T48);
0275 #undef SET
0276 
0277      /* Round 4. */
0278      /* Let [abcd k s t] denote the operation
0279           a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
0280 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
0281 #define SET(a, b, c, d, k, s, Ti)\
0282   t = a + I(b,c,d) + X[k] + Ti;\
0283   a = ROTATE_LEFT(t, s) + b
0284      /* Do the following 16 operations. */
0285     SET(a, b, c, d,  0,  6, T49);
0286     SET(d, a, b, c,  7, 10, T50);
0287     SET(c, d, a, b, 14, 15, T51);
0288     SET(b, c, d, a,  5, 21, T52);
0289     SET(a, b, c, d, 12,  6, T53);
0290     SET(d, a, b, c,  3, 10, T54);
0291     SET(c, d, a, b, 10, 15, T55);
0292     SET(b, c, d, a,  1, 21, T56);
0293     SET(a, b, c, d,  8,  6, T57);
0294     SET(d, a, b, c, 15, 10, T58);
0295     SET(c, d, a, b,  6, 15, T59);
0296     SET(b, c, d, a, 13, 21, T60);
0297     SET(a, b, c, d,  4,  6, T61);
0298     SET(d, a, b, c, 11, 10, T62);
0299     SET(c, d, a, b,  2, 15, T63);
0300     SET(b, c, d, a,  9, 21, T64);
0301 #undef SET
0302 
0303      /* Then perform the following additions. (That is increment each
0304         of the four registers by the value it had before this block
0305         was started.) */
0306     pms->abcd[0] += a;
0307     pms->abcd[1] += b;
0308     pms->abcd[2] += c;
0309     pms->abcd[3] += d;
0310 }
0311 
0312 void
0313 md5_init(md5_state_t *pms)
0314 {
0315     pms->count[0] = pms->count[1] = 0;
0316     pms->abcd[0] = 0x67452301;
0317     pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
0318     pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
0319     pms->abcd[3] = 0x10325476;
0320 }
0321 
0322 void
0323 md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
0324 {
0325     const md5_byte_t *p = data;
0326     int left = nbytes;
0327     int offset = (pms->count[0] >> 3) & 63;
0328     md5_word_t nbits = (md5_word_t)(nbytes << 3);
0329 
0330     if (nbytes <= 0)
0331     return;
0332 
0333     /* Update the message length. */
0334     pms->count[1] += nbytes >> 29;
0335     pms->count[0] += nbits;
0336     if (pms->count[0] < nbits)
0337     pms->count[1]++;
0338 
0339     /* Process an initial partial block. */
0340     if (offset) {
0341     int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
0342 
0343     memcpy(pms->buf + offset, p, copy);
0344     if (offset + copy < 64)
0345         return;
0346     p += copy;
0347     left -= copy;
0348     md5_process(pms, pms->buf);
0349     }
0350 
0351     /* Process full blocks. */
0352     for (; left >= 64; p += 64, left -= 64)
0353     md5_process(pms, p);
0354 
0355     /* Process a final partial block. */
0356     if (left)
0357     memcpy(pms->buf, p, left);
0358 }
0359 
0360 void
0361 md5_finish(md5_state_t *pms, md5_byte_t digest[16])
0362 {
0363     static const md5_byte_t pad[64] = {
0364     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0365     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0366     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0367     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0368     };
0369     md5_byte_t data[8];
0370     int i;
0371 
0372     /* Save the length before padding. */
0373     for (i = 0; i < 8; ++i)
0374     data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
0375     /* Pad to 56 bytes mod 64. */
0376     md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
0377     /* Append the length. */
0378     md5_append(pms, data, 8);
0379     for (i = 0; i < 16; ++i)
0380     digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
0381 }