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