Home | History | Annotate | Line # | Download | only in md
      1 /*	$NetBSD: md5c.c,v 1.5 2012/03/20 16:21:41 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.5 2012/03/20 16:21:41 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 uint16_t UINT2;
     58 typedef uint32_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(UINT4 [4], const unsigned char [64]);
     88 
     89 static void Encode(unsigned char *, UINT4 *, unsigned int);
     90 static void Decode(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 (unsigned char *output,
     98 	UINT4 *input,
     99 	unsigned int len)
    100 {
    101 	unsigned int i, j;
    102 
    103 	for (i = 0, j = 0; j < len; i++, j += 4) {
    104 		output[j] = (unsigned char)(input[i] & 0xff);
    105 		output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
    106 		output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
    107 		output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
    108 	}
    109 }
    110 
    111 /*
    112  * Decodes input (unsigned char) into output (UINT4).  Assumes len is
    113  * a multiple of 4.
    114  */
    115 static void
    116 Decode (UINT4 *output,
    117 	const unsigned char *input,
    118 	unsigned int len)
    119 {
    120 	unsigned int i, j;
    121 
    122 	for (i = 0, j = 0; j < len; i++, j += 4)
    123 		output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
    124 		    (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
    125 }
    126 
    127 static const unsigned char PADDING[64] = {
    128 	0x80, 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, 0, 0, 0, 0,
    130 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    131 };
    132 
    133 /*
    134  * F, G, H and I are basic MD5 functions.
    135  */
    136 #define F(x, y, z)	(((x) & (y)) | ((~x) & (z)))
    137 #define G(x, y, z)	(((x) & (z)) | ((y) & (~z)))
    138 #define H(x, y, z)	((x) ^ (y) ^ (z))
    139 #define I(x, y, z)	((y) ^ ((x) | (~z)))
    140 
    141 /*
    142  * ROTATE_LEFT rotates x left n bits.
    143  */
    144 #define ROTATE_LEFT(x, n)	(((x) << (n)) | ((x) >> (32-(n))))
    145 
    146 /*
    147  * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
    148  * Rotation is separate from addition to prevent recomputation.
    149  */
    150 #define FF(a, b, c, d, x, s, ac) { \
    151 	(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
    152 	(a) = ROTATE_LEFT ((a), (s)); \
    153 	(a) += (b); \
    154 }
    155 
    156 #define GG(a, b, c, d, x, s, ac) { \
    157 	(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
    158 	(a) = ROTATE_LEFT ((a), (s)); \
    159 	(a) += (b); \
    160 }
    161 
    162 #define HH(a, b, c, d, x, s, ac) { \
    163 	(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
    164 	(a) = ROTATE_LEFT ((a), (s)); \
    165 	(a) += (b); \
    166 }
    167 
    168 #define II(a, b, c, d, x, s, ac) { \
    169 	(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
    170 	(a) = ROTATE_LEFT ((a), (s)); \
    171 	(a) += (b); \
    172 }
    173 
    174 /*
    175  * MD5 initialization. Begins an MD5 operation, writing a new context.
    176  */
    177 void
    178 MD5Init(MD5_CTX *context)
    179 {
    180 
    181 	_DIAGASSERT(context != 0);
    182 
    183 	context->count[0] = context->count[1] = 0;
    184 
    185 	/* Load magic initialization constants. */
    186 	context->state[0] = 0x67452301;
    187 	context->state[1] = 0xefcdab89;
    188 	context->state[2] = 0x98badcfe;
    189 	context->state[3] = 0x10325476;
    190 }
    191 
    192 /*
    193  * MD5 block update operation.  Continues an MD5 message-digest
    194  * operation, processing another message block, and updating the
    195  * context.
    196  */
    197 void
    198 MD5Update(MD5_CTX *context,
    199 	const unsigned char *input,	/* input block */
    200 	unsigned int inputLen)		/* length of input block */
    201 {
    202 	unsigned int i, idx, partLen;
    203 
    204 	_DIAGASSERT(context != 0);
    205 	_DIAGASSERT(input != 0);
    206 
    207 	/* Compute number of bytes mod 64 */
    208 	idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
    209 
    210 	/* Update number of bits */
    211 	if ((context->count[0] += ((UINT4)inputLen << 3))
    212 	    < ((UINT4)inputLen << 3))
    213 		context->count[1]++;
    214 	context->count[1] += ((UINT4)inputLen >> 29);
    215 
    216 	partLen = 64 - idx;
    217 
    218 	/* Transform as many times as possible. */
    219 	if (inputLen >= partLen) {
    220 		memcpy((POINTER)&context->buffer[idx], input, partLen);
    221 		MD5Transform(context->state, context->buffer);
    222 
    223 		for (i = partLen; i + 63 < inputLen; i += 64)
    224 			MD5Transform(context->state, &input[i]);
    225 
    226 		idx = 0;
    227 	} else
    228 		i = 0;
    229 
    230 	/* Buffer remaining input */
    231 	memcpy(&context->buffer[idx], &input[i], inputLen - i);
    232 }
    233 
    234 /*
    235  * MD5 finalization.  Ends an MD5 message-digest operation, writing the
    236  * message digest and zeroing the context.
    237  */
    238 void
    239 MD5Final(unsigned char digest[16],	/* message digest */
    240 	MD5_CTX *context)		/* context */
    241 {
    242 	unsigned char bits[8];
    243 	unsigned int idx, padLen;
    244 
    245 	_DIAGASSERT(digest != 0);
    246 	_DIAGASSERT(context != 0);
    247 
    248 	/* Save number of bits */
    249 	Encode(bits, context->count, 8);
    250 
    251 	/* Pad out to 56 mod 64. */
    252 	idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
    253 	padLen = (idx < 56) ? (56 - idx) : (120 - idx);
    254 	MD5Update (context, PADDING, padLen);
    255 
    256 	/* Append length (before padding) */
    257 	MD5Update(context, bits, 8);
    258 
    259 	/* Store state in digest */
    260 	Encode(digest, context->state, 16);
    261 
    262 	/* Zeroize sensitive information. */
    263 	ZEROIZE((POINTER)(void *)context, sizeof(*context));
    264 }
    265 
    266 /*
    267  * MD5 basic transformation. Transforms state based on block.
    268  */
    269 static void
    270 MD5Transform(UINT4 state[4], const unsigned char block[64])
    271 {
    272 	UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
    273 
    274 	Decode(x, block, 64);
    275 
    276 	/* Round 1 */
    277 	FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
    278 	FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
    279 	FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
    280 	FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
    281 	FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
    282 	FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
    283 	FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
    284 	FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
    285 	FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
    286 	FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
    287 	FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
    288 	FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
    289 	FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
    290 	FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
    291 	FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
    292 	FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
    293 
    294 	/* Round 2 */
    295 	GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
    296 	GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
    297 	GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
    298 	GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
    299 	GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
    300 	GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
    301 	GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
    302 	GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
    303 	GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
    304 	GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
    305 	GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
    306 	GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
    307 	GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
    308 	GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
    309 	GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
    310 	GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
    311 
    312 	/* Round 3 */
    313 	HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
    314 	HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
    315 	HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
    316 	HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
    317 	HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
    318 	HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
    319 	HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
    320 	HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
    321 	HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
    322 	HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
    323 	HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
    324 	HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
    325 	HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
    326 	HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
    327 	HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
    328 	HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
    329 
    330 	/* Round 4 */
    331 	II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
    332 	II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
    333 	II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
    334 	II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
    335 	II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
    336 	II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
    337 	II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
    338 	II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
    339 	II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
    340 	II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
    341 	II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
    342 	II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
    343 	II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
    344 	II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
    345 	II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
    346 	II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
    347 
    348 	state[0] += a;
    349 	state[1] += b;
    350 	state[2] += c;
    351 	state[3] += d;
    352 
    353 	/* Zeroize sensitive information. */
    354 	ZEROIZE((POINTER)(void *)x, sizeof (x));
    355 }
    356 
    357 #endif /* HAVE_MD5_H */
    358