1145519Sdarrenr/*	$FreeBSD$	*/
2145510Sdarrenr
3145510Sdarrenr
4145510Sdarrenr
5145510Sdarrenr/*
6145510Sdarrenr ***********************************************************************
7145510Sdarrenr ** md5.c -- the source code for MD5 routines                         **
8145510Sdarrenr ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
9145510Sdarrenr ** Created: 2/17/90 RLR                                              **
10145510Sdarrenr ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
11145510Sdarrenr ***********************************************************************
12145510Sdarrenr */
13145510Sdarrenr
14145510Sdarrenr/*
15145510Sdarrenr ***********************************************************************
16145510Sdarrenr ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
17145510Sdarrenr **                                                                   **
18145510Sdarrenr ** License to copy and use this software is granted provided that    **
19145510Sdarrenr ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
20145510Sdarrenr ** Digest Algorithm" in all material mentioning or referencing this  **
21145510Sdarrenr ** software or this function.                                        **
22145510Sdarrenr **                                                                   **
23145510Sdarrenr ** License is also granted to make and use derivative works          **
24145510Sdarrenr ** provided that such works are identified as "derived from the RSA  **
25145510Sdarrenr ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
26145510Sdarrenr ** material mentioning or referencing the derived work.              **
27145510Sdarrenr **                                                                   **
28145510Sdarrenr ** RSA Data Security, Inc. makes no representations concerning       **
29145510Sdarrenr ** either the merchantability of this software or the suitability    **
30145510Sdarrenr ** of this software for any particular purpose.  It is provided "as  **
31145510Sdarrenr ** is" without express or implied warranty of any kind.              **
32145510Sdarrenr **                                                                   **
33145510Sdarrenr ** These notices must be retained in any copies of any part of this  **
34145510Sdarrenr ** documentation and/or software.                                    **
35145510Sdarrenr ***********************************************************************
36145510Sdarrenr */
37145510Sdarrenr
38255332Scy#if defined(linux) && defined(_KERNEL)
39255332Scyextern void *memcpy(void *, const void *, unsigned long);
40255332Scy# define	bcopy(a,b,c)	memcpy(b,a,c)
41145510Sdarrenr#else
42255332Scy# if defined(_KERNEL) && !defined(__sgi)
43255332Scy#  include <sys/systm.h>
44255332Scy# else
45255332Scy#  include <string.h>
46255332Scy# endif
47145510Sdarrenr#endif
48145510Sdarrenr
49145510Sdarrenr#include "md5.h"
50145510Sdarrenr
51145510Sdarrenr/*
52145510Sdarrenr ***********************************************************************
53145510Sdarrenr **  Message-digest routines:                                         **
54145510Sdarrenr **  To form the message digest for a message M                       **
55145510Sdarrenr **    (1) Initialize a context buffer mdContext using MD5Init        **
56145510Sdarrenr **    (2) Call MD5Update on mdContext and M                          **
57145510Sdarrenr **    (3) Call MD5Final on mdContext                                 **
58145510Sdarrenr **  The message digest is now in mdContext->digest[0...15]           **
59145510Sdarrenr ***********************************************************************
60145510Sdarrenr */
61145510Sdarrenr
62145510Sdarrenr/* forward declaration */
63145510Sdarrenrstatic void Transform __P((UINT4 *, UINT4 *));
64145510Sdarrenr
65145510Sdarrenrstatic unsigned char PADDING[64] = {
66145510Sdarrenr  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67145510Sdarrenr  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68145510Sdarrenr  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69145510Sdarrenr  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70145510Sdarrenr  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71145510Sdarrenr  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72145510Sdarrenr  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73145510Sdarrenr  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
74145510Sdarrenr};
75145510Sdarrenr
76145510Sdarrenr/* F, G, H and I are basic MD5 functions */
77145510Sdarrenr#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
78145510Sdarrenr#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
79145510Sdarrenr#define H(x, y, z) ((x) ^ (y) ^ (z))
80145510Sdarrenr#define I(x, y, z) ((y) ^ ((x) | (~z)))
81145510Sdarrenr
82145510Sdarrenr/* ROTATE_LEFT rotates x left n bits */
83145510Sdarrenr#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
84145510Sdarrenr
85145510Sdarrenr/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
86145510Sdarrenr/* Rotation is separate from addition to prevent recomputation */
87145510Sdarrenr#define FF(a, b, c, d, x, s, ac) \
88145510Sdarrenr  {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
89145510Sdarrenr   (a) = ROTATE_LEFT ((a), (s)); \
90145510Sdarrenr   (a) += (b); \
91145510Sdarrenr  }
92145510Sdarrenr#define GG(a, b, c, d, x, s, ac) \
93145510Sdarrenr  {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
94145510Sdarrenr   (a) = ROTATE_LEFT ((a), (s)); \
95145510Sdarrenr   (a) += (b); \
96145510Sdarrenr  }
97145510Sdarrenr#define HH(a, b, c, d, x, s, ac) \
98145510Sdarrenr  {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
99145510Sdarrenr   (a) = ROTATE_LEFT ((a), (s)); \
100145510Sdarrenr   (a) += (b); \
101145510Sdarrenr  }
102145510Sdarrenr#define II(a, b, c, d, x, s, ac) \
103145510Sdarrenr  {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
104145510Sdarrenr   (a) = ROTATE_LEFT ((a), (s)); \
105145510Sdarrenr   (a) += (b); \
106145510Sdarrenr  }
107145510Sdarrenr
108145510Sdarrenr#ifdef __STDC__
109145510Sdarrenr#define UL(x)	x##U
110145510Sdarrenr#else
111145510Sdarrenr#define UL(x)	x
112145510Sdarrenr#endif
113145510Sdarrenr
114145510Sdarrenr/* The routine MD5Init initializes the message-digest context
115145510Sdarrenr   mdContext. All fields are set to zero.
116145510Sdarrenr */
117145510Sdarrenrvoid MD5Init (mdContext)
118145510SdarrenrMD5_CTX *mdContext;
119145510Sdarrenr{
120145510Sdarrenr  mdContext->i[0] = mdContext->i[1] = (UINT4)0;
121145510Sdarrenr
122145510Sdarrenr  /* Load magic initialization constants.
123145510Sdarrenr   */
124145510Sdarrenr  mdContext->buf[0] = (UINT4)0x67452301;
125145510Sdarrenr  mdContext->buf[1] = (UINT4)0xefcdab89;
126145510Sdarrenr  mdContext->buf[2] = (UINT4)0x98badcfe;
127145510Sdarrenr  mdContext->buf[3] = (UINT4)0x10325476;
128145510Sdarrenr}
129145510Sdarrenr
130145510Sdarrenr/* The routine MD5Update updates the message-digest context to
131145510Sdarrenr   account for the presence of each of the characters inBuf[0..inLen-1]
132145510Sdarrenr   in the message whose digest is being computed.
133145510Sdarrenr */
134145510Sdarrenrvoid MD5Update (mdContext, inBuf, inLen)
135145510SdarrenrMD5_CTX *mdContext;
136145510Sdarrenrunsigned char *inBuf;
137145510Sdarrenrunsigned int inLen;
138145510Sdarrenr{
139145510Sdarrenr  UINT4 in[16];
140145510Sdarrenr  int mdi;
141145510Sdarrenr  unsigned int i, ii;
142145510Sdarrenr
143145510Sdarrenr  /* compute number of bytes mod 64 */
144145510Sdarrenr  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
145145510Sdarrenr
146145510Sdarrenr  /* update number of bits */
147145510Sdarrenr  if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
148145510Sdarrenr    mdContext->i[1]++;
149145510Sdarrenr  mdContext->i[0] += ((UINT4)inLen << 3);
150145510Sdarrenr  mdContext->i[1] += ((UINT4)inLen >> 29);
151145510Sdarrenr
152145510Sdarrenr  while (inLen--) {
153145510Sdarrenr    /* add new character to buffer, increment mdi */
154145510Sdarrenr    mdContext->in[mdi++] = *inBuf++;
155145510Sdarrenr
156145510Sdarrenr    /* transform if necessary */
157145510Sdarrenr    if (mdi == 0x40) {
158145510Sdarrenr      for (i = 0, ii = 0; i < 16; i++, ii += 4)
159145510Sdarrenr        in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
160145510Sdarrenr                (((UINT4)mdContext->in[ii+2]) << 16) |
161145510Sdarrenr                (((UINT4)mdContext->in[ii+1]) << 8) |
162145510Sdarrenr                ((UINT4)mdContext->in[ii]);
163145510Sdarrenr      Transform (mdContext->buf, in);
164145510Sdarrenr      mdi = 0;
165145510Sdarrenr    }
166145510Sdarrenr  }
167145510Sdarrenr}
168145510Sdarrenr
169145510Sdarrenr/* The routine MD5Final terminates the message-digest computation and
170145510Sdarrenr   ends with the desired message digest in mdContext->digest[0...15].
171145510Sdarrenr */
172145510Sdarrenrvoid MD5Final (hash, mdContext)
173145510Sdarrenrunsigned char hash[];
174145510SdarrenrMD5_CTX *mdContext;
175145510Sdarrenr{
176145510Sdarrenr  UINT4 in[16];
177145510Sdarrenr  int mdi;
178145510Sdarrenr  unsigned int i, ii;
179145510Sdarrenr  unsigned int padLen;
180145510Sdarrenr
181145510Sdarrenr  /* save number of bits */
182145510Sdarrenr  in[14] = mdContext->i[0];
183145510Sdarrenr  in[15] = mdContext->i[1];
184145510Sdarrenr
185145510Sdarrenr  /* compute number of bytes mod 64 */
186145510Sdarrenr  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
187145510Sdarrenr
188145510Sdarrenr  /* pad out to 56 mod 64 */
189145510Sdarrenr  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
190145510Sdarrenr  MD5Update (mdContext, PADDING, padLen);
191145510Sdarrenr
192145510Sdarrenr  /* append length in bits and transform */
193145510Sdarrenr  for (i = 0, ii = 0; i < 14; i++, ii += 4)
194145510Sdarrenr    in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
195145510Sdarrenr            (((UINT4)mdContext->in[ii+2]) << 16) |
196145510Sdarrenr            (((UINT4)mdContext->in[ii+1]) << 8) |
197145510Sdarrenr            ((UINT4)mdContext->in[ii]);
198145510Sdarrenr  Transform (mdContext->buf, in);
199145510Sdarrenr
200145510Sdarrenr  /* store buffer in digest */
201145510Sdarrenr  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
202145510Sdarrenr    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
203145510Sdarrenr    mdContext->digest[ii+1] =
204145510Sdarrenr      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
205145510Sdarrenr    mdContext->digest[ii+2] =
206145510Sdarrenr      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
207145510Sdarrenr    mdContext->digest[ii+3] =
208145510Sdarrenr      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
209145510Sdarrenr  }
210145510Sdarrenr  bcopy((char *)mdContext->digest, (char *)hash, 16);
211145510Sdarrenr}
212145510Sdarrenr
213145510Sdarrenr/* Basic MD5 step. Transforms buf based on in.
214145510Sdarrenr */
215145510Sdarrenrstatic void Transform (buf, in)
216145510SdarrenrUINT4 *buf;
217145510SdarrenrUINT4 *in;
218145510Sdarrenr{
219145510Sdarrenr  UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
220145510Sdarrenr
221145510Sdarrenr  /* Round 1 */
222145510Sdarrenr#define S11 7
223145510Sdarrenr#define S12 12
224145510Sdarrenr#define S13 17
225145510Sdarrenr#define S14 22
226145510Sdarrenr  FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
227145510Sdarrenr  FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
228145510Sdarrenr  FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
229145510Sdarrenr  FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
230145510Sdarrenr  FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
231145510Sdarrenr  FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
232145510Sdarrenr  FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
233145510Sdarrenr  FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
234145510Sdarrenr  FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
235145510Sdarrenr  FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
236145510Sdarrenr  FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
237145510Sdarrenr  FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
238145510Sdarrenr  FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
239145510Sdarrenr  FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
240145510Sdarrenr  FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
241145510Sdarrenr  FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
242145510Sdarrenr
243145510Sdarrenr  /* Round 2 */
244145510Sdarrenr#define S21 5
245145510Sdarrenr#define S22 9
246145510Sdarrenr#define S23 14
247145510Sdarrenr#define S24 20
248145510Sdarrenr  GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
249145510Sdarrenr  GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
250145510Sdarrenr  GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
251145510Sdarrenr  GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
252145510Sdarrenr  GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
253145510Sdarrenr  GG ( d, a, b, c, in[10], S22, UL(  38016083)); /* 22 */
254145510Sdarrenr  GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
255145510Sdarrenr  GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
256145510Sdarrenr  GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
257145510Sdarrenr  GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
258145510Sdarrenr  GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
259145510Sdarrenr  GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
260145510Sdarrenr  GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
261145510Sdarrenr  GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
262145510Sdarrenr  GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
263145510Sdarrenr  GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
264145510Sdarrenr
265145510Sdarrenr  /* Round 3 */
266145510Sdarrenr#define S31 4
267145510Sdarrenr#define S32 11
268145510Sdarrenr#define S33 16
269145510Sdarrenr#define S34 23
270145510Sdarrenr  HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
271145510Sdarrenr  HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
272145510Sdarrenr  HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
273145510Sdarrenr  HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
274145510Sdarrenr  HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
275145510Sdarrenr  HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
276145510Sdarrenr  HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
277145510Sdarrenr  HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
278145510Sdarrenr  HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
279145510Sdarrenr  HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
280145510Sdarrenr  HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
281145510Sdarrenr  HH ( b, c, d, a, in[ 6], S34, UL(  76029189)); /* 44 */
282145510Sdarrenr  HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
283145510Sdarrenr  HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
284145510Sdarrenr  HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
285145510Sdarrenr  HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
286145510Sdarrenr
287145510Sdarrenr  /* Round 4 */
288145510Sdarrenr#define S41 6
289145510Sdarrenr#define S42 10
290145510Sdarrenr#define S43 15
291145510Sdarrenr#define S44 21
292145510Sdarrenr  II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
293145510Sdarrenr  II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
294145510Sdarrenr  II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
295145510Sdarrenr  II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
296145510Sdarrenr  II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
297145510Sdarrenr  II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
298145510Sdarrenr  II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
299145510Sdarrenr  II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
300145510Sdarrenr  II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
301145510Sdarrenr  II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
302145510Sdarrenr  II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
303145510Sdarrenr  II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
304145510Sdarrenr  II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
305145510Sdarrenr  II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
306145510Sdarrenr  II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
307145510Sdarrenr  II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
308145510Sdarrenr
309145510Sdarrenr  buf[0] += a;
310145510Sdarrenr  buf[1] += b;
311145510Sdarrenr  buf[2] += c;
312145510Sdarrenr  buf[3] += d;
313145510Sdarrenr}
314145510Sdarrenr
315145510Sdarrenr/*
316145510Sdarrenr ***********************************************************************
317145510Sdarrenr ** End of md5.c                                                      **
318145510Sdarrenr ******************************** (cut) ********************************
319145510Sdarrenr */
320