151852Sbp/*
251852Sbp *  Routines in this file based on work of Volker Lendecke
351852Sbp */
451852Sbp/*$*********************************************************
551852Sbp   $*
651852Sbp   $* This code has been taken from DDJ 11/93, from an
751852Sbp   $* article by Pawel Szczerbina.
851852Sbp   $*
951852Sbp   $* Password encryption routines follow.
1051852Sbp   $* Converted to C from Barry Nance's Pascal
1151852Sbp   $* prog published in the March -93 issue of Byte.
1251852Sbp   $*
1351852Sbp   $* Adapted to be useable for ncpfs by
1451852Sbp   $* Volker Lendecke <lendecke@namu01.gwdg.de> in
1551852Sbp   $* October 1995.
1651852Sbp   $*
1751852Sbp   $********************************************************* */
1851852Sbp
19116189Sobrien#include <sys/cdefs.h>
20116189Sobrien__FBSDID("$FreeBSD$");
2151852Sbp
22116189Sobrien#include <sys/param.h>
23116189Sobrien#include <sys/systm.h>
24116189Sobrien#include <netncp/ncp.h>
25116189Sobrien#include <netncp/ncp_subr.h>
2651852Sbp
2751852Sbptypedef unsigned char buf32[32];
2851852Sbp
2951852Sbpstatic unsigned char encrypttable[256] = {
3051852Sbp0x7, 0x8, 0x0, 0x8, 0x6, 0x4, 0xE, 0x4, 0x5, 0xC, 0x1, 0x7, 0xB, 0xF, 0xA, 0x8,
3151852Sbp0xF, 0x8, 0xC, 0xC, 0x9, 0x4, 0x1, 0xE, 0x4, 0x6, 0x2, 0x4, 0x0, 0xA, 0xB, 0x9,
3251852Sbp0x2, 0xF, 0xB, 0x1, 0xD, 0x2, 0x1, 0x9, 0x5, 0xE, 0x7, 0x0, 0x0, 0x2, 0x6, 0x6,
3351852Sbp0x0, 0x7, 0x3, 0x8, 0x2, 0x9, 0x3, 0xF, 0x7, 0xF, 0xC, 0xF, 0x6, 0x4, 0xA, 0x0,
3451852Sbp0x2, 0x3, 0xA, 0xB, 0xD, 0x8, 0x3, 0xA, 0x1, 0x7, 0xC, 0xF, 0x1, 0x8, 0x9, 0xD,
3551852Sbp0x9, 0x1, 0x9, 0x4, 0xE, 0x4, 0xC, 0x5, 0x5, 0xC, 0x8, 0xB, 0x2, 0x3, 0x9, 0xE,
3651852Sbp0x7, 0x7, 0x6, 0x9, 0xE, 0xF, 0xC, 0x8, 0xD, 0x1, 0xA, 0x6, 0xE, 0xD, 0x0, 0x7,
3751852Sbp0x7, 0xA, 0x0, 0x1, 0xF, 0x5, 0x4, 0xB, 0x7, 0xB, 0xE, 0xC, 0x9, 0x5, 0xD, 0x1,
3851852Sbp0xB, 0xD, 0x1, 0x3, 0x5, 0xD, 0xE, 0x6, 0x3, 0x0, 0xB, 0xB, 0xF, 0x3, 0x6, 0x4,
3951852Sbp0x9, 0xD, 0xA, 0x3, 0x1, 0x4, 0x9, 0x4, 0x8, 0x3, 0xB, 0xE, 0x5, 0x0, 0x5, 0x2,
4051852Sbp0xC, 0xB, 0xD, 0x5, 0xD, 0x5, 0xD, 0x2, 0xD, 0x9, 0xA, 0xC, 0xA, 0x0, 0xB, 0x3,
4151852Sbp0x5, 0x3, 0x6, 0x9, 0x5, 0x1, 0xE, 0xE, 0x0, 0xE, 0x8, 0x2, 0xD, 0x2, 0x2, 0x0,
4251852Sbp0x4, 0xF, 0x8, 0x5, 0x9, 0x6, 0x8, 0x6, 0xB, 0xA, 0xB, 0xF, 0x0, 0x7, 0x2, 0x8,
4351852Sbp0xC, 0x7, 0x3, 0xA, 0x1, 0x4, 0x2, 0x5, 0xF, 0x7, 0xA, 0xC, 0xE, 0x5, 0x9, 0x3,
4451852Sbp0xE, 0x7, 0x1, 0x2, 0xE, 0x1, 0xF, 0x4, 0xA, 0x6, 0xC, 0x6, 0xF, 0x4, 0x3, 0x0,
4551852Sbp0xC, 0x0, 0x3, 0x6, 0xF, 0x8, 0x7, 0xB, 0x2, 0xD, 0xC, 0x6, 0xA, 0xA, 0x8, 0xD
4651852Sbp};
4751852Sbp
4851852Sbpstatic buf32 encryptkeys = {
4951852Sbp    0x48, 0x93, 0x46, 0x67, 0x98, 0x3D, 0xE6, 0x8D,
5051852Sbp    0xB7, 0x10, 0x7A, 0x26, 0x5A, 0xB9, 0xB1, 0x35,
5151852Sbp    0x6B, 0x0F, 0xD5, 0x70, 0xAE, 0xFB, 0xAD, 0x11,
5251852Sbp    0xF4, 0x47, 0xDC, 0xA7, 0xEC, 0xCF, 0x50, 0xC0
5351852Sbp};
5451852Sbp
5551852Sbp/*
5651852Sbp * Create table-based 16-bytes hash from a 32-bytes array
5751852Sbp */
5851852Sbpstatic void
5951852Sbpnw_hash(buf32 temp, unsigned char *target) {
6051852Sbp	short sum;
6151852Sbp	unsigned char b3;
6251852Sbp	int s, b2, i;
6351852Sbp
6451852Sbp	sum = 0;
6551852Sbp
6651852Sbp	for (b2 = 0; b2 <= 1; ++b2) {
6751852Sbp		for (s = 0; s <= 31; ++s) {
6851852Sbp			b3 = (temp[s] + sum) ^ (temp[(s + sum) & 31] - encryptkeys[s]);
6951852Sbp			sum += b3;
7051852Sbp			temp[s] = b3;
7151852Sbp		}
7251852Sbp	}
7351852Sbp
7451852Sbp	for (i = 0; i <= 15; ++i) {
7551852Sbp		target[i] = encrypttable[temp[2 * i]]
7651852Sbp		    | (encrypttable[temp[2 * i + 1]] << 4);
7751852Sbp	}
7851852Sbp}
7951852Sbp
8051852Sbp
8151852Sbp/*
8251852Sbp * Create a 16-bytes pattern from given buffer based on a four bytes key
8351852Sbp */
8451852Sbpvoid
8551852Sbpnw_keyhash(const u_char *key, const u_char *buf, int buflen, u_char *target) {
8651852Sbp	int b2, d, s;
8751852Sbp	buf32 temp;
8851852Sbp
8951852Sbp	while (buflen > 0 && buf[buflen - 1] == 0)
9051852Sbp		buflen--;
9151852Sbp
9251852Sbp	bzero(temp, sizeof(temp));
9351852Sbp
9451852Sbp	d = 0;
9551852Sbp	while (buflen >= 32) {
9651852Sbp		for (s = 0; s <= 31; ++s)
9751852Sbp			temp[s] ^= buf[d++];
9851852Sbp		buflen -= 32;
9951852Sbp	}
10051852Sbp	b2 = d;
10151852Sbp	if (buflen > 0)	{
10251852Sbp		for (s = 0; s <= 31; ++s) {
10351852Sbp			if (d + buflen == b2) {
10451852Sbp				temp[s] ^= encryptkeys[s];
10551852Sbp				b2 = d;
10651852Sbp			} else
10751852Sbp				temp[s] ^= buf[b2++];
10851852Sbp		}
10951852Sbp	}
11051852Sbp	for (s = 0; s <= 31; ++s)
11151852Sbp		temp[s] ^= key[s & 3];
11251852Sbp
11351852Sbp	nw_hash(temp, target);
11451852Sbp}
11551852Sbp
11651852Sbp/*
11751852Sbp * Create an 8-bytes pattern from an 8-bytes key and 16-bytes of data
11851852Sbp */
11951852Sbpvoid
12051852Sbpnw_encrypt(const u_char *fra, const u_char *buf, u_char *target) {
12151852Sbp	buf32 k;
12251852Sbp	int s;
12351852Sbp
12451852Sbp	nw_keyhash(fra, buf, 16, k);
12551852Sbp	nw_keyhash(fra + 4, buf, 16, k + 16);
12651852Sbp
12751852Sbp	for (s = 0; s < 16; s++)
12851852Sbp		k[s] ^= k[31 - s];
12951852Sbp
13051852Sbp	for (s = 0; s < 8; s++)
13151852Sbp		*target++ = k[s] ^ k[15 - s];
13251852Sbp}
13351852Sbp
13455205Speter#ifdef _KERNEL
13551852Sbp/*
13651852Sbp * MD4 routine taken from libmd sources
13751852Sbp */
13851852Sbptypedef u_int32_t	UINT4;
13951852Sbptypedef unsigned char *POINTER;
14051852Sbp
14151852Sbp#define PROTO_LIST(list) list
14251852Sbp
14351852Sbpstatic void Decode PROTO_LIST
14451852Sbp  ((UINT4 *, const unsigned char *, unsigned int));
14551852Sbp
14651852Sbp/* Constants for MD4Transform routine.
14751852Sbp */
14851852Sbp#define S11 3
14951852Sbp#define S12 7
15051852Sbp#define S13 11
15151852Sbp#define S14 19
15251852Sbp#define S21 3
15351852Sbp#define S22 5
15451852Sbp#define S23 9
15551852Sbp#define S24 13
15651852Sbp#define S31 3
15751852Sbp#define S32 9
15851852Sbp#define S33 11
15951852Sbp#define S34 15
16051852Sbp
16151852Sbp/* F, G and H are basic MD4 functions.
16251852Sbp */
16351852Sbp#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
16451852Sbp#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
16551852Sbp#define H(x, y, z) ((x) ^ (y) ^ (z))
16651852Sbp
16751852Sbp/* ROTATE_LEFT rotates x left n bits.
16851852Sbp */
16951852Sbp#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
17051852Sbp
17151852Sbp/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
17251852Sbp/* Rotation is separate from addition to prevent recomputation */
17351852Sbp#define FF(a, b, c, d, x, s) { \
17451852Sbp    (a) += F ((b), (c), (d)) + (x); \
17551852Sbp    (a) = ROTATE_LEFT ((a), (s)); \
17651852Sbp  }
17751852Sbp#define GG(a, b, c, d, x, s) { \
17851852Sbp    (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
17951852Sbp    (a) = ROTATE_LEFT ((a), (s)); \
18051852Sbp  }
18151852Sbp#define HH(a, b, c, d, x, s) { \
18251852Sbp    (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
18351852Sbp    (a) = ROTATE_LEFT ((a), (s)); \
18451852Sbp  }
18551852Sbp
18651852Sbpvoid
18751852Sbpncp_sign(const u_int32_t *state, const char *block, u_int32_t *ostate) {
18851852Sbp	UINT4 a, b, c, d, x[16];
18951852Sbp
19051852Sbp	Decode (x, block, 64);
19151852Sbp	a = state[0];
19251852Sbp	b = state[1];
19351852Sbp	c = state[2];
19451852Sbp	d = state[3];
19551852Sbp	/* Round 1 */
19651852Sbp	FF (a, b, c, d, x[ 0], S11); /* 1 */
19751852Sbp	FF (d, a, b, c, x[ 1], S12); /* 2 */
19851852Sbp	FF (c, d, a, b, x[ 2], S13); /* 3 */
19951852Sbp	FF (b, c, d, a, x[ 3], S14); /* 4 */
20051852Sbp	FF (a, b, c, d, x[ 4], S11); /* 5 */
20151852Sbp	FF (d, a, b, c, x[ 5], S12); /* 6 */
20251852Sbp	FF (c, d, a, b, x[ 6], S13); /* 7 */
20351852Sbp	FF (b, c, d, a, x[ 7], S14); /* 8 */
20451852Sbp	FF (a, b, c, d, x[ 8], S11); /* 9 */
20551852Sbp	FF (d, a, b, c, x[ 9], S12); /* 10 */
20651852Sbp	FF (c, d, a, b, x[10], S13); /* 11 */
20751852Sbp	FF (b, c, d, a, x[11], S14); /* 12 */
20851852Sbp	FF (a, b, c, d, x[12], S11); /* 13 */
20951852Sbp	FF (d, a, b, c, x[13], S12); /* 14 */
21051852Sbp	FF (c, d, a, b, x[14], S13); /* 15 */
21151852Sbp	FF (b, c, d, a, x[15], S14); /* 16 */
21251852Sbp
21351852Sbp	/* Round 2 */
21451852Sbp	GG (a, b, c, d, x[ 0], S21); /* 17 */
21551852Sbp	GG (d, a, b, c, x[ 4], S22); /* 18 */
21651852Sbp	GG (c, d, a, b, x[ 8], S23); /* 19 */
21751852Sbp	GG (b, c, d, a, x[12], S24); /* 20 */
21851852Sbp	GG (a, b, c, d, x[ 1], S21); /* 21 */
21951852Sbp	GG (d, a, b, c, x[ 5], S22); /* 22 */
22051852Sbp	GG (c, d, a, b, x[ 9], S23); /* 23 */
22151852Sbp	GG (b, c, d, a, x[13], S24); /* 24 */
22251852Sbp	GG (a, b, c, d, x[ 2], S21); /* 25 */
22351852Sbp	GG (d, a, b, c, x[ 6], S22); /* 26 */
22451852Sbp	GG (c, d, a, b, x[10], S23); /* 27 */
22551852Sbp	GG (b, c, d, a, x[14], S24); /* 28 */
22651852Sbp	GG (a, b, c, d, x[ 3], S21); /* 29 */
22751852Sbp	GG (d, a, b, c, x[ 7], S22); /* 30 */
22851852Sbp	GG (c, d, a, b, x[11], S23); /* 31 */
22951852Sbp	GG (b, c, d, a, x[15], S24); /* 32 */
23051852Sbp
23151852Sbp	/* Round 3 */
23251852Sbp	HH (a, b, c, d, x[ 0], S31); /* 33 */
23351852Sbp	HH (d, a, b, c, x[ 8], S32); /* 34 */
23451852Sbp	HH (c, d, a, b, x[ 4], S33); /* 35 */
23551852Sbp	HH (b, c, d, a, x[12], S34); /* 36 */
23651852Sbp	HH (a, b, c, d, x[ 2], S31); /* 37 */
23751852Sbp	HH (d, a, b, c, x[10], S32); /* 38 */
23851852Sbp	HH (c, d, a, b, x[ 6], S33); /* 39 */
23951852Sbp	HH (b, c, d, a, x[14], S34); /* 40 */
24051852Sbp	HH (a, b, c, d, x[ 1], S31); /* 41 */
24151852Sbp	HH (d, a, b, c, x[ 9], S32); /* 42 */
24251852Sbp	HH (c, d, a, b, x[ 5], S33); /* 43 */
24351852Sbp	HH (b, c, d, a, x[13], S34); /* 44 */
24451852Sbp	HH (a, b, c, d, x[ 3], S31); /* 45 */
24551852Sbp	HH (d, a, b, c, x[11], S32); /* 46 */
24651852Sbp	HH (c, d, a, b, x[ 7], S33); /* 47 */
24751852Sbp	HH (b, c, d, a, x[15], S34); /* 48 */
24851852Sbp
24951852Sbp	ostate[0] = state[0] + a;
25051852Sbp	ostate[1] = state[1] + b;
25151852Sbp	ostate[2] = state[2] + c;
25251852Sbp	ostate[3] = state[3] + d;
25351852Sbp}
25451852Sbp
25551852Sbp/* Decodes input (unsigned char) into output (UINT4). Assumes len is
25651852Sbp     a multiple of 4.
25751852Sbp */
25851852Sbpstatic void Decode (output, input, len)
25951852Sbp
26051852SbpUINT4 *output;
26151852Sbpconst unsigned char *input;
26251852Sbpunsigned int len;
26351852Sbp{
26451852Sbp  unsigned int i, j;
26551852Sbp
26651852Sbp  for (i = 0, j = 0; j < len; i++, j += 4)
26751852Sbp    output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
26851852Sbp      (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
26951852Sbp}
27051852Sbp
27155205Speter#endif /* _KERNEL */
272