xref: /dragonfly/contrib/cvs-1.12/lib/md5.c (revision 86d7f5d3)
1*86d7f5d3SJohn Marino /* md5.c - Functions to compute MD5 message digest of files or memory blocks
2*86d7f5d3SJohn Marino    according to the definition of MD5 in RFC 1321 from April 1992.
3*86d7f5d3SJohn Marino    Copyright (C) 1995, 1996, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
4*86d7f5d3SJohn Marino    NOTE: The canonical source of this file is maintained with the GNU C
5*86d7f5d3SJohn Marino    Library.  Bugs can be reported to bug-glibc@prep.ai.mit.edu.
6*86d7f5d3SJohn Marino 
7*86d7f5d3SJohn Marino    This program is free software; you can redistribute it and/or modify it
8*86d7f5d3SJohn Marino    under the terms of the GNU General Public License as published by the
9*86d7f5d3SJohn Marino    Free Software Foundation; either version 2, or (at your option) any
10*86d7f5d3SJohn Marino    later version.
11*86d7f5d3SJohn Marino 
12*86d7f5d3SJohn Marino    This program is distributed in the hope that it will be useful,
13*86d7f5d3SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*86d7f5d3SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*86d7f5d3SJohn Marino    GNU General Public License for more details.
16*86d7f5d3SJohn Marino 
17*86d7f5d3SJohn Marino    You should have received a copy of the GNU General Public License
18*86d7f5d3SJohn Marino    along with this program; if not, write to the Free Software Foundation,
19*86d7f5d3SJohn Marino    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
20*86d7f5d3SJohn Marino 
21*86d7f5d3SJohn Marino /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
22*86d7f5d3SJohn Marino 
23*86d7f5d3SJohn Marino #ifdef HAVE_CONFIG_H
24*86d7f5d3SJohn Marino # include <config.h>
25*86d7f5d3SJohn Marino #endif
26*86d7f5d3SJohn Marino 
27*86d7f5d3SJohn Marino #include "md5.h"
28*86d7f5d3SJohn Marino 
29*86d7f5d3SJohn Marino #include <stddef.h>
30*86d7f5d3SJohn Marino #include <string.h>
31*86d7f5d3SJohn Marino 
32*86d7f5d3SJohn Marino #if USE_UNLOCKED_IO
33*86d7f5d3SJohn Marino # include "unlocked-io.h"
34*86d7f5d3SJohn Marino #endif
35*86d7f5d3SJohn Marino 
36*86d7f5d3SJohn Marino #ifdef _LIBC
37*86d7f5d3SJohn Marino # include <endian.h>
38*86d7f5d3SJohn Marino # if __BYTE_ORDER == __BIG_ENDIAN
39*86d7f5d3SJohn Marino #  define WORDS_BIGENDIAN 1
40*86d7f5d3SJohn Marino # endif
41*86d7f5d3SJohn Marino /* We need to keep the namespace clean so define the MD5 function
42*86d7f5d3SJohn Marino    protected using leading __ .  */
43*86d7f5d3SJohn Marino # define md5_init_ctx __md5_init_ctx
44*86d7f5d3SJohn Marino # define md5_process_block __md5_process_block
45*86d7f5d3SJohn Marino # define md5_process_bytes __md5_process_bytes
46*86d7f5d3SJohn Marino # define md5_finish_ctx __md5_finish_ctx
47*86d7f5d3SJohn Marino # define md5_read_ctx __md5_read_ctx
48*86d7f5d3SJohn Marino # define md5_stream __md5_stream
49*86d7f5d3SJohn Marino # define md5_buffer __md5_buffer
50*86d7f5d3SJohn Marino #endif
51*86d7f5d3SJohn Marino 
52*86d7f5d3SJohn Marino #ifdef WORDS_BIGENDIAN
53*86d7f5d3SJohn Marino # define SWAP(n)							\
54*86d7f5d3SJohn Marino     (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
55*86d7f5d3SJohn Marino #else
56*86d7f5d3SJohn Marino # define SWAP(n) (n)
57*86d7f5d3SJohn Marino #endif
58*86d7f5d3SJohn Marino 
59*86d7f5d3SJohn Marino #define BLOCKSIZE 4096
60*86d7f5d3SJohn Marino #if BLOCKSIZE % 64 != 0
61*86d7f5d3SJohn Marino # error "invalid BLOCKSIZE"
62*86d7f5d3SJohn Marino #endif
63*86d7f5d3SJohn Marino 
64*86d7f5d3SJohn Marino /* This array contains the bytes used to pad the buffer to the next
65*86d7f5d3SJohn Marino    64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
66*86d7f5d3SJohn Marino static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
67*86d7f5d3SJohn Marino 
68*86d7f5d3SJohn Marino 
69*86d7f5d3SJohn Marino /* Initialize structure containing state of computation.
70*86d7f5d3SJohn Marino    (RFC 1321, 3.3: Step 3)  */
71*86d7f5d3SJohn Marino void
md5_init_ctx(struct md5_ctx * ctx)72*86d7f5d3SJohn Marino md5_init_ctx (struct md5_ctx *ctx)
73*86d7f5d3SJohn Marino {
74*86d7f5d3SJohn Marino   ctx->A = 0x67452301;
75*86d7f5d3SJohn Marino   ctx->B = 0xefcdab89;
76*86d7f5d3SJohn Marino   ctx->C = 0x98badcfe;
77*86d7f5d3SJohn Marino   ctx->D = 0x10325476;
78*86d7f5d3SJohn Marino 
79*86d7f5d3SJohn Marino   ctx->total[0] = ctx->total[1] = 0;
80*86d7f5d3SJohn Marino   ctx->buflen = 0;
81*86d7f5d3SJohn Marino }
82*86d7f5d3SJohn Marino 
83*86d7f5d3SJohn Marino /* Put result from CTX in first 16 bytes following RESBUF.  The result
84*86d7f5d3SJohn Marino    must be in little endian byte order.
85*86d7f5d3SJohn Marino 
86*86d7f5d3SJohn Marino    IMPORTANT: On some systems it is required that RESBUF is correctly
87*86d7f5d3SJohn Marino    aligned for a 32 bits value.  */
88*86d7f5d3SJohn Marino void *
md5_read_ctx(const struct md5_ctx * ctx,void * resbuf)89*86d7f5d3SJohn Marino md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
90*86d7f5d3SJohn Marino {
91*86d7f5d3SJohn Marino   ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
92*86d7f5d3SJohn Marino   ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
93*86d7f5d3SJohn Marino   ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
94*86d7f5d3SJohn Marino   ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
95*86d7f5d3SJohn Marino 
96*86d7f5d3SJohn Marino   return resbuf;
97*86d7f5d3SJohn Marino }
98*86d7f5d3SJohn Marino 
99*86d7f5d3SJohn Marino /* Process the remaining bytes in the internal buffer and the usual
100*86d7f5d3SJohn Marino    prolog according to the standard and write the result to RESBUF.
101*86d7f5d3SJohn Marino 
102*86d7f5d3SJohn Marino    IMPORTANT: On some systems it is required that RESBUF is correctly
103*86d7f5d3SJohn Marino    aligned for a 32 bits value.  */
104*86d7f5d3SJohn Marino void *
md5_finish_ctx(struct md5_ctx * ctx,void * resbuf)105*86d7f5d3SJohn Marino md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
106*86d7f5d3SJohn Marino {
107*86d7f5d3SJohn Marino   /* Take yet unprocessed bytes into account.  */
108*86d7f5d3SJohn Marino   md5_uint32 bytes = ctx->buflen;
109*86d7f5d3SJohn Marino   size_t pad;
110*86d7f5d3SJohn Marino 
111*86d7f5d3SJohn Marino   /* Now count remaining bytes.  */
112*86d7f5d3SJohn Marino   ctx->total[0] += bytes;
113*86d7f5d3SJohn Marino   if (ctx->total[0] < bytes)
114*86d7f5d3SJohn Marino     ++ctx->total[1];
115*86d7f5d3SJohn Marino 
116*86d7f5d3SJohn Marino   pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
117*86d7f5d3SJohn Marino   memcpy (&ctx->buffer[bytes], fillbuf, pad);
118*86d7f5d3SJohn Marino 
119*86d7f5d3SJohn Marino   /* Put the 64-bit file length in *bits* at the end of the buffer.  */
120*86d7f5d3SJohn Marino   *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
121*86d7f5d3SJohn Marino   *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
122*86d7f5d3SJohn Marino 							(ctx->total[0] >> 29));
123*86d7f5d3SJohn Marino 
124*86d7f5d3SJohn Marino   /* Process last bytes.  */
125*86d7f5d3SJohn Marino   md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
126*86d7f5d3SJohn Marino 
127*86d7f5d3SJohn Marino   return md5_read_ctx (ctx, resbuf);
128*86d7f5d3SJohn Marino }
129*86d7f5d3SJohn Marino 
130*86d7f5d3SJohn Marino /* Compute MD5 message digest for bytes read from STREAM.  The
131*86d7f5d3SJohn Marino    resulting message digest number will be written into the 16 bytes
132*86d7f5d3SJohn Marino    beginning at RESBLOCK.  */
133*86d7f5d3SJohn Marino int
md5_stream(FILE * stream,void * resblock)134*86d7f5d3SJohn Marino md5_stream (FILE *stream, void *resblock)
135*86d7f5d3SJohn Marino {
136*86d7f5d3SJohn Marino   struct md5_ctx ctx;
137*86d7f5d3SJohn Marino   char buffer[BLOCKSIZE + 72];
138*86d7f5d3SJohn Marino   size_t sum;
139*86d7f5d3SJohn Marino 
140*86d7f5d3SJohn Marino   /* Initialize the computation context.  */
141*86d7f5d3SJohn Marino   md5_init_ctx (&ctx);
142*86d7f5d3SJohn Marino 
143*86d7f5d3SJohn Marino   /* Iterate over full file contents.  */
144*86d7f5d3SJohn Marino   while (1)
145*86d7f5d3SJohn Marino     {
146*86d7f5d3SJohn Marino       /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
147*86d7f5d3SJohn Marino 	 computation function processes the whole buffer so that with the
148*86d7f5d3SJohn Marino 	 next round of the loop another block can be read.  */
149*86d7f5d3SJohn Marino       size_t n;
150*86d7f5d3SJohn Marino       sum = 0;
151*86d7f5d3SJohn Marino 
152*86d7f5d3SJohn Marino       /* Read block.  Take care for partial reads.  */
153*86d7f5d3SJohn Marino       while (1)
154*86d7f5d3SJohn Marino 	{
155*86d7f5d3SJohn Marino 	  n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
156*86d7f5d3SJohn Marino 
157*86d7f5d3SJohn Marino 	  sum += n;
158*86d7f5d3SJohn Marino 
159*86d7f5d3SJohn Marino 	  if (sum == BLOCKSIZE)
160*86d7f5d3SJohn Marino 	    break;
161*86d7f5d3SJohn Marino 
162*86d7f5d3SJohn Marino 	  if (n == 0)
163*86d7f5d3SJohn Marino 	    {
164*86d7f5d3SJohn Marino 	      /* Check for the error flag IFF N == 0, so that we don't
165*86d7f5d3SJohn Marino 		 exit the loop after a partial read due to e.g., EAGAIN
166*86d7f5d3SJohn Marino 		 or EWOULDBLOCK.  */
167*86d7f5d3SJohn Marino 	      if (ferror (stream))
168*86d7f5d3SJohn Marino 		return 1;
169*86d7f5d3SJohn Marino 	      goto process_partial_block;
170*86d7f5d3SJohn Marino 	    }
171*86d7f5d3SJohn Marino 
172*86d7f5d3SJohn Marino 	  /* We've read at least one byte, so ignore errors.  But always
173*86d7f5d3SJohn Marino 	     check for EOF, since feof may be true even though N > 0.
174*86d7f5d3SJohn Marino 	     Otherwise, we could end up calling fread after EOF.  */
175*86d7f5d3SJohn Marino 	  if (feof (stream))
176*86d7f5d3SJohn Marino 	    goto process_partial_block;
177*86d7f5d3SJohn Marino 	}
178*86d7f5d3SJohn Marino 
179*86d7f5d3SJohn Marino       /* Process buffer with BLOCKSIZE bytes.  Note that
180*86d7f5d3SJohn Marino 			BLOCKSIZE % 64 == 0
181*86d7f5d3SJohn Marino        */
182*86d7f5d3SJohn Marino       md5_process_block (buffer, BLOCKSIZE, &ctx);
183*86d7f5d3SJohn Marino     }
184*86d7f5d3SJohn Marino 
185*86d7f5d3SJohn Marino  process_partial_block:;
186*86d7f5d3SJohn Marino 
187*86d7f5d3SJohn Marino   /* Process any remaining bytes.  */
188*86d7f5d3SJohn Marino   if (sum > 0)
189*86d7f5d3SJohn Marino     md5_process_bytes (buffer, sum, &ctx);
190*86d7f5d3SJohn Marino 
191*86d7f5d3SJohn Marino   /* Construct result in desired memory.  */
192*86d7f5d3SJohn Marino   md5_finish_ctx (&ctx, resblock);
193*86d7f5d3SJohn Marino   return 0;
194*86d7f5d3SJohn Marino }
195*86d7f5d3SJohn Marino 
196*86d7f5d3SJohn Marino /* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
197*86d7f5d3SJohn Marino    result is always in little endian byte order, so that a byte-wise
198*86d7f5d3SJohn Marino    output yields to the wanted ASCII representation of the message
199*86d7f5d3SJohn Marino    digest.  */
200*86d7f5d3SJohn Marino void *
md5_buffer(const char * buffer,size_t len,void * resblock)201*86d7f5d3SJohn Marino md5_buffer (const char *buffer, size_t len, void *resblock)
202*86d7f5d3SJohn Marino {
203*86d7f5d3SJohn Marino   struct md5_ctx ctx;
204*86d7f5d3SJohn Marino 
205*86d7f5d3SJohn Marino   /* Initialize the computation context.  */
206*86d7f5d3SJohn Marino   md5_init_ctx (&ctx);
207*86d7f5d3SJohn Marino 
208*86d7f5d3SJohn Marino   /* Process whole buffer but last len % 64 bytes.  */
209*86d7f5d3SJohn Marino   md5_process_bytes (buffer, len, &ctx);
210*86d7f5d3SJohn Marino 
211*86d7f5d3SJohn Marino   /* Put result in desired memory area.  */
212*86d7f5d3SJohn Marino   return md5_finish_ctx (&ctx, resblock);
213*86d7f5d3SJohn Marino }
214*86d7f5d3SJohn Marino 
215*86d7f5d3SJohn Marino 
216*86d7f5d3SJohn Marino void
md5_process_bytes(const void * buffer,size_t len,struct md5_ctx * ctx)217*86d7f5d3SJohn Marino md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
218*86d7f5d3SJohn Marino {
219*86d7f5d3SJohn Marino   /* When we already have some bits in our internal buffer concatenate
220*86d7f5d3SJohn Marino      both inputs first.  */
221*86d7f5d3SJohn Marino   if (ctx->buflen != 0)
222*86d7f5d3SJohn Marino     {
223*86d7f5d3SJohn Marino       size_t left_over = ctx->buflen;
224*86d7f5d3SJohn Marino       size_t add = 128 - left_over > len ? len : 128 - left_over;
225*86d7f5d3SJohn Marino 
226*86d7f5d3SJohn Marino       memcpy (&ctx->buffer[left_over], buffer, add);
227*86d7f5d3SJohn Marino       ctx->buflen += add;
228*86d7f5d3SJohn Marino 
229*86d7f5d3SJohn Marino       if (ctx->buflen > 64)
230*86d7f5d3SJohn Marino 	{
231*86d7f5d3SJohn Marino 	  md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
232*86d7f5d3SJohn Marino 
233*86d7f5d3SJohn Marino 	  ctx->buflen &= 63;
234*86d7f5d3SJohn Marino 	  /* The regions in the following copy operation cannot overlap.  */
235*86d7f5d3SJohn Marino 	  memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
236*86d7f5d3SJohn Marino 		  ctx->buflen);
237*86d7f5d3SJohn Marino 	}
238*86d7f5d3SJohn Marino 
239*86d7f5d3SJohn Marino       buffer = (const char *) buffer + add;
240*86d7f5d3SJohn Marino       len -= add;
241*86d7f5d3SJohn Marino     }
242*86d7f5d3SJohn Marino 
243*86d7f5d3SJohn Marino   /* Process available complete blocks.  */
244*86d7f5d3SJohn Marino   if (len >= 64)
245*86d7f5d3SJohn Marino     {
246*86d7f5d3SJohn Marino #if !_STRING_ARCH_unaligned
247*86d7f5d3SJohn Marino # define alignof(type) offsetof (struct { char c; type x; }, x)
248*86d7f5d3SJohn Marino # define UNALIGNED_P(p) (((size_t) p) % alignof (md5_uint32) != 0)
249*86d7f5d3SJohn Marino       if (UNALIGNED_P (buffer))
250*86d7f5d3SJohn Marino 	while (len > 64)
251*86d7f5d3SJohn Marino 	  {
252*86d7f5d3SJohn Marino 	    md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
253*86d7f5d3SJohn Marino 	    buffer = (const char *) buffer + 64;
254*86d7f5d3SJohn Marino 	    len -= 64;
255*86d7f5d3SJohn Marino 	  }
256*86d7f5d3SJohn Marino       else
257*86d7f5d3SJohn Marino #endif
258*86d7f5d3SJohn Marino 	{
259*86d7f5d3SJohn Marino 	  md5_process_block (buffer, len & ~63, ctx);
260*86d7f5d3SJohn Marino 	  buffer = (const char *) buffer + (len & ~63);
261*86d7f5d3SJohn Marino 	  len &= 63;
262*86d7f5d3SJohn Marino 	}
263*86d7f5d3SJohn Marino     }
264*86d7f5d3SJohn Marino 
265*86d7f5d3SJohn Marino   /* Move remaining bytes in internal buffer.  */
266*86d7f5d3SJohn Marino   if (len > 0)
267*86d7f5d3SJohn Marino     {
268*86d7f5d3SJohn Marino       size_t left_over = ctx->buflen;
269*86d7f5d3SJohn Marino 
270*86d7f5d3SJohn Marino       memcpy (&ctx->buffer[left_over], buffer, len);
271*86d7f5d3SJohn Marino       left_over += len;
272*86d7f5d3SJohn Marino       if (left_over >= 64)
273*86d7f5d3SJohn Marino 	{
274*86d7f5d3SJohn Marino 	  md5_process_block (ctx->buffer, 64, ctx);
275*86d7f5d3SJohn Marino 	  left_over -= 64;
276*86d7f5d3SJohn Marino 	  memcpy (ctx->buffer, &ctx->buffer[64], left_over);
277*86d7f5d3SJohn Marino 	}
278*86d7f5d3SJohn Marino       ctx->buflen = left_over;
279*86d7f5d3SJohn Marino     }
280*86d7f5d3SJohn Marino }
281*86d7f5d3SJohn Marino 
282*86d7f5d3SJohn Marino 
283*86d7f5d3SJohn Marino /* These are the four functions used in the four steps of the MD5 algorithm
284*86d7f5d3SJohn Marino    and defined in the RFC 1321.  The first function is a little bit optimized
285*86d7f5d3SJohn Marino    (as found in Colin Plumbs public domain implementation).  */
286*86d7f5d3SJohn Marino /* #define FF(b, c, d) ((b & c) | (~b & d)) */
287*86d7f5d3SJohn Marino #define FF(b, c, d) (d ^ (b & (c ^ d)))
288*86d7f5d3SJohn Marino #define FG(b, c, d) FF (d, b, c)
289*86d7f5d3SJohn Marino #define FH(b, c, d) (b ^ c ^ d)
290*86d7f5d3SJohn Marino #define FI(b, c, d) (c ^ (b | ~d))
291*86d7f5d3SJohn Marino 
292*86d7f5d3SJohn Marino /* Process LEN bytes of BUFFER, accumulating context into CTX.
293*86d7f5d3SJohn Marino    It is assumed that LEN % 64 == 0.  */
294*86d7f5d3SJohn Marino 
295*86d7f5d3SJohn Marino void
md5_process_block(const void * buffer,size_t len,struct md5_ctx * ctx)296*86d7f5d3SJohn Marino md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
297*86d7f5d3SJohn Marino {
298*86d7f5d3SJohn Marino   md5_uint32 correct_words[16];
299*86d7f5d3SJohn Marino   const md5_uint32 *words = buffer;
300*86d7f5d3SJohn Marino   size_t nwords = len / sizeof (md5_uint32);
301*86d7f5d3SJohn Marino   const md5_uint32 *endp = words + nwords;
302*86d7f5d3SJohn Marino   md5_uint32 A = ctx->A;
303*86d7f5d3SJohn Marino   md5_uint32 B = ctx->B;
304*86d7f5d3SJohn Marino   md5_uint32 C = ctx->C;
305*86d7f5d3SJohn Marino   md5_uint32 D = ctx->D;
306*86d7f5d3SJohn Marino 
307*86d7f5d3SJohn Marino   /* First increment the byte count.  RFC 1321 specifies the possible
308*86d7f5d3SJohn Marino      length of the file up to 2^64 bits.  Here we only compute the
309*86d7f5d3SJohn Marino      number of bytes.  Do a double word increment.  */
310*86d7f5d3SJohn Marino   ctx->total[0] += len;
311*86d7f5d3SJohn Marino   if (ctx->total[0] < len)
312*86d7f5d3SJohn Marino     ++ctx->total[1];
313*86d7f5d3SJohn Marino 
314*86d7f5d3SJohn Marino   /* Process all bytes in the buffer with 64 bytes in each round of
315*86d7f5d3SJohn Marino      the loop.  */
316*86d7f5d3SJohn Marino   while (words < endp)
317*86d7f5d3SJohn Marino     {
318*86d7f5d3SJohn Marino       md5_uint32 *cwp = correct_words;
319*86d7f5d3SJohn Marino       md5_uint32 A_save = A;
320*86d7f5d3SJohn Marino       md5_uint32 B_save = B;
321*86d7f5d3SJohn Marino       md5_uint32 C_save = C;
322*86d7f5d3SJohn Marino       md5_uint32 D_save = D;
323*86d7f5d3SJohn Marino 
324*86d7f5d3SJohn Marino       /* First round: using the given function, the context and a constant
325*86d7f5d3SJohn Marino 	 the next context is computed.  Because the algorithms processing
326*86d7f5d3SJohn Marino 	 unit is a 32-bit word and it is determined to work on words in
327*86d7f5d3SJohn Marino 	 little endian byte order we perhaps have to change the byte order
328*86d7f5d3SJohn Marino 	 before the computation.  To reduce the work for the next steps
329*86d7f5d3SJohn Marino 	 we store the swapped words in the array CORRECT_WORDS.  */
330*86d7f5d3SJohn Marino 
331*86d7f5d3SJohn Marino #define OP(a, b, c, d, s, T)						\
332*86d7f5d3SJohn Marino       do								\
333*86d7f5d3SJohn Marino         {								\
334*86d7f5d3SJohn Marino 	  a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;		\
335*86d7f5d3SJohn Marino 	  ++words;							\
336*86d7f5d3SJohn Marino 	  CYCLIC (a, s);						\
337*86d7f5d3SJohn Marino 	  a += b;							\
338*86d7f5d3SJohn Marino         }								\
339*86d7f5d3SJohn Marino       while (0)
340*86d7f5d3SJohn Marino 
341*86d7f5d3SJohn Marino       /* It is unfortunate that C does not provide an operator for
342*86d7f5d3SJohn Marino 	 cyclic rotation.  Hope the C compiler is smart enough.  */
343*86d7f5d3SJohn Marino #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
344*86d7f5d3SJohn Marino 
345*86d7f5d3SJohn Marino       /* Before we start, one word to the strange constants.
346*86d7f5d3SJohn Marino 	 They are defined in RFC 1321 as
347*86d7f5d3SJohn Marino 
348*86d7f5d3SJohn Marino 	 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
349*86d7f5d3SJohn Marino 
350*86d7f5d3SJohn Marino 	 Here is an equivalent invocation using Perl:
351*86d7f5d3SJohn Marino 
352*86d7f5d3SJohn Marino 	 perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}'
353*86d7f5d3SJohn Marino        */
354*86d7f5d3SJohn Marino 
355*86d7f5d3SJohn Marino       /* Round 1.  */
356*86d7f5d3SJohn Marino       OP (A, B, C, D,  7, 0xd76aa478);
357*86d7f5d3SJohn Marino       OP (D, A, B, C, 12, 0xe8c7b756);
358*86d7f5d3SJohn Marino       OP (C, D, A, B, 17, 0x242070db);
359*86d7f5d3SJohn Marino       OP (B, C, D, A, 22, 0xc1bdceee);
360*86d7f5d3SJohn Marino       OP (A, B, C, D,  7, 0xf57c0faf);
361*86d7f5d3SJohn Marino       OP (D, A, B, C, 12, 0x4787c62a);
362*86d7f5d3SJohn Marino       OP (C, D, A, B, 17, 0xa8304613);
363*86d7f5d3SJohn Marino       OP (B, C, D, A, 22, 0xfd469501);
364*86d7f5d3SJohn Marino       OP (A, B, C, D,  7, 0x698098d8);
365*86d7f5d3SJohn Marino       OP (D, A, B, C, 12, 0x8b44f7af);
366*86d7f5d3SJohn Marino       OP (C, D, A, B, 17, 0xffff5bb1);
367*86d7f5d3SJohn Marino       OP (B, C, D, A, 22, 0x895cd7be);
368*86d7f5d3SJohn Marino       OP (A, B, C, D,  7, 0x6b901122);
369*86d7f5d3SJohn Marino       OP (D, A, B, C, 12, 0xfd987193);
370*86d7f5d3SJohn Marino       OP (C, D, A, B, 17, 0xa679438e);
371*86d7f5d3SJohn Marino       OP (B, C, D, A, 22, 0x49b40821);
372*86d7f5d3SJohn Marino 
373*86d7f5d3SJohn Marino       /* For the second to fourth round we have the possibly swapped words
374*86d7f5d3SJohn Marino 	 in CORRECT_WORDS.  Redefine the macro to take an additional first
375*86d7f5d3SJohn Marino 	 argument specifying the function to use.  */
376*86d7f5d3SJohn Marino #undef OP
377*86d7f5d3SJohn Marino #define OP(f, a, b, c, d, k, s, T)					\
378*86d7f5d3SJohn Marino       do								\
379*86d7f5d3SJohn Marino 	{								\
380*86d7f5d3SJohn Marino 	  a += f (b, c, d) + correct_words[k] + T;			\
381*86d7f5d3SJohn Marino 	  CYCLIC (a, s);						\
382*86d7f5d3SJohn Marino 	  a += b;							\
383*86d7f5d3SJohn Marino 	}								\
384*86d7f5d3SJohn Marino       while (0)
385*86d7f5d3SJohn Marino 
386*86d7f5d3SJohn Marino       /* Round 2.  */
387*86d7f5d3SJohn Marino       OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
388*86d7f5d3SJohn Marino       OP (FG, D, A, B, C,  6,  9, 0xc040b340);
389*86d7f5d3SJohn Marino       OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
390*86d7f5d3SJohn Marino       OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
391*86d7f5d3SJohn Marino       OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
392*86d7f5d3SJohn Marino       OP (FG, D, A, B, C, 10,  9, 0x02441453);
393*86d7f5d3SJohn Marino       OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
394*86d7f5d3SJohn Marino       OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
395*86d7f5d3SJohn Marino       OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
396*86d7f5d3SJohn Marino       OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
397*86d7f5d3SJohn Marino       OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
398*86d7f5d3SJohn Marino       OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
399*86d7f5d3SJohn Marino       OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
400*86d7f5d3SJohn Marino       OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
401*86d7f5d3SJohn Marino       OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
402*86d7f5d3SJohn Marino       OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
403*86d7f5d3SJohn Marino 
404*86d7f5d3SJohn Marino       /* Round 3.  */
405*86d7f5d3SJohn Marino       OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
406*86d7f5d3SJohn Marino       OP (FH, D, A, B, C,  8, 11, 0x8771f681);
407*86d7f5d3SJohn Marino       OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
408*86d7f5d3SJohn Marino       OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
409*86d7f5d3SJohn Marino       OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
410*86d7f5d3SJohn Marino       OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
411*86d7f5d3SJohn Marino       OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
412*86d7f5d3SJohn Marino       OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
413*86d7f5d3SJohn Marino       OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
414*86d7f5d3SJohn Marino       OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
415*86d7f5d3SJohn Marino       OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
416*86d7f5d3SJohn Marino       OP (FH, B, C, D, A,  6, 23, 0x04881d05);
417*86d7f5d3SJohn Marino       OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
418*86d7f5d3SJohn Marino       OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
419*86d7f5d3SJohn Marino       OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
420*86d7f5d3SJohn Marino       OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);
421*86d7f5d3SJohn Marino 
422*86d7f5d3SJohn Marino       /* Round 4.  */
423*86d7f5d3SJohn Marino       OP (FI, A, B, C, D,  0,  6, 0xf4292244);
424*86d7f5d3SJohn Marino       OP (FI, D, A, B, C,  7, 10, 0x432aff97);
425*86d7f5d3SJohn Marino       OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
426*86d7f5d3SJohn Marino       OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
427*86d7f5d3SJohn Marino       OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
428*86d7f5d3SJohn Marino       OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
429*86d7f5d3SJohn Marino       OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
430*86d7f5d3SJohn Marino       OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
431*86d7f5d3SJohn Marino       OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
432*86d7f5d3SJohn Marino       OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
433*86d7f5d3SJohn Marino       OP (FI, C, D, A, B,  6, 15, 0xa3014314);
434*86d7f5d3SJohn Marino       OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
435*86d7f5d3SJohn Marino       OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
436*86d7f5d3SJohn Marino       OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
437*86d7f5d3SJohn Marino       OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
438*86d7f5d3SJohn Marino       OP (FI, B, C, D, A,  9, 21, 0xeb86d391);
439*86d7f5d3SJohn Marino 
440*86d7f5d3SJohn Marino       /* Add the starting values of the context.  */
441*86d7f5d3SJohn Marino       A += A_save;
442*86d7f5d3SJohn Marino       B += B_save;
443*86d7f5d3SJohn Marino       C += C_save;
444*86d7f5d3SJohn Marino       D += D_save;
445*86d7f5d3SJohn Marino     }
446*86d7f5d3SJohn Marino 
447*86d7f5d3SJohn Marino   /* Put checksum in context given as argument.  */
448*86d7f5d3SJohn Marino   ctx->A = A;
449*86d7f5d3SJohn Marino   ctx->B = B;
450*86d7f5d3SJohn Marino   ctx->C = C;
451*86d7f5d3SJohn Marino   ctx->D = D;
452*86d7f5d3SJohn Marino }
453