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