18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * MD4 hash implementation
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define	MD4_BLOCK_LENGTH		64
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define	MD4_DIGEST_LENGTH		16
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct MD4Context {
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u32 state[4];			/* state */
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u64 count;			/* number of bits, mod 2^64 */
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 buffer[MD4_BLOCK_LENGTH];	/* input buffer */
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} MD4_CTX;
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void MD4Init(MD4_CTX *ctx);
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len);
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx);
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4_CTX ctx;
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt	if (TEST_FAIL())
35d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt		return -1;
36d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4Init(&ctx);
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < num_elem; i++)
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MD4Update(&ctx, addr[i], len[i]);
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4Final(mac, &ctx);
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* ===== start - public domain MD4 implementation ===== */
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*	$OpenBSD: md4.c,v 1.7 2005/08/08 08:05:35 espie Exp $	*/
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This code implements the MD4 message-digest algorithm.
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The algorithm is due to Ron Rivest.	This code was
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * written by Colin Plumb in 1993, no copyright is claimed.
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This code is in the public domain; do with it what you wish.
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Todd C. Miller modified the MD5 code to do MD4 based on RFC 1186.
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Equivalent code is available from RSA Data Security, Inc.
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This code has been tested against that, and is equivalent,
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * except that you don't need to include two pages of legalese
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * with every copy.
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * To compute the message digest of a chunk of bytes, declare an
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * MD4Context structure, pass it to MD4Init, call MD4Update as
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * needed on buffers full of bytes, and then call MD4Final, which
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will fill a supplied 16-byte array with the digest.
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define	MD4_DIGEST_STRING_LENGTH	(MD4_DIGEST_LENGTH * 2 + 1)
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtMD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH]);
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define PUT_64BIT_LE(cp, value) do {					\
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(cp)[7] = (value) >> 56;					\
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(cp)[6] = (value) >> 48;					\
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(cp)[5] = (value) >> 40;					\
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(cp)[4] = (value) >> 32;					\
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(cp)[3] = (value) >> 24;					\
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(cp)[2] = (value) >> 16;					\
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(cp)[1] = (value) >> 8;						\
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(cp)[0] = (value); } while (0)
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define PUT_32BIT_LE(cp, value) do {					\
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(cp)[3] = (value) >> 24;					\
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(cp)[2] = (value) >> 16;					\
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(cp)[1] = (value) >> 8;						\
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(cp)[0] = (value); } while (0)
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 PADDING[MD4_BLOCK_LENGTH] = {
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Start MD4 accumulation.
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Set bit count to 0 and buffer to mysterious initialization constants.
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void MD4Init(MD4_CTX *ctx)
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ctx->count = 0;
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ctx->state[0] = 0x67452301;
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ctx->state[1] = 0xefcdab89;
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ctx->state[2] = 0x98badcfe;
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ctx->state[3] = 0x10325476;
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Update context to reflect the concatenation of another buffer full
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * of bytes.
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len)
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t have, need;
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Check how many bytes we already have and how many more we need. */
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	have = (size_t)((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	need = MD4_BLOCK_LENGTH - have;
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Update bitcount */
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ctx->count += (u64)len << 3;
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len >= need) {
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (have != 0) {
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(ctx->buffer + have, input, need);
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MD4Transform(ctx->state, ctx->buffer);
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			input += need;
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			len -= need;
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			have = 0;
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Process data in MD4_BLOCK_LENGTH-byte chunks. */
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (len >= MD4_BLOCK_LENGTH) {
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MD4Transform(ctx->state, input);
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			input += MD4_BLOCK_LENGTH;
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			len -= MD4_BLOCK_LENGTH;
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Handle any remaining bytes of data. */
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len != 0)
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(ctx->buffer + have, input, len);
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Pad pad to 64-byte boundary with the bit pattern
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1 0* (64-bit count of bits processed, MSB-first)
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void MD4Pad(MD4_CTX *ctx)
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 count[8];
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t padlen;
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Convert count to 8 bytes in little endian order. */
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	PUT_64BIT_LE(count, ctx->count);
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Pad out to 56 mod 64. */
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	padlen = MD4_BLOCK_LENGTH -
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    ((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (padlen < 1 + 8)
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		padlen += MD4_BLOCK_LENGTH;
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4Update(ctx, count, 8);
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Final wrapup--call MD4Pad, fill in digest and zero out ctx.
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx)
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4Pad(ctx);
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (digest != NULL) {
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (i = 0; i < 4; i++)
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(ctx, 0, sizeof(*ctx));
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* The three core functions - F1 is optimized somewhat */
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* #define F1(x, y, z) (x & y | ~x & z) */
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define F1(x, y, z) (z ^ (x & (y ^ z)))
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define F2(x, y, z) ((x & y) | (x & z) | (y & z))
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define F3(x, y, z) (x ^ y ^ z)
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* This is the central step in the MD4 algorithm. */
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define MD4STEP(f, w, x, y, z, data, s) \
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s) )
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The core of the MD4 algorithm, this alters an existing MD4 hash to
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * reflect the addition of 16 longwords of new data.  MD4Update blocks
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the data and converts bytes into longwords for this routine.
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtMD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH])
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u32 a, b, c, d, in[MD4_BLOCK_LENGTH / 4];
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if BYTE_ORDER == LITTLE_ENDIAN
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(in, block, sizeof(in));
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (a = 0; a < MD4_BLOCK_LENGTH / 4; a++) {
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		in[a] = (u32)(
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (u32)(block[a * 4 + 0]) |
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (u32)(block[a * 4 + 1]) <<  8 |
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (u32)(block[a * 4 + 2]) << 16 |
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (u32)(block[a * 4 + 3]) << 24);
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	a = state[0];
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	b = state[1];
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	c = state[2];
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	d = state[3];
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, a, b, c, d, in[ 0],  3);
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, d, a, b, c, in[ 1],  7);
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, c, d, a, b, in[ 2], 11);
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, b, c, d, a, in[ 3], 19);
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, a, b, c, d, in[ 4],  3);
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, d, a, b, c, in[ 5],  7);
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, c, d, a, b, in[ 6], 11);
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, b, c, d, a, in[ 7], 19);
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, a, b, c, d, in[ 8],  3);
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, d, a, b, c, in[ 9],  7);
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, c, d, a, b, in[10], 11);
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, b, c, d, a, in[11], 19);
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, a, b, c, d, in[12],  3);
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, d, a, b, c, in[13],  7);
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, c, d, a, b, in[14], 11);
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F1, b, c, d, a, in[15], 19);
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, a, b, c, d, in[ 0] + 0x5a827999,  3);
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, d, a, b, c, in[ 4] + 0x5a827999,  5);
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, c, d, a, b, in[ 8] + 0x5a827999,  9);
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, b, c, d, a, in[12] + 0x5a827999, 13);
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, a, b, c, d, in[ 1] + 0x5a827999,  3);
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, d, a, b, c, in[ 5] + 0x5a827999,  5);
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, c, d, a, b, in[ 9] + 0x5a827999,  9);
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, b, c, d, a, in[13] + 0x5a827999, 13);
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, a, b, c, d, in[ 2] + 0x5a827999,  3);
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, d, a, b, c, in[ 6] + 0x5a827999,  5);
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, c, d, a, b, in[10] + 0x5a827999,  9);
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, b, c, d, a, in[14] + 0x5a827999, 13);
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, a, b, c, d, in[ 3] + 0x5a827999,  3);
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, d, a, b, c, in[ 7] + 0x5a827999,  5);
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, c, d, a, b, in[11] + 0x5a827999,  9);
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F2, b, c, d, a, in[15] + 0x5a827999, 13);
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, a, b, c, d, in[ 0] + 0x6ed9eba1,  3);
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, d, a, b, c, in[ 8] + 0x6ed9eba1,  9);
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, c, d, a, b, in[ 4] + 0x6ed9eba1, 11);
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, b, c, d, a, in[12] + 0x6ed9eba1, 15);
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, a, b, c, d, in[ 2] + 0x6ed9eba1,  3);
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, d, a, b, c, in[10] + 0x6ed9eba1,  9);
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, c, d, a, b, in[ 6] + 0x6ed9eba1, 11);
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, b, c, d, a, in[14] + 0x6ed9eba1, 15);
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, a, b, c, d, in[ 1] + 0x6ed9eba1,  3);
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, d, a, b, c, in[ 9] + 0x6ed9eba1,  9);
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, c, d, a, b, in[ 5] + 0x6ed9eba1, 11);
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, b, c, d, a, in[13] + 0x6ed9eba1, 15);
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, a, b, c, d, in[ 3] + 0x6ed9eba1,  3);
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, d, a, b, c, in[11] + 0x6ed9eba1,  9);
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, c, d, a, b, in[ 7] + 0x6ed9eba1, 11);
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	MD4STEP(F3, b, c, d, a, in[15] + 0x6ed9eba1, 15);
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	state[0] += a;
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	state[1] += b;
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	state[2] += c;
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	state[3] += d;
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* ===== end - public domain MD4 implementation ===== */
276