]> git.proxmox.com Git - mirror_qemu.git/blame - crypto/desrfb.c
minikconf: do not include variables from MINIKCONF_ARGS in config-all-devices.mak
[mirror_qemu.git] / crypto / desrfb.c
CommitLineData
6fd27407
TS
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
42f7a448 29#include "qemu/osdep.h"
9fd72468 30#include "crypto/desrfb.h"
6fd27407
TS
31
32static void scrunch(unsigned char *, unsigned long *);
33static void unscrun(unsigned long *, unsigned char *);
34static void desfunc(unsigned long *, unsigned long *);
35static void cookey(unsigned long *);
36
37static unsigned long KnL[32] = { 0L };
38
5bfd5521 39static const unsigned short bytebit[8] = {
2f9f96b2 40 01, 02, 04, 010, 020, 040, 0100, 0200 };
6fd27407 41
5bfd5521 42static const unsigned long bigbyte[24] = {
2f9f96b2
PB
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 };
6fd27407
TS
49
50/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
51
5bfd5521 52static const unsigned char pc1[56] = {
2f9f96b2
PB
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 };
6fd27407 57
5bfd5521 58static const unsigned char totrot[16] = {
2f9f96b2 59 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
6fd27407 60
5bfd5521 61static const unsigned char pc2[48] = {
2f9f96b2
PB
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 };
6fd27407 66
780e264f
BS
67/* Thanks to James Gillogly & Phil Karn! */
68void deskey(unsigned char *key, int edf)
6fd27407 69{
2f9f96b2
PB
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 }
6fd27407 102
780e264f 103static void cookey(register unsigned long *raw1)
6fd27407 104{
2f9f96b2
PB
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 }
6fd27407 124
780e264f 125void usekey(register unsigned long *from)
6fd27407 126{
2f9f96b2 127 register unsigned long *to, *endp;
6fd27407 128
2f9f96b2
PB
129 to = KnL, endp = &KnL[32];
130 while( to < endp ) *to++ = *from++;
131 return;
132 }
6fd27407 133
780e264f 134void des(unsigned char *inblock, unsigned char *outblock)
6fd27407 135{
2f9f96b2 136 unsigned long work[2];
6fd27407 137
2f9f96b2
PB
138 scrunch(inblock, work);
139 desfunc(work, KnL);
140 unscrun(work, outblock);
141 return;
142 }
6fd27407 143
780e264f 144static void scrunch(register unsigned char *outof, register unsigned long *into)
6fd27407 145{
2f9f96b2
PB
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 }
6fd27407 156
780e264f 157static void unscrun(register unsigned long *outof, register unsigned char *into)
6fd27407 158{
2f9f96b2
PB
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 }
6fd27407 169
968467e3 170static const unsigned long SP1[64] = {
2f9f96b2
PB
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 };
6fd27407 187
968467e3 188static const unsigned long SP2[64] = {
2f9f96b2
PB
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 };
6fd27407 205
968467e3 206static const unsigned long SP3[64] = {
2f9f96b2
PB
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 };
6fd27407 223
968467e3 224static const unsigned long SP4[64] = {
2f9f96b2
PB
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 };
6fd27407 241
968467e3 242static const unsigned long SP5[64] = {
2f9f96b2
PB
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 };
6fd27407 259
968467e3 260static const unsigned long SP6[64] = {
2f9f96b2
PB
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 };
6fd27407 277
968467e3 278static const unsigned long SP7[64] = {
2f9f96b2
PB
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 };
6fd27407 295
968467e3 296static const unsigned long SP8[64] = {
2f9f96b2
PB
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 };
6fd27407 313
780e264f 314static void desfunc(register unsigned long *block, register unsigned long *keys)
6fd27407 315{
2f9f96b2
PB
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 }
6fd27407
TS
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 **********************************************************************/