- Timestamp:
- Aug 7, 2009 9:17:39 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 50841
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/md5.h
r21918 r22092 46 46 typedef struct RTMD5CONTEXT 47 47 { 48 uint32_t in[16]; 48 49 uint32_t buf[4]; 49 50 uint32_t bits[2]; 50 uint32_t in[16];51 51 } RTMD5CONTEXT; 52 52 -
trunk/src/VBox/Runtime/common/checksum/md5.cpp
r21918 r22092 1 1 /* $Id$ */ 2 2 /** @file 3 * MD5 message digest functions3 * IPRT - MD5 message digest functions. 4 4 */ 5 5 … … 62 62 * Defined Constants And Macros * 63 63 *******************************************************************************/ 64 #ifdef sgi 65 #define HIGHFIRST 64 /* The four core functions - F1 is optimized somewhat */ 65 #if 1 66 /* #define F1(x, y, z) (x & y | ~x & z) */ 67 # define F1(x, y, z) (z ^ (x & (y ^ z))) 68 # define F2(x, y, z) F1(z, x, y) 69 # define F3(x, y, z) (x ^ y ^ z) 70 # define F4(x, y, z) (y ^ (x | ~z)) 71 #else /* gcc 4.0.1 (x86) benefits from the explicitness of F1() here. */ 72 DECL_FORCE_INLINE(uint32_t) F1(uint32_t x, uint32_t y, uint32_t z) 73 { 74 register uint32_t r = y ^ z; 75 r &= x; 76 r ^= z; 77 return r; 78 } 79 # define F2(x, y, z) F1(z, x, y) 80 DECL_FORCE_INLINE(uint32_t) F3(uint32_t x, uint32_t y, uint32_t z) 81 { 82 register uint32_t r = x ^ y; 83 r ^= z; 84 return r; 85 } 86 DECL_FORCE_INLINE(uint32_t) F4(uint32_t x, uint32_t y, uint32_t z) 87 { 88 register uint32_t r = ~z; 89 r |= x; 90 r ^= y; 91 return r; 92 } 66 93 #endif 67 94 68 #ifdef sun 69 #define HIGHFIRST 70 #endif 71 72 #ifndef HIGHFIRST 73 #define byteReverse(buf, len) /* Nothing */ 74 #else 95 /* This is the central step in the MD5 algorithm. */ 96 #define MD5STEP(f, w, x, y, z, data, s) \ 97 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) 98 99 100 /** 101 * The core of the MD5 algorithm, this alters an existing MD5 hash to reflect 102 * the addition of 16 longwords of new data. RTMd5Update blocks the data and 103 * converts bytes into longwords for this routine. 104 */ 105 static void rtMd5Transform(uint32_t buf[4], uint32_t const in[16]) 106 { 107 uint32_t a, b, c, d; 108 109 a = buf[0]; 110 b = buf[1]; 111 c = buf[2]; 112 d = buf[3]; 113 114 /* fn, w, x, y, z, data, s) */ 115 MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7); 116 MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); 117 MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); 118 MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); 119 MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7); 120 MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); 121 MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); 122 MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); 123 MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7); 124 MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12); 125 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 126 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 127 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 128 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 129 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 130 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 131 132 MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5); 133 MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9); 134 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 135 MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20); 136 MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5); 137 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 138 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 139 MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20); 140 MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5); 141 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 142 MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14); 143 MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20); 144 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 145 MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9); 146 MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14); 147 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 148 149 MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4); 150 MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11); 151 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 152 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 153 MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4); 154 MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11); 155 MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16); 156 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 157 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 158 MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11); 159 MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16); 160 MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23); 161 MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4); 162 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 163 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 164 MD5STEP(F3, b, c, d, a, in[ 2] + 0xc4ac5665, 23); 165 166 MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6); 167 MD5STEP(F4, d, a, b, c, in[ 7] + 0x432aff97, 10); 168 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 169 MD5STEP(F4, b, c, d, a, in[ 5] + 0xfc93a039, 21); 170 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 171 MD5STEP(F4, d, a, b, c, in[ 3] + 0x8f0ccc92, 10); 172 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 173 MD5STEP(F4, b, c, d, a, in[ 1] + 0x85845dd1, 21); 174 MD5STEP(F4, a, b, c, d, in[ 8] + 0x6fa87e4f, 6); 175 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 176 MD5STEP(F4, c, d, a, b, in[ 6] + 0xa3014314, 15); 177 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 178 MD5STEP(F4, a, b, c, d, in[ 4] + 0xf7537e82, 6); 179 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 180 MD5STEP(F4, c, d, a, b, in[ 2] + 0x2ad7d2bb, 15); 181 MD5STEP(F4, b, c, d, a, in[ 9] + 0xeb86d391, 21); 182 183 buf[0] += a; 184 buf[1] += b; 185 buf[2] += c; 186 buf[3] += d; 187 } 188 189 190 #ifdef RT_BIG_ENDIAN 75 191 /* 76 192 * Note: this code is harmless on little-endian machines. 77 193 */ 78 static void byteReverse(uint32_t *buf, unsigned int longs)194 static void rtMd5ByteReverse(uint32_t *buf, unsigned int longs) 79 195 { 80 196 uint32_t t; 81 197 do { 82 t = (uint32_t) *((uint8_t *)buf + 3) << 24 | 83 (uint32_t) *((uint8_t *)buf + 2) << 16 | 84 (uint32_t) *((uint8_t *)buf + 1) << 8 | *(uint8_t *)buf; 198 t = *buf 199 t = RT_LE2H_U32(t); 85 200 *buf = t; 86 201 buf++; 87 202 } while (--longs); 88 203 } 204 #else /* little endian - do nothing */ 205 # define rtMd5ByteReverse(buf, len) do { /* Nothing */ } while (0) 89 206 #endif 90 207 91 static void MD5Transform(uint32_t buf[4], uint32_t in[16]);92 208 93 209 … … 115 231 RTDECL(void) RTMd5Update(PRTMD5CONTEXT ctx, const void *pvBuf, size_t len) 116 232 { 117 const uint8_t *buf = (const uint8_t *)pvBuf;118 uint32_t t;233 const uint8_t *buf = (const uint8_t *)pvBuf; 234 uint32_t t; 119 235 120 236 /* Update bitcount */ 121 122 237 t = ctx->bits[0]; 123 238 if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) … … 128 243 129 244 /* Handle any leading odd-sized chunks */ 130 131 245 if (t) { 132 246 uint8_t *p = (uint8_t *) ctx->in + t; … … 138 252 } 139 253 memcpy(p, buf, t); 140 byteReverse(ctx->in, 16);141 MD5Transform(ctx->buf, ctx->in);254 rtMd5ByteReverse(ctx->in, 16); 255 rtMd5Transform(ctx->buf, ctx->in); 142 256 buf += t; 143 257 len -= t; 144 258 } 259 145 260 /* Process data in 64-byte chunks */ 146 147 while (len >= 64) { 148 memcpy(ctx->in, buf, 64); 149 byteReverse(ctx->in, 16); 150 MD5Transform(ctx->buf, ctx->in); 151 buf += 64; 152 len -= 64; 153 } 154 155 /* Handle any remaining bytes of data. */ 156 261 #ifndef RT_BIG_ENDIAN 262 if (!((uintptr_t)buf & 0x3)) 263 { 264 while (len >= 64) { 265 rtMd5Transform(ctx->buf, (uint32_t const *)buf); 266 buf += 64; 267 len -= 64; 268 } 269 } 270 else 271 #endif 272 { 273 while (len >= 64) { 274 memcpy(ctx->in, buf, 64); 275 rtMd5ByteReverse(ctx->in, 16); 276 rtMd5Transform(ctx->buf, ctx->in); 277 buf += 64; 278 len -= 64; 279 } 280 } 281 282 /* Handle any remaining bytes of data */ 157 283 memcpy(ctx->in, buf, len); 158 284 } … … 184 310 /* Two lots of padding: Pad the first block to 64 bytes */ 185 311 memset(p, 0, count); 186 byteReverse(ctx->in, 16);187 MD5Transform(ctx->buf, ctx->in);312 rtMd5ByteReverse(ctx->in, 16); 313 rtMd5Transform(ctx->buf, ctx->in); 188 314 189 315 /* Now fill the next block with 56 bytes */ … … 193 319 memset(p, 0, count - 8); 194 320 } 195 byteReverse(ctx->in, 14);321 rtMd5ByteReverse(ctx->in, 14); 196 322 197 323 /* Append length in bits and transform */ … … 199 325 ctx->in[15] = ctx->bits[1]; 200 326 201 MD5Transform(ctx->buf, ctx->in);202 byteReverse(ctx->buf, 4);327 rtMd5Transform(ctx->buf, ctx->in); 328 rtMd5ByteReverse(ctx->buf, 4); 203 329 memcpy(digest, ctx->buf, 16); 204 330 memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ … … 209 335 RTDECL(void) RTMd5(const void *pvBuf, size_t cbBuf, uint8_t pabDigest[RTMD5HASHSIZE]) 210 336 { 211 RTMD5CONTEXT Ctx; 212 RTMd5Init(&Ctx); 213 RTMd5Update(&Ctx, pvBuf, cbBuf); 214 RTMd5Final(pabDigest, &Ctx); 337 #if 0 338 RTMD5CONTEXT Ctx[2]; 339 PRTMD5CONTEXT const pCtx = RT_ALIGN_PT(&Ctx[0], 64, PRTMD5CONTEXT); 340 #else 341 RTMD5CONTEXT Ctx; 342 PRTMD5CONTEXT const pCtx = &Ctx; 343 #endif 344 345 RTMd5Init(pCtx); 346 for (;;) 347 { 348 uint32_t cb = (uint32_t)RT_MIN(cbBuf, _2M); 349 RTMd5Update(pCtx, pvBuf, cb); 350 if (cb == cbBuf) 351 break; 352 cbBuf -= cb; 353 pvBuf = (uint8_t const *)pvBuf + cb; 354 } 355 RTMd5Final(pabDigest, pCtx); 215 356 } 216 357 RT_EXPORT_SYMBOL(RTMd5); 217 358 218 219 /* The four core functions - F1 is optimized somewhat */220 221 /* #define F1(x, y, z) (x & y | ~x & z) */222 #define F1(x, y, z) (z ^ (x & (y ^ z)))223 #define F2(x, y, z) F1(z, x, y)224 #define F3(x, y, z) (x ^ y ^ z)225 #define F4(x, y, z) (y ^ (x | ~z))226 227 /* This is the central step in the MD5 algorithm. */228 #define MD5STEP(f, w, x, y, z, data, s) \229 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )230 231 /*232 * The core of the MD5 algorithm, this alters an existing MD5 hash to233 * reflect the addition of 16 longwords of new data. MD5Update blocks234 * the data and converts bytes into longwords for this routine.235 */236 static void MD5Transform(uint32_t buf[4], uint32_t in[16])237 {238 uint32_t a, b, c, d;239 240 a = buf[0];241 b = buf[1];242 c = buf[2];243 d = buf[3];244 245 MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);246 MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);247 MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);248 MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);249 MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);250 MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);251 MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);252 MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);253 MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);254 MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);255 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);256 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);257 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);258 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);259 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);260 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);261 262 MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);263 MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);264 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);265 MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);266 MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);267 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);268 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);269 MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);270 MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);271 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);272 MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);273 MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);274 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);275 MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);276 MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);277 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);278 279 MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);280 MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);281 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);282 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);283 MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);284 MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);285 MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);286 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);287 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);288 MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);289 MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);290 MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);291 MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);292 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);293 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);294 MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);295 296 MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);297 MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);298 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);299 MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);300 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);301 MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);302 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);303 MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);304 MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);305 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);306 MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);307 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);308 MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);309 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);310 MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);311 MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);312 313 buf[0] += a;314 buf[1] += b;315 buf[2] += c;316 buf[3] += d;317 }318 319 320
Note:
See TracChangeset
for help on using the changeset viewer.