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 }