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