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