md5c.c revision 141632
1139804Simp/*- 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 * 2520785Sphk * This code is the same as the code published by RSA Inc. It has been 2620785Sphk * edited for clarity and style only. 271802Sphk */ 281802Sphk 2998756Smux/* 3098756Smux * This file should be kept in sync with src/lib/libmd/md5c.c 3198756Smux */ 3298756Smux#include <sys/cdefs.h> 3398756Smux__FBSDID("$FreeBSD: head/sys/kern/md5c.c 141632 2005-02-10 12:20:42Z phk $"); 3498756Smux 3520785Sphk#include <sys/types.h> 361802Sphk 3755206Speter#ifdef _KERNEL 3820785Sphk#include <sys/systm.h> 3920785Sphk#else 4019099Sphk#include <string.h> 4120785Sphk#endif 421802Sphk 4398756Smux#include <machine/endian.h> 4498756Smux#include <sys/endian.h> 4520785Sphk#include <sys/md5.h> 461802Sphk 4798756Smuxstatic void MD5Transform(u_int32_t [4], const unsigned char [64]); 481802Sphk 4998756Smux#if (BYTE_ORDER == LITTLE_ENDIAN) 506596Sphk#define Encode memcpy 516596Sphk#define Decode memcpy 5298756Smux#else 5320785Sphk 5420785Sphk/* 5520785Sphk * Encodes input (u_int32_t) into output (unsigned char). Assumes len is 5620785Sphk * a multiple of 4. 576596Sphk */ 5820785Sphk 5920785Sphkstatic void 6098756SmuxEncode (unsigned char *output, u_int32_t *input, unsigned int len) 616596Sphk{ 6298756Smux unsigned int i; 6398756Smux u_int32_t *op = (u_int32_t *)output; 646596Sphk 6598756Smux for (i = 0; i < len / 4; i++) 6698756Smux op[i] = htole32(input[i]); 676596Sphk} 686596Sphk 6920785Sphk/* 7020785Sphk * Decodes input (unsigned char) into output (u_int32_t). Assumes len is 7120785Sphk * a multiple of 4. 726596Sphk */ 7320785Sphk 7420785Sphkstatic void 7598756SmuxDecode (u_int32_t *output, const unsigned char *input, unsigned int len) 766596Sphk{ 7798756Smux unsigned int i; 7898756Smux const u_int32_t *ip = (const u_int32_t *)input; 796596Sphk 8098756Smux for (i = 0; i < len / 4; i++) 81114706Sphk output[i] = le32dec(&ip[i]); 826596Sphk} 8398756Smux#endif 846596Sphk 851802Sphkstatic unsigned char PADDING[64] = { 861802Sphk 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 871802Sphk 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 881802Sphk 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 891802Sphk}; 901802Sphk 9120785Sphk/* F, G, H and I are basic MD5 functions. */ 921802Sphk#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 931802Sphk#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 941802Sphk#define H(x, y, z) ((x) ^ (y) ^ (z)) 951802Sphk#define I(x, y, z) ((y) ^ ((x) | (~z))) 961802Sphk 9720785Sphk/* ROTATE_LEFT rotates x left n bits. */ 981802Sphk#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 991802Sphk 10020785Sphk/* 10120785Sphk * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 10220785Sphk * Rotation is separate from addition to prevent recomputation. 1031802Sphk */ 1041802Sphk#define FF(a, b, c, d, x, s, ac) { \ 10520785Sphk (a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ 10620785Sphk (a) = ROTATE_LEFT ((a), (s)); \ 10720785Sphk (a) += (b); \ 10820785Sphk } 1091802Sphk#define GG(a, b, c, d, x, s, ac) { \ 11020785Sphk (a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ 11120785Sphk (a) = ROTATE_LEFT ((a), (s)); \ 11220785Sphk (a) += (b); \ 11320785Sphk } 1141802Sphk#define HH(a, b, c, d, x, s, ac) { \ 11520785Sphk (a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ 11620785Sphk (a) = ROTATE_LEFT ((a), (s)); \ 11720785Sphk (a) += (b); \ 11820785Sphk } 1191802Sphk#define II(a, b, c, d, x, s, ac) { \ 12020785Sphk (a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ 12120785Sphk (a) = ROTATE_LEFT ((a), (s)); \ 12220785Sphk (a) += (b); \ 12320785Sphk } 1241802Sphk 12520785Sphk/* MD5 initialization. Begins an MD5 operation, writing a new context. */ 12620785Sphk 12720785Sphkvoid 12820785SphkMD5Init (context) 12920785Sphk MD5_CTX *context; 1301802Sphk{ 13120785Sphk 13220785Sphk context->count[0] = context->count[1] = 0; 13320785Sphk 13420785Sphk /* Load magic initialization constants. */ 13520785Sphk context->state[0] = 0x67452301; 13620785Sphk context->state[1] = 0xefcdab89; 13720785Sphk context->state[2] = 0x98badcfe; 13820785Sphk context->state[3] = 0x10325476; 1391802Sphk} 1401802Sphk 14120785Sphk/* 14220785Sphk * MD5 block update operation. Continues an MD5 message-digest 14320785Sphk * operation, processing another message block, and updating the 14420785Sphk * context. 1451802Sphk */ 14620785Sphk 14720785Sphkvoid 14820785SphkMD5Update (context, input, inputLen) 14920785Sphk MD5_CTX *context; 15020785Sphk const unsigned char *input; 15120785Sphk unsigned int inputLen; 1521802Sphk{ 15320785Sphk unsigned int i, index, partLen; 1541802Sphk 15520785Sphk /* Compute number of bytes mod 64 */ 15620785Sphk index = (unsigned int)((context->count[0] >> 3) & 0x3F); 1571802Sphk 15820785Sphk /* Update number of bits */ 15920785Sphk if ((context->count[0] += ((u_int32_t)inputLen << 3)) 16020785Sphk < ((u_int32_t)inputLen << 3)) 16120785Sphk context->count[1]++; 16220785Sphk context->count[1] += ((u_int32_t)inputLen >> 29); 1631802Sphk 16420785Sphk partLen = 64 - index; 1651802Sphk 16620785Sphk /* Transform as many times as possible. */ 16720785Sphk if (inputLen >= partLen) { 16830631Sphk memcpy((void *)&context->buffer[index], (const void *)input, 16920785Sphk partLen); 17020785Sphk MD5Transform (context->state, context->buffer); 1711802Sphk 17220785Sphk for (i = partLen; i + 63 < inputLen; i += 64) 17320785Sphk MD5Transform (context->state, &input[i]); 1741802Sphk 17520785Sphk index = 0; 17620785Sphk } 17720785Sphk else 17820785Sphk i = 0; 1791802Sphk 18020785Sphk /* Buffer remaining input */ 18130631Sphk memcpy ((void *)&context->buffer[index], (const void *)&input[i], 18220785Sphk inputLen-i); 1831802Sphk} 1841802Sphk 18520785Sphk/* 18634909Sphk * MD5 padding. Adds padding followed by original length. 1871802Sphk */ 18820785Sphk 189141632Sphkstatic void 190141632SphkMD5Pad (MD5_CTX *context) 1911802Sphk{ 19220785Sphk unsigned char bits[8]; 19320785Sphk unsigned int index, padLen; 1941802Sphk 19520785Sphk /* Save number of bits */ 19620785Sphk Encode (bits, context->count, 8); 1971802Sphk 19820785Sphk /* Pad out to 56 mod 64. */ 19920785Sphk index = (unsigned int)((context->count[0] >> 3) & 0x3f); 20020785Sphk padLen = (index < 56) ? (56 - index) : (120 - index); 20120785Sphk MD5Update (context, PADDING, padLen); 2021802Sphk 20320785Sphk /* Append length (before padding) */ 20420785Sphk MD5Update (context, bits, 8); 20534909Sphk} 2061802Sphk 20734909Sphk/* 20834909Sphk * MD5 finalization. Ends an MD5 message-digest operation, writing the 20934909Sphk * the message digest and zeroizing the context. 21034909Sphk */ 21134909Sphk 21234909Sphkvoid 21334909SphkMD5Final (digest, context) 21434909Sphk unsigned char digest[16]; 21534909Sphk MD5_CTX *context; 21634909Sphk{ 21734909Sphk /* Do padding. */ 21834909Sphk MD5Pad (context); 21934909Sphk 22020785Sphk /* Store state in digest */ 22120785Sphk Encode (digest, context->state, 16); 22220785Sphk 22320785Sphk /* Zeroize sensitive information. */ 22420785Sphk memset ((void *)context, 0, sizeof (*context)); 2251802Sphk} 2261802Sphk 22720785Sphk/* MD5 basic transformation. Transforms state based on block. */ 22820785Sphk 22998756Smuxstatic void 23020785SphkMD5Transform (state, block) 23120785Sphk u_int32_t state[4]; 23220785Sphk const unsigned char block[64]; 2331802Sphk{ 23420785Sphk u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 2351802Sphk 23620785Sphk Decode (x, block, 64); 2371802Sphk 23820785Sphk /* Round 1 */ 23920785Sphk#define S11 7 24020785Sphk#define S12 12 24120785Sphk#define S13 17 24220785Sphk#define S14 22 24320785Sphk FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 24420785Sphk FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 24520785Sphk FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 24620785Sphk FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 24720785Sphk FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 24820785Sphk FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 24920785Sphk FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 25020785Sphk FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 25120785Sphk FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 25220785Sphk FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 25320785Sphk FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 25420785Sphk FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 25520785Sphk FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 25620785Sphk FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 25720785Sphk FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 25820785Sphk FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 2591802Sphk 26020785Sphk /* Round 2 */ 26120785Sphk#define S21 5 26220785Sphk#define S22 9 26320785Sphk#define S23 14 26420785Sphk#define S24 20 26520785Sphk GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 26620785Sphk GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 26720785Sphk GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 26820785Sphk GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 26920785Sphk GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 27020785Sphk GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 27120785Sphk GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 27220785Sphk GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 27320785Sphk GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 27420785Sphk GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 27520785Sphk GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 27620785Sphk GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 27720785Sphk GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 27820785Sphk GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 27920785Sphk GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 28020785Sphk GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 2811802Sphk 28220785Sphk /* Round 3 */ 28320785Sphk#define S31 4 28420785Sphk#define S32 11 28520785Sphk#define S33 16 28620785Sphk#define S34 23 28720785Sphk HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 28820785Sphk HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 28920785Sphk HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 29020785Sphk HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 29120785Sphk HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 29220785Sphk HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 29320785Sphk HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 29420785Sphk HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 29520785Sphk HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 29620785Sphk HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 29720785Sphk HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 29820785Sphk HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 29920785Sphk HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 30020785Sphk HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 30120785Sphk HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 30220785Sphk HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 3031802Sphk 30420785Sphk /* Round 4 */ 30520785Sphk#define S41 6 30620785Sphk#define S42 10 30720785Sphk#define S43 15 30820785Sphk#define S44 21 30920785Sphk II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 31020785Sphk II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 31120785Sphk II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 31220785Sphk II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 31320785Sphk II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 31420785Sphk II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 31520785Sphk II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 31620785Sphk II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 31720785Sphk II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 31820785Sphk II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 31920785Sphk II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 32020785Sphk II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 32120785Sphk II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 32220785Sphk II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 32320785Sphk II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 32420785Sphk II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 3251802Sphk 32620785Sphk state[0] += a; 32720785Sphk state[1] += b; 32820785Sphk state[2] += c; 32920785Sphk state[3] += d; 3301802Sphk 33120785Sphk /* Zeroize sensitive information. */ 33220785Sphk memset ((void *)x, 0, sizeof (x)); 3331802Sphk} 334