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