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