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