Home | History | Annotate | Line # | Download | only in md
md4c.c revision 1.4
      1  1.4    cegger /*	$NetBSD: md4c.c,v 1.4 2009/03/16 05:59:21 cegger 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.4    cegger __RCSID("$NetBSD: md4c.c,v 1.4 2009/03/16 05:59:21 cegger 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.3       apb typedef uint16_t UINT2;
     61  1.3       apb 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.4    cegger MD4Init(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.4    cegger MD4Update (MD4_CTX *context,		/* context */
    153  1.4    cegger 	const unsigned char *input,	/* input block */
    154  1.4    cegger 	unsigned int inputLen)		/* length of input block */
    155  1.1  christos {
    156  1.1  christos 	unsigned int i, idx, partLen;
    157  1.1  christos 
    158  1.1  christos 	_DIAGASSERT(context != 0);
    159  1.1  christos 	_DIAGASSERT(input != 0);
    160  1.1  christos 
    161  1.1  christos 	/* Compute number of bytes mod 64 */
    162  1.1  christos 	idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
    163  1.1  christos 
    164  1.1  christos 	/* Update number of bits */
    165  1.1  christos 	if ((context->count[0] += ((UINT4)inputLen << 3))
    166  1.1  christos 	    < ((UINT4)inputLen << 3))
    167  1.1  christos 		context->count[1]++;
    168  1.1  christos 	context->count[1] += ((UINT4)inputLen >> 29);
    169  1.1  christos 
    170  1.1  christos 	partLen = 64 - idx;
    171  1.1  christos 
    172  1.1  christos 	/* Transform as many times as possible. */
    173  1.1  christos 	if (inputLen >= partLen) {
    174  1.1  christos 		memcpy(&context->buffer[idx], input, partLen);
    175  1.1  christos 		MD4Transform(context->state, context->buffer);
    176  1.1  christos 
    177  1.1  christos 		for (i = partLen; i + 63 < inputLen; i += 64)
    178  1.1  christos 			MD4Transform(context->state, &input[i]);
    179  1.1  christos 
    180  1.1  christos 		idx = 0;
    181  1.1  christos 	} else
    182  1.1  christos 		i = 0;
    183  1.1  christos 
    184  1.1  christos 	/* Buffer remaining input */
    185  1.1  christos 	memcpy(&context->buffer[idx], &input[i], inputLen - i);
    186  1.1  christos }
    187  1.1  christos 
    188  1.1  christos /*
    189  1.1  christos  * MD4 finalization.  Ends an MD4 message-digest operation, writing the
    190  1.1  christos  * message digest and zeroing the context.
    191  1.1  christos  */
    192  1.1  christos void
    193  1.4    cegger MD4Final (unsigned char digest[16],	/* message digest */
    194  1.4    cegger 	MD4_CTX *context)		/* context */
    195  1.1  christos {
    196  1.1  christos 	unsigned char bits[8];
    197  1.1  christos 	unsigned int idx, padLen;
    198  1.1  christos 
    199  1.1  christos 	_DIAGASSERT(digest != 0);
    200  1.1  christos 	_DIAGASSERT(context != 0);
    201  1.1  christos 
    202  1.1  christos 	/* Save number of bits */
    203  1.1  christos 	Encode(bits, context->count, 8);
    204  1.1  christos 
    205  1.1  christos 	/* Pad out to 56 mod 64. */
    206  1.1  christos 	idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
    207  1.1  christos 	padLen = (idx < 56) ? (56 - idx) : (120 - idx);
    208  1.1  christos 	MD4Update(context, PADDING, padLen);
    209  1.1  christos 
    210  1.1  christos 	/* Append length (before padding) */
    211  1.1  christos 	MD4Update(context, bits, 8);
    212  1.1  christos 
    213  1.1  christos 	/* Store state in digest */
    214  1.1  christos 	Encode(digest, context->state, 16);
    215  1.1  christos 
    216  1.1  christos 	/* Zeroize sensitive information. */
    217  1.1  christos 	memset(context, 0, sizeof(*context));
    218  1.1  christos }
    219  1.1  christos 
    220  1.1  christos /*
    221  1.1  christos  * MD4 basic transformation.  Transforms state based on block.
    222  1.1  christos  */
    223  1.1  christos static void
    224  1.4    cegger MD4Transform (UINT4 state[4], const unsigned char block[64])
    225  1.1  christos {
    226  1.1  christos 	UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
    227  1.1  christos 
    228  1.1  christos 	Decode(x, block, 64);
    229  1.1  christos 
    230  1.1  christos 	/* Round 1 */
    231  1.1  christos 	FF (a, b, c, d, x[ 0], S11); /* 1 */
    232  1.1  christos 	FF (d, a, b, c, x[ 1], S12); /* 2 */
    233  1.1  christos 	FF (c, d, a, b, x[ 2], S13); /* 3 */
    234  1.1  christos 	FF (b, c, d, a, x[ 3], S14); /* 4 */
    235  1.1  christos 	FF (a, b, c, d, x[ 4], S11); /* 5 */
    236  1.1  christos 	FF (d, a, b, c, x[ 5], S12); /* 6 */
    237  1.1  christos 	FF (c, d, a, b, x[ 6], S13); /* 7 */
    238  1.1  christos 	FF (b, c, d, a, x[ 7], S14); /* 8 */
    239  1.1  christos 	FF (a, b, c, d, x[ 8], S11); /* 9 */
    240  1.1  christos 	FF (d, a, b, c, x[ 9], S12); /* 10 */
    241  1.1  christos 	FF (c, d, a, b, x[10], S13); /* 11 */
    242  1.1  christos 	FF (b, c, d, a, x[11], S14); /* 12 */
    243  1.1  christos 	FF (a, b, c, d, x[12], S11); /* 13 */
    244  1.1  christos 	FF (d, a, b, c, x[13], S12); /* 14 */
    245  1.1  christos 	FF (c, d, a, b, x[14], S13); /* 15 */
    246  1.1  christos 	FF (b, c, d, a, x[15], S14); /* 16 */
    247  1.1  christos 
    248  1.1  christos 	/* Round 2 */
    249  1.1  christos 	GG (a, b, c, d, x[ 0], S21); /* 17 */
    250  1.1  christos 	GG (d, a, b, c, x[ 4], S22); /* 18 */
    251  1.1  christos 	GG (c, d, a, b, x[ 8], S23); /* 19 */
    252  1.1  christos 	GG (b, c, d, a, x[12], S24); /* 20 */
    253  1.1  christos 	GG (a, b, c, d, x[ 1], S21); /* 21 */
    254  1.1  christos 	GG (d, a, b, c, x[ 5], S22); /* 22 */
    255  1.1  christos 	GG (c, d, a, b, x[ 9], S23); /* 23 */
    256  1.1  christos 	GG (b, c, d, a, x[13], S24); /* 24 */
    257  1.1  christos 	GG (a, b, c, d, x[ 2], S21); /* 25 */
    258  1.1  christos 	GG (d, a, b, c, x[ 6], S22); /* 26 */
    259  1.1  christos 	GG (c, d, a, b, x[10], S23); /* 27 */
    260  1.1  christos 	GG (b, c, d, a, x[14], S24); /* 28 */
    261  1.1  christos 	GG (a, b, c, d, x[ 3], S21); /* 29 */
    262  1.1  christos 	GG (d, a, b, c, x[ 7], S22); /* 30 */
    263  1.1  christos 	GG (c, d, a, b, x[11], S23); /* 31 */
    264  1.1  christos 	GG (b, c, d, a, x[15], S24); /* 32 */
    265  1.1  christos 
    266  1.1  christos 	/* Round 3 */
    267  1.1  christos 	HH (a, b, c, d, x[ 0], S31); /* 33 */
    268  1.1  christos 	HH (d, a, b, c, x[ 8], S32); /* 34 */
    269  1.1  christos 	HH (c, d, a, b, x[ 4], S33); /* 35 */
    270  1.1  christos 	HH (b, c, d, a, x[12], S34); /* 36 */
    271  1.1  christos 	HH (a, b, c, d, x[ 2], S31); /* 37 */
    272  1.1  christos 	HH (d, a, b, c, x[10], S32); /* 38 */
    273  1.1  christos 	HH (c, d, a, b, x[ 6], S33); /* 39 */
    274  1.1  christos 	HH (b, c, d, a, x[14], S34); /* 40 */
    275  1.1  christos 	HH (a, b, c, d, x[ 1], S31); /* 41 */
    276  1.1  christos 	HH (d, a, b, c, x[ 9], S32); /* 42 */
    277  1.1  christos 	HH (c, d, a, b, x[ 5], S33); /* 43 */
    278  1.1  christos 	HH (b, c, d, a, x[13], S34); /* 44 */
    279  1.1  christos 	HH (a, b, c, d, x[ 3], S31); /* 45 */
    280  1.1  christos 	HH (d, a, b, c, x[11], S32); /* 46 */
    281  1.1  christos 	HH (c, d, a, b, x[ 7], S33); /* 47 */
    282  1.1  christos 	HH (b, c, d, a, x[15], S34); /* 48 */
    283  1.1  christos 
    284  1.1  christos 	state[0] += a;
    285  1.1  christos 	state[1] += b;
    286  1.1  christos 	state[2] += c;
    287  1.1  christos 	state[3] += d;
    288  1.1  christos 
    289  1.1  christos 	/* Zeroize sensitive information. */
    290  1.1  christos 	memset(x, 0, sizeof (x));
    291  1.1  christos }
    292  1.1  christos 
    293  1.1  christos /*
    294  1.1  christos  * Encodes input (UINT4) into output (unsigned char). Assumes len is
    295  1.1  christos  * a multiple of 4.
    296  1.1  christos  */
    297  1.1  christos static void
    298  1.4    cegger Encode(unsigned char *output, UINT4 *input, unsigned int len)
    299  1.1  christos {
    300  1.1  christos 	unsigned int i, j;
    301  1.1  christos 
    302  1.1  christos 	for (i = 0, j = 0; j < len; i++, j += 4) {
    303  1.1  christos 		output[j] = (unsigned char)(input[i] & 0xff);
    304  1.1  christos 		output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
    305  1.1  christos 		output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
    306  1.1  christos 		output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
    307  1.1  christos 	}
    308  1.1  christos }
    309  1.1  christos 
    310  1.1  christos /*
    311  1.1  christos  * Decodes input (unsigned char) into output (UINT4). Assumes len is
    312  1.1  christos  * a multiple of 4.
    313  1.1  christos  */
    314  1.1  christos static void
    315  1.4    cegger Decode(UINT4 *output, const unsigned char *input, unsigned int len)
    316  1.1  christos {
    317  1.1  christos 	unsigned int i, j;
    318  1.1  christos 
    319  1.1  christos 	for (i = 0, j = 0; j < len; i++, j += 4)
    320  1.1  christos 		output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
    321  1.1  christos 		    (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
    322  1.1  christos }
    323  1.1  christos 
    324  1.1  christos #endif /* HAVE_MD4_H */
    325