Home | History | Annotate | Line # | Download | only in md
md4c.c revision 1.2.18.1
      1  1.2.18.1      matt /*	md4c.c,v 1.2 2005/12/24 08:34:10 matt Exp	*/
      2       1.1  christos 
      3       1.1  christos /*
      4       1.1  christos  * This file is derived from the RSA Data Security, Inc. MD4 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) 1990-2, RSA Data Security, Inc. All rights reserved.
     11       1.1  christos  *
     12       1.1  christos  * License to copy and use this software is granted provided that it
     13       1.1  christos  * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
     14       1.1  christos  * Algorithm" in all material mentioning or referencing this software
     15       1.1  christos  * or this function.
     16       1.1  christos  *
     17       1.1  christos  * License is also granted to make and use derivative works provided
     18       1.1  christos  * that such works are identified as "derived from the RSA Data
     19       1.1  christos  * Security, Inc. MD4 Message-Digest Algorithm" in all material
     20       1.1  christos  * mentioning or referencing the derived work.
     21       1.1  christos  *
     22       1.1  christos  * RSA Data Security, Inc. makes no representations concerning either
     23       1.1  christos  * the merchantability of this software or the suitability of this
     24       1.1  christos  * software for any particular purpose. It is provided "as is"
     25       1.1  christos  * without express or implied warranty of any kind.
     26       1.1  christos  *
     27       1.1  christos  * These notices must be retained in any copies of any part of this
     28       1.1  christos  * documentation and/or software.
     29       1.1  christos  */
     30       1.1  christos 
     31       1.1  christos #if !defined(_KERNEL) && !defined(_STANDALONE)
     32       1.1  christos #include <sys/cdefs.h>
     33       1.1  christos #if defined(LIBC_SCCS) && !defined(lint)
     34  1.2.18.1      matt __RCSID("md4c.c,v 1.2 2005/12/24 08:34:10 matt Exp");
     35       1.1  christos #endif /* LIBC_SCCS and not lint */
     36       1.1  christos 
     37       1.1  christos #include "namespace.h"
     38       1.1  christos 
     39       1.1  christos #include <sys/types.h>
     40       1.1  christos 
     41       1.1  christos #include <assert.h>
     42       1.1  christos #include <md4.h>
     43       1.1  christos #include <string.h>
     44       1.1  christos 
     45       1.1  christos #if HAVE_NBTOOL_CONFIG_H
     46       1.1  christos #include "nbtool_config.h"
     47       1.1  christos #endif
     48       1.1  christos 
     49       1.1  christos #else
     50       1.1  christos 
     51       1.2      matt #include <sys/param.h>
     52       1.1  christos #include <sys/md4.h>
     53       1.1  christos #include <lib/libkern/libkern.h>
     54       1.1  christos 
     55       1.1  christos #endif /* !_KERNEL && !_STANDALONE */
     56       1.1  christos 
     57       1.1  christos #if !HAVE_MD4_H
     58       1.1  christos 
     59       1.1  christos typedef unsigned char *POINTER;
     60  1.2.18.1      matt typedef uint16_t UINT2;
     61  1.2.18.1      matt typedef uint32_t UINT4;
     62       1.1  christos 
     63       1.1  christos /*
     64       1.1  christos  * Constants for MD4Transform routine.
     65       1.1  christos  */
     66       1.1  christos #define S11 3
     67       1.1  christos #define S12 7
     68       1.1  christos #define S13 11
     69       1.1  christos #define S14 19
     70       1.1  christos #define S21 3
     71       1.1  christos #define S22 5
     72       1.1  christos #define S23 9
     73       1.1  christos #define S24 13
     74       1.1  christos #define S31 3
     75       1.1  christos #define S32 9
     76       1.1  christos #define S33 11
     77       1.1  christos #define S34 15
     78       1.1  christos 
     79       1.1  christos static void MD4Transform __P((UINT4 [4], const unsigned char [64]));
     80       1.1  christos 
     81       1.1  christos static void Encode __P((unsigned char *, UINT4 *, unsigned int));
     82       1.1  christos static void Decode __P((UINT4 *, const unsigned char *, unsigned int));
     83       1.1  christos 
     84       1.1  christos static const unsigned char PADDING[64] = {
     85       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,
     86       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,
     87       1.1  christos 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
     88       1.1  christos };
     89       1.1  christos 
     90       1.1  christos /*
     91       1.1  christos  * F, G and H are basic MD4 functions.
     92       1.1  christos  */
     93       1.1  christos #define F(x, y, z)	(((x) & (y)) | ((~x) & (z)))
     94       1.1  christos #define G(x, y, z)	(((x) & (y)) | ((x) & (z)) | ((y) & (z)))
     95       1.1  christos #define H(x, y, z)	((x) ^ (y) ^ (z))
     96       1.1  christos 
     97       1.1  christos /*
     98       1.1  christos  * ROTATE_LEFT rotates x left n bits.
     99       1.1  christos  */
    100       1.1  christos #define ROTATE_LEFT(x, n)	(((x) << (n)) | ((x) >> (32-(n))))
    101       1.1  christos 
    102       1.1  christos /*
    103       1.1  christos  * FF, GG and HH are transformations for rounds 1, 2 and 3.
    104       1.1  christos  * Rotation is separate from addition to prevent recomputation.
    105       1.1  christos  */
    106       1.1  christos #define FF(a, b, c, d, x, s) { \
    107       1.1  christos 	(a) += F ((b), (c), (d)) + (x); \
    108       1.1  christos 	(a) = ROTATE_LEFT ((a), (s)); \
    109       1.1  christos }
    110       1.1  christos 
    111       1.1  christos #define GG(a, b, c, d, x, s) { \
    112       1.1  christos 	(a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
    113       1.1  christos 	(a) = ROTATE_LEFT ((a), (s)); \
    114       1.1  christos }
    115       1.1  christos 
    116       1.1  christos #define HH(a, b, c, d, x, s) { \
    117       1.1  christos 	(a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
    118       1.1  christos 	(a) = ROTATE_LEFT ((a), (s)); \
    119       1.1  christos }
    120       1.1  christos 
    121       1.1  christos #if !defined(_KERNEL) && !defined(_STANDALONE) && defined(__weak_alias)
    122       1.1  christos __weak_alias(MD4Init,_MD4Init)
    123       1.1  christos __weak_alias(MD4Update,_MD4Update)
    124       1.1  christos __weak_alias(MD4Final,_MD4Final)
    125       1.1  christos __weak_alias(MD4Transform,_MD4Transform)
    126       1.1  christos #endif
    127       1.1  christos 
    128       1.1  christos /*
    129       1.1  christos  * MD4 initialization. Begins an MD4 operation, writing a new context.
    130       1.1  christos  */
    131       1.1  christos void
    132       1.1  christos MD4Init(context)
    133       1.1  christos 	MD4_CTX *context;		/* context */
    134       1.1  christos {
    135       1.1  christos 
    136       1.1  christos 	_DIAGASSERT(context != 0);
    137       1.1  christos 
    138       1.1  christos 	context->count[0] = context->count[1] = 0;
    139       1.1  christos 
    140       1.1  christos 	/* Load magic initialization constants. */
    141       1.1  christos 	context->state[0] = 0x67452301;
    142       1.1  christos 	context->state[1] = 0xefcdab89;
    143       1.1  christos 	context->state[2] = 0x98badcfe;
    144       1.1  christos 	context->state[3] = 0x10325476;
    145       1.1  christos }
    146       1.1  christos 
    147       1.1  christos /*
    148       1.1  christos  * MD4 block update operation.  Continues an MD4 message-digest
    149       1.1  christos  * operation, processing another message block, and updating the
    150       1.1  christos  * context.
    151       1.1  christos  */
    152       1.1  christos void
    153       1.1  christos MD4Update (context, input, inputLen)
    154       1.1  christos 	MD4_CTX *context;		/* context */
    155       1.1  christos 	const unsigned char *input;	/* input block */
    156       1.1  christos 	unsigned int inputLen;		/* length of input block */
    157       1.1  christos {
    158       1.1  christos 	unsigned int i, idx, partLen;
    159       1.1  christos 
    160       1.1  christos 	_DIAGASSERT(context != 0);
    161       1.1  christos 	_DIAGASSERT(input != 0);
    162       1.1  christos 
    163       1.1  christos 	/* Compute number of bytes mod 64 */
    164       1.1  christos 	idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
    165       1.1  christos 
    166       1.1  christos 	/* Update number of bits */
    167       1.1  christos 	if ((context->count[0] += ((UINT4)inputLen << 3))
    168       1.1  christos 	    < ((UINT4)inputLen << 3))
    169       1.1  christos 		context->count[1]++;
    170       1.1  christos 	context->count[1] += ((UINT4)inputLen >> 29);
    171       1.1  christos 
    172       1.1  christos 	partLen = 64 - idx;
    173       1.1  christos 
    174       1.1  christos 	/* Transform as many times as possible. */
    175       1.1  christos 	if (inputLen >= partLen) {
    176       1.1  christos 		memcpy(&context->buffer[idx], input, partLen);
    177       1.1  christos 		MD4Transform(context->state, context->buffer);
    178       1.1  christos 
    179       1.1  christos 		for (i = partLen; i + 63 < inputLen; i += 64)
    180       1.1  christos 			MD4Transform(context->state, &input[i]);
    181       1.1  christos 
    182       1.1  christos 		idx = 0;
    183       1.1  christos 	} else
    184       1.1  christos 		i = 0;
    185       1.1  christos 
    186       1.1  christos 	/* Buffer remaining input */
    187       1.1  christos 	memcpy(&context->buffer[idx], &input[i], inputLen - i);
    188       1.1  christos }
    189       1.1  christos 
    190       1.1  christos /*
    191       1.1  christos  * MD4 finalization.  Ends an MD4 message-digest operation, writing the
    192       1.1  christos  * message digest and zeroing the context.
    193       1.1  christos  */
    194       1.1  christos void
    195       1.1  christos MD4Final (digest, context)
    196       1.1  christos 	unsigned char digest[16];	/* message digest */
    197       1.1  christos 	MD4_CTX *context;		/* context */
    198       1.1  christos {
    199       1.1  christos 	unsigned char bits[8];
    200       1.1  christos 	unsigned int idx, padLen;
    201       1.1  christos 
    202       1.1  christos 	_DIAGASSERT(digest != 0);
    203       1.1  christos 	_DIAGASSERT(context != 0);
    204       1.1  christos 
    205       1.1  christos 	/* Save number of bits */
    206       1.1  christos 	Encode(bits, context->count, 8);
    207       1.1  christos 
    208       1.1  christos 	/* Pad out to 56 mod 64. */
    209       1.1  christos 	idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
    210       1.1  christos 	padLen = (idx < 56) ? (56 - idx) : (120 - idx);
    211       1.1  christos 	MD4Update(context, PADDING, padLen);
    212       1.1  christos 
    213       1.1  christos 	/* Append length (before padding) */
    214       1.1  christos 	MD4Update(context, bits, 8);
    215       1.1  christos 
    216       1.1  christos 	/* Store state in digest */
    217       1.1  christos 	Encode(digest, context->state, 16);
    218       1.1  christos 
    219       1.1  christos 	/* Zeroize sensitive information. */
    220       1.1  christos 	memset(context, 0, sizeof(*context));
    221       1.1  christos }
    222       1.1  christos 
    223       1.1  christos /*
    224       1.1  christos  * MD4 basic transformation.  Transforms state based on block.
    225       1.1  christos  */
    226       1.1  christos static void
    227       1.1  christos MD4Transform (state, block)
    228       1.1  christos 	UINT4 state[4];
    229       1.1  christos 	const unsigned char block[64];
    230       1.1  christos {
    231       1.1  christos 	UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
    232       1.1  christos 
    233       1.1  christos 	Decode(x, block, 64);
    234       1.1  christos 
    235       1.1  christos 	/* Round 1 */
    236       1.1  christos 	FF (a, b, c, d, x[ 0], S11); /* 1 */
    237       1.1  christos 	FF (d, a, b, c, x[ 1], S12); /* 2 */
    238       1.1  christos 	FF (c, d, a, b, x[ 2], S13); /* 3 */
    239       1.1  christos 	FF (b, c, d, a, x[ 3], S14); /* 4 */
    240       1.1  christos 	FF (a, b, c, d, x[ 4], S11); /* 5 */
    241       1.1  christos 	FF (d, a, b, c, x[ 5], S12); /* 6 */
    242       1.1  christos 	FF (c, d, a, b, x[ 6], S13); /* 7 */
    243       1.1  christos 	FF (b, c, d, a, x[ 7], S14); /* 8 */
    244       1.1  christos 	FF (a, b, c, d, x[ 8], S11); /* 9 */
    245       1.1  christos 	FF (d, a, b, c, x[ 9], S12); /* 10 */
    246       1.1  christos 	FF (c, d, a, b, x[10], S13); /* 11 */
    247       1.1  christos 	FF (b, c, d, a, x[11], S14); /* 12 */
    248       1.1  christos 	FF (a, b, c, d, x[12], S11); /* 13 */
    249       1.1  christos 	FF (d, a, b, c, x[13], S12); /* 14 */
    250       1.1  christos 	FF (c, d, a, b, x[14], S13); /* 15 */
    251       1.1  christos 	FF (b, c, d, a, x[15], S14); /* 16 */
    252       1.1  christos 
    253       1.1  christos 	/* Round 2 */
    254       1.1  christos 	GG (a, b, c, d, x[ 0], S21); /* 17 */
    255       1.1  christos 	GG (d, a, b, c, x[ 4], S22); /* 18 */
    256       1.1  christos 	GG (c, d, a, b, x[ 8], S23); /* 19 */
    257       1.1  christos 	GG (b, c, d, a, x[12], S24); /* 20 */
    258       1.1  christos 	GG (a, b, c, d, x[ 1], S21); /* 21 */
    259       1.1  christos 	GG (d, a, b, c, x[ 5], S22); /* 22 */
    260       1.1  christos 	GG (c, d, a, b, x[ 9], S23); /* 23 */
    261       1.1  christos 	GG (b, c, d, a, x[13], S24); /* 24 */
    262       1.1  christos 	GG (a, b, c, d, x[ 2], S21); /* 25 */
    263       1.1  christos 	GG (d, a, b, c, x[ 6], S22); /* 26 */
    264       1.1  christos 	GG (c, d, a, b, x[10], S23); /* 27 */
    265       1.1  christos 	GG (b, c, d, a, x[14], S24); /* 28 */
    266       1.1  christos 	GG (a, b, c, d, x[ 3], S21); /* 29 */
    267       1.1  christos 	GG (d, a, b, c, x[ 7], S22); /* 30 */
    268       1.1  christos 	GG (c, d, a, b, x[11], S23); /* 31 */
    269       1.1  christos 	GG (b, c, d, a, x[15], S24); /* 32 */
    270       1.1  christos 
    271       1.1  christos 	/* Round 3 */
    272       1.1  christos 	HH (a, b, c, d, x[ 0], S31); /* 33 */
    273       1.1  christos 	HH (d, a, b, c, x[ 8], S32); /* 34 */
    274       1.1  christos 	HH (c, d, a, b, x[ 4], S33); /* 35 */
    275       1.1  christos 	HH (b, c, d, a, x[12], S34); /* 36 */
    276       1.1  christos 	HH (a, b, c, d, x[ 2], S31); /* 37 */
    277       1.1  christos 	HH (d, a, b, c, x[10], S32); /* 38 */
    278       1.1  christos 	HH (c, d, a, b, x[ 6], S33); /* 39 */
    279       1.1  christos 	HH (b, c, d, a, x[14], S34); /* 40 */
    280       1.1  christos 	HH (a, b, c, d, x[ 1], S31); /* 41 */
    281       1.1  christos 	HH (d, a, b, c, x[ 9], S32); /* 42 */
    282       1.1  christos 	HH (c, d, a, b, x[ 5], S33); /* 43 */
    283       1.1  christos 	HH (b, c, d, a, x[13], S34); /* 44 */
    284       1.1  christos 	HH (a, b, c, d, x[ 3], S31); /* 45 */
    285       1.1  christos 	HH (d, a, b, c, x[11], S32); /* 46 */
    286       1.1  christos 	HH (c, d, a, b, x[ 7], S33); /* 47 */
    287       1.1  christos 	HH (b, c, d, a, x[15], S34); /* 48 */
    288       1.1  christos 
    289       1.1  christos 	state[0] += a;
    290       1.1  christos 	state[1] += b;
    291       1.1  christos 	state[2] += c;
    292       1.1  christos 	state[3] += d;
    293       1.1  christos 
    294       1.1  christos 	/* Zeroize sensitive information. */
    295       1.1  christos 	memset(x, 0, sizeof (x));
    296       1.1  christos }
    297       1.1  christos 
    298       1.1  christos /*
    299       1.1  christos  * Encodes input (UINT4) into output (unsigned char). Assumes len is
    300       1.1  christos  * a multiple of 4.
    301       1.1  christos  */
    302       1.1  christos static void
    303       1.1  christos Encode(output, input, len)
    304       1.1  christos 	unsigned char *output;
    305       1.1  christos 	UINT4 *input;
    306       1.1  christos 	unsigned int len;
    307       1.1  christos {
    308       1.1  christos 	unsigned int i, j;
    309       1.1  christos 
    310       1.1  christos 	for (i = 0, j = 0; j < len; i++, j += 4) {
    311       1.1  christos 		output[j] = (unsigned char)(input[i] & 0xff);
    312       1.1  christos 		output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
    313       1.1  christos 		output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
    314       1.1  christos 		output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
    315       1.1  christos 	}
    316       1.1  christos }
    317       1.1  christos 
    318       1.1  christos /*
    319       1.1  christos  * Decodes input (unsigned char) into output (UINT4). Assumes len is
    320       1.1  christos  * a multiple of 4.
    321       1.1  christos  */
    322       1.1  christos static void
    323       1.1  christos Decode(output, input, len)
    324       1.1  christos 	UINT4 *output;
    325       1.1  christos 	const unsigned char *input;
    326       1.1  christos 	unsigned int len;
    327       1.1  christos {
    328       1.1  christos 	unsigned int i, j;
    329       1.1  christos 
    330       1.1  christos 	for (i = 0, j = 0; j < len; i++, j += 4)
    331       1.1  christos 		output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
    332       1.1  christos 		    (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
    333       1.1  christos }
    334       1.1  christos 
    335       1.1  christos #endif /* HAVE_MD4_H */
    336