KEIS

Dependents:   EthernetInterface

Fork of lwip by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers md5.c Source File

md5.c

00001 /*
00002  ***********************************************************************
00003  ** md5.c -- the source code for MD5 routines                         **
00004  ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
00005  ** Created: 2/17/90 RLR                                              **
00006  ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
00007  ***********************************************************************
00008  */
00009 
00010 /*
00011  ***********************************************************************
00012  ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
00013  **                                                                   **
00014  ** License to copy and use this software is granted provided that    **
00015  ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
00016  ** Digest Algorithm" in all material mentioning or referencing this  **
00017  ** software or this function.                                        **
00018  **                                                                   **
00019  ** License is also granted to make and use derivative works          **
00020  ** provided that such works are identified as "derived from the RSA  **
00021  ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
00022  ** material mentioning or referencing the derived work.              **
00023  **                                                                   **
00024  ** RSA Data Security, Inc. makes no representations concerning       **
00025  ** either the merchantability of this software or the suitability    **
00026  ** of this software for any particular purpose.  It is provided "as  **
00027  ** is" without express or implied warranty of any kind.              **
00028  **                                                                   **
00029  ** These notices must be retained in any copies of any part of this  **
00030  ** documentation and/or software.                                    **
00031  ***********************************************************************
00032  */
00033 
00034 #include "lwip/opt.h"
00035 
00036 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
00037 
00038 #if CHAP_SUPPORT || MD5_SUPPORT
00039 
00040 #include "ppp.h"
00041 #include "pppdebug.h"
00042 
00043 #include "md5.h"
00044 
00045 #include <string.h>
00046 
00047 /*
00048  ***********************************************************************
00049  **  Message-digest routines:                                         **
00050  **  To form the message digest for a message M                       **
00051  **    (1) Initialize a context buffer mdContext using MD5Init        **
00052  **    (2) Call MD5Update on mdContext and M                          **
00053  **    (3) Call MD5Final on mdContext                                 **
00054  **  The message digest is now in mdContext->digest[0...15]           **
00055  ***********************************************************************
00056  */
00057 
00058 /* forward declaration */
00059 static void Transform (u32_t *buf, u32_t *in);
00060 
00061 static unsigned char PADDING[64] = {
00062   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00063   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00064   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00065   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00066   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00067   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00068   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00069   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00070 };
00071 
00072 /* F, G, H and I are basic MD5 functions */
00073 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00074 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00075 #define H(x, y, z) ((x) ^ (y) ^ (z))
00076 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00077 
00078 /* ROTATE_LEFT rotates x left n bits */
00079 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00080 
00081 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
00082 /* Rotation is separate from addition to prevent recomputation */
00083 #define FF(a, b, c, d, x, s, ac) \
00084   {(a) += F ((b), (c), (d)) + (x) + (u32_t)(ac); \
00085    (a) = ROTATE_LEFT ((a), (s)); \
00086    (a) += (b); \
00087   }
00088 #define GG(a, b, c, d, x, s, ac) \
00089   {(a) += G ((b), (c), (d)) + (x) + (u32_t)(ac); \
00090    (a) = ROTATE_LEFT ((a), (s)); \
00091    (a) += (b); \
00092   }
00093 #define HH(a, b, c, d, x, s, ac) \
00094   {(a) += H ((b), (c), (d)) + (x) + (u32_t)(ac); \
00095    (a) = ROTATE_LEFT ((a), (s)); \
00096    (a) += (b); \
00097   }
00098 #define II(a, b, c, d, x, s, ac) \
00099   {(a) += I ((b), (c), (d)) + (x) + (u32_t)(ac); \
00100    (a) = ROTATE_LEFT ((a), (s)); \
00101    (a) += (b); \
00102   }
00103 
00104 #ifdef __STDC__
00105 #define UL(x) x##UL
00106 #else
00107 #ifdef WIN32
00108 #define UL(x) x##UL
00109 #else
00110 #define UL(x) x
00111 #endif
00112 #endif
00113 
00114 /* The routine MD5Init initializes the message-digest context
00115    mdContext. All fields are set to zero.
00116  */
00117 void
00118 MD5Init (MD5_CTX *mdContext)
00119 {
00120   mdContext->i[0] = mdContext->i[1] = (u32_t)0;
00121 
00122   /* Load magic initialization constants. */
00123   mdContext->buf[0] = (u32_t)0x67452301UL;
00124   mdContext->buf[1] = (u32_t)0xefcdab89UL;
00125   mdContext->buf[2] = (u32_t)0x98badcfeUL;
00126   mdContext->buf[3] = (u32_t)0x10325476UL;
00127 }
00128 
00129 /* The routine MD5Update updates the message-digest context to
00130    account for the presence of each of the characters inBuf[0..inLen-1]
00131    in the message whose digest is being computed.
00132  */
00133 void
00134 MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
00135 {
00136   u32_t in[16];
00137   int mdi;
00138   unsigned int i, ii;
00139 
00140 #if 0
00141   PPPDEBUG(LOG_INFO, ("MD5Update: %u:%.*H\n", inLen, LWIP_MIN(inLen, 20) * 2, inBuf));
00142   PPPDEBUG(LOG_INFO, ("MD5Update: %u:%s\n", inLen, inBuf));
00143 #endif
00144   
00145   /* compute number of bytes mod 64 */
00146   mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
00147 
00148   /* update number of bits */
00149   if ((mdContext->i[0] + ((u32_t)inLen << 3)) < mdContext->i[0]) {
00150     mdContext->i[1]++;
00151   }
00152   mdContext->i[0] += ((u32_t)inLen << 3);
00153   mdContext->i[1] += ((u32_t)inLen >> 29);
00154 
00155   while (inLen--) {
00156     /* add new character to buffer, increment mdi */
00157     mdContext->in[mdi++] = *inBuf++;
00158 
00159     /* transform if necessary */
00160     if (mdi == 0x40) {
00161       for (i = 0, ii = 0; i < 16; i++, ii += 4) {
00162         in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |
00163                 (((u32_t)mdContext->in[ii+2]) << 16) |
00164                 (((u32_t)mdContext->in[ii+1]) << 8)  |
00165                 ((u32_t)mdContext->in[ii]);
00166       }
00167       Transform (mdContext->buf, in);
00168       mdi = 0;
00169     }
00170   }
00171 }
00172 
00173 /* The routine MD5Final terminates the message-digest computation and
00174    ends with the desired message digest in mdContext->digest[0...15].
00175  */
00176 void
00177 MD5Final (unsigned char hash[], MD5_CTX *mdContext)
00178 {
00179   u32_t in[16];
00180   int mdi;
00181   unsigned int i, ii;
00182   unsigned int padLen;
00183 
00184   /* save number of bits */
00185   in[14] = mdContext->i[0];
00186   in[15] = mdContext->i[1];
00187 
00188   /* compute number of bytes mod 64 */
00189   mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
00190 
00191   /* pad out to 56 mod 64 */
00192   padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
00193   MD5Update (mdContext, PADDING, padLen);
00194 
00195   /* append length in bits and transform */
00196   for (i = 0, ii = 0; i < 14; i++, ii += 4) {
00197     in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |
00198             (((u32_t)mdContext->in[ii+2]) << 16) |
00199             (((u32_t)mdContext->in[ii+1]) << 8)  |
00200             ((u32_t)mdContext->in[ii]);
00201   }
00202   Transform (mdContext->buf, in);
00203 
00204   /* store buffer in digest */
00205   for (i = 0, ii = 0; i < 4; i++, ii += 4) {
00206     mdContext->digest[ii]   = (unsigned char)(mdContext->buf[i] & 0xFF);
00207     mdContext->digest[ii+1] =
00208       (unsigned char)((mdContext->buf[i] >> 8)  & 0xFF);
00209     mdContext->digest[ii+2] =
00210       (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
00211     mdContext->digest[ii+3] =
00212       (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
00213   }
00214   SMEMCPY(hash, mdContext->digest, 16);
00215 }
00216 
00217 /* Basic MD5 step. Transforms buf based on in.
00218  */
00219 static void
00220 Transform (u32_t *buf, u32_t *in)
00221 {
00222   u32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3];
00223 
00224   /* Round 1 */
00225 #define S11 7
00226 #define S12 12
00227 #define S13 17
00228 #define S14 22
00229   FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
00230   FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
00231   FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
00232   FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
00233   FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
00234   FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
00235   FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
00236   FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
00237   FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
00238   FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
00239   FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
00240   FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
00241   FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
00242   FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
00243   FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
00244   FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
00245 
00246   /* Round 2 */
00247 #define S21 5
00248 #define S22 9
00249 #define S23 14
00250 #define S24 20
00251   GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
00252   GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
00253   GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
00254   GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
00255   GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
00256   GG ( d, a, b, c, in[10], S22, UL(  38016083)); /* 22 */
00257   GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
00258   GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
00259   GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
00260   GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
00261   GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
00262   GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
00263   GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
00264   GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
00265   GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
00266   GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
00267 
00268   /* Round 3 */
00269 #define S31 4
00270 #define S32 11
00271 #define S33 16
00272 #define S34 23
00273   HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
00274   HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
00275   HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
00276   HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
00277   HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
00278   HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
00279   HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
00280   HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
00281   HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
00282   HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
00283   HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
00284   HH ( b, c, d, a, in[ 6], S34, UL(  76029189)); /* 44 */
00285   HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
00286   HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
00287   HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
00288   HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
00289 
00290   /* Round 4 */
00291 #define S41 6
00292 #define S42 10
00293 #define S43 15
00294 #define S44 21
00295   II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
00296   II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
00297   II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
00298   II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
00299   II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
00300   II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
00301   II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
00302   II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
00303   II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
00304   II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
00305   II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
00306   II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
00307   II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
00308   II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
00309   II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
00310   II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
00311 
00312   buf[0] += a;
00313   buf[1] += b;
00314   buf[2] += c;
00315   buf[3] += d;
00316 }
00317 
00318 #endif /* CHAP_SUPPORT || MD5_SUPPORT */
00319 
00320 #endif /* PPP_SUPPORT */