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