]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/unix/netkey.c
kbdfs: simplfy
[plan9front.git] / sys / src / cmd / unix / netkey.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>\r
4 \r
5 extern long read(int, void*, long);
6 typedef unsigned char uchar;\r
7 typedef unsigned long ulong;\r
8 #define NAMELEN 28\r
9
10 /*********** auth.h ************/
11 typedef struct  Ticket          Ticket;
12 typedef struct  Ticketreq       Ticketreq;
13 typedef struct  Authenticator   Authenticator;
14 typedef struct  Nvrsafe         Nvrsafe;
15 typedef struct  Passwordreq     Passwordreq;
16 typedef struct  Chalstate       Chalstate;
17
18 enum
19 {
20         DOMLEN=         48,             /* length of an authentication domain name */
21         DESKEYLEN=      7,              /* length of a des key for encrypt/decrypt */
22         CHALLEN=        8,              /* length of a challenge */
23         NETCHLEN=       16,             /* max network challenge length */
24         CONFIGLEN=      14,
25
26         KEYDBLEN=       NAMELEN+DESKEYLEN+4+2
27 };
28
29 /* encryption numberings (anti-replay) */
30 enum
31 {
32         AuthTreq=1,     /* ticket request */
33         AuthChal=2,     /* challenge box request */
34         AuthPass=3,     /* change password */
35
36         AuthOK=4,       /* reply follows */
37         AuthErr=5,      /* error follows */
38
39         AuthTs=64,      /* ticket encrypted with server's key */
40         AuthTc,         /* ticket encrypted with client's key */
41         AuthAs,         /* server generated authenticator */
42         AuthAc          /* client generated authenticator */
43 };
44
45 struct Ticketreq
46 {
47         char    type;
48         char    authid[NAMELEN];        /* server's encryption id */
49         char    authdom[DOMLEN];        /* server's authentication domain */
50         char    chal[CHALLEN];          /* challenge from server */
51         char    hostid[NAMELEN];        /* host's encryption id */
52         char    uid[NAMELEN];           /* uid of requesting user on host */
53 };
54 #define TICKREQLEN      (3*NAMELEN+CHALLEN+DOMLEN+1)
55
56 struct Ticket
57 {
58         char    num;                    /* replay protection */
59         char    chal[CHALLEN];          /* server challenge */
60         char    cuid[NAMELEN];          /* uid on client */
61         char    suid[NAMELEN];          /* uid on server */
62         char    key[DESKEYLEN];         /* nonce DES key */
63 };
64 #define TICKETLEN       (CHALLEN+2*NAMELEN+DESKEYLEN+1)
65
66 struct Authenticator
67 {
68         char    num;                    /* replay protection */
69         char    chal[CHALLEN];
70         ulong   id;                     /* authenticator id, ++'d with each auth */
71 };
72 #define AUTHENTLEN      (CHALLEN+4+1)
73
74 struct Passwordreq
75 {
76         char    num;
77         char    old[NAMELEN];
78         char    new[NAMELEN];
79 };
80 #define PASSREQLEN      (2*NAMELEN+1)
81
82 struct Nvrsafe
83 {
84         char    machkey[DESKEYLEN];
85         uchar   machsum;
86         char    authkey[DESKEYLEN];
87         uchar   authsum;
88         char    config[CONFIGLEN];
89         uchar   configsum;
90         char    authid[NAMELEN];
91         uchar   authidsum;
92         char    authdom[DOMLEN];
93         uchar   authdomsum;
94 };
95
96 struct Chalstate
97 {
98         int     afd;                    /* /dev/authenticate */
99         int     asfd;                   /* authdial() */
100         char    chal[NETCHLEN];         /* challenge/response */
101 };
102
103
104 /************ crypt.c *************/
105 /*
106  *      Data Encryption Standard
107  *      D.P.Mitchell  83/06/08.
108  *
109  *      block_cipher(key, block, decrypting)
110  */
111 static  long    ip_low(char [8]);
112 static  long    ip_high(char [8]);
113 static  void    fp(long, long, char[8]);
114 static  void    key_setup(char[DESKEYLEN], char[128]);
115 static  void    block_cipher(char[128], char[8], int);
116
117 /*
118  * destructively encrypt the buffer, which
119  * must be at least 8 characters long.
120  */
121 int
122 encrypt9(void *key, void *vbuf, int n)
123 {
124         char ekey[128], *buf;
125         int i, r;
126
127         if(n < 8)
128                 return 0;
129         key_setup(key, ekey);
130         buf = vbuf;
131         n--;
132         r = n % 7;
133         n /= 7;
134         for(i = 0; i < n; i++){
135                 block_cipher(ekey, buf, 0);
136                 buf += 7;
137         }
138         if(r)
139                 block_cipher(ekey, buf - 7 + r, 0);
140         return 1;
141 }
142
143 /*
144  * destructively decrypt the buffer, which
145  * must be at least 8 characters long.
146  */
147 int
148 decrypt(void *key, void *vbuf, int n)
149 {
150         char ekey[128], *buf;
151         int i, r;
152
153         if(n < 8)
154                 return 0;
155         key_setup(key, ekey);
156         buf = vbuf;
157         n--;
158         r = n % 7;
159         n /= 7;
160         buf += n * 7;
161         if(r)
162                 block_cipher(ekey, buf - 7 + r, 1);
163         for(i = 0; i < n; i++){
164                 buf -= 7;
165                 block_cipher(ekey, buf, 1);
166         }
167         return 1;
168 }
169
170 /*
171  *      Tables for Combined S and P Boxes
172  */
173
174 static long  s0p[] = {
175 0x00410100,0x00010000,0x40400000,0x40410100,0x00400000,0x40010100,0x40010000,0x40400000,
176 0x40010100,0x00410100,0x00410000,0x40000100,0x40400100,0x00400000,0x00000000,0x40010000,
177 0x00010000,0x40000000,0x00400100,0x00010100,0x40410100,0x00410000,0x40000100,0x00400100,
178 0x40000000,0x00000100,0x00010100,0x40410000,0x00000100,0x40400100,0x40410000,0x00000000,
179 0x00000000,0x40410100,0x00400100,0x40010000,0x00410100,0x00010000,0x40000100,0x00400100,
180 0x40410000,0x00000100,0x00010100,0x40400000,0x40010100,0x40000000,0x40400000,0x00410000,
181 0x40410100,0x00010100,0x00410000,0x40400100,0x00400000,0x40000100,0x40010000,0x00000000,
182 0x00010000,0x00400000,0x40400100,0x00410100,0x40000000,0x40410000,0x00000100,0x40010100,
183 };
184
185 static long  s1p[] = {
186 0x08021002,0x00000000,0x00021000,0x08020000,0x08000002,0x00001002,0x08001000,0x00021000,
187 0x00001000,0x08020002,0x00000002,0x08001000,0x00020002,0x08021000,0x08020000,0x00000002,
188 0x00020000,0x08001002,0x08020002,0x00001000,0x00021002,0x08000000,0x00000000,0x00020002,
189 0x08001002,0x00021002,0x08021000,0x08000002,0x08000000,0x00020000,0x00001002,0x08021002,
190 0x00020002,0x08021000,0x08001000,0x00021002,0x08021002,0x00020002,0x08000002,0x00000000,
191 0x08000000,0x00001002,0x00020000,0x08020002,0x00001000,0x08000000,0x00021002,0x08001002,
192 0x08021000,0x00001000,0x00000000,0x08000002,0x00000002,0x08021002,0x00021000,0x08020000,
193 0x08020002,0x00020000,0x00001002,0x08001000,0x08001002,0x00000002,0x08020000,0x00021000,
194 };
195
196 static long  s2p[] = {
197 0x20800000,0x00808020,0x00000020,0x20800020,0x20008000,0x00800000,0x20800020,0x00008020,
198 0x00800020,0x00008000,0x00808000,0x20000000,0x20808020,0x20000020,0x20000000,0x20808000,
199 0x00000000,0x20008000,0x00808020,0x00000020,0x20000020,0x20808020,0x00008000,0x20800000,
200 0x20808000,0x00800020,0x20008020,0x00808000,0x00008020,0x00000000,0x00800000,0x20008020,
201 0x00808020,0x00000020,0x20000000,0x00008000,0x20000020,0x20008000,0x00808000,0x20800020,
202 0x00000000,0x00808020,0x00008020,0x20808000,0x20008000,0x00800000,0x20808020,0x20000000,
203 0x20008020,0x20800000,0x00800000,0x20808020,0x00008000,0x00800020,0x20800020,0x00008020,
204 0x00800020,0x00000000,0x20808000,0x20000020,0x20800000,0x20008020,0x00000020,0x00808000,
205 };
206
207 static long  s3p[] = {
208 0x00080201,0x02000200,0x00000001,0x02080201,0x00000000,0x02080000,0x02000201,0x00080001,
209 0x02080200,0x02000001,0x02000000,0x00000201,0x02000001,0x00080201,0x00080000,0x02000000,
210 0x02080001,0x00080200,0x00000200,0x00000001,0x00080200,0x02000201,0x02080000,0x00000200,
211 0x00000201,0x00000000,0x00080001,0x02080200,0x02000200,0x02080001,0x02080201,0x00080000,
212 0x02080001,0x00000201,0x00080000,0x02000001,0x00080200,0x02000200,0x00000001,0x02080000,
213 0x02000201,0x00000000,0x00000200,0x00080001,0x00000000,0x02080001,0x02080200,0x00000200,
214 0x02000000,0x02080201,0x00080201,0x00080000,0x02080201,0x00000001,0x02000200,0x00080201,
215 0x00080001,0x00080200,0x02080000,0x02000201,0x00000201,0x02000000,0x02000001,0x02080200,
216 };
217
218 static long  s4p[] = {
219 0x01000000,0x00002000,0x00000080,0x01002084,0x01002004,0x01000080,0x00002084,0x01002000,
220 0x00002000,0x00000004,0x01000004,0x00002080,0x01000084,0x01002004,0x01002080,0x00000000,
221 0x00002080,0x01000000,0x00002004,0x00000084,0x01000080,0x00002084,0x00000000,0x01000004,
222 0x00000004,0x01000084,0x01002084,0x00002004,0x01002000,0x00000080,0x00000084,0x01002080,
223 0x01002080,0x01000084,0x00002004,0x01002000,0x00002000,0x00000004,0x01000004,0x01000080,
224 0x01000000,0x00002080,0x01002084,0x00000000,0x00002084,0x01000000,0x00000080,0x00002004,
225 0x01000084,0x00000080,0x00000000,0x01002084,0x01002004,0x01002080,0x00000084,0x00002000,
226 0x00002080,0x01002004,0x01000080,0x00000084,0x00000004,0x00002084,0x01002000,0x01000004,
227 };
228
229 static long  s5p[] = {
230 0x10000008,0x00040008,0x00000000,0x10040400,0x00040008,0x00000400,0x10000408,0x00040000,
231 0x00000408,0x10040408,0x00040400,0x10000000,0x10000400,0x10000008,0x10040000,0x00040408,
232 0x00040000,0x10000408,0x10040008,0x00000000,0x00000400,0x00000008,0x10040400,0x10040008,
233 0x10040408,0x10040000,0x10000000,0x00000408,0x00000008,0x00040400,0x00040408,0x10000400,
234 0x00000408,0x10000000,0x10000400,0x00040408,0x10040400,0x00040008,0x00000000,0x10000400,
235 0x10000000,0x00000400,0x10040008,0x00040000,0x00040008,0x10040408,0x00040400,0x00000008,
236 0x10040408,0x00040400,0x00040000,0x10000408,0x10000008,0x10040000,0x00040408,0x00000000,
237 0x00000400,0x10000008,0x10000408,0x10040400,0x10040000,0x00000408,0x00000008,0x10040008,
238 };
239
240 static long  s6p[] = {
241 0x00000800,0x00000040,0x00200040,0x80200000,0x80200840,0x80000800,0x00000840,0x00000000,
242 0x00200000,0x80200040,0x80000040,0x00200800,0x80000000,0x00200840,0x00200800,0x80000040,
243 0x80200040,0x00000800,0x80000800,0x80200840,0x00000000,0x00200040,0x80200000,0x00000840,
244 0x80200800,0x80000840,0x00200840,0x80000000,0x80000840,0x80200800,0x00000040,0x00200000,
245 0x80000840,0x00200800,0x80200800,0x80000040,0x00000800,0x00000040,0x00200000,0x80200800,
246 0x80200040,0x80000840,0x00000840,0x00000000,0x00000040,0x80200000,0x80000000,0x00200040,
247 0x00000000,0x80200040,0x00200040,0x00000840,0x80000040,0x00000800,0x80200840,0x00200000,
248 0x00200840,0x80000000,0x80000800,0x80200840,0x80200000,0x00200840,0x00200800,0x80000800,
249 };
250
251 static long  s7p[] = {
252 0x04100010,0x04104000,0x00004010,0x00000000,0x04004000,0x00100010,0x04100000,0x04104010,
253 0x00000010,0x04000000,0x00104000,0x00004010,0x00104010,0x04004010,0x04000010,0x04100000,
254 0x00004000,0x00104010,0x00100010,0x04004000,0x04104010,0x04000010,0x00000000,0x00104000,
255 0x04000000,0x00100000,0x04004010,0x04100010,0x00100000,0x00004000,0x04104000,0x00000010,
256 0x00100000,0x00004000,0x04000010,0x04104010,0x00004010,0x04000000,0x00000000,0x00104000,
257 0x04100010,0x04004010,0x04004000,0x00100010,0x04104000,0x00000010,0x00100010,0x04004000,
258 0x04104010,0x00100000,0x04100000,0x04000010,0x00104000,0x00004010,0x04004010,0x04100000,
259 0x00000010,0x04104000,0x00104010,0x00000000,0x04000000,0x04100010,0x00004000,0x00104010,
260 };
261
262 /*
263  *      DES electronic codebook encryption of one block
264  */
265 static void
266 block_cipher(char expanded_key[128], char text[8], int decrypting)
267 {
268         char *key;
269         long crypto, temp, right, left;
270         int i, key_offset;
271
272         key = expanded_key;
273         left = ip_low(text);
274         right = ip_high(text);
275         if (decrypting) {
276                 key_offset = 16;
277                 key = key + 128 - 8;
278         } else
279                 key_offset = 0;
280         for (i = 0; i < 16; i++) {
281                 temp = (right << 1) | ((right >> 31) & 1);
282                 crypto  = s0p[(temp         & 0x3f) ^ *key++];
283                 crypto |= s1p[((temp >>  4) & 0x3f) ^ *key++];
284                 crypto |= s2p[((temp >>  8) & 0x3f) ^ *key++];
285                 crypto |= s3p[((temp >> 12) & 0x3f) ^ *key++];
286                 crypto |= s4p[((temp >> 16) & 0x3f) ^ *key++];
287                 crypto |= s5p[((temp >> 20) & 0x3f) ^ *key++];
288                 crypto |= s6p[((temp >> 24) & 0x3f) ^ *key++];
289                 temp = ((right & 1) << 5) | ((right >> 27) & 0x1f);
290                 crypto |= s7p[temp ^ *key++];
291                 temp = left;
292                 left = right;
293                 right = temp ^ crypto;
294                 key -= key_offset;
295         }
296         /*
297          *      standard final permutation (IPI)
298          *      left and right are reversed here
299          */
300         fp(right, left, text);
301 }
302
303 /*
304  *      Initial Permutation
305  */
306 static long iptab[] = {
307         0x00000000, 0x00008000, 0x00000000, 0x00008000,
308         0x00000080, 0x00008080, 0x00000080, 0x00008080
309 };
310
311 static long
312 ip_low(char block[8])
313 {
314         int i;
315         long l;
316
317         l = 0;
318         for(i = 0; i < 8; i++){
319                 l |= iptab[(block[i] >> 4) & 7] >> i;
320                 l |= iptab[block[i] & 7] << (16 - i);
321         }
322         return l;
323 }
324
325 static long
326 ip_high(char block[8])
327 {
328         int i;
329         long l;
330
331         l = 0;
332         for(i = 0; i < 8; i++){
333                 l |= iptab[(block[i] >> 5) & 7] >> i;
334                 l |= iptab[(block[i] >> 1) & 7] << (16 - i);
335         }
336         return l;
337 }
338
339 /*
340  *      Final Permutation
341  */
342 static unsigned long    fptab[] = {
343 0x00000000,0x80000000,0x00800000,0x80800000,0x00008000,0x80008000,0x00808000,0x80808000,
344 0x00000080,0x80000080,0x00800080,0x80800080,0x00008080,0x80008080,0x00808080,0x80808080,
345 };
346
347 static void
348 fp(long left, long right, char text[8])
349 {
350         unsigned long ta[2], t, v[2];
351         int i, j, sh;
352
353         ta[0] = right;
354         ta[1] = left;
355         v[0] = v[1] = 0;
356         for(i = 0; i < 2; i++){
357                 t = ta[i];
358                 sh = i;
359                 for(j = 0; j < 4; j++){
360                         v[1] |= fptab[t & 0xf] >> sh;
361                         t >>= 4;
362                         v[0] |= fptab[t & 0xf] >> sh;
363                         t >>= 4;
364                         sh += 2;
365                 }
366         }
367         for(i = 0; i < 2; i++)
368                 for(j = 0; j < 4; j++){
369                         *text++ = (char)(v[i]&0xff);
370                         v[i] >>= 8;
371                 }
372 }
373
374 /*
375  *      Key set-up
376  */
377 static uchar keyexpand[][15][2] = {
378         {   3,  2,   9,  8,  18,  8,  27, 32,  33,  2,  42, 16,  48,  8,  65, 16, 
379            74,  2,  80,  2,  89,  4,  99, 16, 104,  4, 122, 32,   0,  0, },
380         {   1,  4,   8,  1,  18,  4,  25, 32,  34, 32,  41,  8,  50,  8,  59, 32, 
381            64, 16,  75,  4,  90,  1,  97, 16, 106,  2, 112,  2, 123,  1, },
382         {   2,  1,  19,  8,  35,  1,  40,  1,  50,  4,  57, 32,  75,  2,  80, 32, 
383            89,  1,  96, 16, 107,  4, 120,  8,   0,  0,   0,  0,   0,  0, },
384         {   4, 32,  20,  2,  31,  4,  37, 32,  47,  1,  54,  1,  63,  2,  68,  1, 
385            78,  4,  84,  8, 101, 16, 108,  4, 119, 16, 126,  8,   0,  0, },
386         {   5,  4,  15,  4,  21, 32,  31,  1,  38,  1,  47,  2,  53,  2,  68,  8, 
387            85, 16,  92,  4, 103, 16, 108, 32, 118, 32, 124,  2,   0,  0, },
388         {  15,  2,  21,  2,  39,  8,  46, 16,  55, 32,  61,  1,  71, 16,  76, 32, 
389            86, 32,  93,  4, 102,  2, 108, 16, 117,  8, 126,  1,   0,  0, },
390         {  14, 16,  23, 32,  29,  1,  38,  8,  52,  2,  63,  4,  70,  2,  76, 16, 
391            85,  8, 100,  1, 110,  4, 116,  8, 127,  8,   0,  0,   0,  0, },
392         {   1,  8,   8, 32,  17,  1,  24, 16,  35,  4,  50,  1,  57, 16,  67,  8, 
393            83,  1,  88,  1,  98,  4, 105, 32, 114, 32, 123,  2,   0,  0, },
394         {   0,  1,  11, 16,  16,  4,  35,  2,  40, 32,  49,  1,  56, 16,  65,  2, 
395            74, 16,  80,  8,  99,  8, 115,  1, 121,  4,   0,  0,   0,  0, },
396         {   9, 16,  18,  2,  24,  2,  33,  4,  43, 16,  48,  4,  66, 32,  73,  8, 
397            82,  8,  91, 32,  97,  2, 106, 16, 112,  8, 122,  1,   0,  0, },
398         {  14, 32,  21,  4,  30,  2,  36, 16,  45,  8,  60,  1,  69,  2,  87,  8, 
399            94, 16, 103, 32, 109,  1, 118,  8, 124, 32,   0,  0,   0,  0, },
400         {   7,  4,  14,  2,  20, 16,  29,  8,  44,  1,  54,  4,  60,  8,  71,  8, 
401            78, 16,  87, 32,  93,  1, 102,  8, 116,  2, 125,  4,   0,  0, },
402         {   7,  2,  12,  1,  22,  4,  28,  8,  45, 16,  52,  4,  63, 16,  70,  8, 
403            84,  2,  95,  4, 101, 32, 111,  1, 118,  1,   0,  0,   0,  0, },
404         {   6, 16,  13, 16,  20,  4,  31, 16,  36, 32,  46, 32,  53,  4,  62,  2, 
405            69, 32,  79,  1,  86,  1,  95,  2, 101,  2, 119,  8,   0,  0, },
406         {   0, 32,  10,  8,  19, 32,  25,  2,  34, 16,  40,  8,  59,  8,  66,  2, 
407            72,  2,  81,  4,  91, 16,  96,  4, 115,  2, 121,  8,   0,  0, },
408         {   3, 16,  10,  4,  17, 32,  26, 32,  33,  8,  42,  8,  51, 32,  57,  2, 
409            67,  4,  82,  1,  89, 16,  98,  2, 104,  2, 113,  4, 120,  1, },
410         {   1, 16,  11,  8,  27,  1,  32,  1,  42,  4,  49, 32,  58, 32,  67,  2, 
411            72, 32,  81,  1,  88, 16,  99,  4, 114,  1,   0,  0,   0,  0, },
412         {   6, 32,  12,  2,  23,  4,  29, 32,  39,  1,  46,  1,  55,  2,  61,  2, 
413            70,  4,  76,  8,  93, 16, 100,  4, 111, 16, 116, 32,   0,  0, },
414         {   6,  2,  13, 32,  23,  1,  30,  1,  39,  2,  45,  2,  63,  8,  77, 16, 
415            84,  4,  95, 16, 100, 32, 110, 32, 117,  4, 127,  4,   0,  0, },
416         {   4,  1,  13,  2,  31,  8,  38, 16,  47, 32,  53,  1,  62,  8,  68, 32, 
417            78, 32,  85,  4,  94,  2, 100, 16, 109,  8, 127,  2,   0,  0, },
418         {   5, 16,  15, 32,  21,  1,  30,  8,  44,  2,  55,  4,  61, 32,  68, 16, 
419            77,  8,  92,  1, 102,  4, 108,  8, 126, 16,   0,  0,   0,  0, },
420         {   2,  8,   9,  1,  16, 16,  27,  4,  42,  1,  49, 16,  58,  2,  75,  1, 
421            80,  1,  90,  4,  97, 32, 106, 32, 113,  8, 120, 32,   0,  0, },
422         {   2,  4,   8,  4,  27,  2,  32, 32,  41,  1,  48, 16,  59,  4,  66, 16, 
423            72,  8,  91,  8, 107,  1, 112,  1, 123, 16,   0,  0,   0,  0, },
424         {   3,  8,  10,  2,  16,  2,  25,  4,  35, 16,  40,  4,  59,  2,  65,  8, 
425            74,  8,  83, 32,  89,  2,  98, 16, 104,  8, 121, 16,   0,  0, },
426         {   4,  2,  13,  4,  22,  2,  28, 16,  37,  8,  52,  1,  62,  4,  79,  8, 
427            86, 16,  95, 32, 101,  1, 110,  8, 126, 32,   0,  0,   0,  0, },
428         {   5, 32,  12, 16,  21,  8,  36,  1,  46,  4,  52,  8,  70, 16,  79, 32, 
429            85,  1,  94,  8, 108,  2, 119,  4, 126,  2,   0,  0,   0,  0, },
430         {   5,  2,  14,  4,  20,  8,  37, 16,  44,  4,  55, 16,  60, 32,  76,  2, 
431            87,  4,  93, 32, 103,  1, 110,  1, 119,  2, 124,  1,   0,  0, },
432         {   7, 32,  12,  4,  23, 16,  28, 32,  38, 32,  45,  4,  54,  2,  60, 16, 
433            71,  1,  78,  1,  87,  2,  93,  2, 111,  8, 118, 16, 125, 16, },
434         {   1,  1,  11, 32,  17,  2,  26, 16,  32,  8,  51,  8,  64,  2,  73,  4, 
435            83, 16,  88,  4, 107,  2, 112, 32, 122,  8,   0,  0,   0,  0, },
436         {   0,  4,   9, 32,  18, 32,  25,  8,  34,  8,  43, 32,  49,  2,  58, 16, 
437            74,  1,  81, 16,  90,  2,  96,  2, 105,  4, 115, 16, 122,  4, },
438         {   2,  2,  19,  1,  24,  1,  34,  4,  41, 32,  50, 32,  57,  8,  64, 32, 
439            73,  1,  80, 16,  91,  4, 106,  1, 113, 16, 123,  8,   0,  0, },
440         {   3,  4,  10, 16,  16,  8,  35,  8,  51,  1,  56,  1,  67, 16,  72,  4, 
441            91,  2,  96, 32, 105,  1, 112, 16, 121,  2,   0,  0,   0,  0, },
442         {   4, 16,  15,  1,  22,  1,  31,  2,  37,  2,  55,  8,  62, 16,  69, 16, 
443            76,  4,  87, 16,  92, 32, 102, 32, 109,  4, 118,  2, 125, 32, },
444         {   6,  4,  23,  8,  30, 16,  39, 32,  45,  1,  54,  8,  70, 32,  77,  4, 
445            86,  2,  92, 16, 101,  8, 116,  1, 125,  2,   0,  0,   0,  0, },
446         {   4,  4,  13,  1,  22,  8,  36,  2,  47,  4,  53, 32,  63,  1,  69,  8, 
447            84,  1,  94,  4, 100,  8, 117, 16, 127, 32,   0,  0,   0,  0, },
448         {   3, 32,   8, 16,  19,  4,  34,  1,  41, 16,  50,  2,  56,  2,  67,  1, 
449            72,  1,  82,  4,  89, 32,  98, 32, 105,  8, 114,  8, 121,  1, },
450         {   1, 32,  19,  2,  24, 32,  33,  1,  40, 16,  51,  4,  64,  8,  83,  8, 
451            99,  1, 104,  1, 114,  4, 120,  4,   0,  0,   0,  0,   0,  0, },
452         {   8,  2,  17,  4,  27, 16,  32,  4,  51,  2,  56, 32,  66,  8,  75, 32, 
453            81,  2,  90, 16,  96,  8, 115,  8, 122,  2,   0,  0,   0,  0, },
454         {   2, 16,  18,  1,  25, 16,  34,  2,  40,  2,  49,  4,  59, 16,  66,  4, 
455            73, 32,  82, 32,  89,  8,  98,  8, 107, 32, 113,  2, 123,  4, },
456         {   7,  1,  13,  8,  28,  1,  38,  4,  44,  8,  61, 16,  71, 32,  77,  1, 
457            86,  8, 100,  2, 111,  4, 117, 32, 124, 16,   0,  0,   0,  0, },
458         {  12,  8,  29, 16,  36,  4,  47, 16,  52, 32,  62, 32,  68,  2,  79,  4, 
459            85, 32,  95,  1, 102,  1, 111,  2, 117,  2, 126,  4,   0,  0, },
460         {   5,  1,  15, 16,  20, 32,  30, 32,  37,  4,  46,  2,  52, 16,  61,  8, 
461            70,  1,  79,  2,  85,  2, 103,  8, 110, 16, 119, 32, 124,  4, },
462         {   0, 16,   9,  2,  18, 16,  24,  8,  43,  8,  59,  1,  65,  4,  75, 16, 
463            80,  4,  99,  2, 104, 32, 113,  1, 123, 32,   0,  0,   0,  0, },
464         {  10, 32,  17,  8,  26,  8,  35, 32,  41,  2,  50, 16,  56,  8,  66,  1, 
465            73, 16,  82,  2,  88,  2,  97,  4, 107, 16, 112,  4, 121, 32, },
466         {   0,  2,  11,  1,  16,  1,  26,  4,  33, 32,  42, 32,  49,  8,  58,  8, 
467            65,  1,  72, 16,  83,  4,  98,  1, 105, 16, 114,  2,   0,  0, },
468         {   8,  8,  27,  8,  43,  1,  48,  1,  58,  4,  64,  4,  83,  2,  88, 32, 
469            97,  1, 104, 16, 115,  4, 122, 16,   0,  0,   0,  0,   0,  0, },
470         {   5,  8,  14,  1,  23,  2,  29,  2,  47,  8,  54, 16,  63, 32,  68,  4, 
471            79, 16,  84, 32,  94, 32, 101,  4, 110,  2, 116, 16, 127,  1, },
472         {   4,  8,  15,  8,  22, 16,  31, 32,  37,  1,  46,  8,  60,  2,  69,  4, 
473            78,  2,  84, 16,  93,  8, 108,  1, 118,  4,   0,  0,   0,  0, },
474         {   7, 16,  14,  8,  28,  2,  39,  4,  45, 32,  55,  1,  62,  1,  76,  1, 
475            86,  4,  92,  8, 109, 16, 116,  4, 125,  1,   0,  0,   0,  0, },
476         {   1,  2,  11,  4,  26,  1,  33, 16,  42,  2,  48,  2,  57,  4,  64,  1, 
477            74,  4,  81, 32,  90, 32,  97,  8, 106,  8, 115, 32, 120, 16, },
478         {   2, 32,  11,  2,  16, 32,  25,  1,  32, 16,  43,  4,  58,  1,  75,  8, 
479            91,  1,  96,  1, 106,  4, 113, 32,   0,  0,   0,  0,   0,  0, },
480         {   3,  1,   9,  4,  19, 16,  24,  4,  43,  2,  48, 32,  57,  1,  67, 32, 
481            73,  2,  82, 16,  88,  8, 107,  8, 120,  2,   0,  0,   0,  0, },
482         {   0,  8,  10,  1,  17, 16,  26,  2,  32,  2,  41,  4,  51, 16,  56,  4, 
483            65, 32,  74, 32,  81,  8,  90,  8,  99, 32, 105,  2, 114, 16, },
484         {   6,  1,  20,  1,  30,  4,  36,  8,  53, 16,  60,  4,  69,  1,  78,  8, 
485            92,  2, 103,  4, 109, 32, 119,  1, 125,  8,   0,  0,   0,  0, },
486         {   7,  8,  21, 16,  28,  4,  39, 16,  44, 32,  54, 32,  61,  4,  71,  4, 
487            77, 32,  87,  1,  94,  1, 103,  2, 109,  2, 124,  8,   0,  0, },
488         {   6,  8,  12, 32,  22, 32,  29,  4,  38,  2,  44, 16,  53,  8,  71,  2, 
489            77,  2,  95,  8, 102, 16, 111, 32, 117,  1, 127, 16,   0,  0, }
490 };
491
492 static void
493 key_setup(char key[DESKEYLEN], char *ek)
494 {
495         int i, j, k, mask;
496         uchar (*x)[2];
497
498         memset(ek, 0, 128);
499         x = keyexpand[0];
500         for(i = 0; i < 7; i++){
501                 k = key[i];
502                 for(mask = 0x80; mask; mask >>= 1){
503                         if(k & mask)
504                                 for(j = 0; j < 15; j++)
505                                         ek[x[j][0]] |= x[j][1];
506                         x += 15;
507                 }
508         }
509 }
510
511
512 /************ netkey main.c *************/
513 int
514 passtokey(char *key, char *p)
515 {
516         uchar buf[NAMELEN], *t;
517         int i, n;
518
519         n = strlen(p);
520         if(n >= NAMELEN)
521                 n = NAMELEN-1;
522         memset(buf, ' ', 8);
523         t = buf;
524         strncpy((char*)t, p, n);
525         t[n] = '\0';
526         memset(key, 0, DESKEYLEN);
527         for(;;){
528                 for(i = 0; i < DESKEYLEN; i++)
529                         key[i] = (t[i] >> i) + (t[i+1] << (8 - (i+1)));
530                 if(n <= 8)
531                         return 1;
532                 n -= 8;
533                 t += 8;
534                 if(n < 8){
535                         t -= 8 - n;
536                         n = 8;
537                 }
538                 encrypt9(key, t, 8);
539         }
540 }
541
542 int
543 netcrypt(void *key, void *chal)
544 {
545         uchar buf[8], *p;
546
547         strncpy((char*)buf, chal, 7);
548         buf[7] = '\0';
549         for(p = buf; *p && *p != '\n'; p++)
550                 ;
551         *p = '\0';
552         encrypt9(key, buf, 8);
553         sprintf(chal, "%.2x%.2x%.2x%.2x", buf[0], buf[1], buf[2], buf[3]);
554         return 1;
555 }
556
557 void
558 main(int argc, char *argv[])
559 {
560         char buf[32], pass[32], key[DESKEYLEN];
561         int n;
562
563         printf("Run this directly on the local processor, NOT in a\n");
564         printf("      window to a computer across the network.\n");
565         printf("Type when no one else is looking.\n\n");
566         printf("password: ");
567         fflush(stdout);
568         n = read(0, pass, sizeof pass - 1);
569         if(n <= 0)
570                 exit(0);
571         pass[n] = 0;\r
572         if(pass[n-1]=='\n')\r
573                 pass[--n] = 0;\r
574         if(pass[n-1]=='\r')\r
575                 pass[--n] = 0;
576         passtokey(key,pass);\r
577         for(;;){
578                 printf("challenge: ");
579                 fflush(stdout);
580                 n = read(0, buf, sizeof buf - 1);
581                 if(n <= 0)
582                         exit(0);
583                 buf[n] = '\0';
584                 netcrypt(key, buf);
585                 printf("response: %s\n", buf);
586         }
587 }