1*567219e1Smatt /* $NetBSD: md4c.c,v 1.5 2012/03/20 16:21:41 matt Exp $ */
237c9f0a6Schristos
337c9f0a6Schristos /*
437c9f0a6Schristos * This file is derived from the RSA Data Security, Inc. MD4 Message-Digest
537c9f0a6Schristos * Algorithm and has been modified by Jason R. Thorpe <thorpej@NetBSD.org>
637c9f0a6Schristos * for portability and formatting.
737c9f0a6Schristos */
837c9f0a6Schristos
937c9f0a6Schristos /*
1037c9f0a6Schristos * Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
1137c9f0a6Schristos *
1237c9f0a6Schristos * License to copy and use this software is granted provided that it
1337c9f0a6Schristos * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
1437c9f0a6Schristos * Algorithm" in all material mentioning or referencing this software
1537c9f0a6Schristos * or this function.
1637c9f0a6Schristos *
1737c9f0a6Schristos * License is also granted to make and use derivative works provided
1837c9f0a6Schristos * that such works are identified as "derived from the RSA Data
1937c9f0a6Schristos * Security, Inc. MD4 Message-Digest Algorithm" in all material
2037c9f0a6Schristos * mentioning or referencing the derived work.
2137c9f0a6Schristos *
2237c9f0a6Schristos * RSA Data Security, Inc. makes no representations concerning either
2337c9f0a6Schristos * the merchantability of this software or the suitability of this
2437c9f0a6Schristos * software for any particular purpose. It is provided "as is"
2537c9f0a6Schristos * without express or implied warranty of any kind.
2637c9f0a6Schristos *
2737c9f0a6Schristos * These notices must be retained in any copies of any part of this
2837c9f0a6Schristos * documentation and/or software.
2937c9f0a6Schristos */
3037c9f0a6Schristos
3137c9f0a6Schristos #if !defined(_KERNEL) && !defined(_STANDALONE)
3237c9f0a6Schristos #include <sys/cdefs.h>
3337c9f0a6Schristos #if defined(LIBC_SCCS) && !defined(lint)
34*567219e1Smatt __RCSID("$NetBSD: md4c.c,v 1.5 2012/03/20 16:21:41 matt Exp $");
3537c9f0a6Schristos #endif /* LIBC_SCCS and not lint */
3637c9f0a6Schristos
3737c9f0a6Schristos #include "namespace.h"
3837c9f0a6Schristos
3937c9f0a6Schristos #include <sys/types.h>
4037c9f0a6Schristos
4137c9f0a6Schristos #include <assert.h>
4237c9f0a6Schristos #include <md4.h>
4337c9f0a6Schristos #include <string.h>
4437c9f0a6Schristos
4537c9f0a6Schristos #if HAVE_NBTOOL_CONFIG_H
4637c9f0a6Schristos #include "nbtool_config.h"
4737c9f0a6Schristos #endif
4837c9f0a6Schristos
4937c9f0a6Schristos #else
5037c9f0a6Schristos
519abe0ed1Smatt #include <sys/param.h>
5237c9f0a6Schristos #include <sys/md4.h>
5337c9f0a6Schristos #include <lib/libkern/libkern.h>
5437c9f0a6Schristos
5537c9f0a6Schristos #endif /* !_KERNEL && !_STANDALONE */
5637c9f0a6Schristos
5737c9f0a6Schristos #if !HAVE_MD4_H
5837c9f0a6Schristos
5937c9f0a6Schristos typedef unsigned char *POINTER;
60267197ecSapb typedef uint16_t UINT2;
61267197ecSapb typedef uint32_t UINT4;
6237c9f0a6Schristos
6337c9f0a6Schristos /*
6437c9f0a6Schristos * Constants for MD4Transform routine.
6537c9f0a6Schristos */
6637c9f0a6Schristos #define S11 3
6737c9f0a6Schristos #define S12 7
6837c9f0a6Schristos #define S13 11
6937c9f0a6Schristos #define S14 19
7037c9f0a6Schristos #define S21 3
7137c9f0a6Schristos #define S22 5
7237c9f0a6Schristos #define S23 9
7337c9f0a6Schristos #define S24 13
7437c9f0a6Schristos #define S31 3
7537c9f0a6Schristos #define S32 9
7637c9f0a6Schristos #define S33 11
7737c9f0a6Schristos #define S34 15
7837c9f0a6Schristos
79*567219e1Smatt static void MD4Transform(UINT4 [4], const unsigned char [64]);
8037c9f0a6Schristos
81*567219e1Smatt static void Encode(unsigned char *, UINT4 *, unsigned int);
82*567219e1Smatt static void Decode(UINT4 *, const unsigned char *, unsigned int);
8337c9f0a6Schristos
8437c9f0a6Schristos static const unsigned char PADDING[64] = {
8537c9f0a6Schristos 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8637c9f0a6Schristos 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8737c9f0a6Schristos 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
8837c9f0a6Schristos };
8937c9f0a6Schristos
9037c9f0a6Schristos /*
9137c9f0a6Schristos * F, G and H are basic MD4 functions.
9237c9f0a6Schristos */
9337c9f0a6Schristos #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
9437c9f0a6Schristos #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
9537c9f0a6Schristos #define H(x, y, z) ((x) ^ (y) ^ (z))
9637c9f0a6Schristos
9737c9f0a6Schristos /*
9837c9f0a6Schristos * ROTATE_LEFT rotates x left n bits.
9937c9f0a6Schristos */
10037c9f0a6Schristos #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
10137c9f0a6Schristos
10237c9f0a6Schristos /*
10337c9f0a6Schristos * FF, GG and HH are transformations for rounds 1, 2 and 3.
10437c9f0a6Schristos * Rotation is separate from addition to prevent recomputation.
10537c9f0a6Schristos */
10637c9f0a6Schristos #define FF(a, b, c, d, x, s) { \
10737c9f0a6Schristos (a) += F ((b), (c), (d)) + (x); \
10837c9f0a6Schristos (a) = ROTATE_LEFT ((a), (s)); \
10937c9f0a6Schristos }
11037c9f0a6Schristos
11137c9f0a6Schristos #define GG(a, b, c, d, x, s) { \
11237c9f0a6Schristos (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
11337c9f0a6Schristos (a) = ROTATE_LEFT ((a), (s)); \
11437c9f0a6Schristos }
11537c9f0a6Schristos
11637c9f0a6Schristos #define HH(a, b, c, d, x, s) { \
11737c9f0a6Schristos (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
11837c9f0a6Schristos (a) = ROTATE_LEFT ((a), (s)); \
11937c9f0a6Schristos }
12037c9f0a6Schristos
12137c9f0a6Schristos #if !defined(_KERNEL) && !defined(_STANDALONE) && defined(__weak_alias)
__weak_alias(MD4Init,_MD4Init)12237c9f0a6Schristos __weak_alias(MD4Init,_MD4Init)
12337c9f0a6Schristos __weak_alias(MD4Update,_MD4Update)
12437c9f0a6Schristos __weak_alias(MD4Final,_MD4Final)
12537c9f0a6Schristos __weak_alias(MD4Transform,_MD4Transform)
12637c9f0a6Schristos #endif
12737c9f0a6Schristos
12837c9f0a6Schristos /*
12937c9f0a6Schristos * MD4 initialization. Begins an MD4 operation, writing a new context.
13037c9f0a6Schristos */
13137c9f0a6Schristos void
13296276685Scegger MD4Init(MD4_CTX *context) /* context */
13337c9f0a6Schristos {
13437c9f0a6Schristos
13537c9f0a6Schristos _DIAGASSERT(context != 0);
13637c9f0a6Schristos
13737c9f0a6Schristos context->count[0] = context->count[1] = 0;
13837c9f0a6Schristos
13937c9f0a6Schristos /* Load magic initialization constants. */
14037c9f0a6Schristos context->state[0] = 0x67452301;
14137c9f0a6Schristos context->state[1] = 0xefcdab89;
14237c9f0a6Schristos context->state[2] = 0x98badcfe;
14337c9f0a6Schristos context->state[3] = 0x10325476;
14437c9f0a6Schristos }
14537c9f0a6Schristos
14637c9f0a6Schristos /*
14737c9f0a6Schristos * MD4 block update operation. Continues an MD4 message-digest
14837c9f0a6Schristos * operation, processing another message block, and updating the
14937c9f0a6Schristos * context.
15037c9f0a6Schristos */
15137c9f0a6Schristos void
MD4Update(MD4_CTX * context,const unsigned char * input,unsigned int inputLen)15296276685Scegger MD4Update (MD4_CTX *context, /* context */
15396276685Scegger const unsigned char *input, /* input block */
15496276685Scegger unsigned int inputLen) /* length of input block */
15537c9f0a6Schristos {
15637c9f0a6Schristos unsigned int i, idx, partLen;
15737c9f0a6Schristos
15837c9f0a6Schristos _DIAGASSERT(context != 0);
15937c9f0a6Schristos _DIAGASSERT(input != 0);
16037c9f0a6Schristos
16137c9f0a6Schristos /* Compute number of bytes mod 64 */
16237c9f0a6Schristos idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
16337c9f0a6Schristos
16437c9f0a6Schristos /* Update number of bits */
16537c9f0a6Schristos if ((context->count[0] += ((UINT4)inputLen << 3))
16637c9f0a6Schristos < ((UINT4)inputLen << 3))
16737c9f0a6Schristos context->count[1]++;
16837c9f0a6Schristos context->count[1] += ((UINT4)inputLen >> 29);
16937c9f0a6Schristos
17037c9f0a6Schristos partLen = 64 - idx;
17137c9f0a6Schristos
17237c9f0a6Schristos /* Transform as many times as possible. */
17337c9f0a6Schristos if (inputLen >= partLen) {
17437c9f0a6Schristos memcpy(&context->buffer[idx], input, partLen);
17537c9f0a6Schristos MD4Transform(context->state, context->buffer);
17637c9f0a6Schristos
17737c9f0a6Schristos for (i = partLen; i + 63 < inputLen; i += 64)
17837c9f0a6Schristos MD4Transform(context->state, &input[i]);
17937c9f0a6Schristos
18037c9f0a6Schristos idx = 0;
18137c9f0a6Schristos } else
18237c9f0a6Schristos i = 0;
18337c9f0a6Schristos
18437c9f0a6Schristos /* Buffer remaining input */
18537c9f0a6Schristos memcpy(&context->buffer[idx], &input[i], inputLen - i);
18637c9f0a6Schristos }
18737c9f0a6Schristos
18837c9f0a6Schristos /*
18937c9f0a6Schristos * MD4 finalization. Ends an MD4 message-digest operation, writing the
19037c9f0a6Schristos * message digest and zeroing the context.
19137c9f0a6Schristos */
19237c9f0a6Schristos void
MD4Final(unsigned char digest[16],MD4_CTX * context)19396276685Scegger MD4Final (unsigned char digest[16], /* message digest */
19496276685Scegger MD4_CTX *context) /* context */
19537c9f0a6Schristos {
19637c9f0a6Schristos unsigned char bits[8];
19737c9f0a6Schristos unsigned int idx, padLen;
19837c9f0a6Schristos
19937c9f0a6Schristos _DIAGASSERT(digest != 0);
20037c9f0a6Schristos _DIAGASSERT(context != 0);
20137c9f0a6Schristos
20237c9f0a6Schristos /* Save number of bits */
20337c9f0a6Schristos Encode(bits, context->count, 8);
20437c9f0a6Schristos
20537c9f0a6Schristos /* Pad out to 56 mod 64. */
20637c9f0a6Schristos idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
20737c9f0a6Schristos padLen = (idx < 56) ? (56 - idx) : (120 - idx);
20837c9f0a6Schristos MD4Update(context, PADDING, padLen);
20937c9f0a6Schristos
21037c9f0a6Schristos /* Append length (before padding) */
21137c9f0a6Schristos MD4Update(context, bits, 8);
21237c9f0a6Schristos
21337c9f0a6Schristos /* Store state in digest */
21437c9f0a6Schristos Encode(digest, context->state, 16);
21537c9f0a6Schristos
21637c9f0a6Schristos /* Zeroize sensitive information. */
21737c9f0a6Schristos memset(context, 0, sizeof(*context));
21837c9f0a6Schristos }
21937c9f0a6Schristos
22037c9f0a6Schristos /*
22137c9f0a6Schristos * MD4 basic transformation. Transforms state based on block.
22237c9f0a6Schristos */
22337c9f0a6Schristos static void
MD4Transform(UINT4 state[4],const unsigned char block[64])22496276685Scegger MD4Transform (UINT4 state[4], const unsigned char block[64])
22537c9f0a6Schristos {
22637c9f0a6Schristos UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
22737c9f0a6Schristos
22837c9f0a6Schristos Decode(x, block, 64);
22937c9f0a6Schristos
23037c9f0a6Schristos /* Round 1 */
23137c9f0a6Schristos FF (a, b, c, d, x[ 0], S11); /* 1 */
23237c9f0a6Schristos FF (d, a, b, c, x[ 1], S12); /* 2 */
23337c9f0a6Schristos FF (c, d, a, b, x[ 2], S13); /* 3 */
23437c9f0a6Schristos FF (b, c, d, a, x[ 3], S14); /* 4 */
23537c9f0a6Schristos FF (a, b, c, d, x[ 4], S11); /* 5 */
23637c9f0a6Schristos FF (d, a, b, c, x[ 5], S12); /* 6 */
23737c9f0a6Schristos FF (c, d, a, b, x[ 6], S13); /* 7 */
23837c9f0a6Schristos FF (b, c, d, a, x[ 7], S14); /* 8 */
23937c9f0a6Schristos FF (a, b, c, d, x[ 8], S11); /* 9 */
24037c9f0a6Schristos FF (d, a, b, c, x[ 9], S12); /* 10 */
24137c9f0a6Schristos FF (c, d, a, b, x[10], S13); /* 11 */
24237c9f0a6Schristos FF (b, c, d, a, x[11], S14); /* 12 */
24337c9f0a6Schristos FF (a, b, c, d, x[12], S11); /* 13 */
24437c9f0a6Schristos FF (d, a, b, c, x[13], S12); /* 14 */
24537c9f0a6Schristos FF (c, d, a, b, x[14], S13); /* 15 */
24637c9f0a6Schristos FF (b, c, d, a, x[15], S14); /* 16 */
24737c9f0a6Schristos
24837c9f0a6Schristos /* Round 2 */
24937c9f0a6Schristos GG (a, b, c, d, x[ 0], S21); /* 17 */
25037c9f0a6Schristos GG (d, a, b, c, x[ 4], S22); /* 18 */
25137c9f0a6Schristos GG (c, d, a, b, x[ 8], S23); /* 19 */
25237c9f0a6Schristos GG (b, c, d, a, x[12], S24); /* 20 */
25337c9f0a6Schristos GG (a, b, c, d, x[ 1], S21); /* 21 */
25437c9f0a6Schristos GG (d, a, b, c, x[ 5], S22); /* 22 */
25537c9f0a6Schristos GG (c, d, a, b, x[ 9], S23); /* 23 */
25637c9f0a6Schristos GG (b, c, d, a, x[13], S24); /* 24 */
25737c9f0a6Schristos GG (a, b, c, d, x[ 2], S21); /* 25 */
25837c9f0a6Schristos GG (d, a, b, c, x[ 6], S22); /* 26 */
25937c9f0a6Schristos GG (c, d, a, b, x[10], S23); /* 27 */
26037c9f0a6Schristos GG (b, c, d, a, x[14], S24); /* 28 */
26137c9f0a6Schristos GG (a, b, c, d, x[ 3], S21); /* 29 */
26237c9f0a6Schristos GG (d, a, b, c, x[ 7], S22); /* 30 */
26337c9f0a6Schristos GG (c, d, a, b, x[11], S23); /* 31 */
26437c9f0a6Schristos GG (b, c, d, a, x[15], S24); /* 32 */
26537c9f0a6Schristos
26637c9f0a6Schristos /* Round 3 */
26737c9f0a6Schristos HH (a, b, c, d, x[ 0], S31); /* 33 */
26837c9f0a6Schristos HH (d, a, b, c, x[ 8], S32); /* 34 */
26937c9f0a6Schristos HH (c, d, a, b, x[ 4], S33); /* 35 */
27037c9f0a6Schristos HH (b, c, d, a, x[12], S34); /* 36 */
27137c9f0a6Schristos HH (a, b, c, d, x[ 2], S31); /* 37 */
27237c9f0a6Schristos HH (d, a, b, c, x[10], S32); /* 38 */
27337c9f0a6Schristos HH (c, d, a, b, x[ 6], S33); /* 39 */
27437c9f0a6Schristos HH (b, c, d, a, x[14], S34); /* 40 */
27537c9f0a6Schristos HH (a, b, c, d, x[ 1], S31); /* 41 */
27637c9f0a6Schristos HH (d, a, b, c, x[ 9], S32); /* 42 */
27737c9f0a6Schristos HH (c, d, a, b, x[ 5], S33); /* 43 */
27837c9f0a6Schristos HH (b, c, d, a, x[13], S34); /* 44 */
27937c9f0a6Schristos HH (a, b, c, d, x[ 3], S31); /* 45 */
28037c9f0a6Schristos HH (d, a, b, c, x[11], S32); /* 46 */
28137c9f0a6Schristos HH (c, d, a, b, x[ 7], S33); /* 47 */
28237c9f0a6Schristos HH (b, c, d, a, x[15], S34); /* 48 */
28337c9f0a6Schristos
28437c9f0a6Schristos state[0] += a;
28537c9f0a6Schristos state[1] += b;
28637c9f0a6Schristos state[2] += c;
28737c9f0a6Schristos state[3] += d;
28837c9f0a6Schristos
28937c9f0a6Schristos /* Zeroize sensitive information. */
29037c9f0a6Schristos memset(x, 0, sizeof (x));
29137c9f0a6Schristos }
29237c9f0a6Schristos
29337c9f0a6Schristos /*
29437c9f0a6Schristos * Encodes input (UINT4) into output (unsigned char). Assumes len is
29537c9f0a6Schristos * a multiple of 4.
29637c9f0a6Schristos */
29737c9f0a6Schristos static void
Encode(unsigned char * output,UINT4 * input,unsigned int len)29896276685Scegger Encode(unsigned char *output, UINT4 *input, unsigned int len)
29937c9f0a6Schristos {
30037c9f0a6Schristos unsigned int i, j;
30137c9f0a6Schristos
30237c9f0a6Schristos for (i = 0, j = 0; j < len; i++, j += 4) {
30337c9f0a6Schristos output[j] = (unsigned char)(input[i] & 0xff);
30437c9f0a6Schristos output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
30537c9f0a6Schristos output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
30637c9f0a6Schristos output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
30737c9f0a6Schristos }
30837c9f0a6Schristos }
30937c9f0a6Schristos
31037c9f0a6Schristos /*
31137c9f0a6Schristos * Decodes input (unsigned char) into output (UINT4). Assumes len is
31237c9f0a6Schristos * a multiple of 4.
31337c9f0a6Schristos */
31437c9f0a6Schristos static void
Decode(UINT4 * output,const unsigned char * input,unsigned int len)31596276685Scegger Decode(UINT4 *output, const unsigned char *input, unsigned int len)
31637c9f0a6Schristos {
31737c9f0a6Schristos unsigned int i, j;
31837c9f0a6Schristos
31937c9f0a6Schristos for (i = 0, j = 0; j < len; i++, j += 4)
32037c9f0a6Schristos output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
32137c9f0a6Schristos (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
32237c9f0a6Schristos }
32337c9f0a6Schristos
32437c9f0a6Schristos #endif /* HAVE_MD4_H */
325