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