Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:18

0001 
0002 /*
0003  ***********************************************************************
0004  ** md5.c -- the source code for MD5 routines                         **
0005  ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
0006  ** Created: 2/17/90 RLR                                              **
0007  ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
0008  ***********************************************************************
0009  */
0010 
0011 /*
0012  ***********************************************************************
0013  ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
0014  **                                                                   **
0015  ** License to copy and use this software is granted provided that    **
0016  ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
0017  ** Digest Algorithm" in all material mentioning or referencing this  **
0018  ** software or this function.                                        **
0019  **                                                                   **
0020  ** License is also granted to make and use derivative works          **
0021  ** provided that such works are identified as "derived from the RSA  **
0022  ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
0023  ** material mentioning or referencing the derived work.              **
0024  **                                                                   **
0025  ** RSA Data Security, Inc. makes no representations concerning       **
0026  ** either the merchantability of this software or the suitability    **
0027  ** of this software for any particular purpose.  It is provided "as  **
0028  ** is" without express or implied warranty of any kind.              **
0029  **                                                                   **
0030  ** These notices must be retained in any copies of any part of this  **
0031  ** documentation and/or software.                                    **
0032  ***********************************************************************
0033  */
0034 
0035 #ifdef HAVE_CONFIG_H
0036 #include "config.h"
0037 #endif
0038 
0039 #include <string.h> /* memcpy */
0040 
0041 #include "md5.h"
0042 
0043 /*
0044  ***********************************************************************
0045  **  Message-digest routines:                                         **
0046  **  To form the message digest for a message M                       **
0047  **    (1) Initialize a context buffer mdContext using MD5Init        **
0048  **    (2) Call MD5Update on mdContext and M                          **
0049  **    (3) Call MD5Final on mdContext                                 **
0050  **  The message digest is now in mdContext->digest[0...15]           **
0051  ***********************************************************************
0052  */
0053 
0054 /* forward declaration */
0055 static void Transform (UINT4 *buf, UINT4 *in);
0056 
0057 static unsigned char PADDING[64] = {
0058   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0059   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0060   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0061   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0062   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0063   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0064   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0065   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0066 };
0067 
0068 /* F, G, H and I are basic MD5 functions */
0069 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
0070 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
0071 #define H(x, y, z) ((x) ^ (y) ^ (z))
0072 #define I(x, y, z) ((y) ^ ((x) | (~z)))
0073 
0074 /* ROTATE_LEFT rotates x left n bits */
0075 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
0076 
0077 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
0078 /* Rotation is separate from addition to prevent recomputation */
0079 #define FF(a, b, c, d, x, s, ac) \
0080   {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
0081    (a) = ROTATE_LEFT ((a), (s)); \
0082    (a) += (b); \
0083   }
0084 #define GG(a, b, c, d, x, s, ac) \
0085   {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
0086    (a) = ROTATE_LEFT ((a), (s)); \
0087    (a) += (b); \
0088   }
0089 #define HH(a, b, c, d, x, s, ac) \
0090   {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
0091    (a) = ROTATE_LEFT ((a), (s)); \
0092    (a) += (b); \
0093   }
0094 #define II(a, b, c, d, x, s, ac) \
0095   {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
0096    (a) = ROTATE_LEFT ((a), (s)); \
0097    (a) += (b); \
0098   }
0099 
0100 #ifdef __STDC__
0101 #define UL(x)   x##U
0102 #else
0103 #define UL(x)   x
0104 #endif
0105 
0106 /* The routine MD5Init initializes the message-digest context
0107    mdContext. All fields are set to zero.
0108  */
0109 void MD5Init (
0110   MD5_CTX *mdContext )
0111 {
0112   mdContext->i[0] = mdContext->i[1] = (UINT4)0;
0113 
0114   /* Load magic initialization constants.
0115    */
0116   mdContext->buf[0] = (UINT4)0x67452301;
0117   mdContext->buf[1] = (UINT4)0xefcdab89;
0118   mdContext->buf[2] = (UINT4)0x98badcfe;
0119   mdContext->buf[3] = (UINT4)0x10325476;
0120 }
0121 
0122 /* The routine MD5Update updates the message-digest context to
0123    account for the presence of each of the characters inBuf[0..inLen-1]
0124    in the message whose digest is being computed.
0125  */
0126 void MD5Update (
0127   MD5_CTX *mdContext,
0128   const void *inBufArg,
0129   unsigned int inLen )
0130 {
0131   UINT4 in[16];
0132   int mdi;
0133   unsigned int i, ii;
0134   const unsigned char *inBuf;
0135 
0136   inBuf = inBufArg;
0137 
0138   /* compute number of bytes mod 64 */
0139   mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
0140 
0141   /* update number of bits */
0142   if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
0143     mdContext->i[1]++;
0144   mdContext->i[0] += ((UINT4)inLen << 3);
0145   mdContext->i[1] += ((UINT4)inLen >> 29);
0146 
0147   while (inLen--) {
0148     /* add new character to buffer, increment mdi */
0149     mdContext->in[mdi++] = *inBuf++;
0150 
0151     /* transform if necessary */
0152     if (mdi == 0x40) {
0153       for (i = 0, ii = 0; i < 16; i++, ii += 4)
0154         in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
0155                 (((UINT4)mdContext->in[ii+2]) << 16) |
0156                 (((UINT4)mdContext->in[ii+1]) << 8) |
0157                 ((UINT4)mdContext->in[ii]);
0158       Transform (mdContext->buf, in);
0159       mdi = 0;
0160     }
0161   }
0162 }
0163 
0164 /* The routine MD5Final terminates the message-digest computation and
0165    ends with the desired message digest in mdContext->digest[0...15].
0166  */
0167 void MD5Final (
0168   unsigned char hash[16],
0169   MD5_CTX *mdContext )
0170 {
0171   UINT4 in[16];
0172   int mdi;
0173   unsigned int i, ii;
0174   unsigned int padLen;
0175 
0176   /* save number of bits */
0177   in[14] = mdContext->i[0];
0178   in[15] = mdContext->i[1];
0179 
0180   /* compute number of bytes mod 64 */
0181   mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
0182 
0183   /* pad out to 56 mod 64 */
0184   padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
0185   MD5Update (mdContext, PADDING, padLen);
0186 
0187   /* append length in bits and transform */
0188   for (i = 0, ii = 0; i < 14; i++, ii += 4)
0189     in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
0190             (((UINT4)mdContext->in[ii+2]) << 16) |
0191             (((UINT4)mdContext->in[ii+1]) << 8) |
0192             ((UINT4)mdContext->in[ii]);
0193   Transform (mdContext->buf, in);
0194 
0195   /* store buffer in digest */
0196   for (i = 0, ii = 0; i < 4; i++, ii += 4) {
0197     mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
0198     mdContext->digest[ii+1] =
0199       (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
0200     mdContext->digest[ii+2] =
0201       (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
0202     mdContext->digest[ii+3] =
0203       (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
0204   }
0205   memcpy(hash, mdContext->digest, 16);
0206 }
0207 
0208 /* Basic MD5 step. Transforms buf based on in.
0209  */
0210 static void Transform (
0211   UINT4 *buf,
0212   UINT4 *in )
0213 {
0214   UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
0215 
0216   /* Round 1 */
0217 #define S11 7
0218 #define S12 12
0219 #define S13 17
0220 #define S14 22
0221   FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
0222   FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
0223   FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
0224   FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
0225   FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
0226   FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
0227   FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
0228   FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
0229   FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
0230   FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
0231   FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
0232   FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
0233   FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
0234   FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
0235   FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
0236   FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
0237 
0238   /* Round 2 */
0239 #define S21 5
0240 #define S22 9
0241 #define S23 14
0242 #define S24 20
0243   GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
0244   GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
0245   GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
0246   GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
0247   GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
0248   GG ( d, a, b, c, in[10], S22, UL(  38016083)); /* 22 */
0249   GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
0250   GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
0251   GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
0252   GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
0253   GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
0254   GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
0255   GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
0256   GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
0257   GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
0258   GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
0259 
0260   /* Round 3 */
0261 #define S31 4
0262 #define S32 11
0263 #define S33 16
0264 #define S34 23
0265   HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
0266   HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
0267   HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
0268   HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
0269   HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
0270   HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
0271   HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
0272   HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
0273   HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
0274   HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
0275   HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
0276   HH ( b, c, d, a, in[ 6], S34, UL(  76029189)); /* 44 */
0277   HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
0278   HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
0279   HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
0280   HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
0281 
0282   /* Round 4 */
0283 #define S41 6
0284 #define S42 10
0285 #define S43 15
0286 #define S44 21
0287   II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
0288   II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
0289   II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
0290   II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
0291   II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
0292   II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
0293   II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
0294   II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
0295   II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
0296   II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
0297   II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
0298   II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
0299   II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
0300   II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
0301   II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
0302   II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
0303 
0304   buf[0] += a;
0305   buf[1] += b;
0306   buf[2] += c;
0307   buf[3] += d;
0308 }
0309 
0310 /*
0311  ***********************************************************************
0312  ** End of md5.c                                                      **
0313  ******************************** (cut) ********************************
0314  */