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