190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/*
2f71323e297a928af368937089d3ed71239786f86Andreas Huber * This code implements the MD5 message-digest algorithm.
3f71323e297a928af368937089d3ed71239786f86Andreas Huber * The algorithm is due to Ron Rivest.  This code was
4f71323e297a928af368937089d3ed71239786f86Andreas Huber * written by Colin Plumb in 1993, no copyright is claimed.
5f71323e297a928af368937089d3ed71239786f86Andreas Huber * This code is in the public domain; do with it what you wish.
690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
7f71323e297a928af368937089d3ed71239786f86Andreas Huber * Equivalent code is available from RSA Data Security, Inc.
8f71323e297a928af368937089d3ed71239786f86Andreas Huber * This code has been tested against that, and is equivalent,
9f71323e297a928af368937089d3ed71239786f86Andreas Huber * except that you don't need to include two pages of legalese
10f71323e297a928af368937089d3ed71239786f86Andreas Huber * with every copy.
11f71323e297a928af368937089d3ed71239786f86Andreas Huber *
12f71323e297a928af368937089d3ed71239786f86Andreas Huber * To compute the message digest of a chunk of bytes, declare an
13f71323e297a928af368937089d3ed71239786f86Andreas Huber * MD5Context structure, pass it to MD5Init, call MD5Update as
14f71323e297a928af368937089d3ed71239786f86Andreas Huber * needed on buffers full of bytes, and then call MD5Final, which
15f71323e297a928af368937089d3ed71239786f86Andreas Huber * will fill a supplied 16-byte array with the digest.
16f71323e297a928af368937089d3ed71239786f86Andreas Huber *
17f71323e297a928af368937089d3ed71239786f86Andreas Huber * Changed so as no longer to depend on Colin Plumb's `usual.h' header
18f71323e297a928af368937089d3ed71239786f86Andreas Huber * definitions
19f71323e297a928af368937089d3ed71239786f86Andreas Huber *  - Ian Jackson <ian@chiark.greenend.org.uk>.
20f71323e297a928af368937089d3ed71239786f86Andreas Huber * Still in the public domain.
2190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
2290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
23f71323e297a928af368937089d3ed71239786f86Andreas Huber#include <string.h>   /* for memcpy() */
2490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "md5_utils.h"
2690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
27f71323e297a928af368937089d3ed71239786f86Andreas Hubervoid
28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangbyteSwap(UWORD32 *buf, unsigned words) {
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  md5byte *p;
3090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Only swap bytes for big endian machines */
32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i = 1;
3390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (*(char *)&i == 1)
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return;
3690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  p = (md5byte *)buf;
38f71323e297a928af368937089d3ed71239786f86Andreas Huber
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  do {
40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |
41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang             ((unsigned)p[1] << 8 | p[0]);
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    p += 4;
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } while (--words);
44f71323e297a928af368937089d3ed71239786f86Andreas Huber}
4590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
46f71323e297a928af368937089d3ed71239786f86Andreas Huber/*
47f71323e297a928af368937089d3ed71239786f86Andreas Huber * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
48f71323e297a928af368937089d3ed71239786f86Andreas Huber * initialization constants.
4990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
50f71323e297a928af368937089d3ed71239786f86Andreas Hubervoid
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangMD5Init(struct MD5Context *ctx) {
52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->buf[0] = 0x67452301;
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->buf[1] = 0xefcdab89;
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->buf[2] = 0x98badcfe;
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->buf[3] = 0x10325476;
56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
57ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->bytes[0] = 0;
58ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->bytes[1] = 0;
5990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
6090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
61f71323e297a928af368937089d3ed71239786f86Andreas Huber/*
62f71323e297a928af368937089d3ed71239786f86Andreas Huber * Update context to reflect the concatenation of another buffer full
63f71323e297a928af368937089d3ed71239786f86Andreas Huber * of bytes.
6490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
65f71323e297a928af368937089d3ed71239786f86Andreas Hubervoid
66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangMD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) {
67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  UWORD32 t;
6890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Update byte count */
7090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  t = ctx->bytes[0];
7290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if ((ctx->bytes[0] = t + len) < t)
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ctx->bytes[1]++;  /* Carry from low to high */
7590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  t = 64 - (t & 0x3f);  /* Space available in ctx->in (at least 1) */
7790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (t > len) {
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    memcpy((md5byte *)ctx->in + 64 - t, buf, len);
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return;
81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
8290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
83ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* First chunk is an odd size */
84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  memcpy((md5byte *)ctx->in + 64 - t, buf, t);
85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  byteSwap(ctx->in, 16);
86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5Transform(ctx->buf, ctx->in);
87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  buf += t;
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  len -= t;
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Process data in 64-byte chunks */
91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  while (len >= 64) {
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    memcpy(ctx->in, buf, 64);
93f71323e297a928af368937089d3ed71239786f86Andreas Huber    byteSwap(ctx->in, 16);
94f71323e297a928af368937089d3ed71239786f86Andreas Huber    MD5Transform(ctx->buf, ctx->in);
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    buf += 64;
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    len -= 64;
97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Handle any remaining bytes of data. */
100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  memcpy(ctx->in, buf, len);
10190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
10290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
103f71323e297a928af368937089d3ed71239786f86Andreas Huber/*
104f71323e297a928af368937089d3ed71239786f86Andreas Huber * Final wrapup - pad to 64-byte boundary with the bit pattern
105f71323e297a928af368937089d3ed71239786f86Andreas Huber * 1 0* (64-bit count of bits processed, MSB-first)
10690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
107f71323e297a928af368937089d3ed71239786f86Andreas Hubervoid
108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangMD5Final(md5byte digest[16], struct MD5Context *ctx) {
109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  md5byte *p = (md5byte *)ctx->in + count;
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Set the first char of padding to 0x80.  There is always room. */
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *p++ = 0x80;
114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Bytes of padding needed to make 56 bytes (-8..55) */
116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  count = 56 - 1 - count;
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (count < 0) {  /* Padding forces an extra block */
119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    memset(p, 0, count + 8);
120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    byteSwap(ctx->in, 16);
121f71323e297a928af368937089d3ed71239786f86Andreas Huber    MD5Transform(ctx->buf, ctx->in);
122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    p = (md5byte *)ctx->in;
123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    count = 56;
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  memset(p, 0, count);
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  byteSwap(ctx->in, 14);
128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Append length in bits and transform */
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->in[14] = ctx->bytes[0] << 3;
131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5Transform(ctx->buf, ctx->in);
133f71323e297a928af368937089d3ed71239786f86Andreas Huber
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  byteSwap(ctx->buf, 4);
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  memcpy(digest, ctx->buf, 16);
136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
13790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
13890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
139f71323e297a928af368937089d3ed71239786f86Andreas Huber#ifndef ASM_MD5
140f71323e297a928af368937089d3ed71239786f86Andreas Huber
141f71323e297a928af368937089d3ed71239786f86Andreas Huber/* The four core functions - F1 is optimized somewhat */
142f71323e297a928af368937089d3ed71239786f86Andreas Huber
143f71323e297a928af368937089d3ed71239786f86Andreas Huber/* #define F1(x, y, z) (x & y | ~x & z) */
144f71323e297a928af368937089d3ed71239786f86Andreas Huber#define F1(x, y, z) (z ^ (x & (y ^ z)))
145f71323e297a928af368937089d3ed71239786f86Andreas Huber#define F2(x, y, z) F1(z, x, y)
146f71323e297a928af368937089d3ed71239786f86Andreas Huber#define F3(x, y, z) (x ^ y ^ z)
147f71323e297a928af368937089d3ed71239786f86Andreas Huber#define F4(x, y, z) (y ^ (x | ~z))
148f71323e297a928af368937089d3ed71239786f86Andreas Huber
149f71323e297a928af368937089d3ed71239786f86Andreas Huber/* This is the central step in the MD5 algorithm. */
150f71323e297a928af368937089d3ed71239786f86Andreas Huber#define MD5STEP(f,w,x,y,z,in,s) \
151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
152f71323e297a928af368937089d3ed71239786f86Andreas Huber
153f71323e297a928af368937089d3ed71239786f86Andreas Huber/*
154f71323e297a928af368937089d3ed71239786f86Andreas Huber * The core of the MD5 algorithm, this alters an existing MD5 hash to
155f71323e297a928af368937089d3ed71239786f86Andreas Huber * reflect the addition of 16 longwords of new data.  MD5Update blocks
156f71323e297a928af368937089d3ed71239786f86Andreas Huber * the data and converts bytes into longwords for this routine.
15790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
158f71323e297a928af368937089d3ed71239786f86Andreas Hubervoid
159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangMD5Transform(UWORD32 buf[4], UWORD32 const in[16]) {
160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  register UWORD32 a, b, c, d;
161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  a = buf[0];
163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  b = buf[1];
164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  c = buf[2];
165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  d = buf[3];
166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  buf[0] += a;
236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  buf[1] += b;
237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  buf[2] += c;
238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  buf[3] += d;
23990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
240f71323e297a928af368937089d3ed71239786f86Andreas Huber
241f71323e297a928af368937089d3ed71239786f86Andreas Huber#endif
242