1/* 2 File: MD5.c 3 4 Written by: Colin Plumb 5 6 Copyright: Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. 7 8 Change History (most recent first): 9 10 <7> 10/06/98 ap Changed to compile with C++. 11 12 To Do: 13*/ 14 15/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. 16 * 17 * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT 18 * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE 19 * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE 20 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, 21 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL 22 * EXPOSE YOU TO LIABILITY. 23 *************************************************************************** 24 * 25 * MD5.c 26 */ 27 28/* 29 * This code implements the MD5 message-digest algorithm. 30 * The algorithm is due to Ron Rivest. This code was 31 * written by Colin Plumb in 1993, no copyright is claimed. 32 * This code is in the public domain; do with it what you wish. 33 * 34 * Equivalent code is available from RSA Data Security, Inc. 35 * This code has been tested against that, and is equivalent, 36 * except that you don't need to include two pages of legalese 37 * with every copy. 38 * 39 * To compute the message digest of a chunk of bytes, declare an 40 * MD5Context structure, pass it to MD5Init, call MD5Update as 41 * needed on buffers full of bytes, and then call MD5Final, which 42 * will fill a supplied 16-byte array with the digest. 43 */ 44 45/* 46 * Revision History 47 * ---------------- 48 * 06 Feb 1997 at Apple 49 * Fixed endian-dependent cast in MD5Final() 50 * Made byteReverse() tolerant of platform-dependent alignment 51 * restrictions 52 */ 53 54#include "ckconfig.h" 55 56#if CRYPTKIT_MD5_ENABLE && !CRYPTKIT_LIBMD_DIGEST 57 58#include "ckMD5.h" 59#include "platform.h" 60#include "byteRep.h" 61#include <stdlib.h> 62 63 64#define MD5_DEBUG 0 65 66#if MD5_DEBUG 67static inline void dumpCtx(MD5Context *ctx, char *label) 68{ 69 int i; 70 71 printf("%s\n", label); 72 printf("buf = "); 73 for(i=0; i<4; i++) { 74 printf("%x:", ctx->buf[i]); 75 } 76 printf("\nbits: %d:%d\n", ctx->bits[0], ctx->bits[1]); 77 printf("in[]:\n "); 78 for(i=0; i<64; i++) { 79 printf("%02x:", ctx->in[i]); 80 if((i % 16) == 15) { 81 printf("\n "); 82 } 83 } 84 printf("\n"); 85} 86#else // MD5_DEBUG 87#define dumpCtx(ctx, label) 88#endif // MD5_DEBUG 89 90static void MD5Transform(UINT32 buf[4], UINT32 const in[16]); 91 92#if __LITTLE_ENDIAN__ 93#define byteReverse(buf, len) /* Nothing */ 94#else 95static void byteReverse(unsigned char *buf, unsigned longs); 96 97#ifndef ASM_MD5 98/* 99 * Note: this code is harmless on little-endian machines. 100 */ 101static void byteReverse(unsigned char *buf, unsigned longs) 102{ 103#if old_way 104 /* 105 * this code is NOT harmless on big-endian machine which require 106 * natural alignment. 107 */ 108 UINT32 t; 109 do { 110 t = (UINT32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | 111 ((unsigned) buf[1] << 8 | buf[0]); 112 *(UINT32 *) buf = t; 113 buf += 4; 114 } while (--longs); 115#else // new_way 116 117 unsigned char t; 118 do { 119 t = buf[0]; 120 buf[0] = buf[3]; 121 buf[3] = t; 122 t = buf[1]; 123 buf[1] = buf[2]; 124 buf[2] = t; 125 buf += 4; 126 } while (--longs); 127#endif // old_way 128} 129#endif // ASM_MD5 130#endif // __LITTLE_ENDIAN__ 131 132/* 133 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 134 * initialization constants. 135 */ 136void MD5Init(MD5Context *ctx) 137{ 138 ctx->buf[0] = 0x67452301; 139 ctx->buf[1] = 0xefcdab89; 140 ctx->buf[2] = 0x98badcfe; 141 ctx->buf[3] = 0x10325476; 142 143 ctx->bits[0] = 0; 144 ctx->bits[1] = 0; 145} 146 147/* 148 * Update context to reflect the concatenation of another buffer full 149 * of bytes. 150 */ 151void MD5Update(MD5Context *ctx, unsigned char const *buf, unsigned len) 152{ 153 UINT32 t; 154 155 dumpCtx(ctx, "MD5.c update top"); 156 /* Update bitcount */ 157 158 t = ctx->bits[0]; 159 if ((ctx->bits[0] = t + ((UINT32) len << 3)) < t) 160 ctx->bits[1]++; /* Carry from low to high */ 161 ctx->bits[1] += len >> 29; 162 163 t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ 164 165 /* Handle any leading odd-sized chunks */ 166 167 if (t) { 168 unsigned char *p = (unsigned char *) ctx->in + t; 169 170 t = 64 - t; 171 if (len < t) { 172 memcpy(p, buf, len); 173 return; 174 } 175 memcpy(p, buf, t); 176 byteReverse(ctx->in, 16); 177 MD5Transform(ctx->buf, (UINT32 *) ctx->in); 178 dumpCtx(ctx, "update - return from transform (1)"); 179 buf += t; 180 len -= t; 181 } 182 /* Process data in 64-byte chunks */ 183 184 while (len >= 64) { 185 memcpy(ctx->in, buf, 64); 186 byteReverse(ctx->in, 16); 187 MD5Transform(ctx->buf, (UINT32 *) ctx->in); 188 dumpCtx(ctx, "update - return from transform (2)"); 189 buf += 64; 190 len -= 64; 191 } 192 193 /* Handle any remaining bytes of data. */ 194 195 memcpy(ctx->in, buf, len); 196} 197 198/* 199 * Final wrapup - pad to 64-byte boundary with the bit pattern 200 * 1 0* (64-bit count of bits processed, MSB-first) 201 */ 202void MD5Final(MD5Context *ctx, unsigned char *digest) 203{ 204 unsigned count; 205 unsigned char *p; 206 207 dumpCtx(ctx, "final top"); 208 209 /* Compute number of bytes mod 64 */ 210 count = (ctx->bits[0] >> 3) & 0x3F; 211 212 /* Set the first char of padding to 0x80. This is safe since there is 213 always at least one byte free */ 214 p = ctx->in + count; 215 *p++ = 0x80; 216 #if MD5_DEBUG 217 printf("in[%d] = %x\n", count, ctx->in[count]); 218 #endif 219 /* Bytes of padding needed to make 64 bytes */ 220 count = 64 - 1 - count; 221 222 /* Pad out to 56 mod 64 */ 223 dumpCtx(ctx, "final, before pad"); 224 if (count < 8) { 225 /* Two lots of padding: Pad the first block to 64 bytes */ 226 bzero(p, count); 227 byteReverse(ctx->in, 16); 228 MD5Transform(ctx->buf, (UINT32 *) ctx->in); 229 230 /* Now fill the next block with 56 bytes */ 231 bzero(ctx->in, 56); 232 } else { 233 /* Pad block to 56 bytes */ 234 bzero(p, count - 8); 235 } 236 byteReverse(ctx->in, 14); 237 238 /* Append length in bits and transform */ 239 #if old_way 240 /* 241 * On a little endian machine, this writes the l.s. byte of 242 * the bit count to ctx->in[56] and the m.s byte of the bit count to 243 * ctx->in[63]. 244 */ 245 ((UINT32 *) ctx->in)[14] = ctx->bits[0]; 246 ((UINT32 *) ctx->in)[15] = ctx->bits[1]; 247 #else // new_way 248 intToByteRep(ctx->bits[0], &ctx->in[56]); 249 intToByteRep(ctx->bits[1], &ctx->in[60]); 250 #endif // new_way 251 252 dumpCtx(ctx, "last transform"); 253 MD5Transform(ctx->buf, (UINT32 *) ctx->in); 254 byteReverse((unsigned char *) ctx->buf, 4); 255 memcpy(digest, ctx->buf, MD5_DIGEST_SIZE); 256 dumpCtx(ctx, "final end"); 257 258 bzero(ctx, sizeof(*ctx)); /* In case it's sensitive */ 259} 260 261#ifndef ASM_MD5 262 263/* The four core functions - F1 is optimized somewhat */ 264 265/* #define F1(x, y, z) (x & y | ~x & z) */ 266#define F1(x, y, z) (z ^ (x & (y ^ z))) 267#define F2(x, y, z) F1(z, x, y) 268#define F3(x, y, z) (x ^ y ^ z) 269#define F4(x, y, z) (y ^ (x | ~z)) 270 271/* This is the central step in the MD5 algorithm. */ 272#define MD5STEP(f, w, x, y, z, data, s) \ 273 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) 274 275/* 276 * The core of the MD5 algorithm, this alters an existing MD5 hash to 277 * reflect the addition of 16 longwords of new data. MD5Update blocks 278 * the data and converts bytes into longwords for this routine. 279 */ 280static void MD5Transform(UINT32 buf[4], UINT32 const in[16]) 281{ 282 register UINT32 a, b, c, d; 283 284 a = buf[0]; 285 b = buf[1]; 286 c = buf[2]; 287 d = buf[3]; 288 289 MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 290 MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 291 MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 292 MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 293 MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 294 MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 295 MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 296 MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 297 MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 298 MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 299 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 300 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 301 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 302 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 303 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 304 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 305 306 MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 307 MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 308 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 309 MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 310 MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 311 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 312 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 313 MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 314 MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 315 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 316 MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 317 MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 318 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 319 MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 320 MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 321 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 322 323 MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 324 MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 325 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 326 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 327 MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 328 MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 329 MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 330 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 331 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 332 MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 333 MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 334 MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 335 MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 336 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 337 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 338 MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 339 340 MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 341 MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 342 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 343 MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 344 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 345 MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 346 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 347 MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 348 MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 349 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 350 MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 351 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 352 MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 353 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 354 MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 355 MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 356 357 buf[0] += a; 358 buf[1] += b; 359 buf[2] += c; 360 buf[3] += d; 361} 362 363#endif /* ASM_MD5 */ 364 365#endif /* CRYPTKIT_MD5_ENABLE && CRYPTKIT_LIBMD_DIGEST */ 366