summaryrefslogtreecommitdiff
path: root/noncore/comm/keypebble/d3des.c
Unidiff
Diffstat (limited to 'noncore/comm/keypebble/d3des.c') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/comm/keypebble/d3des.c439
1 files changed, 439 insertions, 0 deletions
diff --git a/noncore/comm/keypebble/d3des.c b/noncore/comm/keypebble/d3des.c
new file mode 100644
index 0000000..b0f065e
--- a/dev/null
+++ b/noncore/comm/keypebble/d3des.c
@@ -0,0 +1,439 @@
1/*
2 * This is D3DES (V5.09) by Richard Outerbridge with the double and
3 * triple-length support removed for use in VNC. Also the bytebit[] array
4 * has been reversed so that the most significant bit in each byte of the
5 * key is ignored, not the least significant.
6 *
7 * These changes are Copyright (C) 1998 Olivetti & Oracle Research Laboratory
8 *
9 * This software is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 */
13
14/* D3DES (V5.09) -
15 *
16 * A portable, public domain, version of the Data Encryption Standard.
17 *
18 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
19 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
20 * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
21 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
22 * for humouring me on.
23 *
24 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
25 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
26 */
27
28#include "d3des.h"
29
30static void scrunch(unsigned char *, unsigned long *);
31static void unscrun(unsigned long *, unsigned char *);
32static void desfunc(unsigned long *, unsigned long *);
33static void cookey(unsigned long *);
34
35static unsigned long KnL[32] = { 0L };
36static unsigned long KnR[32] = { 0L };
37static unsigned long Kn3[32] = { 0L };
38static unsigned char Df_Key[24] = {
39 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
40 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
41 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 };
42
43 static unsigned short bytebit[8]= {
44 01, 02, 04, 010, 020, 040, 0100, 0200 };
45
46static unsigned long bigbyte[24] = {
47 0x800000L, 0x400000L, 0x200000L,0x100000L,
48 0x80000L, 0x40000L, 0x20000L,0x10000L,
49 0x8000L, 0x4000L, 0x2000L,0x1000L,
50 0x800L, 0x400L, 0x200L, 0x100L,
51 0x80L, 0x40L, 0x20L, 0x10L,
52 0x8L, 0x4L, 0x2L, 0x1L};
53
54/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
55
56static unsigned char pc1[56] = {
57 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
58 9, 1, 58, 50, 42, 34, 26,18, 10, 2, 59, 51, 43, 35,
59 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
60 13, 5, 60, 52, 44, 36, 28,20, 12, 4, 27, 19, 11, 3 };
61
62static unsigned char totrot[16] = {
63 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
64
65static unsigned char pc2[48] = {
66 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
67 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
68 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
69 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
70
71 void deskey(key, edf)/* Thanks to James Gillogly & Phil Karn! */
72unsigned char *key;
73short edf;
74{
75 register int i, j, l, m, n;
76 unsigned char pc1m[56], pcr[56];
77 unsigned long kn[32];
78
79 for ( j = 0; j < 56; j++ ) {
80 l = pc1[j];
81 m = l & 07;
82 pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
83 }
84 for( i = 0; i < 16; i++ ) {
85 if( edf == DE1 ) m = (15 - i) << 1;
86 else m = i << 1;
87 n = m + 1;
88 kn[m] = kn[n] = 0L;
89 for( j = 0; j < 28; j++ ) {
90 l = j + totrot[i];
91 if( l < 28 ) pcr[j] = pc1m[l];
92 else pcr[j] = pc1m[l - 28];
93 }
94 for( j = 28; j < 56; j++ ) {
95 l = j + totrot[i];
96 if( l < 56 ) pcr[j] = pc1m[l];
97 else pcr[j] = pc1m[l - 28];
98 }
99 for( j = 0; j < 24; j++ ) {
100 if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
101 if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
102 }
103 }
104 cookey(kn);
105 return;
106 }
107
108static void cookey(raw1)
109register unsigned long *raw1;
110{
111 register unsigned long *cook, *raw0;
112 unsigned long dough[32];
113 register int i;
114
115 cook = dough;
116 for( i = 0; i < 16; i++, raw1++ ) {
117 raw0 = raw1++;
118 *cook = (*raw0 & 0x00fc0000L) << 6;
119 *cook|= (*raw0 & 0x00000fc0L) << 10;
120 *cook|= (*raw1 & 0x00fc0000L) >> 10;
121 *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
122 *cook = (*raw0 & 0x0003f000L) << 12;
123 *cook|= (*raw0 & 0x0000003fL) << 16;
124 *cook|= (*raw1 & 0x0003f000L) >> 4;
125 *cook++ |= (*raw1 & 0x0000003fL);
126 }
127 usekey(dough);
128 return;
129 }
130
131void cpkey(into)
132register unsigned long *into;
133{
134 register unsigned long *from, *endp;
135
136 from = KnL, endp = &KnL[32];
137 while( from < endp ) *into++ = *from++;
138 return;
139 }
140
141void usekey(from)
142register unsigned long *from;
143{
144 register unsigned long *to, *endp;
145
146 to = KnL, endp = &KnL[32];
147 while( to < endp ) *to++ = *from++;
148 return;
149 }
150
151void des(inblock, outblock)
152unsigned char *inblock, *outblock;
153{
154 unsigned long work[2];
155
156 scrunch(inblock, work);
157 desfunc(work, KnL);
158 unscrun(work, outblock);
159 return;
160 }
161
162static void scrunch(outof, into)
163register unsigned char *outof;
164register unsigned long *into;
165{
166 *into = (*outof++ & 0xffL) << 24;
167 *into|= (*outof++ & 0xffL) << 16;
168 *into|= (*outof++ & 0xffL) << 8;
169 *into++ |= (*outof++ & 0xffL);
170 *into = (*outof++ & 0xffL) << 24;
171 *into|= (*outof++ & 0xffL) << 16;
172 *into|= (*outof++ & 0xffL) << 8;
173 *into|= (*outof & 0xffL);
174 return;
175 }
176
177static void unscrun(outof, into)
178register unsigned long *outof;
179register unsigned char *into;
180{
181 *into++ = (*outof >> 24) & 0xffL;
182 *into++ = (*outof >> 16) & 0xffL;
183 *into++ = (*outof >> 8) & 0xffL;
184 *into++ = *outof++ & 0xffL;
185 *into++ = (*outof >> 24) & 0xffL;
186 *into++ = (*outof >> 16) & 0xffL;
187 *into++ = (*outof >> 8) & 0xffL;
188 *into = *outof & 0xffL;
189 return;
190 }
191
192static unsigned long SP1[64] = {
193 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
194 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
195 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
196 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
197 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
198 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
199 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
200 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
201 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
202 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
203 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
204 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
205 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
206 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
207 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
208 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
209
210static unsigned long SP2[64] = {
211 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
212 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
213 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
214 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
215 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
216 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
217 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
218 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
219 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
220 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
221 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
222 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
223 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
224 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
225 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
226 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
227
228static unsigned long SP3[64] = {
229 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
230 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
231 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
232 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
233 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
234 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
235 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
236 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
237 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
238 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
239 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
240 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
241 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
242 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
243 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
244 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
245
246static unsigned long SP4[64] = {
247 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
248 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
249 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
250 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
251 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
252 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
253 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
254 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
255 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
256 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
257 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
258 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
259 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
260 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
261 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
262 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
263
264static unsigned long SP5[64] = {
265 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
266 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
267 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
268 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
269 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
270 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
271 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
272 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
273 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
274 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
275 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
276 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
277 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
278 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
279 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
280 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
281
282static unsigned long SP6[64] = {
283 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
284 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
285 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
286 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
287 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
288 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
289 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
290 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
291 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
292 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
293 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
294 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
295 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
296 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
297 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
298 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
299
300static unsigned long SP7[64] = {
301 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
302 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
303 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
304 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
305 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
306 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
307 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
308 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
309 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
310 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
311 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
312 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
313 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
314 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
315 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
316 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
317
318static unsigned long SP8[64] = {
319 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
320 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
321 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
322 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
323 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
324 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
325 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
326 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
327 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
328 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
329 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
330 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
331 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
332 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
333 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
334 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
335
336static void desfunc(block, keys)
337register unsigned long *block, *keys;
338{
339 register unsigned long fval, work, right, leftt;
340 register int round;
341
342 leftt = block[0];
343 right = block[1];
344 work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
345 right ^= work;
346 leftt ^= (work << 4);
347 work = ((leftt >> 16) ^ right) & 0x0000ffffL;
348 right ^= work;
349 leftt ^= (work << 16);
350 work = ((right >> 2) ^ leftt) & 0x33333333L;
351 leftt ^= work;
352 right ^= (work << 2);
353 work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
354 leftt ^= work;
355 right ^= (work << 8);
356 right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
357 work = (leftt ^ right) & 0xaaaaaaaaL;
358 leftt ^= work;
359 right ^= work;
360 leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
361
362 for( round = 0; round < 8; round++ ) {
363 work = (right << 28) | (right >> 4);
364 work ^= *keys++;
365 fval = SP7[ work & 0x3fL];
366 fval |= SP5[(work >> 8) & 0x3fL];
367 fval |= SP3[(work >> 16) & 0x3fL];
368 fval |= SP1[(work >> 24) & 0x3fL];
369 work = right ^ *keys++;
370 fval |= SP8[ work & 0x3fL];
371 fval |= SP6[(work >> 8) & 0x3fL];
372 fval |= SP4[(work >> 16) & 0x3fL];
373 fval |= SP2[(work >> 24) & 0x3fL];
374 leftt ^= fval;
375 work = (leftt << 28) | (leftt >> 4);
376 work ^= *keys++;
377 fval = SP7[ work & 0x3fL];
378 fval |= SP5[(work >> 8) & 0x3fL];
379 fval |= SP3[(work >> 16) & 0x3fL];
380 fval |= SP1[(work >> 24) & 0x3fL];
381 work = leftt ^ *keys++;
382 fval |= SP8[ work & 0x3fL];
383 fval |= SP6[(work >> 8) & 0x3fL];
384 fval |= SP4[(work >> 16) & 0x3fL];
385 fval |= SP2[(work >> 24) & 0x3fL];
386 right ^= fval;
387 }
388
389 right = (right << 31) | (right >> 1);
390 work = (leftt ^ right) & 0xaaaaaaaaL;
391 leftt ^= work;
392 right ^= work;
393 leftt = (leftt << 31) | (leftt >> 1);
394 work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
395 right ^= work;
396 leftt ^= (work << 8);
397 work = ((leftt >> 2) ^ right) & 0x33333333L;
398 right ^= work;
399 leftt ^= (work << 2);
400 work = ((right >> 16) ^ leftt) & 0x0000ffffL;
401 leftt ^= work;
402 right ^= (work << 16);
403 work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
404 leftt ^= work;
405 right ^= (work << 4);
406 *block++ = right;
407 *block = leftt;
408 return;
409 }
410
411/* Validation sets:
412 *
413 * Single-length key, single-length plaintext -
414 * Key : 0123 4567 89ab cdef
415 * Plain : 0123 4567 89ab cde7
416 * Cipher : c957 4425 6a5e d31d
417 *
418 * Double-length key, single-length plaintext -
419 * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
420 * Plain : 0123 4567 89ab cde7
421 * Cipher : 7f1d 0a77 826b 8aff
422 *
423 * Double-length key, double-length plaintext -
424 * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
425 * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
426 * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
427 *
428 * Triple-length key, single-length plaintext -
429 * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
430 * Plain : 0123 4567 89ab cde7
431 * Cipher : de0b 7c06 ae5e 0ed5
432 *
433 * Triple-length key, double-length plaintext -
434 * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
435 * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
436 * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5
437 *
438 * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
439 **********************************************************************/