122347Spst/* md4c.c: "RSA Data Security, Inc. MD4 Message-Digest Algorithm"
222347Spst
329964Sache%%% portions-copyright-cmetz-96
492906SmarkmPortions of this software are Copyright 1996-1999 by Craig Metz, All Rights
522347SpstReserved. The Inner Net License Version 2 applies to these portions of
622347Spstthe software.
722347SpstYou should have received a copy of the license with this software. If
822347Spstyou didn't get a copy, you may request one from <license@inner.net>.
922347Spst
1022347SpstPortions of this software are Copyright 1995 by Randall Atkinson and Dan
1122347SpstMcDonald, All Rights Reserved. All Rights under this copyright are assigned
1222347Spstto the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
1322347SpstLicense Agreement applies to this software.
1422347Spst
1522347Spst	History:
1622347Spst
1722347Spst	Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
1822347Spst              Use the real memcpy() and memset(). Use unified context
1922347Spst              structure.
2022347Spst	Modified at NRL for OPIE 2.0.
2122347Spst	Originally from RSADSI reference code.
2222347Spst*/
2322347Spst/* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
2422347Spst
2522347Spst   License to copy and use this software is granted provided that it
2622347Spst   is identified as the "RSA Data Security, Inc. MD4 Message-Digest
2722347Spst   Algorithm" in all material mentioning or referencing this software
2822347Spst   or this function.
2922347Spst
3022347Spst   License is also granted to make and use derivative works provided
3122347Spst   that such works are identified as "derived from the RSA Data
3222347Spst   Security, Inc. MD4 Message-Digest Algorithm" in all material
3322347Spst   mentioning or referencing the derived work.
3422347Spst
3522347Spst   RSA Data Security, Inc. makes no representations concerning either
3622347Spst   the merchantability of this software or the suitability of this
3722347Spst   software for any particular purpose. It is provided "as is"
3822347Spst   without express or implied warranty of any kind.
3922347Spst
4022347Spst   These notices must be retained in any copies of any part of this
4122347Spst   documentation and/or software.
4222347Spst */
4322347Spst
4422347Spst#include "opie_cfg.h"
4522347Spst#include "opie.h"
4622347Spst
4722347Spst/* Constants for MD4Transform routine.
4822347Spst */
4922347Spst#define S11 3
5022347Spst#define S12 7
5122347Spst#define S13 11
5222347Spst#define S14 19
5322347Spst#define S21 3
5422347Spst#define S22 5
5522347Spst#define S23 9
5622347Spst#define S24 13
5722347Spst#define S31 3
5822347Spst#define S32 9
5922347Spst#define S33 11
6022347Spst#define S34 15
6122347Spst
6222347Spststatic VOIDRET MD4Transform __P((UINT4[4], unsigned char[64]));
6322347Spststatic VOIDRET Encode __P((unsigned char *, UINT4 *, unsigned int));
6422347Spststatic VOIDRET Decode __P((UINT4 *, unsigned char *, unsigned int));
6522347Spst
6622347Spststatic unsigned char PADDING[64] =
6722347Spst{
6822347Spst  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6922347Spst  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7022347Spst  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
7122347Spst};
7222347Spst
7322347Spst/* F, G and H are basic MD4 functions.
7422347Spst */
7522347Spst#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
7622347Spst#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
7722347Spst#define H(x, y, z) ((x) ^ (y) ^ (z))
7822347Spst
7922347Spst/* ROTATE_LEFT rotates x left n bits.
8022347Spst */
8122347Spst#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
8222347Spst
8322347Spst/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
8422347Spst/* Rotation is separate from addition to prevent recomputation */
8522347Spst
8622347Spst#define FF(a, b, c, d, x, s) { \
8722347Spst    (a) += F ((b), (c), (d)) + (x); \
8822347Spst    (a) = ROTATE_LEFT ((a), (s)); \
8922347Spst  }
9022347Spst#define GG(a, b, c, d, x, s) { \
9122347Spst    (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
9222347Spst    (a) = ROTATE_LEFT ((a), (s)); \
9322347Spst  }
9422347Spst#define HH(a, b, c, d, x, s) { \
9522347Spst    (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
9622347Spst    (a) = ROTATE_LEFT ((a), (s)); \
9722347Spst  }
9822347Spst
9922347Spst/* MD4 initialization. Begins an MD4 operation, writing a new context.
10022347Spst */
10122347SpstVOIDRET opiemd4init FUNCTION((context), struct opiemdx_ctx *context)
10222347Spst{
10322347Spst  context->count[0] = context->count[1] = 0;
10422347Spst
10522347Spst  /* Load magic initialization constants. */
10622347Spst  context->state[0] = 0x67452301;
10722347Spst  context->state[1] = 0xefcdab89;
10822347Spst  context->state[2] = 0x98badcfe;
10922347Spst  context->state[3] = 0x10325476;
11022347Spst}
11122347Spst
11222347Spst/* MD4 block update operation. Continues an MD4 message-digest
11322347Spst   operation, processing another message block, and updating the
11422347Spst   context.
11522347Spst */
11622347SpstVOIDRET opiemd4update FUNCTION((context, input, inputLen), struct opiemdx_ctx *context AND unsigned char *input AND unsigned int inputLen)
11722347Spst{
11822347Spst  unsigned int i, index, partLen;
11922347Spst
12022347Spst  /* Compute number of bytes mod 64 */
12122347Spst  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
12222347Spst  /* Update number of bits */
12322347Spst  if ((context->count[0] += ((UINT4) inputLen << 3))
12422347Spst      < ((UINT4) inputLen << 3))
12522347Spst    context->count[1]++;
12622347Spst  context->count[1] += ((UINT4) inputLen >> 29);
12722347Spst
12822347Spst  partLen = 64 - index;
12922347Spst
13022347Spst  /* Transform as many times as possible. */
13122347Spst  if (inputLen >= partLen) {
13222347Spst    memcpy((POINTER) & context->buffer[index], (POINTER) input, partLen);
13322347Spst    MD4Transform(context->state, context->buffer);
13422347Spst
13522347Spst    for (i = partLen; i + 63 < inputLen; i += 64)
13622347Spst      MD4Transform(context->state, &input[i]);
13722347Spst
13822347Spst    index = 0;
13922347Spst  } else
14022347Spst    i = 0;
14122347Spst
14222347Spst  /* Buffer remaining input */
14322347Spst  memcpy((POINTER) & context->buffer[index], (POINTER) & input[i], inputLen - i);
14422347Spst}
14522347Spst
14622347Spst/* MD4 finalization. Ends an MD4 message-digest operation, writing the
14722347Spst   the message digest and zeroizing the context.
14822347Spst */
14922347SpstVOIDRET opiemd4final FUNCTION((digest, context), unsigned char *digest AND struct opiemdx_ctx *context)
15022347Spst{
15122347Spst  unsigned char bits[8];
15222347Spst  unsigned int index, padLen;
15322347Spst
15422347Spst  /* Save number of bits */
15522347Spst  Encode(bits, context->count, 8);
15622347Spst
15722347Spst  /* Pad out to 56 mod 64. */
15822347Spst  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
15922347Spst  padLen = (index < 56) ? (56 - index) : (120 - index);
16022347Spst  opiemd4update(context, PADDING, padLen);
16122347Spst
16222347Spst  /* Append length (before padding) */
16322347Spst  opiemd4update(context, bits, 8);
16422347Spst  /* Store state in digest */
16522347Spst  Encode(digest, context->state, 16);
16622347Spst
16722347Spst  /* Zeroize sensitive information. */
16822347Spst  memset((POINTER) context, 0, sizeof(*context));
16922347Spst}
17022347Spst
17122347Spst/* MD4 basic transformation. Transforms state based on block.
17222347Spst */
17322347Spststatic VOIDRET MD4Transform FUNCTION((state, block), UINT4 state[4] AND unsigned char block[64])
17422347Spst{
17522347Spst  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
17622347Spst
17722347Spst  Decode(x, block, 64);
17822347Spst
17922347Spst  /* Round 1 */
18022347Spst  FF(a, b, c, d, x[0], S11);	/* 1 */
18122347Spst  FF(d, a, b, c, x[1], S12);	/* 2 */
18222347Spst  FF(c, d, a, b, x[2], S13);	/* 3 */
18322347Spst  FF(b, c, d, a, x[3], S14);	/* 4 */
18422347Spst  FF(a, b, c, d, x[4], S11);	/* 5 */
18522347Spst  FF(d, a, b, c, x[5], S12);	/* 6 */
18622347Spst  FF(c, d, a, b, x[6], S13);	/* 7 */
18722347Spst  FF(b, c, d, a, x[7], S14);	/* 8 */
18822347Spst  FF(a, b, c, d, x[8], S11);	/* 9 */
18922347Spst  FF(d, a, b, c, x[9], S12);	/* 10 */
19022347Spst  FF(c, d, a, b, x[10], S13);	/* 11 */
19122347Spst  FF(b, c, d, a, x[11], S14);	/* 12 */
19222347Spst  FF(a, b, c, d, x[12], S11);	/* 13 */
19322347Spst  FF(d, a, b, c, x[13], S12);	/* 14 */
19422347Spst  FF(c, d, a, b, x[14], S13);	/* 15 */
19522347Spst  FF(b, c, d, a, x[15], S14);	/* 16 */
19622347Spst
19722347Spst  /* Round 2 */
19822347Spst  GG(a, b, c, d, x[0], S21);	/* 17 */
19922347Spst  GG(d, a, b, c, x[4], S22);	/* 18 */
20022347Spst  GG(c, d, a, b, x[8], S23);	/* 19 */
20122347Spst  GG(b, c, d, a, x[12], S24);	/* 20 */
20222347Spst  GG(a, b, c, d, x[1], S21);	/* 21 */
20322347Spst  GG(d, a, b, c, x[5], S22);	/* 22 */
20422347Spst  GG(c, d, a, b, x[9], S23);	/* 23 */
20522347Spst  GG(b, c, d, a, x[13], S24);	/* 24 */
20622347Spst  GG(a, b, c, d, x[2], S21);	/* 25 */
20722347Spst  GG(d, a, b, c, x[6], S22);	/* 26 */
20822347Spst  GG(c, d, a, b, x[10], S23);	/* 27 */
20922347Spst  GG(b, c, d, a, x[14], S24);	/* 28 */
21022347Spst  GG(a, b, c, d, x[3], S21);	/* 29 */
21122347Spst  GG(d, a, b, c, x[7], S22);	/* 30 */
21222347Spst  GG(c, d, a, b, x[11], S23);	/* 31 */
21322347Spst  GG(b, c, d, a, x[15], S24);	/* 32 */
21422347Spst
21522347Spst  /* Round 3 */
21622347Spst  HH(a, b, c, d, x[0], S31);	/* 33 */
21722347Spst  HH(d, a, b, c, x[8], S32);	/* 34 */
21822347Spst  HH(c, d, a, b, x[4], S33);	/* 35 */
21922347Spst  HH(b, c, d, a, x[12], S34);	/* 36 */
22022347Spst  HH(a, b, c, d, x[2], S31);	/* 37 */
22122347Spst  HH(d, a, b, c, x[10], S32);	/* 38 */
22222347Spst  HH(c, d, a, b, x[6], S33);	/* 39 */
22322347Spst  HH(b, c, d, a, x[14], S34);	/* 40 */
22422347Spst  HH(a, b, c, d, x[1], S31);	/* 41 */
22522347Spst  HH(d, a, b, c, x[9], S32);	/* 42 */
22622347Spst  HH(c, d, a, b, x[5], S33);	/* 43 */
22722347Spst  HH(b, c, d, a, x[13], S34);	/* 44 */
22822347Spst  HH(a, b, c, d, x[3], S31);	/* 45 */
22922347Spst  HH(d, a, b, c, x[11], S32);	/* 46 */
23022347Spst  HH(c, d, a, b, x[7], S33);	/* 47 */
23122347Spst  HH(b, c, d, a, x[15], S34);	/* 48 */
23222347Spst
23322347Spst  state[0] += a;
23422347Spst  state[1] += b;
23522347Spst  state[2] += c;
23622347Spst  state[3] += d;
23722347Spst
23822347Spst  /* Zeroize sensitive information. */
23922347Spst  memset((POINTER) x, 0, sizeof(x));
24022347Spst}
24122347Spst
24222347Spst/* Encodes input (UINT4) into output (unsigned char). Assumes len is
24322347Spst   a multiple of 4.
24422347Spst */
24522347Spststatic VOIDRET Encode FUNCTION((output, input, len), unsigned char *output AND UINT4 *input AND unsigned int len)
24622347Spst{
24722347Spst  unsigned int i, j;
24822347Spst
24922347Spst  for (i = 0, j = 0; j < len; i++, j += 4) {
25022347Spst    output[j] = (unsigned char) (input[i] & 0xff);
25122347Spst    output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
25222347Spst    output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
25322347Spst    output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
25422347Spst  }
25522347Spst}
25622347Spst
25722347Spst/* Decodes input (unsigned char) into output (UINT4). Assumes len is
25822347Spst   a multiple of 4.
25922347Spst */
26022347Spststatic VOIDRET Decode FUNCTION((output, input, len), UINT4 *output AND unsigned char *input AND unsigned int len)
26122347Spst{
26222347Spst  unsigned int i, j;
26322347Spst
26422347Spst  for (i = 0, j = 0; j < len; i++, j += 4)
26522347Spst    output[i] = ((UINT4) input[j]) | (((UINT4) input[j + 1]) << 8) |
26622347Spst      (((UINT4) input[j + 2]) << 16) | (((UINT4) input[j + 3]) << 24);
26722347Spst}
268