stdlibs/libcrypt/src/libmd/md5c.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2  * © Portions copyright (c) 2005-2006 Nokia Corporation.
       
     3  * All rights reserved.
       
     4  *
       
     5  * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
       
     6  *
       
     7  * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
       
     8  * rights reserved.
       
     9  *
       
    10  * License to copy and use this software is granted provided that it
       
    11  * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
       
    12  * Algorithm" in all material mentioning or referencing this software
       
    13  * or this function.
       
    14  *
       
    15  * License is also granted to make and use derivative works provided
       
    16  * that such works are identified as "derived from the RSA Data
       
    17  * Security, Inc. MD5 Message-Digest Algorithm" in all material
       
    18  * mentioning or referencing the derived work.
       
    19  *
       
    20  * RSA Data Security, Inc. makes no representations concerning either
       
    21  * the merchantability of this software or the suitability of this
       
    22  * software for any particular purpose. It is provided "as is"
       
    23  * without express or implied warranty of any kind.
       
    24  *
       
    25  * These notices must be retained in any copies of any part of this
       
    26  * documentation and/or software.
       
    27  *
       
    28  * This code is the same as the code published by RSA Inc.  It has been
       
    29  * edited for clarity and style only.
       
    30  */
       
    31 
       
    32 #ifndef EMULATOR 
       
    33 #define EMULATOR ((defined(__WINS__) || defined(__WINSCW__)))
       
    34 #endif
       
    35 
       
    36 #ifdef SYMBIAN
       
    37 #include <sys/types.h>
       
    38 #include <string.h>
       
    39 #include <arpa/inet.h>
       
    40 #include <sys/md5.h>
       
    41 
       
    42 #else
       
    43 
       
    44 #include <sys/cdefs.h>
       
    45 __FBSDID("$FreeBSD: src/lib/libmd/md5c.c,v 1.16 2003/06/05 13:17:32 markm Exp $");
       
    46 
       
    47 #include <sys/types.h>
       
    48 
       
    49 #ifdef _KERNEL
       
    50 #include <sys/systm.h>
       
    51 #else
       
    52 #include <string.h>
       
    53 #endif
       
    54 
       
    55 #include <machine/endian.h>
       
    56 #include <sys/endian.h>
       
    57 #include <sys/md5.h>
       
    58 
       
    59 #endif /* end ifdef SYMBIAN */
       
    60 
       
    61 static void MD5Transform(u_int32_t [4], const unsigned char [64]);
       
    62 
       
    63 #ifndef SYMBIAN
       
    64 
       
    65 #ifdef _KERNEL
       
    66 #define memset(x,y,z)	bzero(x,z);
       
    67 #define memcpy(x,y,z)	bcopy(y, x, z)
       
    68 #endif
       
    69 
       
    70 #endif /* end ifndef SYMBIAN */
       
    71 
       
    72 #ifdef SYMBIAN
       
    73 
       
    74 /* Since EPOC32 is little-endian, Encode and Decode are defined to be
       
    75  * memcpy()
       
    76  */
       
    77 #define Encode memcpy
       
    78 #define Decode memcpy
       
    79 #else
       
    80 
       
    81 #if (BYTE_ORDER == LITTLE_ENDIAN)
       
    82 #define Encode memcpy
       
    83 #define Decode memcpy
       
    84 #else 
       
    85 
       
    86 /*
       
    87  * Encodes input (u_int32_t) into output (unsigned char). Assumes len is
       
    88  * a multiple of 4.
       
    89  */
       
    90 
       
    91 static void
       
    92 Encode (unsigned char *output, u_int32_t *input, unsigned int len)
       
    93 {
       
    94 	unsigned int i;
       
    95 	u_int32_t *op = (u_int32_t *)output;
       
    96 
       
    97 	for (i = 0; i < len / 4; i++)
       
    98 		op[i] = htole32(input[i]);
       
    99 }
       
   100 
       
   101 /*
       
   102  * Decodes input (unsigned char) into output (u_int32_t). Assumes len is
       
   103  * a multiple of 4.
       
   104  */
       
   105 
       
   106 static void
       
   107 Decode (u_int32_t *output, const unsigned char *input, unsigned int len)
       
   108 {
       
   109 	unsigned int i;
       
   110 	const u_int32_t *ip = (const u_int32_t *)input;
       
   111 
       
   112 	for (i = 0; i < len / 4; i++)
       
   113 		output[i] = le32toh(ip[i]);
       
   114 }
       
   115 #endif
       
   116 
       
   117 #endif /* ifdef SYMBIAN */
       
   118 
       
   119 #if !EMULATOR
       
   120 static unsigned char PADDING[64] = {
       
   121   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       
   122   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       
   123   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
       
   124 };
       
   125 #else
       
   126 const unsigned char PADDING[64] = {
       
   127   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       
   128   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       
   129   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
       
   130 };
       
   131 #endif
       
   132 
       
   133 /* F, G, H and I are basic MD5 functions. */
       
   134 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
       
   135 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
       
   136 #define H(x, y, z) ((x) ^ (y) ^ (z))
       
   137 #define I(x, y, z) ((y) ^ ((x) | (~z)))
       
   138 
       
   139 /* ROTATE_LEFT rotates x left n bits. */
       
   140 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
       
   141 
       
   142 /*
       
   143  * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
       
   144  * Rotation is separate from addition to prevent recomputation.
       
   145  */
       
   146 #define FF(a, b, c, d, x, s, ac) { \
       
   147 	(a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
       
   148 	(a) = ROTATE_LEFT ((a), (s)); \
       
   149 	(a) += (b); \
       
   150 	}
       
   151 #define GG(a, b, c, d, x, s, ac) { \
       
   152 	(a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
       
   153 	(a) = ROTATE_LEFT ((a), (s)); \
       
   154 	(a) += (b); \
       
   155 	}
       
   156 #define HH(a, b, c, d, x, s, ac) { \
       
   157 	(a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
       
   158 	(a) = ROTATE_LEFT ((a), (s)); \
       
   159 	(a) += (b); \
       
   160 	}
       
   161 #define II(a, b, c, d, x, s, ac) { \
       
   162 	(a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
       
   163 	(a) = ROTATE_LEFT ((a), (s)); \
       
   164 	(a) += (b); \
       
   165 	}
       
   166 
       
   167 /* MD5 initialization. Begins an MD5 operation, writing a new context. */
       
   168 #ifdef SYMBIAN
       
   169 void MD5Init (MD5_CTX *context)
       
   170 {
       
   171 #else
       
   172 void
       
   173 MD5Init (context)
       
   174 	MD5_CTX *context;
       
   175 {
       
   176 #endif
       
   177 
       
   178 	context->count[0] = context->count[1] = 0;
       
   179 
       
   180 	/* Load magic initialization constants.  */
       
   181 	context->state[0] = 0x67452301;
       
   182 	context->state[1] = 0xefcdab89;
       
   183 	context->state[2] = 0x98badcfe;
       
   184 	context->state[3] = 0x10325476;
       
   185 }
       
   186 
       
   187 /* 
       
   188  * MD5 block update operation. Continues an MD5 message-digest
       
   189  * operation, processing another message block, and updating the
       
   190  * context.
       
   191  */
       
   192 #ifdef SYMBIAN
       
   193 void MD5Update(MD5_CTX *context, const unsigned char *input, unsigned int inputLen)
       
   194 {
       
   195 #else
       
   196 void
       
   197 MD5Update (context, input, inputLen)
       
   198 	MD5_CTX *context;
       
   199 	const unsigned char *input;
       
   200 	unsigned int inputLen;
       
   201 {
       
   202 #endif
       
   203 	unsigned int i, idx, partLen;
       
   204 
       
   205 	/* Compute number of bytes mod 64 */
       
   206 	idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
       
   207 
       
   208 	/* Update number of bits */
       
   209 	if ((context->count[0] += ((u_int32_t)inputLen << 3))
       
   210 	    < ((u_int32_t)inputLen << 3))
       
   211 		context->count[1]++;
       
   212 	context->count[1] += ((u_int32_t)inputLen >> 29);
       
   213 
       
   214 	partLen = 64 - idx;
       
   215 
       
   216 	/* Transform as many times as possible. */
       
   217 	if (inputLen >= partLen) {
       
   218 		memcpy((void *)&context->buffer[idx], (const void *)input,
       
   219 		    partLen);
       
   220 		MD5Transform (context->state, context->buffer);
       
   221 
       
   222 		for (i = partLen; i + 63 < inputLen; i += 64)
       
   223 			MD5Transform (context->state, &input[i]);
       
   224 
       
   225 		idx = 0;
       
   226 	}
       
   227 	else
       
   228 		i = 0;
       
   229 
       
   230 	/* Buffer remaining input */
       
   231 	memcpy ((void *)&context->buffer[idx], (const void *)&input[i],
       
   232 	    inputLen-i);
       
   233 }
       
   234 
       
   235 /*
       
   236  * MD5 padding. Adds padding followed by original length.
       
   237  */
       
   238 
       
   239 #ifdef SYMBIAN
       
   240 void MD5Pad (MD5_CTX *context)
       
   241 {
       
   242 #else
       
   243 void
       
   244 MD5Pad (context)
       
   245 	MD5_CTX *context;
       
   246 {
       
   247 #endif
       
   248 
       
   249 	unsigned char bits[8];
       
   250 	unsigned int idx, padLen;
       
   251 
       
   252 	/* Save number of bits */
       
   253 	Encode (bits, context->count, 8);
       
   254 
       
   255 	/* Pad out to 56 mod 64. */
       
   256 	idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
       
   257 	padLen = (idx < 56) ? (56 - idx) : (120 - idx);
       
   258 	MD5Update (context, PADDING, padLen);
       
   259 
       
   260 	/* Append length (before padding) */
       
   261 	MD5Update (context, bits, 8);
       
   262 }
       
   263 
       
   264 /*
       
   265  * MD5 finalization. Ends an MD5 message-digest operation, writing the
       
   266  * the message digest and zeroizing the context.
       
   267  */
       
   268 #ifdef SYMBIAN
       
   269 void MD5Final (unsigned char digest[16], MD5_CTX *context)
       
   270 {
       
   271 #else
       
   272 void
       
   273 MD5Final (digest, context)
       
   274 	unsigned char digest[16];
       
   275 	MD5_CTX *context;
       
   276 {
       
   277 #endif
       
   278 	/* Do padding. */
       
   279 	MD5Pad (context);
       
   280 
       
   281 	/* Store state in digest */
       
   282 	Encode (digest, context->state, 16);
       
   283 
       
   284 	/* Zeroize sensitive information. */
       
   285 	memset ((void *)context, 0, sizeof (*context));
       
   286 }
       
   287 
       
   288 /* MD5 basic transformation. Transforms state based on block. */
       
   289 
       
   290 #ifdef SYMBIAN
       
   291 static void MD5Transform ( u_int32_t state[4], const unsigned char block[64])
       
   292 {
       
   293 #else
       
   294 static void
       
   295 MD5Transform (state, block)
       
   296 	u_int32_t state[4];
       
   297 	const unsigned char block[64];
       
   298 {
       
   299 #endif
       
   300 	u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
       
   301 
       
   302 	Decode (x, block, 64);
       
   303 
       
   304 	/* Round 1 */
       
   305 #define S11 7
       
   306 #define S12 12
       
   307 #define S13 17
       
   308 #define S14 22
       
   309 	FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
       
   310 	FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
       
   311 	FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
       
   312 	FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
       
   313 	FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
       
   314 	FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
       
   315 	FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
       
   316 	FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
       
   317 	FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
       
   318 	FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
       
   319 	FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
       
   320 	FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
       
   321 	FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
       
   322 	FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
       
   323 	FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
       
   324 	FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
       
   325 
       
   326 	/* Round 2 */
       
   327 #define S21 5
       
   328 #define S22 9
       
   329 #define S23 14
       
   330 #define S24 20
       
   331 	GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
       
   332 	GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
       
   333 	GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
       
   334 	GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
       
   335 	GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
       
   336 	GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
       
   337 	GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
       
   338 	GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
       
   339 	GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
       
   340 	GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
       
   341 	GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
       
   342 	GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
       
   343 	GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
       
   344 	GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
       
   345 	GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
       
   346 	GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
       
   347 
       
   348 	/* Round 3 */
       
   349 #define S31 4
       
   350 #define S32 11
       
   351 #define S33 16
       
   352 #define S34 23
       
   353 	HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
       
   354 	HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
       
   355 	HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
       
   356 	HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
       
   357 	HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
       
   358 	HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
       
   359 	HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
       
   360 	HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
       
   361 	HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
       
   362 	HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
       
   363 	HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
       
   364 	HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
       
   365 	HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
       
   366 	HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
       
   367 	HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
       
   368 	HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
       
   369 
       
   370 	/* Round 4 */
       
   371 #define S41 6
       
   372 #define S42 10
       
   373 #define S43 15
       
   374 #define S44 21
       
   375 	II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
       
   376 	II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
       
   377 	II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
       
   378 	II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
       
   379 	II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
       
   380 	II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
       
   381 	II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
       
   382 	II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
       
   383 	II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
       
   384 	II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
       
   385 	II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
       
   386 	II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
       
   387 	II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
       
   388 	II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
       
   389 	II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
       
   390 	II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
       
   391 
       
   392 	state[0] += a;
       
   393 	state[1] += b;
       
   394 	state[2] += c;
       
   395 	state[3] += d;
       
   396 
       
   397 	/* Zeroize sensitive information. */
       
   398 	memset ((void *)x, 0, sizeof (x));
       
   399 }