File indexing completed on 2025-01-19 03:55:20

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