md5c.c revision 6596
11556Srgrimes/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm 21556Srgrimes * $FreeBSD: head/lib/libmd/md5c.c 6596 1995-02-21 06:01:49Z phk $ 31556Srgrimes */ 4207944Sjilles 5207944Sjilles/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 61556Srgrimesrights reserved. 71556Srgrimes 81556SrgrimesLicense to copy and use this software is granted provided that it 91556Srgrimesis identified as the "RSA Data Security, Inc. MD5 Message-Digest 101556SrgrimesAlgorithm" in all material mentioning or referencing this software 111556Srgrimesor this function. 121556Srgrimes 131556SrgrimesLicense is also granted to make and use derivative works provided 141556Srgrimesthat such works are identified as "derived from the RSA Data 151556SrgrimesSecurity, Inc. MD5 Message-Digest Algorithm" in all material 161556Srgrimesmentioning or referencing the derived work. 171556Srgrimes 181556SrgrimesRSA Data Security, Inc. makes no representations concerning either 191556Srgrimesthe merchantability of this software or the suitability of this 201556Srgrimessoftware for any particular purpose. It is provided "as is" 211556Srgrimeswithout express or implied warranty of any kind. 221556Srgrimes 231556SrgrimesThese notices must be retained in any copies of any part of this 241556Srgrimesdocumentation and/or software. 251556Srgrimes */ 261556Srgrimes 271556Srgrimes#include "md5.h" 281556Srgrimes 291556Srgrimestypedef unsigned char *POINTER; 301556Srgrimestypedef unsigned short int UINT2; 311556Srgrimestypedef unsigned long int UINT4; 321556Srgrimes 331556Srgrimes#define PROTO_LIST(list) list 341556Srgrimes 351556Srgrimes/* Constants for MD5Transform routine. 3636150Scharnier */ 3736150Scharnier#define S11 7 3836150Scharnier#define S12 12 391556Srgrimes#define S13 17 4099110Sobrien#define S14 22 4199110Sobrien#define S21 5 421556Srgrimes#define S22 9 4317987Speter#define S23 14 4417987Speter#define S24 20 4517987Speter#define S31 4 4617987Speter#define S32 11 4717987Speter#define S33 16 4817987Speter#define S34 23 4917987Speter#define S41 6 5017987Speter#define S42 10 5119281Sache#define S43 15 5238887Stegge#define S44 21 53108286Stjr 5417987Speterstatic void MD5Transform PROTO_LIST ((UINT4 [4], const unsigned char [64])); 551556Srgrimes 561556Srgrimes#ifdef i386 571556Srgrimes#define Encode memcpy 581556Srgrimes#define Decode memcpy 591556Srgrimes#else /* i386 */ 601556Srgrimes/* Encodes input (UINT4) into output (unsigned char). Assumes len is 611556Srgrimes a multiple of 4. 621556Srgrimes */ 631556Srgrimesstatic void Encode (output, input, len) 641556Srgrimesunsigned char *output; 651556SrgrimesUINT4 *input; 661556Srgrimesunsigned int len; 671556Srgrimes{ 681556Srgrimes unsigned int i, j; 691556Srgrimes 701556Srgrimes for (i = 0, j = 0; j < len; i++, j += 4) { 711556Srgrimes output[j] = (unsigned char)(input[i] & 0xff); 721556Srgrimes output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 731556Srgrimes output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 741556Srgrimes output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 7517987Speter } 7617987Speter} 771556Srgrimes 781556Srgrimes/* Decodes input (unsigned char) into output (UINT4). Assumes len is 791556Srgrimes a multiple of 4. 801556Srgrimes */ 811556Srgrimesstatic void Decode (output, input, len) 821556SrgrimesUINT4 *output; 831556Srgrimesconst unsigned char *input; 841556Srgrimesunsigned int len; 851556Srgrimes{ 861556Srgrimes unsigned int i, j; 87194975Sjilles 881556Srgrimes for (i = 0, j = 0; j < len; i++, j += 4) 891556Srgrimes output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | 901556Srgrimes (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); 91213760Sobrien} 92213760Sobrien#endif /* i386 */ 93213760Sobrien 94213760Sobrienstatic unsigned char PADDING[64] = { 95213760Sobrien 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 961556Srgrimes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9790111Simp 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 9890111Simp}; 9990111Simp 10090111Simp/* F, G, H and I are basic MD5 functions. 10190111Simp */ 10290111Simp#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 103164081Sstefanf#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 10490111Simp#define H(x, y, z) ((x) ^ (y) ^ (z)) 105155301Sschweikh#define I(x, y, z) ((y) ^ ((x) | (~z))) 10690111Simp 10790111Simp/* ROTATE_LEFT rotates x left n bits. 10890111Simp */ 10990111Simp#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 11090111Simp 11190111Simp/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 11290111SimpRotation is separate from addition to prevent recomputation. 11390111Simp */ 1141556Srgrimes#define FF(a, b, c, d, x, s, ac) { \ 11590111Simp (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ 116118374Sache (a) = ROTATE_LEFT ((a), (s)); \ 11719281Sache (a) += (b); \ 11819281Sache } 11919281Sache#define GG(a, b, c, d, x, s, ac) { \ 12019281Sache (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ 12119281Sache (a) = ROTATE_LEFT ((a), (s)); \ 122118374Sache (a) += (b); \ 12319281Sache } 12419281Sache#define HH(a, b, c, d, x, s, ac) { \ 1251556Srgrimes (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ 1261556Srgrimes (a) = ROTATE_LEFT ((a), (s)); \ 12790111Simp (a) += (b); \ 12890111Simp } 1291556Srgrimes#define II(a, b, c, d, x, s, ac) { \ 1301556Srgrimes (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ 1311556Srgrimes (a) = ROTATE_LEFT ((a), (s)); \ 13290111Simp (a) += (b); \ 13390111Simp } 1341556Srgrimes 1351556Srgrimes/* MD5 initialization. Begins an MD5 operation, writing a new context. 13639137Stegge */ 1371556Srgrimesvoid MD5Init (context) 1381556SrgrimesMD5_CTX *context; /* context */ 1391556Srgrimes{ 1401556Srgrimes context->count[0] = context->count[1] = 0; 141212243Sjilles /* Load magic initialization constants. 142212243Sjilles*/ 143212243Sjilles context->state[0] = 0x67452301; 144212243Sjilles context->state[1] = 0xefcdab89; 145212243Sjilles context->state[2] = 0x98badcfe; 146212243Sjilles context->state[3] = 0x10325476; 147212243Sjilles} 148212243Sjilles 149212243Sjilles/* MD5 block update operation. Continues an MD5 message-digest 150212243Sjilles operation, processing another message block, and updating the 151212243Sjilles context. 1521556Srgrimes */ 1531556Srgrimesvoid MD5Update (context, input, inputLen) 15490111SimpMD5_CTX *context; /* context */ 15517987Speterconst unsigned char *input; /* input block */ 1561556Srgrimesunsigned int inputLen; /* length of input block */ 1571556Srgrimes{ 1581556Srgrimes unsigned int i, index, partLen; 1591556Srgrimes 1601556Srgrimes /* Compute number of bytes mod 64 */ 1611556Srgrimes index = (unsigned int)((context->count[0] >> 3) & 0x3F); 1621556Srgrimes 1631556Srgrimes /* Update number of bits */ 1641556Srgrimes if ((context->count[0] += ((UINT4)inputLen << 3)) 1651556Srgrimes < ((UINT4)inputLen << 3)) 1661556Srgrimes context->count[1]++; 1671556Srgrimes context->count[1] += ((UINT4)inputLen >> 29); 1681556Srgrimes 1691556Srgrimes partLen = 64 - index; 1701556Srgrimes 1711556Srgrimes /* Transform as many times as possible. 1721556Srgrimes*/ 1731556Srgrimes if (inputLen >= partLen) { 1741556Srgrimes memcpy 1751556Srgrimes ((POINTER)&context->buffer[index], (POINTER)input, partLen); 1761556Srgrimes MD5Transform (context->state, context->buffer); 1771556Srgrimes 1781556Srgrimes for (i = partLen; i + 63 < inputLen; i += 64) 1791556Srgrimes MD5Transform (context->state, &input[i]); 1801556Srgrimes 1811556Srgrimes index = 0; 1821556Srgrimes } 1831556Srgrimes else 1841556Srgrimes i = 0; 1851556Srgrimes 1861556Srgrimes /* Buffer remaining input */ 1871556Srgrimes memcpy 1881556Srgrimes ((POINTER)&context->buffer[index], (POINTER)&input[i], 1891556Srgrimes inputLen-i); 1901556Srgrimes} 1911556Srgrimes 1921556Srgrimes/* MD5 finalization. Ends an MD5 message-digest operation, writing the 1931556Srgrimes the message digest and zeroizing the context. 1941556Srgrimes */ 1951556Srgrimesvoid MD5Final (digest, context) 1961556Srgrimesunsigned char digest[16]; /* message digest */ 1971556SrgrimesMD5_CTX *context; /* context */ 1981556Srgrimes{ 1991556Srgrimes unsigned char bits[8]; 2001556Srgrimes unsigned int index, padLen; 2011556Srgrimes 2021556Srgrimes /* Save number of bits */ 2031556Srgrimes Encode (bits, context->count, 8); 204212243Sjilles 205212243Sjilles /* Pad out to 56 mod 64. 206212243Sjilles*/ 207212243Sjilles index = (unsigned int)((context->count[0] >> 3) & 0x3f); 208212243Sjilles padLen = (index < 56) ? (56 - index) : (120 - index); 209212243Sjilles MD5Update (context, PADDING, padLen); 210212243Sjilles 2111556Srgrimes /* Append length (before padding) */ 2121556Srgrimes MD5Update (context, bits, 8); 21390111Simp /* Store state in digest */ 21417987Speter Encode (digest, context->state, 16); 21525233Ssteve 216104672Stjr /* Zeroize sensitive information. 2171556Srgrimes*/ 2181556Srgrimes memset ((POINTER)context, 0, sizeof (*context)); 2191556Srgrimes} 2201556Srgrimes 2211556Srgrimes/* MD5 basic transformation. Transforms state based on block. 2221556Srgrimes */ 2231556Srgrimesstatic void MD5Transform (state, block) 224212243SjillesUINT4 state[4]; 2251556Srgrimesconst unsigned char block[64]; 22638887Stegge{ 22738887Stegge UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 22838887Stegge 22938887Stegge Decode (x, block, 64); 23039137Stegge 23139137Stegge /* Round 1 */ 23238887Stegge FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 2331556Srgrimes FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 2341556Srgrimes FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 2351556Srgrimes FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 2361556Srgrimes FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 2371556Srgrimes FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 2381556Srgrimes FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 2391556Srgrimes FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 2401556Srgrimes FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 2411556Srgrimes FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 2421556Srgrimes FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 2431556Srgrimes FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 2441556Srgrimes FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 2451556Srgrimes FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 2461556Srgrimes FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 2471556Srgrimes FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 2481556Srgrimes 2491556Srgrimes /* Round 2 */ 2501556Srgrimes GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 2511556Srgrimes GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 2521556Srgrimes GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 2531556Srgrimes GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 2541556Srgrimes GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 2551556Srgrimes GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 2561556Srgrimes GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 2571556Srgrimes GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 2581556Srgrimes GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 2591556Srgrimes GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 2601556Srgrimes GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 2611556Srgrimes GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 2621556Srgrimes GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 2631556Srgrimes GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 2641556Srgrimes GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 2651556Srgrimes GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 2661556Srgrimes 2671556Srgrimes /* Round 3 */ 2681556Srgrimes HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 2691556Srgrimes HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 2701556Srgrimes HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 2711556Srgrimes HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 2721556Srgrimes HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 2731556Srgrimes HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 274212243Sjilles HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 275212243Sjilles HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 276212243Sjilles HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 277212243Sjilles HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 2781556Srgrimes HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 27990111Simp HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 28017987Speter HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 2811556Srgrimes HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 2821556Srgrimes HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 2831556Srgrimes HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 284108935Stjr 2851556Srgrimes /* Round 4 */ 28617987Speter II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 2871556Srgrimes II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 288200988Sjilles II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 289200988Sjilles II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 290200988Sjilles II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 291200988Sjilles II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 292200988Sjilles II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 293200988Sjilles II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 29439137Stegge II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 29539137Stegge II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 2961556Srgrimes II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 2971556Srgrimes II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 2981556Srgrimes II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 2991556Srgrimes II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 3001556Srgrimes II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 301206150Sjilles II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 3021556Srgrimes 3031556Srgrimes state[0] += a; 3041556Srgrimes state[1] += b; 3051556Srgrimes state[2] += c; 3061556Srgrimes state[3] += d; 3071556Srgrimes 3081556Srgrimes /* Zeroize sensitive information. 3091556Srgrimes*/ 3101556Srgrimes memset ((POINTER)x, 0, sizeof (x)); 3111556Srgrimes} 3121556Srgrimes 3131556Srgrimes