BPicture: Fix archive constructor.
[haiku.git] / src / kits / mail / des.c
blob8e9e6d81788f68bf184144706b225e502769e582
1 /* DES - encryption algorithm, removed double and triple DES
2 **
3 ** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
4 */
6 /* D3DES (V5.09) -
8 * A portable, public domain, version of the Data Encryption Standard.
10 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
11 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
12 * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
13 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
14 * for humouring me on.
16 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
17 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
20 #include <des.h>
21 #include <string.h>
23 #define ZOIDBERG_KEY "Zoidberg"
25 static void scrunch(unsigned char *, unsigned long *);
26 static void unscrun(unsigned long *, unsigned char *);
27 static void desfunc(unsigned long *, unsigned long *);
28 static void cookey(unsigned long *);
30 static unsigned long KnL[32] = { 0L };
31 //static unsigned long KnR[32] = { 0L };
32 //static unsigned long Kn3[32] = { 0L };
33 //static unsigned char Df_Key[24] = {
34 // 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
35 // 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
36 // 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 };
38 static unsigned short bytebit[8] = {
39 0200, 0100, 040, 020, 010, 04, 02, 01 };
41 static unsigned long bigbyte[24] = {
42 0x800000L, 0x400000L, 0x200000L, 0x100000L,
43 0x80000L, 0x40000L, 0x20000L, 0x10000L,
44 0x8000L, 0x4000L, 0x2000L, 0x1000L,
45 0x800L, 0x400L, 0x200L, 0x100L,
46 0x80L, 0x40L, 0x20L, 0x10L,
47 0x8L, 0x4L, 0x2L, 0x1L };
49 /* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
51 static unsigned char pc1[56] = {
52 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
53 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
54 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
55 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };
57 static unsigned char totrot[16] = {
58 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
60 static unsigned char pc2[48] = {
61 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
62 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
63 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
64 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
67 void des_decrypt(char *in,int length,char *out)
69 des_setkey((unsigned char *)(ZOIDBERG_KEY),DES_DECRYPT);
70 length = (length + 7) / 8;
71 while (length-- > 0)
73 des_crypt((unsigned char *)(in),(unsigned char *)(out));
74 in += 8; out += 8;
79 void des_encrypt(char *in,char *out)
81 int length = (strlen(in) + 7) / 8;
83 des_setkey((unsigned char *)(ZOIDBERG_KEY),DES_ENCRYPT);
84 while (length-- > 0)
86 des_crypt((unsigned char *)(in),(unsigned char *)(out));
87 in += 8; out += 8;
92 void des_setkey(unsigned char *key,short edf) /* Thanks to James Gillogly & Phil Karn! */
94 register int i, j, l, m, n;
95 unsigned char pc1m[56], pcr[56];
96 unsigned long kn[32];
98 for ( j = 0; j < 56; j++ )
100 l = pc1[j];
101 m = l & 07;
102 pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
104 for( i = 0; i < 16; i++ )
106 if (edf == DES_DECRYPT) m = (15 - i) << 1;
107 else m = i << 1;
108 n = m + 1;
109 kn[m] = kn[n] = 0L;
110 for (j = 0;j < 28;j++)
112 l = j + totrot[i];
113 if (l < 28) pcr[j] = pc1m[l];
114 else pcr[j] = pc1m[l - 28];
116 for (j = 28;j < 56;j++)
118 l = j + totrot[i];
119 if (l < 56) pcr[j] = pc1m[l];
120 else pcr[j] = pc1m[l - 28];
122 for (j = 0;j < 24;j++)
124 if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
125 if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
128 cookey(kn);
132 static void cookey(register unsigned long *raw1)
134 register unsigned long *cook, *raw0;
135 unsigned long dough[32];
136 register int i;
138 cook = dough;
139 for( i = 0; i < 16; i++, raw1++ )
141 raw0 = raw1++;
142 *cook = (*raw0 & 0x00fc0000L) << 6;
143 *cook |= (*raw0 & 0x00000fc0L) << 10;
144 *cook |= (*raw1 & 0x00fc0000L) >> 10;
145 *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
146 *cook = (*raw0 & 0x0003f000L) << 12;
147 *cook |= (*raw0 & 0x0000003fL) << 16;
148 *cook |= (*raw1 & 0x0003f000L) >> 4;
149 *cook++ |= (*raw1 & 0x0000003fL);
151 des_usekey(dough);
155 void des_cpkey(register unsigned long *into)
157 register unsigned long *from, *endp;
159 from = KnL, endp = &KnL[32];
160 while( from < endp ) *into++ = *from++;
164 void des_usekey(register unsigned long *from)
166 register unsigned long *to, *endp;
168 to = KnL, endp = &KnL[32];
169 while( to < endp ) *to++ = *from++;
173 void des_crypt(unsigned char *inblock,unsigned char *outblock)
175 unsigned long work[2];
177 scrunch(inblock, work);
178 desfunc(work, KnL);
179 unscrun(work, outblock);
183 static void scrunch(register unsigned char *outof,register unsigned long *into)
185 *into = (*outof++ & 0xffL) << 24;
186 *into |= (*outof++ & 0xffL) << 16;
187 *into |= (*outof++ & 0xffL) << 8;
188 *into++ |= (*outof++ & 0xffL);
189 *into = (*outof++ & 0xffL) << 24;
190 *into |= (*outof++ & 0xffL) << 16;
191 *into |= (*outof++ & 0xffL) << 8;
192 *into |= (*outof & 0xffL);
196 static void unscrun(register unsigned long *outof,register unsigned char *into)
198 *into++ = (*outof >> 24) & 0xffL;
199 *into++ = (*outof >> 16) & 0xffL;
200 *into++ = (*outof >> 8) & 0xffL;
201 *into++ = *outof++ & 0xffL;
202 *into++ = (*outof >> 24) & 0xffL;
203 *into++ = (*outof >> 16) & 0xffL;
204 *into++ = (*outof >> 8) & 0xffL;
205 *into = *outof & 0xffL;
208 static unsigned long SP1[64] = {
209 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
210 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
211 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
212 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
213 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
214 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
215 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
216 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
217 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
218 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
219 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
220 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
221 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
222 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
223 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
224 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
226 static unsigned long SP2[64] = {
227 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
228 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
229 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
230 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
231 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
232 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
233 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
234 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
235 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
236 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
237 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
238 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
239 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
240 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
241 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
242 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
244 static unsigned long SP3[64] = {
245 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
246 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
247 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
248 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
249 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
250 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
251 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
252 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
253 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
254 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
255 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
256 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
257 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
258 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
259 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
260 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
262 static unsigned long SP4[64] = {
263 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
264 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
265 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
266 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
267 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
268 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
269 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
270 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
271 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
272 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
273 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
274 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
275 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
276 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
277 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
278 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
280 static unsigned long SP5[64] = {
281 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
282 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
283 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
284 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
285 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
286 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
287 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
288 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
289 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
290 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
291 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
292 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
293 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
294 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
295 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
296 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
298 static unsigned long SP6[64] = {
299 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
300 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
301 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
302 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
303 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
304 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
305 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
306 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
307 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
308 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
309 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
310 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
311 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
312 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
313 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
314 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
316 static unsigned long SP7[64] = {
317 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
318 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
319 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
320 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
321 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
322 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
323 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
324 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
325 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
326 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
327 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
328 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
329 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
330 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
331 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
332 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
334 static unsigned long SP8[64] = {
335 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
336 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
337 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
338 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
339 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
340 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
341 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
342 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
343 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
344 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
345 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
346 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
347 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
348 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
349 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
350 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
353 static void desfunc(register unsigned long *block,unsigned long *keys)
355 register unsigned long fval, work, right, leftt;
356 register int round;
358 leftt = block[0];
359 right = block[1];
360 work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
361 right ^= work;
362 leftt ^= (work << 4);
363 work = ((leftt >> 16) ^ right) & 0x0000ffffL;
364 right ^= work;
365 leftt ^= (work << 16);
366 work = ((right >> 2) ^ leftt) & 0x33333333L;
367 leftt ^= work;
368 right ^= (work << 2);
369 work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
370 leftt ^= work;
371 right ^= (work << 8);
372 right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
373 work = (leftt ^ right) & 0xaaaaaaaaL;
374 leftt ^= work;
375 right ^= work;
376 leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
378 for( round = 0; round < 8; round++ )
380 work = (right << 28) | (right >> 4);
381 work ^= *keys++;
382 fval = SP7[ work & 0x3fL];
383 fval |= SP5[(work >> 8) & 0x3fL];
384 fval |= SP3[(work >> 16) & 0x3fL];
385 fval |= SP1[(work >> 24) & 0x3fL];
386 work = right ^ *keys++;
387 fval |= SP8[ work & 0x3fL];
388 fval |= SP6[(work >> 8) & 0x3fL];
389 fval |= SP4[(work >> 16) & 0x3fL];
390 fval |= SP2[(work >> 24) & 0x3fL];
391 leftt ^= fval;
392 work = (leftt << 28) | (leftt >> 4);
393 work ^= *keys++;
394 fval = SP7[ work & 0x3fL];
395 fval |= SP5[(work >> 8) & 0x3fL];
396 fval |= SP3[(work >> 16) & 0x3fL];
397 fval |= SP1[(work >> 24) & 0x3fL];
398 work = leftt ^ *keys++;
399 fval |= SP8[ work & 0x3fL];
400 fval |= SP6[(work >> 8) & 0x3fL];
401 fval |= SP4[(work >> 16) & 0x3fL];
402 fval |= SP2[(work >> 24) & 0x3fL];
403 right ^= fval;
406 right = (right << 31) | (right >> 1);
407 work = (leftt ^ right) & 0xaaaaaaaaL;
408 leftt ^= work;
409 right ^= work;
410 leftt = (leftt << 31) | (leftt >> 1);
411 work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
412 right ^= work;
413 leftt ^= (work << 8);
414 work = ((leftt >> 2) ^ right) & 0x33333333L;
415 right ^= work;
416 leftt ^= (work << 2);
417 work = ((right >> 16) ^ leftt) & 0x0000ffffL;
418 leftt ^= work;
419 right ^= (work << 16);
420 work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
421 leftt ^= work;
422 right ^= (work << 4);
423 *block++ = right;
424 *block = leftt;
428 /* Validation sets:
430 * Single-length key, single-length plaintext -
431 * Key : 0123 4567 89ab cdef
432 * Plain : 0123 4567 89ab cde7
433 * Cipher : c957 4425 6a5e d31d