12a6b7db3Sskrll /* md5.c - Functions to compute MD5 message digest of files or memory blocks
22a6b7db3Sskrll    according to the definition of MD5 in RFC 1321 from April 1992.
3*f22f0ef4Schristos    Copyright (C) 1995-2022 Free Software Foundation, Inc.
42a6b7db3Sskrll 
52a6b7db3Sskrll    NOTE: This source is derived from an old version taken from the GNU C
62a6b7db3Sskrll    Library (glibc).
72a6b7db3Sskrll 
82a6b7db3Sskrll    This program is free software; you can redistribute it and/or modify it
92a6b7db3Sskrll    under the terms of the GNU General Public License as published by the
102a6b7db3Sskrll    Free Software Foundation; either version 2, or (at your option) any
112a6b7db3Sskrll    later version.
122a6b7db3Sskrll 
132a6b7db3Sskrll    This program is distributed in the hope that it will be useful,
142a6b7db3Sskrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
152a6b7db3Sskrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
162a6b7db3Sskrll    GNU General Public License for more details.
172a6b7db3Sskrll 
182a6b7db3Sskrll    You should have received a copy of the GNU General Public License
192a6b7db3Sskrll    along with this program; if not, write to the Free Software Foundation,
202a6b7db3Sskrll    Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
212a6b7db3Sskrll 
222a6b7db3Sskrll /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
232a6b7db3Sskrll 
242a6b7db3Sskrll #ifdef HAVE_CONFIG_H
252a6b7db3Sskrll # include <config.h>
262a6b7db3Sskrll #endif
272a6b7db3Sskrll 
282a6b7db3Sskrll #include <sys/types.h>
292a6b7db3Sskrll 
302a6b7db3Sskrll #if STDC_HEADERS || defined _LIBC
312a6b7db3Sskrll # include <stdlib.h>
322a6b7db3Sskrll # include <string.h>
332a6b7db3Sskrll #else
342a6b7db3Sskrll # ifndef HAVE_MEMCPY
352a6b7db3Sskrll #  define memcpy(d, s, n) bcopy ((s), (d), (n))
362a6b7db3Sskrll # endif
372a6b7db3Sskrll #endif
382a6b7db3Sskrll 
392a6b7db3Sskrll #include "ansidecl.h"
402a6b7db3Sskrll #include "md5.h"
412a6b7db3Sskrll 
422a6b7db3Sskrll #ifdef _LIBC
432a6b7db3Sskrll # include <endian.h>
442a6b7db3Sskrll # if __BYTE_ORDER == __BIG_ENDIAN
452a6b7db3Sskrll #  define WORDS_BIGENDIAN 1
462a6b7db3Sskrll # endif
472a6b7db3Sskrll #endif
482a6b7db3Sskrll 
492a6b7db3Sskrll #ifdef WORDS_BIGENDIAN
502a6b7db3Sskrll # define SWAP(n)							\
512a6b7db3Sskrll     (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
522a6b7db3Sskrll #else
532a6b7db3Sskrll # define SWAP(n) (n)
542a6b7db3Sskrll #endif
552a6b7db3Sskrll 
562a6b7db3Sskrll 
572a6b7db3Sskrll /* This array contains the bytes used to pad the buffer to the next
582a6b7db3Sskrll    64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
592a6b7db3Sskrll static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
602a6b7db3Sskrll 
612a6b7db3Sskrll 
622a6b7db3Sskrll /* Initialize structure containing state of computation.
632a6b7db3Sskrll    (RFC 1321, 3.3: Step 3)  */
642a6b7db3Sskrll void
md5_init_ctx(struct md5_ctx * ctx)652a6b7db3Sskrll md5_init_ctx (struct md5_ctx *ctx)
662a6b7db3Sskrll {
672a6b7db3Sskrll   ctx->A = (md5_uint32) 0x67452301;
682a6b7db3Sskrll   ctx->B = (md5_uint32) 0xefcdab89;
692a6b7db3Sskrll   ctx->C = (md5_uint32) 0x98badcfe;
702a6b7db3Sskrll   ctx->D = (md5_uint32) 0x10325476;
712a6b7db3Sskrll 
722a6b7db3Sskrll   ctx->total[0] = ctx->total[1] = 0;
732a6b7db3Sskrll   ctx->buflen = 0;
742a6b7db3Sskrll }
752a6b7db3Sskrll 
762a6b7db3Sskrll /* Put result from CTX in first 16 bytes following RESBUF.  The result
772a6b7db3Sskrll    must be in little endian byte order.
782a6b7db3Sskrll 
7905caefcfSchristos    IMPORTANT: RESBUF may not be aligned as strongly as MD5_UNIT32 so we
8005caefcfSchristos    put things in a local (aligned) buffer first, then memcpy into RESBUF.  */
812a6b7db3Sskrll void *
md5_read_ctx(const struct md5_ctx * ctx,void * resbuf)822a6b7db3Sskrll md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
832a6b7db3Sskrll {
8405caefcfSchristos   md5_uint32 buffer[4];
8505caefcfSchristos 
8605caefcfSchristos   buffer[0] = SWAP (ctx->A);
8705caefcfSchristos   buffer[1] = SWAP (ctx->B);
8805caefcfSchristos   buffer[2] = SWAP (ctx->C);
8905caefcfSchristos   buffer[3] = SWAP (ctx->D);
9005caefcfSchristos 
9105caefcfSchristos   memcpy (resbuf, buffer, 16);
922a6b7db3Sskrll 
932a6b7db3Sskrll   return resbuf;
942a6b7db3Sskrll }
952a6b7db3Sskrll 
962a6b7db3Sskrll /* Process the remaining bytes in the internal buffer and the usual
972a6b7db3Sskrll    prolog according to the standard and write the result to RESBUF.
982a6b7db3Sskrll 
992a6b7db3Sskrll    IMPORTANT: On some systems it is required that RESBUF is correctly
1002a6b7db3Sskrll    aligned for a 32 bits value.  */
1012a6b7db3Sskrll void *
md5_finish_ctx(struct md5_ctx * ctx,void * resbuf)1022a6b7db3Sskrll md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
1032a6b7db3Sskrll {
1042a6b7db3Sskrll   /* Take yet unprocessed bytes into account.  */
1052a6b7db3Sskrll   md5_uint32 bytes = ctx->buflen;
10605caefcfSchristos   md5_uint32 swap_bytes;
1072a6b7db3Sskrll   size_t pad;
1082a6b7db3Sskrll 
1092a6b7db3Sskrll   /* Now count remaining bytes.  */
1102a6b7db3Sskrll   ctx->total[0] += bytes;
1112a6b7db3Sskrll   if (ctx->total[0] < bytes)
1122a6b7db3Sskrll     ++ctx->total[1];
1132a6b7db3Sskrll 
1142a6b7db3Sskrll   pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
1152a6b7db3Sskrll   memcpy (&ctx->buffer[bytes], fillbuf, pad);
1162a6b7db3Sskrll 
11705caefcfSchristos   /* Put the 64-bit file length in *bits* at the end of the buffer.
11805caefcfSchristos      Use memcpy to avoid aliasing problems.  On most systems, this
11905caefcfSchristos      will be optimized away to the same code.  */
12005caefcfSchristos   swap_bytes = SWAP (ctx->total[0] << 3);
12105caefcfSchristos   memcpy (&ctx->buffer[bytes + pad], &swap_bytes, sizeof (swap_bytes));
12205caefcfSchristos   swap_bytes = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
12305caefcfSchristos   memcpy (&ctx->buffer[bytes + pad + 4], &swap_bytes, sizeof (swap_bytes));
1242a6b7db3Sskrll 
1252a6b7db3Sskrll   /* Process last bytes.  */
1262a6b7db3Sskrll   md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
1272a6b7db3Sskrll 
1282a6b7db3Sskrll   return md5_read_ctx (ctx, resbuf);
1292a6b7db3Sskrll }
1302a6b7db3Sskrll 
1312a6b7db3Sskrll /* Compute MD5 message digest for bytes read from STREAM.  The
1322a6b7db3Sskrll    resulting message digest number will be written into the 16 bytes
1332a6b7db3Sskrll    beginning at RESBLOCK.  */
1342a6b7db3Sskrll int
md5_stream(FILE * stream,void * resblock)1352a6b7db3Sskrll md5_stream (FILE *stream, void *resblock)
1362a6b7db3Sskrll {
1372a6b7db3Sskrll   /* Important: BLOCKSIZE must be a multiple of 64.  */
1382a6b7db3Sskrll #define BLOCKSIZE 4096
1392a6b7db3Sskrll   struct md5_ctx ctx;
1402a6b7db3Sskrll   char buffer[BLOCKSIZE + 72];
1412a6b7db3Sskrll   size_t sum;
1422a6b7db3Sskrll 
1432a6b7db3Sskrll   /* Initialize the computation context.  */
1442a6b7db3Sskrll   md5_init_ctx (&ctx);
1452a6b7db3Sskrll 
1462a6b7db3Sskrll   /* Iterate over full file contents.  */
1472a6b7db3Sskrll   while (1)
1482a6b7db3Sskrll     {
1492a6b7db3Sskrll       /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
1502a6b7db3Sskrll 	 computation function processes the whole buffer so that with the
1512a6b7db3Sskrll 	 next round of the loop another block can be read.  */
1522a6b7db3Sskrll       size_t n;
1532a6b7db3Sskrll       sum = 0;
1542a6b7db3Sskrll 
1552a6b7db3Sskrll       /* Read block.  Take care for partial reads.  */
1562a6b7db3Sskrll       do
1572a6b7db3Sskrll 	{
1582a6b7db3Sskrll 	  n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
1592a6b7db3Sskrll 
1602a6b7db3Sskrll 	  sum += n;
1612a6b7db3Sskrll 	}
1622a6b7db3Sskrll       while (sum < BLOCKSIZE && n != 0);
1632a6b7db3Sskrll       if (n == 0 && ferror (stream))
1642a6b7db3Sskrll         return 1;
1652a6b7db3Sskrll 
1662a6b7db3Sskrll       /* If end of file is reached, end the loop.  */
1672a6b7db3Sskrll       if (n == 0)
1682a6b7db3Sskrll 	break;
1692a6b7db3Sskrll 
1702a6b7db3Sskrll       /* Process buffer with BLOCKSIZE bytes.  Note that
1712a6b7db3Sskrll 			BLOCKSIZE % 64 == 0
1722a6b7db3Sskrll        */
1732a6b7db3Sskrll       md5_process_block (buffer, BLOCKSIZE, &ctx);
1742a6b7db3Sskrll     }
1752a6b7db3Sskrll 
1762a6b7db3Sskrll   /* Add the last bytes if necessary.  */
1772a6b7db3Sskrll   if (sum > 0)
1782a6b7db3Sskrll     md5_process_bytes (buffer, sum, &ctx);
1792a6b7db3Sskrll 
1802a6b7db3Sskrll   /* Construct result in desired memory.  */
1812a6b7db3Sskrll   md5_finish_ctx (&ctx, resblock);
1822a6b7db3Sskrll   return 0;
1832a6b7db3Sskrll }
1842a6b7db3Sskrll 
1852a6b7db3Sskrll /* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
1862a6b7db3Sskrll    result is always in little endian byte order, so that a byte-wise
1872a6b7db3Sskrll    output yields to the wanted ASCII representation of the message
1882a6b7db3Sskrll    digest.  */
1892a6b7db3Sskrll void *
md5_buffer(const char * buffer,size_t len,void * resblock)1902a6b7db3Sskrll md5_buffer (const char *buffer, size_t len, void *resblock)
1912a6b7db3Sskrll {
1922a6b7db3Sskrll   struct md5_ctx ctx;
1932a6b7db3Sskrll 
1942a6b7db3Sskrll   /* Initialize the computation context.  */
1952a6b7db3Sskrll   md5_init_ctx (&ctx);
1962a6b7db3Sskrll 
1972a6b7db3Sskrll   /* Process whole buffer but last len % 64 bytes.  */
1982a6b7db3Sskrll   md5_process_bytes (buffer, len, &ctx);
1992a6b7db3Sskrll 
2002a6b7db3Sskrll   /* Put result in desired memory area.  */
2012a6b7db3Sskrll   return md5_finish_ctx (&ctx, resblock);
2022a6b7db3Sskrll }
2032a6b7db3Sskrll 
2042a6b7db3Sskrll 
2052a6b7db3Sskrll void
md5_process_bytes(const void * buffer,size_t len,struct md5_ctx * ctx)2062a6b7db3Sskrll md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
2072a6b7db3Sskrll {
2082a6b7db3Sskrll   /* When we already have some bits in our internal buffer concatenate
2092a6b7db3Sskrll      both inputs first.  */
2102a6b7db3Sskrll   if (ctx->buflen != 0)
2112a6b7db3Sskrll     {
2122a6b7db3Sskrll       size_t left_over = ctx->buflen;
2132a6b7db3Sskrll       size_t add = 128 - left_over > len ? len : 128 - left_over;
2142a6b7db3Sskrll 
2152a6b7db3Sskrll       memcpy (&ctx->buffer[left_over], buffer, add);
2162a6b7db3Sskrll       ctx->buflen += add;
2172a6b7db3Sskrll 
2182a6b7db3Sskrll       if (left_over + add > 64)
2192a6b7db3Sskrll 	{
2202a6b7db3Sskrll 	  md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx);
2212a6b7db3Sskrll 	  /* The regions in the following copy operation cannot overlap.  */
2222a6b7db3Sskrll 	  memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
2232a6b7db3Sskrll 		  (left_over + add) & 63);
2242a6b7db3Sskrll 	  ctx->buflen = (left_over + add) & 63;
2252a6b7db3Sskrll 	}
2262a6b7db3Sskrll 
2272a6b7db3Sskrll       buffer = (const void *) ((const char *) buffer + add);
2282a6b7db3Sskrll       len -= add;
2292a6b7db3Sskrll     }
2302a6b7db3Sskrll 
2312a6b7db3Sskrll   /* Process available complete blocks.  */
2322a6b7db3Sskrll   if (len > 64)
2332a6b7db3Sskrll     {
234fa2c2dd3Schristos #if !_STRING_ARCH_unaligned || defined UBSAN_BOOTSTRAP
2352a6b7db3Sskrll /* To check alignment gcc has an appropriate operator.  Other
2362a6b7db3Sskrll    compilers don't.  */
2372a6b7db3Sskrll # if __GNUC__ >= 2
2382a6b7db3Sskrll #  define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
2392a6b7db3Sskrll # else
2402a6b7db3Sskrll #  define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
2412a6b7db3Sskrll # endif
2422a6b7db3Sskrll       if (UNALIGNED_P (buffer))
2432a6b7db3Sskrll         while (len > 64)
2442a6b7db3Sskrll           {
2452a6b7db3Sskrll 	    memcpy (ctx->buffer, buffer, 64);
2462a6b7db3Sskrll             md5_process_block (ctx->buffer, 64, ctx);
2472a6b7db3Sskrll             buffer = (const char *) buffer + 64;
2482a6b7db3Sskrll             len -= 64;
2492a6b7db3Sskrll           }
2502a6b7db3Sskrll       else
2512a6b7db3Sskrll #endif
25205caefcfSchristos 	{
2532a6b7db3Sskrll 	  md5_process_block (buffer, len & ~63, ctx);
2542a6b7db3Sskrll 	  buffer = (const void *) ((const char *) buffer + (len & ~63));
2552a6b7db3Sskrll 	  len &= 63;
2562a6b7db3Sskrll 	}
25705caefcfSchristos     }
2582a6b7db3Sskrll 
2592a6b7db3Sskrll   /* Move remaining bytes in internal buffer.  */
2602a6b7db3Sskrll   if (len > 0)
2612a6b7db3Sskrll     {
2622a6b7db3Sskrll       memcpy (ctx->buffer, buffer, len);
2632a6b7db3Sskrll       ctx->buflen = len;
2642a6b7db3Sskrll     }
2652a6b7db3Sskrll }
2662a6b7db3Sskrll 
2672a6b7db3Sskrll 
2682a6b7db3Sskrll /* These are the four functions used in the four steps of the MD5 algorithm
2692a6b7db3Sskrll    and defined in the RFC 1321.  The first function is a little bit optimized
2702a6b7db3Sskrll    (as found in Colin Plumbs public domain implementation).  */
2712a6b7db3Sskrll /* #define FF(b, c, d) ((b & c) | (~b & d)) */
2722a6b7db3Sskrll #define FF(b, c, d) (d ^ (b & (c ^ d)))
2732a6b7db3Sskrll #define FG(b, c, d) FF (d, b, c)
2742a6b7db3Sskrll #define FH(b, c, d) (b ^ c ^ d)
2752a6b7db3Sskrll #define FI(b, c, d) (c ^ (b | ~d))
2762a6b7db3Sskrll 
2772a6b7db3Sskrll /* Process LEN bytes of BUFFER, accumulating context into CTX.
2782a6b7db3Sskrll    It is assumed that LEN % 64 == 0.  */
2792a6b7db3Sskrll 
2802a6b7db3Sskrll void
md5_process_block(const void * buffer,size_t len,struct md5_ctx * ctx)2812a6b7db3Sskrll md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
2822a6b7db3Sskrll {
2832a6b7db3Sskrll   md5_uint32 correct_words[16];
2842a6b7db3Sskrll   const md5_uint32 *words = (const md5_uint32 *) buffer;
2852a6b7db3Sskrll   size_t nwords = len / sizeof (md5_uint32);
2862a6b7db3Sskrll   const md5_uint32 *endp = words + nwords;
2872a6b7db3Sskrll   md5_uint32 A = ctx->A;
2882a6b7db3Sskrll   md5_uint32 B = ctx->B;
2892a6b7db3Sskrll   md5_uint32 C = ctx->C;
2902a6b7db3Sskrll   md5_uint32 D = ctx->D;
2912a6b7db3Sskrll 
2922a6b7db3Sskrll   /* First increment the byte count.  RFC 1321 specifies the possible
2932a6b7db3Sskrll      length of the file up to 2^64 bits.  Here we only compute the
2942a6b7db3Sskrll      number of bytes.  Do a double word increment.  */
2952a6b7db3Sskrll   ctx->total[0] += len;
2965ba6b03cSchristos   ctx->total[1] += ((len >> 31) >> 1) + (ctx->total[0] < len);
2972a6b7db3Sskrll 
2982a6b7db3Sskrll   /* Process all bytes in the buffer with 64 bytes in each round of
2992a6b7db3Sskrll      the loop.  */
3002a6b7db3Sskrll   while (words < endp)
3012a6b7db3Sskrll     {
3022a6b7db3Sskrll       md5_uint32 *cwp = correct_words;
3032a6b7db3Sskrll       md5_uint32 A_save = A;
3042a6b7db3Sskrll       md5_uint32 B_save = B;
3052a6b7db3Sskrll       md5_uint32 C_save = C;
3062a6b7db3Sskrll       md5_uint32 D_save = D;
3072a6b7db3Sskrll 
3082a6b7db3Sskrll       /* First round: using the given function, the context and a constant
3092a6b7db3Sskrll 	 the next context is computed.  Because the algorithms processing
3102a6b7db3Sskrll 	 unit is a 32-bit word and it is determined to work on words in
3112a6b7db3Sskrll 	 little endian byte order we perhaps have to change the byte order
3122a6b7db3Sskrll 	 before the computation.  To reduce the work for the next steps
3132a6b7db3Sskrll 	 we store the swapped words in the array CORRECT_WORDS.  */
3142a6b7db3Sskrll 
3152a6b7db3Sskrll #define OP(a, b, c, d, s, T)						\
3162a6b7db3Sskrll       do								\
3172a6b7db3Sskrll         {								\
3182a6b7db3Sskrll 	  a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;		\
3192a6b7db3Sskrll 	  ++words;							\
3202a6b7db3Sskrll 	  CYCLIC (a, s);						\
3212a6b7db3Sskrll 	  a += b;							\
3222a6b7db3Sskrll         }								\
3232a6b7db3Sskrll       while (0)
3242a6b7db3Sskrll 
3252a6b7db3Sskrll       /* It is unfortunate that C does not provide an operator for
3262a6b7db3Sskrll 	 cyclic rotation.  Hope the C compiler is smart enough.  */
3272a6b7db3Sskrll #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
3282a6b7db3Sskrll 
3292a6b7db3Sskrll       /* Before we start, one word to the strange constants.
3302a6b7db3Sskrll 	 They are defined in RFC 1321 as
3312a6b7db3Sskrll 
3322a6b7db3Sskrll 	 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
3332a6b7db3Sskrll        */
3342a6b7db3Sskrll 
3352a6b7db3Sskrll       /* Round 1.  */
3362a6b7db3Sskrll       OP (A, B, C, D,  7, (md5_uint32) 0xd76aa478);
3372a6b7db3Sskrll       OP (D, A, B, C, 12, (md5_uint32) 0xe8c7b756);
3382a6b7db3Sskrll       OP (C, D, A, B, 17, (md5_uint32) 0x242070db);
3392a6b7db3Sskrll       OP (B, C, D, A, 22, (md5_uint32) 0xc1bdceee);
3402a6b7db3Sskrll       OP (A, B, C, D,  7, (md5_uint32) 0xf57c0faf);
3412a6b7db3Sskrll       OP (D, A, B, C, 12, (md5_uint32) 0x4787c62a);
3422a6b7db3Sskrll       OP (C, D, A, B, 17, (md5_uint32) 0xa8304613);
3432a6b7db3Sskrll       OP (B, C, D, A, 22, (md5_uint32) 0xfd469501);
3442a6b7db3Sskrll       OP (A, B, C, D,  7, (md5_uint32) 0x698098d8);
3452a6b7db3Sskrll       OP (D, A, B, C, 12, (md5_uint32) 0x8b44f7af);
3462a6b7db3Sskrll       OP (C, D, A, B, 17, (md5_uint32) 0xffff5bb1);
3472a6b7db3Sskrll       OP (B, C, D, A, 22, (md5_uint32) 0x895cd7be);
3482a6b7db3Sskrll       OP (A, B, C, D,  7, (md5_uint32) 0x6b901122);
3492a6b7db3Sskrll       OP (D, A, B, C, 12, (md5_uint32) 0xfd987193);
3502a6b7db3Sskrll       OP (C, D, A, B, 17, (md5_uint32) 0xa679438e);
3512a6b7db3Sskrll       OP (B, C, D, A, 22, (md5_uint32) 0x49b40821);
3522a6b7db3Sskrll 
3532a6b7db3Sskrll       /* For the second to fourth round we have the possibly swapped words
3542a6b7db3Sskrll 	 in CORRECT_WORDS.  Redefine the macro to take an additional first
3552a6b7db3Sskrll 	 argument specifying the function to use.  */
3562a6b7db3Sskrll #undef OP
3572a6b7db3Sskrll #define OP(a, b, c, d, k, s, T)						\
3582a6b7db3Sskrll       do 								\
3592a6b7db3Sskrll 	{								\
3602a6b7db3Sskrll 	  a += FX (b, c, d) + correct_words[k] + T;			\
3612a6b7db3Sskrll 	  CYCLIC (a, s);						\
3622a6b7db3Sskrll 	  a += b;							\
3632a6b7db3Sskrll 	}								\
3642a6b7db3Sskrll       while (0)
3652a6b7db3Sskrll 
3662a6b7db3Sskrll #define FX(b, c, d) FG (b, c, d)
3672a6b7db3Sskrll 
3682a6b7db3Sskrll       /* Round 2.  */
3692a6b7db3Sskrll       OP (A, B, C, D,  1,  5, (md5_uint32) 0xf61e2562);
3702a6b7db3Sskrll       OP (D, A, B, C,  6,  9, (md5_uint32) 0xc040b340);
3712a6b7db3Sskrll       OP (C, D, A, B, 11, 14, (md5_uint32) 0x265e5a51);
3722a6b7db3Sskrll       OP (B, C, D, A,  0, 20, (md5_uint32) 0xe9b6c7aa);
3732a6b7db3Sskrll       OP (A, B, C, D,  5,  5, (md5_uint32) 0xd62f105d);
3742a6b7db3Sskrll       OP (D, A, B, C, 10,  9, (md5_uint32) 0x02441453);
3752a6b7db3Sskrll       OP (C, D, A, B, 15, 14, (md5_uint32) 0xd8a1e681);
3762a6b7db3Sskrll       OP (B, C, D, A,  4, 20, (md5_uint32) 0xe7d3fbc8);
3772a6b7db3Sskrll       OP (A, B, C, D,  9,  5, (md5_uint32) 0x21e1cde6);
3782a6b7db3Sskrll       OP (D, A, B, C, 14,  9, (md5_uint32) 0xc33707d6);
3792a6b7db3Sskrll       OP (C, D, A, B,  3, 14, (md5_uint32) 0xf4d50d87);
3802a6b7db3Sskrll       OP (B, C, D, A,  8, 20, (md5_uint32) 0x455a14ed);
3812a6b7db3Sskrll       OP (A, B, C, D, 13,  5, (md5_uint32) 0xa9e3e905);
3822a6b7db3Sskrll       OP (D, A, B, C,  2,  9, (md5_uint32) 0xfcefa3f8);
3832a6b7db3Sskrll       OP (C, D, A, B,  7, 14, (md5_uint32) 0x676f02d9);
3842a6b7db3Sskrll       OP (B, C, D, A, 12, 20, (md5_uint32) 0x8d2a4c8a);
3852a6b7db3Sskrll 
3862a6b7db3Sskrll #undef FX
3872a6b7db3Sskrll #define FX(b, c, d) FH (b, c, d)
3882a6b7db3Sskrll 
3892a6b7db3Sskrll       /* Round 3.  */
3902a6b7db3Sskrll       OP (A, B, C, D,  5,  4, (md5_uint32) 0xfffa3942);
3912a6b7db3Sskrll       OP (D, A, B, C,  8, 11, (md5_uint32) 0x8771f681);
3922a6b7db3Sskrll       OP (C, D, A, B, 11, 16, (md5_uint32) 0x6d9d6122);
3932a6b7db3Sskrll       OP (B, C, D, A, 14, 23, (md5_uint32) 0xfde5380c);
3942a6b7db3Sskrll       OP (A, B, C, D,  1,  4, (md5_uint32) 0xa4beea44);
3952a6b7db3Sskrll       OP (D, A, B, C,  4, 11, (md5_uint32) 0x4bdecfa9);
3962a6b7db3Sskrll       OP (C, D, A, B,  7, 16, (md5_uint32) 0xf6bb4b60);
3972a6b7db3Sskrll       OP (B, C, D, A, 10, 23, (md5_uint32) 0xbebfbc70);
3982a6b7db3Sskrll       OP (A, B, C, D, 13,  4, (md5_uint32) 0x289b7ec6);
3992a6b7db3Sskrll       OP (D, A, B, C,  0, 11, (md5_uint32) 0xeaa127fa);
4002a6b7db3Sskrll       OP (C, D, A, B,  3, 16, (md5_uint32) 0xd4ef3085);
4012a6b7db3Sskrll       OP (B, C, D, A,  6, 23, (md5_uint32) 0x04881d05);
4022a6b7db3Sskrll       OP (A, B, C, D,  9,  4, (md5_uint32) 0xd9d4d039);
4032a6b7db3Sskrll       OP (D, A, B, C, 12, 11, (md5_uint32) 0xe6db99e5);
4042a6b7db3Sskrll       OP (C, D, A, B, 15, 16, (md5_uint32) 0x1fa27cf8);
4052a6b7db3Sskrll       OP (B, C, D, A,  2, 23, (md5_uint32) 0xc4ac5665);
4062a6b7db3Sskrll 
4072a6b7db3Sskrll #undef FX
4082a6b7db3Sskrll #define FX(b, c, d) FI (b, c, d)
4092a6b7db3Sskrll 
4102a6b7db3Sskrll       /* Round 4.  */
4112a6b7db3Sskrll       OP (A, B, C, D,  0,  6, (md5_uint32) 0xf4292244);
4122a6b7db3Sskrll       OP (D, A, B, C,  7, 10, (md5_uint32) 0x432aff97);
4132a6b7db3Sskrll       OP (C, D, A, B, 14, 15, (md5_uint32) 0xab9423a7);
4142a6b7db3Sskrll       OP (B, C, D, A,  5, 21, (md5_uint32) 0xfc93a039);
4152a6b7db3Sskrll       OP (A, B, C, D, 12,  6, (md5_uint32) 0x655b59c3);
4162a6b7db3Sskrll       OP (D, A, B, C,  3, 10, (md5_uint32) 0x8f0ccc92);
4172a6b7db3Sskrll       OP (C, D, A, B, 10, 15, (md5_uint32) 0xffeff47d);
4182a6b7db3Sskrll       OP (B, C, D, A,  1, 21, (md5_uint32) 0x85845dd1);
4192a6b7db3Sskrll       OP (A, B, C, D,  8,  6, (md5_uint32) 0x6fa87e4f);
4202a6b7db3Sskrll       OP (D, A, B, C, 15, 10, (md5_uint32) 0xfe2ce6e0);
4212a6b7db3Sskrll       OP (C, D, A, B,  6, 15, (md5_uint32) 0xa3014314);
4222a6b7db3Sskrll       OP (B, C, D, A, 13, 21, (md5_uint32) 0x4e0811a1);
4232a6b7db3Sskrll       OP (A, B, C, D,  4,  6, (md5_uint32) 0xf7537e82);
4242a6b7db3Sskrll       OP (D, A, B, C, 11, 10, (md5_uint32) 0xbd3af235);
4252a6b7db3Sskrll       OP (C, D, A, B,  2, 15, (md5_uint32) 0x2ad7d2bb);
4262a6b7db3Sskrll       OP (B, C, D, A,  9, 21, (md5_uint32) 0xeb86d391);
4272a6b7db3Sskrll 
4282a6b7db3Sskrll       /* Add the starting values of the context.  */
4292a6b7db3Sskrll       A += A_save;
4302a6b7db3Sskrll       B += B_save;
4312a6b7db3Sskrll       C += C_save;
4322a6b7db3Sskrll       D += D_save;
4332a6b7db3Sskrll     }
4342a6b7db3Sskrll 
4352a6b7db3Sskrll   /* Put checksum in context given as argument.  */
4362a6b7db3Sskrll   ctx->A = A;
4372a6b7db3Sskrll   ctx->B = B;
4382a6b7db3Sskrll   ctx->C = C;
4392a6b7db3Sskrll   ctx->D = D;
4402a6b7db3Sskrll }
441