Initial import from FreeBSD RELENG_4:
[dragonfly.git] / lib / libncp / ncpl_crypt.c
1 /* 
2  *  Routines in this file based on the work of Volker Lendecke,
3  *  Adapted for ncplib by Boris Popov
4  *  Please note that ncpl_crypt.c file should be indentical to this one
5  *
6  * $FreeBSD: src/lib/libncp/ncpl_crypt.c,v 1.1 1999/10/12 11:56:39 bp Exp $
7  */
8 #include <sys/param.h>
9 #include <sys/errno.h>
10 #include <sys/malloc.h>
11 #include <string.h>
12
13 /*$*********************************************************
14    $*
15    $* This code has been taken from DDJ 11/93, from an 
16    $* article by Pawel Szczerbina.
17    $*
18    $* Password encryption routines follow.
19    $* Converted to C from Barry Nance's Pascal
20    $* prog published in the March -93 issue of Byte.
21    $*
22    $* Adapted to be useable for ncpfs by 
23    $* Volker Lendecke <lendecke@namu01.gwdg.de> in 
24    $* October 1995. 
25    $*
26    $********************************************************* */
27
28
29
30 typedef unsigned char buf32[32];
31
32 static unsigned char encrypttable[256] = {
33 0x7, 0x8, 0x0, 0x8, 0x6, 0x4, 0xE, 0x4, 0x5, 0xC, 0x1, 0x7, 0xB, 0xF, 0xA, 0x8,
34 0xF, 0x8, 0xC, 0xC, 0x9, 0x4, 0x1, 0xE, 0x4, 0x6, 0x2, 0x4, 0x0, 0xA, 0xB, 0x9,
35 0x2, 0xF, 0xB, 0x1, 0xD, 0x2, 0x1, 0x9, 0x5, 0xE, 0x7, 0x0, 0x0, 0x2, 0x6, 0x6,
36 0x0, 0x7, 0x3, 0x8, 0x2, 0x9, 0x3, 0xF, 0x7, 0xF, 0xC, 0xF, 0x6, 0x4, 0xA, 0x0,
37 0x2, 0x3, 0xA, 0xB, 0xD, 0x8, 0x3, 0xA, 0x1, 0x7, 0xC, 0xF, 0x1, 0x8, 0x9, 0xD,
38 0x9, 0x1, 0x9, 0x4, 0xE, 0x4, 0xC, 0x5, 0x5, 0xC, 0x8, 0xB, 0x2, 0x3, 0x9, 0xE,
39 0x7, 0x7, 0x6, 0x9, 0xE, 0xF, 0xC, 0x8, 0xD, 0x1, 0xA, 0x6, 0xE, 0xD, 0x0, 0x7,
40 0x7, 0xA, 0x0, 0x1, 0xF, 0x5, 0x4, 0xB, 0x7, 0xB, 0xE, 0xC, 0x9, 0x5, 0xD, 0x1,
41 0xB, 0xD, 0x1, 0x3, 0x5, 0xD, 0xE, 0x6, 0x3, 0x0, 0xB, 0xB, 0xF, 0x3, 0x6, 0x4,
42 0x9, 0xD, 0xA, 0x3, 0x1, 0x4, 0x9, 0x4, 0x8, 0x3, 0xB, 0xE, 0x5, 0x0, 0x5, 0x2,
43 0xC, 0xB, 0xD, 0x5, 0xD, 0x5, 0xD, 0x2, 0xD, 0x9, 0xA, 0xC, 0xA, 0x0, 0xB, 0x3,
44 0x5, 0x3, 0x6, 0x9, 0x5, 0x1, 0xE, 0xE, 0x0, 0xE, 0x8, 0x2, 0xD, 0x2, 0x2, 0x0,
45 0x4, 0xF, 0x8, 0x5, 0x9, 0x6, 0x8, 0x6, 0xB, 0xA, 0xB, 0xF, 0x0, 0x7, 0x2, 0x8,
46 0xC, 0x7, 0x3, 0xA, 0x1, 0x4, 0x2, 0x5, 0xF, 0x7, 0xA, 0xC, 0xE, 0x5, 0x9, 0x3,
47 0xE, 0x7, 0x1, 0x2, 0xE, 0x1, 0xF, 0x4, 0xA, 0x6, 0xC, 0x6, 0xF, 0x4, 0x3, 0x0,
48 0xC, 0x0, 0x3, 0x6, 0xF, 0x8, 0x7, 0xB, 0x2, 0xD, 0xC, 0x6, 0xA, 0xA, 0x8, 0xD
49 };
50
51 static buf32 encryptkeys = {
52     0x48, 0x93, 0x46, 0x67, 0x98, 0x3D, 0xE6, 0x8D,
53     0xB7, 0x10, 0x7A, 0x26, 0x5A, 0xB9, 0xB1, 0x35,
54     0x6B, 0x0F, 0xD5, 0x70, 0xAE, 0xFB, 0xAD, 0x11,
55     0xF4, 0x47, 0xDC, 0xA7, 0xEC, 0xCF, 0x50, 0xC0
56 };
57
58 /*
59  * Create table-based 16-bytes hash from a 32-bytes array
60  */
61 static void
62 nw_hash(buf32 temp, unsigned char *target) {
63         short sum;
64         unsigned char b3;
65         int s, b2, i;
66
67         sum = 0;
68
69         for (b2 = 0; b2 <= 1; ++b2) {
70                 for (s = 0; s <= 31; ++s) {
71                         b3 = (temp[s] + sum) ^ (temp[(s + sum) & 31] - encryptkeys[s]);
72                         sum += b3;
73                         temp[s] = b3;
74                 }
75         }
76
77         for (i = 0; i <= 15; ++i) {
78                 target[i] = encrypttable[temp[2 * i]]
79                     | (encrypttable[temp[2 * i + 1]] << 4);
80         }
81 }
82
83
84 /*
85  * Create a 16-bytes pattern from given buffer based on a four bytes key
86  */
87 void
88 nw_keyhash(const u_char *key, const u_char *buf, int buflen, u_char *target) {
89         int b2, d, s;
90         buf32 temp;
91
92         while (buflen > 0 && buf[buflen - 1] == 0)
93                 buflen--;
94
95         bzero(temp, sizeof(temp));
96
97         d = 0;
98         while (buflen >= 32) {
99                 for (s = 0; s <= 31; ++s)
100                         temp[s] ^= buf[d++];
101                 buflen -= 32;
102         }
103         b2 = d;
104         if (buflen > 0) {
105                 for (s = 0; s <= 31; ++s) {
106                         if (d + buflen == b2) {
107                                 temp[s] ^= encryptkeys[s];
108                                 b2 = d;
109                         } else
110                                 temp[s] ^= buf[b2++];
111                 }
112         }
113         for (s = 0; s <= 31; ++s)
114                 temp[s] ^= key[s & 3];
115
116         nw_hash(temp, target);
117 }
118
119 /*
120  * Create an 8-bytes pattern from an 8-bytes key and 16-bytes of data
121  */
122 void
123 nw_encrypt(const u_char *fra, const u_char *buf, u_char *target) {
124         buf32 k;
125         int s;
126
127         nw_keyhash(fra, buf, 16, k);
128         nw_keyhash(fra + 4, buf, 16, k + 16);
129
130         for (s = 0; s < 16; s++)
131                 k[s] ^= k[31 - s];
132
133         for (s = 0; s < 8; s++)
134                 *target++ = k[s] ^ k[15 - s];
135 }
136
137