Back to home page

MITgcm

 
 

    


File indexing completed on 2018-03-02 18:44:58 UTC

view on githubraw file Latest commit ec6cf3b0 on 2003-08-26 20:45:25 UTC
ec6cf3b09d Ed H*0001 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
                0002  */
                0003 
                0004 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
                0005 rights reserved.
                0006 
                0007 License to copy and use this software is granted provided that it
                0008 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
                0009 Algorithm" in all material mentioning or referencing this software
                0010 or this function.
                0011 
                0012 License is also granted to make and use derivative works provided
                0013 that such works are identified as "derived from the RSA Data
                0014 Security, Inc. MD5 Message-Digest Algorithm" in all material
                0015 mentioning or referencing the derived work.
                0016 
                0017 RSA Data Security, Inc. makes no representations concerning either
                0018 the merchantability of this software or the suitability of this
                0019 software for any particular purpose. It is provided "as is"
                0020 without express or implied warranty of any kind.
                0021 
                0022 These notices must be retained in any copies of any part of this
                0023 documentation and/or software.
                0024  */
                0025 
                0026 #include "md5.h"
                0027 
                0028 /* Constants for MD5Transform routine.
                0029  */
                0030 
                0031 #define S11 7
                0032 #define S12 12
                0033 #define S13 17
                0034 #define S14 22
                0035 #define S21 5
                0036 #define S22 9
                0037 #define S23 14
                0038 #define S24 20
                0039 #define S31 4
                0040 #define S32 11
                0041 #define S33 16
                0042 #define S34 23
                0043 #define S41 6
                0044 #define S42 10
                0045 #define S43 15
                0046 #define S44 21
                0047 
                0048 static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
                0049 static void Encode PROTO_LIST
                0050   ((unsigned char *, UINT4 *, unsigned int));
                0051 static void Decode PROTO_LIST
                0052   ((UINT4 *, unsigned char *, unsigned int));
                0053 static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
                0054 static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
                0055 
                0056 static unsigned char PADDING[64] = {
                0057   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0058   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0059   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
                0060 };
                0061 
                0062 /* F, G, H and I are basic MD5 functions.
                0063  */
                0064 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
                0065 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
                0066 #define H(x, y, z) ((x) ^ (y) ^ (z))
                0067 #define I(x, y, z) ((y) ^ ((x) | (~z)))
                0068 
                0069 /* ROTATE_LEFT rotates x left n bits.
                0070  */
                0071 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
                0072 
                0073 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
                0074 Rotation is separate from addition to prevent recomputation.
                0075  */
                0076 #define FF(a, b, c, d, x, s, ac) { \
                0077  (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
                0078  (a) = ROTATE_LEFT ((a), (s)); \
                0079  (a) += (b); \
                0080   }
                0081 #define GG(a, b, c, d, x, s, ac) { \
                0082  (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
                0083  (a) = ROTATE_LEFT ((a), (s)); \
                0084  (a) += (b); \
                0085   }
                0086 #define HH(a, b, c, d, x, s, ac) { \
                0087  (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
                0088  (a) = ROTATE_LEFT ((a), (s)); \
                0089  (a) += (b); \
                0090   }
                0091 #define II(a, b, c, d, x, s, ac) { \
                0092  (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
                0093  (a) = ROTATE_LEFT ((a), (s)); \
                0094  (a) += (b); \
                0095   }
                0096 
                0097 /* MD5 initialization. Begins an MD5 operation, writing a new context.
                0098  */
                0099 void MD5Init (MD5_CTX *context)
                0100                                                          /* context */
                0101 {
                0102   context->count[0] = context->count[1] = 0;
                0103   /* Load magic initialization constants.
                0104 */
                0105   context->state[0] = 0x67452301;
                0106   context->state[1] = 0xefcdab89;
                0107   context->state[2] = 0x98badcfe;
                0108   context->state[3] = 0x10325476;
                0109 }
                0110 
                0111 /* MD5 block update operation. Continues an MD5 message-digest
                0112   operation, processing another message block, and updating the
                0113   context.
                0114  */
                0115 void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)
                0116                                                          /* context */
                0117                                                      /* input block */
                0118                                            /* length of input block */
                0119 {
                0120   unsigned int i, index, partLen;
                0121 
                0122   /* Compute number of bytes mod 64 */
                0123   index = (unsigned int)((context->count[0] >> 3) & 0x3F);
                0124 
                0125   /* Update number of bits */
                0126   if ((context->count[0] += ((UINT4)inputLen << 3))
                0127    < ((UINT4)inputLen << 3))
                0128  context->count[1]++;
                0129   context->count[1] += ((UINT4)inputLen >> 29);
                0130 
                0131   partLen = 64 - index;
                0132 
                0133   /* Transform as many times as possible.
                0134 */
                0135   if (inputLen >= partLen) {
                0136  MD5_memcpy
                0137    ((POINTER)&context->buffer[index], (POINTER)input, partLen);
                0138  MD5Transform (context->state, context->buffer);
                0139 
                0140  for (i = partLen; i + 63 < inputLen; i += 64)
                0141    MD5Transform (context->state, &input[i]);
                0142 
                0143  index = 0;
                0144   }
                0145   else
                0146  i = 0;
                0147 
                0148   /* Buffer remaining input */
                0149   MD5_memcpy
                0150  ((POINTER)&context->buffer[index], (POINTER)&input[i],
                0151   inputLen-i);
                0152 }
                0153 
                0154 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
                0155   the message digest and zeroizing the context.
                0156  */
                0157 void MD5Final (unsigned char *digest, MD5_CTX *context)
                0158                                                   /* message digest */
                0159                                                         /* context */
                0160 {
                0161   unsigned char bits[8];
                0162   unsigned int index, padLen;
                0163 
                0164   /* Save number of bits */
                0165   Encode (bits, context->count, 8);
                0166 
                0167   /* Pad out to 56 mod 64.
                0168 */
                0169   index = (unsigned int)((context->count[0] >> 3) & 0x3f);
                0170   padLen = (index < 56) ? (56 - index) : (120 - index);
                0171   MD5Update (context, PADDING, padLen);
                0172 
                0173   /* Append length (before padding) */
                0174   MD5Update (context, bits, 8);
                0175 
                0176   /* Store state in digest */
                0177   Encode (digest, context->state, 16);
                0178 
                0179   /* Zeroize sensitive information.
                0180 */
                0181   MD5_memset ((POINTER)context, 0, sizeof (*context));
                0182 }
                0183 
                0184 /* MD5 basic transformation. Transforms state based on block.
                0185  */
                0186 static void MD5Transform (UINT4 *state, unsigned char *block)
                0187 {
                0188   UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
                0189 
                0190   Decode (x, block, 64);
                0191 
                0192   /* Round 1 */
                0193   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
                0194   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
                0195   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
                0196   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
                0197   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
                0198   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
                0199   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
                0200   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
                0201   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
                0202   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
                0203   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
                0204   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
                0205   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
                0206   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
                0207   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
                0208   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
                0209 
                0210  /* Round 2 */
                0211   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
                0212   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
                0213   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
                0214   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
                0215   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
                0216   GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
                0217   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
                0218   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
                0219   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
                0220   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
                0221   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
                0222   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
                0223   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
                0224   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
                0225   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
                0226   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
                0227 
                0228   /* Round 3 */
                0229   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
                0230   HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
                0231   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
                0232   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
                0233   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
                0234   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
                0235   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
                0236   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
                0237   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
                0238   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
                0239   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
                0240   HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
                0241   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
                0242   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
                0243   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
                0244   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
                0245 
                0246   /* Round 4 */
                0247   II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
                0248   II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
                0249   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
                0250   II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
                0251   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
                0252   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
                0253   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
                0254   II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
                0255   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
                0256   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
                0257   II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
                0258   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
                0259   II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
                0260   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
                0261   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
                0262   II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
                0263 
                0264   state[0] += a;
                0265   state[1] += b;
                0266   state[2] += c;
                0267   state[3] += d;
                0268 
                0269   /* Zeroize sensitive information.
                0270 */
                0271   MD5_memset ((POINTER)x, 0, sizeof (x));
                0272 }
                0273 
                0274 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
                0275   a multiple of 4.
                0276  */
                0277 static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
                0278 {
                0279   unsigned int i, j;
                0280 
                0281   for (i = 0, j = 0; j < len; i++, j += 4) {
                0282  output[j] = (unsigned char)(input[i] & 0xff);
                0283  output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
                0284  output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
                0285  output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
                0286   }
                0287 }
                0288 
                0289 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
                0290   a multiple of 4.
                0291  */
                0292 static void Decode (UINT4 *output, unsigned char *input, unsigned int len)
                0293 {
                0294   unsigned int i, j;
                0295 
                0296   for (i = 0, j = 0; j < len; i++, j += 4)
                0297  output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
                0298    (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
                0299 }
                0300 
                0301 /* Note: Replace "for loop" with standard memcpy if possible.
                0302  */
                0303 
                0304 static void MD5_memcpy (POINTER output, POINTER input, unsigned int len)
                0305 {
                0306   unsigned int i;
                0307 
                0308   for (i = 0; i < len; i++)
                0309  output[i] = input[i];
                0310 }
                0311 
                0312 /* Note: Replace "for loop" with standard memset if possible.
                0313  */
                0314 static void MD5_memset (POINTER output, int value, unsigned int len)
                0315 {
                0316   unsigned int i;
                0317 
                0318   for (i = 0; i < len; i++)
                0319  ((char *)output)[i] = (char)value;
                0320 }