1845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/*
2845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * MD4 hash implementation
3845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
4845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
5845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This program is free software; you can redistribute it and/or modify
6845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * it under the terms of the GNU General Public License version 2 as
7845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * published by the Free Software Foundation.
8845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
9845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Alternatively, this software may be distributed under the terms of BSD
10845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * license.
11845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
12845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * See README and COPYING for more details.
13845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
14845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
15845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "includes.h"
16845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
17845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "common.h"
18845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "crypto.h"
19845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
20845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
21845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef INTERNAL_MD4
22845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
23845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define	MD4_BLOCK_LENGTH		64
24845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define	MD4_DIGEST_LENGTH		16
25845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
26845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projecttypedef struct MD4Context {
27845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	u32 state[4];			/* state */
28845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	u64 count;			/* number of bits, mod 2^64 */
29845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	u8 buffer[MD4_BLOCK_LENGTH];	/* input buffer */
30845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project} MD4_CTX;
31845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
32845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
33845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void MD4Init(MD4_CTX *ctx);
34845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len);
35845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx);
36845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
37845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
38845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
39845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
40845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4_CTX ctx;
41845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	size_t i;
42845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
43845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4Init(&ctx);
44845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < num_elem; i++)
45845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		MD4Update(&ctx, addr[i], len[i]);
46845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4Final(mac, &ctx);
47845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
48845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
49845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
50845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* ===== start - public domain MD4 implementation ===== */
51845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/*	$OpenBSD: md4.c,v 1.7 2005/08/08 08:05:35 espie Exp $	*/
52845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
53845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/*
54845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This code implements the MD4 message-digest algorithm.
55845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * The algorithm is due to Ron Rivest.	This code was
56845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * written by Colin Plumb in 1993, no copyright is claimed.
57845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This code is in the public domain; do with it what you wish.
58845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Todd C. Miller modified the MD5 code to do MD4 based on RFC 1186.
59845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
60845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Equivalent code is available from RSA Data Security, Inc.
61845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This code has been tested against that, and is equivalent,
62845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * except that you don't need to include two pages of legalese
63845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * with every copy.
64845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
65845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * To compute the message digest of a chunk of bytes, declare an
66845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * MD4Context structure, pass it to MD4Init, call MD4Update as
67845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * needed on buffers full of bytes, and then call MD4Final, which
68845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * will fill a supplied 16-byte array with the digest.
69845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
70845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
71845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define	MD4_DIGEST_STRING_LENGTH	(MD4_DIGEST_LENGTH * 2 + 1)
72845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
73845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
74845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void
75845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectMD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH]);
76845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
77845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define PUT_64BIT_LE(cp, value) do {					\
78845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	(cp)[7] = (value) >> 56;					\
79845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	(cp)[6] = (value) >> 48;					\
80845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	(cp)[5] = (value) >> 40;					\
81845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	(cp)[4] = (value) >> 32;					\
82845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	(cp)[3] = (value) >> 24;					\
83845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	(cp)[2] = (value) >> 16;					\
84845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	(cp)[1] = (value) >> 8;						\
85845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	(cp)[0] = (value); } while (0)
86845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
87845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define PUT_32BIT_LE(cp, value) do {					\
88845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	(cp)[3] = (value) >> 24;					\
89845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	(cp)[2] = (value) >> 16;					\
90845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	(cp)[1] = (value) >> 8;						\
91845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	(cp)[0] = (value); } while (0)
92845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
93845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic u8 PADDING[MD4_BLOCK_LENGTH] = {
94845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
95845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
96845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
97845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project};
98845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
99845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/*
100845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Start MD4 accumulation.
101845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Set bit count to 0 and buffer to mysterious initialization constants.
102845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
103845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void MD4Init(MD4_CTX *ctx)
104845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
105845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ctx->count = 0;
106845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ctx->state[0] = 0x67452301;
107845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ctx->state[1] = 0xefcdab89;
108845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ctx->state[2] = 0x98badcfe;
109845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ctx->state[3] = 0x10325476;
110845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
111845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
112845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/*
113845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Update context to reflect the concatenation of another buffer full
114845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * of bytes.
115845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
116845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len)
117845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
118845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	size_t have, need;
119845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
120845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* Check how many bytes we already have and how many more we need. */
121845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	have = (size_t)((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
122845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	need = MD4_BLOCK_LENGTH - have;
123845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
124845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* Update bitcount */
125845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	ctx->count += (u64)len << 3;
126845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
127845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (len >= need) {
128845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (have != 0) {
129845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			os_memcpy(ctx->buffer + have, input, need);
130845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			MD4Transform(ctx->state, ctx->buffer);
131845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			input += need;
132845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			len -= need;
133845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			have = 0;
134845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
135845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
136845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		/* Process data in MD4_BLOCK_LENGTH-byte chunks. */
137845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		while (len >= MD4_BLOCK_LENGTH) {
138845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			MD4Transform(ctx->state, input);
139845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			input += MD4_BLOCK_LENGTH;
140845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			len -= MD4_BLOCK_LENGTH;
141845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
142845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
143845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
144845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* Handle any remaining bytes of data. */
145845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (len != 0)
146845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		os_memcpy(ctx->buffer + have, input, len);
147845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
148845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
149845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/*
150845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Pad pad to 64-byte boundary with the bit pattern
151845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * 1 0* (64-bit count of bits processed, MSB-first)
152845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
153845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void MD4Pad(MD4_CTX *ctx)
154845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
155845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	u8 count[8];
156845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	size_t padlen;
157845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
158845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* Convert count to 8 bytes in little endian order. */
159845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	PUT_64BIT_LE(count, ctx->count);
160845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
161845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* Pad out to 56 mod 64. */
162845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	padlen = MD4_BLOCK_LENGTH -
163845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	    ((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
164845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (padlen < 1 + 8)
165845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		padlen += MD4_BLOCK_LENGTH;
166845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
167845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4Update(ctx, count, 8);
168845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
169845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
170845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/*
171845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Final wrapup--call MD4Pad, fill in digest and zero out ctx.
172845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
173845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx)
174845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
175845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int i;
176845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
177845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4Pad(ctx);
178845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (digest != NULL) {
179845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		for (i = 0; i < 4; i++)
180845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
181845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		os_memset(ctx, 0, sizeof(*ctx));
182845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
183845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
184845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
185845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
186845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* The three core functions - F1 is optimized somewhat */
187845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
188845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* #define F1(x, y, z) (x & y | ~x & z) */
189845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define F1(x, y, z) (z ^ (x & (y ^ z)))
190845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define F2(x, y, z) ((x & y) | (x & z) | (y & z))
191845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define F3(x, y, z) (x ^ y ^ z)
192845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
193845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* This is the central step in the MD4 algorithm. */
194845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#define MD4STEP(f, w, x, y, z, data, s) \
195845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s) )
196845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
197845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/*
198845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * The core of the MD4 algorithm, this alters an existing MD4 hash to
199845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * reflect the addition of 16 longwords of new data.  MD4Update blocks
200845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * the data and converts bytes into longwords for this routine.
201845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
202845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void
203845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source ProjectMD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH])
204845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
205845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	u32 a, b, c, d, in[MD4_BLOCK_LENGTH / 4];
206845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
207845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#if BYTE_ORDER == LITTLE_ENDIAN
208845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	os_memcpy(in, block, sizeof(in));
209845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#else
210845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (a = 0; a < MD4_BLOCK_LENGTH / 4; a++) {
211845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		in[a] = (u32)(
212845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		    (u32)(block[a * 4 + 0]) |
213845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		    (u32)(block[a * 4 + 1]) <<  8 |
214845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		    (u32)(block[a * 4 + 2]) << 16 |
215845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		    (u32)(block[a * 4 + 3]) << 24);
216845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
217845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif
218845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
219845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	a = state[0];
220845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	b = state[1];
221845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	c = state[2];
222845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	d = state[3];
223845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
224845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, a, b, c, d, in[ 0],  3);
225845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, d, a, b, c, in[ 1],  7);
226845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, c, d, a, b, in[ 2], 11);
227845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, b, c, d, a, in[ 3], 19);
228845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, a, b, c, d, in[ 4],  3);
229845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, d, a, b, c, in[ 5],  7);
230845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, c, d, a, b, in[ 6], 11);
231845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, b, c, d, a, in[ 7], 19);
232845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, a, b, c, d, in[ 8],  3);
233845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, d, a, b, c, in[ 9],  7);
234845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, c, d, a, b, in[10], 11);
235845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, b, c, d, a, in[11], 19);
236845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, a, b, c, d, in[12],  3);
237845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, d, a, b, c, in[13],  7);
238845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, c, d, a, b, in[14], 11);
239845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F1, b, c, d, a, in[15], 19);
240845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
241845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, a, b, c, d, in[ 0] + 0x5a827999,  3);
242845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, d, a, b, c, in[ 4] + 0x5a827999,  5);
243845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, c, d, a, b, in[ 8] + 0x5a827999,  9);
244845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, b, c, d, a, in[12] + 0x5a827999, 13);
245845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, a, b, c, d, in[ 1] + 0x5a827999,  3);
246845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, d, a, b, c, in[ 5] + 0x5a827999,  5);
247845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, c, d, a, b, in[ 9] + 0x5a827999,  9);
248845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, b, c, d, a, in[13] + 0x5a827999, 13);
249845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, a, b, c, d, in[ 2] + 0x5a827999,  3);
250845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, d, a, b, c, in[ 6] + 0x5a827999,  5);
251845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, c, d, a, b, in[10] + 0x5a827999,  9);
252845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, b, c, d, a, in[14] + 0x5a827999, 13);
253845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, a, b, c, d, in[ 3] + 0x5a827999,  3);
254845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, d, a, b, c, in[ 7] + 0x5a827999,  5);
255845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, c, d, a, b, in[11] + 0x5a827999,  9);
256845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F2, b, c, d, a, in[15] + 0x5a827999, 13);
257845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
258845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, a, b, c, d, in[ 0] + 0x6ed9eba1,  3);
259845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, d, a, b, c, in[ 8] + 0x6ed9eba1,  9);
260845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, c, d, a, b, in[ 4] + 0x6ed9eba1, 11);
261845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, b, c, d, a, in[12] + 0x6ed9eba1, 15);
262845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, a, b, c, d, in[ 2] + 0x6ed9eba1,  3);
263845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, d, a, b, c, in[10] + 0x6ed9eba1,  9);
264845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, c, d, a, b, in[ 6] + 0x6ed9eba1, 11);
265845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, b, c, d, a, in[14] + 0x6ed9eba1, 15);
266845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, a, b, c, d, in[ 1] + 0x6ed9eba1,  3);
267845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, d, a, b, c, in[ 9] + 0x6ed9eba1,  9);
268845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, c, d, a, b, in[ 5] + 0x6ed9eba1, 11);
269845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, b, c, d, a, in[13] + 0x6ed9eba1, 15);
270845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, a, b, c, d, in[ 3] + 0x6ed9eba1,  3);
271845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, d, a, b, c, in[11] + 0x6ed9eba1,  9);
272845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, c, d, a, b, in[ 7] + 0x6ed9eba1, 11);
273845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	MD4STEP(F3, b, c, d, a, in[15] + 0x6ed9eba1, 15);
274845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
275845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	state[0] += a;
276845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	state[1] += b;
277845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	state[2] += c;
278845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	state[3] += d;
279845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
280845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* ===== end - public domain MD4 implementation ===== */
281845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
282845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* INTERNAL_MD4 */
283