md5c.c revision 34909
120785Sphk/* 220785Sphk * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm 320785Sphk * 420785Sphk * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 520785Sphk * rights reserved. 620785Sphk * 720785Sphk * License to copy and use this software is granted provided that it 820785Sphk * is identified as the "RSA Data Security, Inc. MD5 Message-Digest 920785Sphk * Algorithm" in all material mentioning or referencing this software 1020785Sphk * or this function. 1120785Sphk * 1220785Sphk * License is also granted to make and use derivative works provided 1320785Sphk * that such works are identified as "derived from the RSA Data 1420785Sphk * Security, Inc. MD5 Message-Digest Algorithm" in all material 1520785Sphk * mentioning or referencing the derived work. 1620785Sphk * 1720785Sphk * RSA Data Security, Inc. makes no representations concerning either 1820785Sphk * the merchantability of this software or the suitability of this 1920785Sphk * software for any particular purpose. It is provided "as is" 2020785Sphk * without express or implied warranty of any kind. 2120785Sphk * 2220785Sphk * These notices must be retained in any copies of any part of this 2320785Sphk * documentation and/or software. 2420785Sphk * 2534909Sphk * $Id: md5c.c,v 1.10 1997/10/21 13:28:36 phk Exp $ 2620785Sphk * 2720785Sphk * This code is the same as the code published by RSA Inc. It has been 2820785Sphk * edited for clarity and style only. 291802Sphk */ 301802Sphk 3120785Sphk#include <sys/types.h> 321802Sphk 3320785Sphk#ifdef KERNEL 3420785Sphk#include <sys/systm.h> 3520785Sphk#else 3619099Sphk#include <string.h> 3720785Sphk#endif 381802Sphk 3920785Sphk#include <sys/md5.h> 401802Sphk 4120785Sphkstatic void MD5Transform __P((u_int32_t [4], const unsigned char [64])); 421802Sphk 4320785Sphk#ifdef KERNEL 4420785Sphk#define memset(x,y,z) bzero(x,z); 4520785Sphk#define memcpy(x,y,z) bcopy(y, x, z) 4620785Sphk#endif 471802Sphk 486596Sphk#ifdef i386 496596Sphk#define Encode memcpy 506596Sphk#define Decode memcpy 516596Sphk#else /* i386 */ 5220785Sphk 5320785Sphk/* 5420785Sphk * Encodes input (u_int32_t) into output (unsigned char). Assumes len is 5520785Sphk * a multiple of 4. 566596Sphk */ 5720785Sphk 5820785Sphkstatic void 5920785SphkEncode (output, input, len) 6020785Sphk unsigned char *output; 6120785Sphk u_int32_t *input; 6220785Sphk unsigned int len; 636596Sphk{ 6420785Sphk unsigned int i, j; 656596Sphk 6620785Sphk for (i = 0, j = 0; j < len; i++, j += 4) { 6720785Sphk output[j] = (unsigned char)(input[i] & 0xff); 6820785Sphk output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 6920785Sphk output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 7020785Sphk output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 7120785Sphk } 726596Sphk} 736596Sphk 7420785Sphk/* 7520785Sphk * Decodes input (unsigned char) into output (u_int32_t). Assumes len is 7620785Sphk * a multiple of 4. 776596Sphk */ 7820785Sphk 7920785Sphkstatic void 8020785SphkDecode (output, input, len) 8120785Sphk u_int32_t *output; 8220785Sphk const unsigned char *input; 8320785Sphk unsigned int len; 846596Sphk{ 8520785Sphk unsigned int i, j; 866596Sphk 8720785Sphk for (i = 0, j = 0; j < len; i++, j += 4) 8820785Sphk output[i] = ((u_int32_t)input[j]) | (((u_int32_t)input[j+1]) << 8) | 8920785Sphk (((u_int32_t)input[j+2]) << 16) | (((u_int32_t)input[j+3]) << 24); 906596Sphk} 916596Sphk#endif /* i386 */ 926596Sphk 931802Sphkstatic unsigned char PADDING[64] = { 941802Sphk 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 951802Sphk 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 961802Sphk 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 971802Sphk}; 981802Sphk 9920785Sphk/* F, G, H and I are basic MD5 functions. */ 1001802Sphk#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 1011802Sphk#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 1021802Sphk#define H(x, y, z) ((x) ^ (y) ^ (z)) 1031802Sphk#define I(x, y, z) ((y) ^ ((x) | (~z))) 1041802Sphk 10520785Sphk/* ROTATE_LEFT rotates x left n bits. */ 1061802Sphk#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 1071802Sphk 10820785Sphk/* 10920785Sphk * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 11020785Sphk * Rotation is separate from addition to prevent recomputation. 1111802Sphk */ 1121802Sphk#define FF(a, b, c, d, x, s, ac) { \ 11320785Sphk (a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ 11420785Sphk (a) = ROTATE_LEFT ((a), (s)); \ 11520785Sphk (a) += (b); \ 11620785Sphk } 1171802Sphk#define GG(a, b, c, d, x, s, ac) { \ 11820785Sphk (a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ 11920785Sphk (a) = ROTATE_LEFT ((a), (s)); \ 12020785Sphk (a) += (b); \ 12120785Sphk } 1221802Sphk#define HH(a, b, c, d, x, s, ac) { \ 12320785Sphk (a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ 12420785Sphk (a) = ROTATE_LEFT ((a), (s)); \ 12520785Sphk (a) += (b); \ 12620785Sphk } 1271802Sphk#define II(a, b, c, d, x, s, ac) { \ 12820785Sphk (a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ 12920785Sphk (a) = ROTATE_LEFT ((a), (s)); \ 13020785Sphk (a) += (b); \ 13120785Sphk } 1321802Sphk 13320785Sphk/* MD5 initialization. Begins an MD5 operation, writing a new context. */ 13420785Sphk 13520785Sphkvoid 13620785SphkMD5Init (context) 13720785Sphk MD5_CTX *context; 1381802Sphk{ 13920785Sphk 14020785Sphk context->count[0] = context->count[1] = 0; 14120785Sphk 14220785Sphk /* Load magic initialization constants. */ 14320785Sphk context->state[0] = 0x67452301; 14420785Sphk context->state[1] = 0xefcdab89; 14520785Sphk context->state[2] = 0x98badcfe; 14620785Sphk context->state[3] = 0x10325476; 1471802Sphk} 1481802Sphk 14920785Sphk/* 15020785Sphk * MD5 block update operation. Continues an MD5 message-digest 15120785Sphk * operation, processing another message block, and updating the 15220785Sphk * context. 1531802Sphk */ 15420785Sphk 15520785Sphkvoid 15620785SphkMD5Update (context, input, inputLen) 15720785Sphk MD5_CTX *context; 15820785Sphk const unsigned char *input; 15920785Sphk unsigned int inputLen; 1601802Sphk{ 16120785Sphk unsigned int i, index, partLen; 1621802Sphk 16320785Sphk /* Compute number of bytes mod 64 */ 16420785Sphk index = (unsigned int)((context->count[0] >> 3) & 0x3F); 1651802Sphk 16620785Sphk /* Update number of bits */ 16720785Sphk if ((context->count[0] += ((u_int32_t)inputLen << 3)) 16820785Sphk < ((u_int32_t)inputLen << 3)) 16920785Sphk context->count[1]++; 17020785Sphk context->count[1] += ((u_int32_t)inputLen >> 29); 1711802Sphk 17220785Sphk partLen = 64 - index; 1731802Sphk 17420785Sphk /* Transform as many times as possible. */ 17520785Sphk if (inputLen >= partLen) { 17634909Sphk memcpy((void *)&context->buffer[index], (const void *)input, 17720785Sphk partLen); 17820785Sphk MD5Transform (context->state, context->buffer); 1791802Sphk 18020785Sphk for (i = partLen; i + 63 < inputLen; i += 64) 18120785Sphk MD5Transform (context->state, &input[i]); 1821802Sphk 18320785Sphk index = 0; 18420785Sphk } 18520785Sphk else 18620785Sphk i = 0; 1871802Sphk 18820785Sphk /* Buffer remaining input */ 18934909Sphk memcpy ((void *)&context->buffer[index], (const void *)&input[i], 19020785Sphk inputLen-i); 1911802Sphk} 1921802Sphk 19320785Sphk/* 19434909Sphk * MD5 padding. Adds padding followed by original length. 1951802Sphk */ 19620785Sphk 19720785Sphkvoid 19834909SphkMD5Pad (context) 19920785Sphk MD5_CTX *context; 2001802Sphk{ 20120785Sphk unsigned char bits[8]; 20220785Sphk unsigned int index, padLen; 2031802Sphk 20420785Sphk /* Save number of bits */ 20520785Sphk Encode (bits, context->count, 8); 2061802Sphk 20720785Sphk /* Pad out to 56 mod 64. */ 20820785Sphk index = (unsigned int)((context->count[0] >> 3) & 0x3f); 20920785Sphk padLen = (index < 56) ? (56 - index) : (120 - index); 21020785Sphk MD5Update (context, PADDING, padLen); 2111802Sphk 21220785Sphk /* Append length (before padding) */ 21320785Sphk MD5Update (context, bits, 8); 21434909Sphk} 2151802Sphk 21634909Sphk/* 21734909Sphk * MD5 finalization. Ends an MD5 message-digest operation, writing the 21834909Sphk * the message digest and zeroizing the context. 21934909Sphk */ 22034909Sphk 22134909Sphkvoid 22234909SphkMD5Final (digest, context) 22334909Sphk unsigned char digest[16]; 22434909Sphk MD5_CTX *context; 22534909Sphk{ 22634909Sphk /* Do padding. */ 22734909Sphk MD5Pad (context); 22834909Sphk 22920785Sphk /* Store state in digest */ 23020785Sphk Encode (digest, context->state, 16); 23120785Sphk 23220785Sphk /* Zeroize sensitive information. */ 23320785Sphk memset ((void *)context, 0, sizeof (*context)); 2341802Sphk} 2351802Sphk 23620785Sphk/* MD5 basic transformation. Transforms state based on block. */ 23720785Sphk 23820785Sphkstatic void 23920785SphkMD5Transform (state, block) 24020785Sphk u_int32_t state[4]; 24120785Sphk const unsigned char block[64]; 2421802Sphk{ 24320785Sphk u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 2441802Sphk 24520785Sphk Decode (x, block, 64); 2461802Sphk 24720785Sphk /* Round 1 */ 24820785Sphk#define S11 7 24920785Sphk#define S12 12 25020785Sphk#define S13 17 25120785Sphk#define S14 22 25220785Sphk FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 25320785Sphk FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 25420785Sphk FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 25520785Sphk FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 25620785Sphk FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 25720785Sphk FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 25820785Sphk FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 25920785Sphk FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 26020785Sphk FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 26120785Sphk FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 26220785Sphk FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 26320785Sphk FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 26420785Sphk FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 26520785Sphk FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 26620785Sphk FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 26720785Sphk FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 2681802Sphk 26920785Sphk /* Round 2 */ 27020785Sphk#define S21 5 27120785Sphk#define S22 9 27220785Sphk#define S23 14 27320785Sphk#define S24 20 27420785Sphk GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 27520785Sphk GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 27620785Sphk GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 27720785Sphk GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 27820785Sphk GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 27920785Sphk GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 28020785Sphk GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 28120785Sphk GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 28220785Sphk GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 28320785Sphk GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 28420785Sphk GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 28520785Sphk GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 28620785Sphk GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 28720785Sphk GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 28820785Sphk GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 28920785Sphk GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 2901802Sphk 29120785Sphk /* Round 3 */ 29220785Sphk#define S31 4 29320785Sphk#define S32 11 29420785Sphk#define S33 16 29520785Sphk#define S34 23 29620785Sphk HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 29720785Sphk HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 29820785Sphk HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 29920785Sphk HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 30020785Sphk HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 30120785Sphk HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 30220785Sphk HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 30320785Sphk HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 30420785Sphk HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 30520785Sphk HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 30620785Sphk HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 30720785Sphk HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 30820785Sphk HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 30920785Sphk HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 31020785Sphk HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 31120785Sphk HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 3121802Sphk 31320785Sphk /* Round 4 */ 31420785Sphk#define S41 6 31520785Sphk#define S42 10 31620785Sphk#define S43 15 31720785Sphk#define S44 21 31820785Sphk II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 31920785Sphk II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 32020785Sphk II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 32120785Sphk II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 32220785Sphk II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 32320785Sphk II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 32420785Sphk II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 32520785Sphk II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 32620785Sphk II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 32720785Sphk II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 32820785Sphk II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 32920785Sphk II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 33020785Sphk II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 33120785Sphk II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 33220785Sphk II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 33320785Sphk II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 3341802Sphk 33520785Sphk state[0] += a; 33620785Sphk state[1] += b; 33720785Sphk state[2] += c; 33820785Sphk state[3] += d; 3391802Sphk 34020785Sphk /* Zeroize sensitive information. */ 34120785Sphk memset ((void *)x, 0, sizeof (x)); 3421802Sphk} 343