ze-filter  (ze-filter-0.8.0-develop-180218)
zeMD5.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 2000, 2001 Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /* $Id: md5.c,v 1.9.206.1 2004/03/06 08:14:32 marka Exp $ */
19 
20 /*
21  * This code implements the MD5 message-digest algorithm.
22  * The algorithm is due to Ron Rivest. This code was
23  * written by Colin Plumb in 1993, no copyright is claimed.
24  * This code is in the public domain; do with it what you wish.
25  *
26  * Equivalent code is available from RSA Data Security, Inc.
27  * This code has been tested against that, and is equivalent,
28  * except that you don't need to include two pages of legalese
29  * with every copy.
30  *
31  * To compute the message digest of a chunk of bytes, declare an
32  * MD5Context structure, pass it to MD5Init, call MD5Update as
33  * needed on buffers full of bytes, and then call MD5Final, which
34  * will fill a supplied 16-byte array with the digest.
35  */
36 
37 #include "config.h"
38 
39 #include <ze-sys.h>
40 #include <macros.h>
41 #include <libze.h>
42 
43 static void
44 byteSwap(uint32_t * buf, unsigned words)
45 {
46  unsigned char *p = (unsigned char *) buf;
47 
48  do
49  {
50  *buf++ = (uint32_t) ((unsigned) p[3] << 8 | p[2]) << 16 |
51  ((unsigned) p[1] << 8 | p[0]);
52  p += 4;
53  } while (--words);
54 }
55 
56 /*
57  * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
58  * initialization constants.
59  */
60 void
62 {
63  ctx->buf[0] = 0x67452301;
64  ctx->buf[1] = 0xefcdab89;
65  ctx->buf[2] = 0x98badcfe;
66  ctx->buf[3] = 0x10325476;
67 
68  ctx->bytes[0] = 0;
69  ctx->bytes[1] = 0;
70 }
71 
72 void
74 {
75  memset(ctx, 0, sizeof (ZEMD5_T));
76 }
77 
78 /* The four core functions - F1 is optimized somewhat */
79 
80 /* #define F1(x, y, z) (x & y | ~x & z) */
81 #define F1(x, y, z) (z ^ (x & (y ^ z)))
82 #define F2(x, y, z) F1(z, x, y)
83 #define F3(x, y, z) (x ^ y ^ z)
84 #define F4(x, y, z) (y ^ (x | ~z))
85 
86 /* This is the central step in the MD5 algorithm. */
87 #define MD5STEP(f,w,x,y,z,in,s) \
88  (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
89 
90 /*
91  * The core of the MD5 algorithm, this alters an existing MD5 hash to
92  * reflect the addition of 16 longwords of new data. MD5Update blocks
93  * the data and converts bytes into longwords for this routine.
94  */
95 static void
96 transform(uint32_t buf[4], uint32_t const in[16])
97 {
98  register uint32_t a, b, c, d;
99 
100  a = buf[0];
101  b = buf[1];
102  c = buf[2];
103  d = buf[3];
104 
105  MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
106  MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
107  MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
108  MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
109  MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
110  MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
111  MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
112  MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
113  MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
114  MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
115  MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
116  MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
117  MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
118  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
119  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
120  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
121 
122  MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
123  MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
124  MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
125  MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
126  MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
127  MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
128  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
129  MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
130  MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
131  MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
132  MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
133  MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
134  MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
135  MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
136  MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
137  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
138 
139  MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
140  MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
141  MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
142  MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
143  MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
144  MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
145  MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
146  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
147  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
148  MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
149  MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
150  MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
151  MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
152  MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
153  MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
154  MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
155 
156  MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
157  MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
158  MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
159  MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
160  MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
161  MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
162  MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
163  MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
164  MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
165  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
166  MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
167  MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
168  MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
169  MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
170  MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
171  MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
172 
173  buf[0] += a;
174  buf[1] += b;
175  buf[2] += c;
176  buf[3] += d;
177 }
178 
179 /*
180  * Update context to reflect the concatenation of another buffer full
181  * of bytes.
182  */
183 void
184 zeMD5_Update(ZEMD5_T * ctx, const unsigned char *buf, unsigned int len)
185 {
186  uint32_t t;
187 
188  /* Update byte count */
189 
190  t = ctx->bytes[0];
191  if ((ctx->bytes[0] = t + len) < t)
192  ctx->bytes[1]++; /* Carry from low to high */
193 
194  t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
195  if (t > len)
196  {
197  memcpy((unsigned char *) ctx->in + 64 - t, buf, len);
198  return;
199  }
200  /* First chunk is an odd size */
201  memcpy((unsigned char *) ctx->in + 64 - t, buf, t);
202  byteSwap(ctx->in, 16);
203  transform(ctx->buf, ctx->in);
204  buf += t;
205  len -= t;
206 
207  /* Process data in 64-byte chunks */
208  while (len >= 64)
209  {
210  memcpy(ctx->in, buf, 64);
211  byteSwap(ctx->in, 16);
212  transform(ctx->buf, ctx->in);
213  buf += 64;
214  len -= 64;
215  }
216 
217  /* Handle any remaining bytes of data. */
218  memcpy(ctx->in, buf, len);
219 }
220 
221 /*
222  * Final wrapup - pad to 64-byte boundary with the bit pattern
223  * 1 0* (64-bit count of bits processed, MSB-first)
224  */
225 void
226 zeMD5_Final(ZEMD5_T * ctx, unsigned char *digest)
227 {
228  int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
229  unsigned char *p = (unsigned char *) ctx->in + count;
230 
231  /* Set the first char of padding to 0x80. There is always room. */
232  *p++ = 0x80;
233 
234  /* Bytes of padding needed to make 56 bytes (-8..55) */
235  count = 56 - 1 - count;
236 
237  if (count < 0)
238  { /* Padding forces an extra block */
239  memset(p, 0, count + 8);
240  byteSwap(ctx->in, 16);
241  transform(ctx->buf, ctx->in);
242  p = (unsigned char *) ctx->in;
243  count = 56;
244  }
245  memset(p, 0, count);
246  byteSwap(ctx->in, 14);
247 
248  /* Append length in bits and transform */
249  ctx->in[14] = ctx->bytes[0] << 3;
250  ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
251  transform(ctx->buf, ctx->in);
252 
253  byteSwap(ctx->buf, 4);
254  memcpy(digest, ctx->buf, 16);
255  memset(ctx, 0, sizeof (ZEMD5_T)); /* In case it's sensitive */
256 }
257 
#define F2(x, y, z)
Definition: zeMD5.c:82
#define F3(x, y, z)
Definition: zeMD5.c:83
Definition: zeMD5.h:47
uint32_t buf[4]
Definition: zeMD5.h:49
void zeMD5_Update(ZEMD5_T *ctx, const unsigned char *buf, unsigned int len)
Definition: zeMD5.c:184
uint32_t bytes[2]
Definition: zeMD5.h:50
#define MD5STEP(f, w, x, y, z, in, s)
Definition: zeMD5.c:87
#define memcpy(d, s, n)
Definition: ze-sys.h:224
#define F4(x, y, z)
Definition: zeMD5.c:84
void zeMD5_Invalidate(ZEMD5_T *ctx)
Definition: zeMD5.c:73
void zeMD5_Final(ZEMD5_T *ctx, unsigned char *digest)
Definition: zeMD5.c:226
void zeMD5_Init(ZEMD5_T *ctx)
Definition: zeMD5.c:61
#define F1(x, y, z)
Definition: zeMD5.c:81
long uint32_t
Definition: ze-sys.h:489
uint32_t in[16]
Definition: zeMD5.h:51