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