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