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