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