152153Sbp/*
252153Sbp *  Routines in this file based on the work of Volker Lendecke,
352153Sbp *  Adapted for ncplib by Boris Popov
452153Sbp *  Please note that ncpl_crypt.c file should be indentical to this one
552153Sbp */
684213Sdillon
784213Sdillon#include <sys/cdefs.h>
884213Sdillon__FBSDID("$FreeBSD$");
984213Sdillon
1052153Sbp#include <sys/param.h>
1152153Sbp#include <sys/errno.h>
1252153Sbp#include <sys/malloc.h>
1352153Sbp#include <string.h>
1452153Sbp
1552153Sbp/*$*********************************************************
1652153Sbp   $*
1752153Sbp   $* This code has been taken from DDJ 11/93, from an
1852153Sbp   $* article by Pawel Szczerbina.
1952153Sbp   $*
2052153Sbp   $* Password encryption routines follow.
2152153Sbp   $* Converted to C from Barry Nance's Pascal
2252153Sbp   $* prog published in the March -93 issue of Byte.
2352153Sbp   $*
2452153Sbp   $* Adapted to be useable for ncpfs by
2552153Sbp   $* Volker Lendecke <lendecke@namu01.gwdg.de> in
2652153Sbp   $* October 1995.
2752153Sbp   $*
2852153Sbp   $********************************************************* */
2952153Sbp
3052153Sbp
3152153Sbp
3252153Sbptypedef unsigned char buf32[32];
3352153Sbp
3452153Sbpstatic unsigned char encrypttable[256] = {
3552153Sbp0x7, 0x8, 0x0, 0x8, 0x6, 0x4, 0xE, 0x4, 0x5, 0xC, 0x1, 0x7, 0xB, 0xF, 0xA, 0x8,
3652153Sbp0xF, 0x8, 0xC, 0xC, 0x9, 0x4, 0x1, 0xE, 0x4, 0x6, 0x2, 0x4, 0x0, 0xA, 0xB, 0x9,
3752153Sbp0x2, 0xF, 0xB, 0x1, 0xD, 0x2, 0x1, 0x9, 0x5, 0xE, 0x7, 0x0, 0x0, 0x2, 0x6, 0x6,
3852153Sbp0x0, 0x7, 0x3, 0x8, 0x2, 0x9, 0x3, 0xF, 0x7, 0xF, 0xC, 0xF, 0x6, 0x4, 0xA, 0x0,
3952153Sbp0x2, 0x3, 0xA, 0xB, 0xD, 0x8, 0x3, 0xA, 0x1, 0x7, 0xC, 0xF, 0x1, 0x8, 0x9, 0xD,
4052153Sbp0x9, 0x1, 0x9, 0x4, 0xE, 0x4, 0xC, 0x5, 0x5, 0xC, 0x8, 0xB, 0x2, 0x3, 0x9, 0xE,
4152153Sbp0x7, 0x7, 0x6, 0x9, 0xE, 0xF, 0xC, 0x8, 0xD, 0x1, 0xA, 0x6, 0xE, 0xD, 0x0, 0x7,
4252153Sbp0x7, 0xA, 0x0, 0x1, 0xF, 0x5, 0x4, 0xB, 0x7, 0xB, 0xE, 0xC, 0x9, 0x5, 0xD, 0x1,
4352153Sbp0xB, 0xD, 0x1, 0x3, 0x5, 0xD, 0xE, 0x6, 0x3, 0x0, 0xB, 0xB, 0xF, 0x3, 0x6, 0x4,
4452153Sbp0x9, 0xD, 0xA, 0x3, 0x1, 0x4, 0x9, 0x4, 0x8, 0x3, 0xB, 0xE, 0x5, 0x0, 0x5, 0x2,
4552153Sbp0xC, 0xB, 0xD, 0x5, 0xD, 0x5, 0xD, 0x2, 0xD, 0x9, 0xA, 0xC, 0xA, 0x0, 0xB, 0x3,
4652153Sbp0x5, 0x3, 0x6, 0x9, 0x5, 0x1, 0xE, 0xE, 0x0, 0xE, 0x8, 0x2, 0xD, 0x2, 0x2, 0x0,
4752153Sbp0x4, 0xF, 0x8, 0x5, 0x9, 0x6, 0x8, 0x6, 0xB, 0xA, 0xB, 0xF, 0x0, 0x7, 0x2, 0x8,
4852153Sbp0xC, 0x7, 0x3, 0xA, 0x1, 0x4, 0x2, 0x5, 0xF, 0x7, 0xA, 0xC, 0xE, 0x5, 0x9, 0x3,
4952153Sbp0xE, 0x7, 0x1, 0x2, 0xE, 0x1, 0xF, 0x4, 0xA, 0x6, 0xC, 0x6, 0xF, 0x4, 0x3, 0x0,
5052153Sbp0xC, 0x0, 0x3, 0x6, 0xF, 0x8, 0x7, 0xB, 0x2, 0xD, 0xC, 0x6, 0xA, 0xA, 0x8, 0xD
5152153Sbp};
5252153Sbp
5352153Sbpstatic buf32 encryptkeys = {
5452153Sbp    0x48, 0x93, 0x46, 0x67, 0x98, 0x3D, 0xE6, 0x8D,
5552153Sbp    0xB7, 0x10, 0x7A, 0x26, 0x5A, 0xB9, 0xB1, 0x35,
5652153Sbp    0x6B, 0x0F, 0xD5, 0x70, 0xAE, 0xFB, 0xAD, 0x11,
5752153Sbp    0xF4, 0x47, 0xDC, 0xA7, 0xEC, 0xCF, 0x50, 0xC0
5852153Sbp};
5952153Sbp
6052153Sbp/*
6152153Sbp * Create table-based 16-bytes hash from a 32-bytes array
6252153Sbp */
6352153Sbpstatic void
6452153Sbpnw_hash(buf32 temp, unsigned char *target) {
6552153Sbp	short sum;
6652153Sbp	unsigned char b3;
6752153Sbp	int s, b2, i;
6852153Sbp
6952153Sbp	sum = 0;
7052153Sbp
7152153Sbp	for (b2 = 0; b2 <= 1; ++b2) {
7252153Sbp		for (s = 0; s <= 31; ++s) {
7352153Sbp			b3 = (temp[s] + sum) ^ (temp[(s + sum) & 31] - encryptkeys[s]);
7452153Sbp			sum += b3;
7552153Sbp			temp[s] = b3;
7652153Sbp		}
7752153Sbp	}
7852153Sbp
7952153Sbp	for (i = 0; i <= 15; ++i) {
8052153Sbp		target[i] = encrypttable[temp[2 * i]]
8152153Sbp		    | (encrypttable[temp[2 * i + 1]] << 4);
8252153Sbp	}
8352153Sbp}
8452153Sbp
8552153Sbp
8652153Sbp/*
8752153Sbp * Create a 16-bytes pattern from given buffer based on a four bytes key
8852153Sbp */
8952153Sbpvoid
9052153Sbpnw_keyhash(const u_char *key, const u_char *buf, int buflen, u_char *target) {
9152153Sbp	int b2, d, s;
9252153Sbp	buf32 temp;
9352153Sbp
9452153Sbp	while (buflen > 0 && buf[buflen - 1] == 0)
9552153Sbp		buflen--;
9652153Sbp
9752153Sbp	bzero(temp, sizeof(temp));
9852153Sbp
9952153Sbp	d = 0;
10052153Sbp	while (buflen >= 32) {
10152153Sbp		for (s = 0; s <= 31; ++s)
10252153Sbp			temp[s] ^= buf[d++];
10352153Sbp		buflen -= 32;
10452153Sbp	}
10552153Sbp	b2 = d;
10652153Sbp	if (buflen > 0)	{
10752153Sbp		for (s = 0; s <= 31; ++s) {
10852153Sbp			if (d + buflen == b2) {
10952153Sbp				temp[s] ^= encryptkeys[s];
11052153Sbp				b2 = d;
11152153Sbp			} else
11252153Sbp				temp[s] ^= buf[b2++];
11352153Sbp		}
11452153Sbp	}
11552153Sbp	for (s = 0; s <= 31; ++s)
11652153Sbp		temp[s] ^= key[s & 3];
11752153Sbp
11852153Sbp	nw_hash(temp, target);
11952153Sbp}
12052153Sbp
12152153Sbp/*
12252153Sbp * Create an 8-bytes pattern from an 8-bytes key and 16-bytes of data
12352153Sbp */
12452153Sbpvoid
12552153Sbpnw_encrypt(const u_char *fra, const u_char *buf, u_char *target) {
12652153Sbp	buf32 k;
12752153Sbp	int s;
12852153Sbp
12952153Sbp	nw_keyhash(fra, buf, 16, k);
13052153Sbp	nw_keyhash(fra + 4, buf, 16, k + 16);
13152153Sbp
13252153Sbp	for (s = 0; s < 16; s++)
13352153Sbp		k[s] ^= k[31 - s];
13452153Sbp
13552153Sbp	for (s = 0; s < 8; s++)
13652153Sbp		*target++ = k[s] ^ k[15 - s];
13752153Sbp}
13852153Sbp
13952153Sbp
140