1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27: #ifdef DEBUG
28: #include <stdio.h>
29: #endif
30: #include <string.h>
31:
32: #ifndef STATIC
33: #define STATIC static
34: #endif
35:
36: #ifndef DOS
37: #include "ufc-crypt.h"
38: #else
39:
40:
41:
42:
43: #include "pl.h"
44: #include "ufc.h"
45: #endif
46: #include "crypt.h"
47: #include "crypt-private.h"
48:
49:
50: #if __STDC__ - 0
51: #ifndef __GNU_LIBRARY__
52: void _ufc_clearmem (char *start, int cnt);
53: void _ufc_copymem (char *from, char *to, int cnt);
54: #endif
55: #ifdef _UFC_32_
56: STATIC void shuffle_sb (long32 *k, ufc_long saltbits);
57: #else
58: STATIC void shuffle_sb (long64 *k, ufc_long saltbits);
59: #endif
60: #endif
61:
62:
63:
64:
65:
66:
67: static const int pc1[56] = {
68: 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
69: 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
70: 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
71: 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
72: };
73:
74:
75:
76:
77:
78: static const int rots[16] = {
79: 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
80: };
81:
82:
83:
84:
85:
86: static const int pc2[48] = {
87: 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
88: 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
89: 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
90: 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
91: };
92:
93:
94:
95:
96:
97: static const int esel[48] = {
98: 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
99: 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
100: 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
101: 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1
102: };
103:
104:
105:
106:
107:
108: static const int perm32[32] = {
109: 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
110: 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
111: };
112:
113:
114:
115:
116: static const int sbox[8][4][16]= {
117: { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
118: { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
119: { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
120: { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }
121: },
122:
123: { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
124: { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
125: { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
126: { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }
127: },
128:
129: { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
130: { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
131: { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
132: { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }
133: },
134:
135: { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
136: { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
137: { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
138: { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }
139: },
140:
141: { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
142: { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
143: { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
144: { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }
145: },
146:
147: { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
148: { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
149: { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
150: { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }
151: },
152:
153: { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
154: { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
155: { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
156: { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }
157: },
158:
159: { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
160: { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
161: { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
162: { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 }
163: }
164: };
165:
166:
167:
168:
169:
170: static const int initial_perm[64] = {
171: 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
172: 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
173: 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
174: 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
175: };
176:
177:
178:
179:
180:
181: static const int final_perm[64] = {
182: 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
183: 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
184: 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
185: 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
186: };
187:
188: #define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.')
189: #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
190:
191: static const ufc_long BITMASK[24] = {
192: 0x40000000, 0x20000000, 0x10000000, 0x08000000, 0x04000000, 0x02000000,
193: 0x01000000, 0x00800000, 0x00400000, 0x00200000, 0x00100000, 0x00080000,
194: 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200,
195: 0x00000100, 0x00000080, 0x00000040, 0x00000020, 0x00000010, 0x00000008
196: };
197:
198: static const unsigned char bytemask[8] = {
199: 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
200: };
201:
202: static const ufc_long longmask[32] = {
203: 0x80000000, 0x40000000, 0x20000000, 0x10000000,
204: 0x08000000, 0x04000000, 0x02000000, 0x01000000,
205: 0x00800000, 0x00400000, 0x00200000, 0x00100000,
206: 0x00080000, 0x00040000, 0x00020000, 0x00010000,
207: 0x00008000, 0x00004000, 0x00002000, 0x00001000,
208: 0x00000800, 0x00000400, 0x00000200, 0x00000100,
209: 0x00000080, 0x00000040, 0x00000020, 0x00000010,
210: 0x00000008, 0x00000004, 0x00000002, 0x00000001
211: };
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223: static ufc_long do_pc1[8][2][128];
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236: static ufc_long do_pc2[8][128];
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247: static ufc_long eperm32tab[4][256][2];
248:
249:
250:
251:
252:
253:
254:
255:
256: static ufc_long efp[16][64][2];
257:
258:
259:
260:
261:
262: struct crypt_data _ufc_foobar;
263:
264: #ifdef __GNU_LIBRARY__
265: #include <bits/libc-lock.h>
266:
267: __libc_lock_define_initialized (static, _ufc_tables_lock)
268: #endif
269:
270: #ifdef DEBUG
271:
272: void
273: _ufc_prbits(a, n)
274: ufc_long *a;
275: int n;
276: {
277: ufc_long i, j, t, tmp;
278: n /= 8;
279: for(i = 0; i < n; i++) {
280: tmp=0;
281: for(j = 0; j < 8; j++) {
282: t=8*i+j;
283: tmp|=(a[t/24] & BITMASK[t % 24])?bytemask[j]:0;
284: }
285: (void)printf("%02x ",tmp);
286: }
287: printf(" ");
288: }
289:
290: static void
291: _ufc_set_bits(v, b)
292: ufc_long v;
293: ufc_long *b;
294: {
295: ufc_long i;
296: *b = 0;
297: for(i = 0; i < 24; i++) {
298: if(v & longmask[8 + i])
299: *b |= BITMASK[i];
300: }
301: }
302:
303: #endif
304:
305: #ifndef __GNU_LIBRARY__
306:
307:
308:
309:
310:
311:
312: void
313: _ufc_clearmem(start, cnt)
314: char *start;
315: int cnt;
316: {
317: while(cnt--)
318: *start++ = '\0';
319: }
320:
321: void
322: _ufc_copymem(from, to, cnt)
323: char *from, *to;
324: int cnt;
325: {
326: while(cnt--)
327: *to++ = *from++;
328: }
329: #else
330: #define _ufc_clearmem(start, cnt) memset(start, 0, cnt)
331: #define _ufc_copymem(from, to, cnt) memcpy(to, from, cnt)
332: #endif
333:
334:
335:
336: #define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf];
337:
338:
339:
340:
341:
342:
343: void
344: __init_des_r(__data)
345: struct crypt_data * __restrict __data;
346: {
347: int comes_from_bit;
348: int bit, sg;
349: ufc_long j;
350: ufc_long mask1, mask2;
351: int e_inverse[64];
352: static volatile int small_tables_initialized = 0;
353:
354: #ifdef _UFC_32_
355: long32 *sb[4];
356: sb[0] = (long32*)__data->sb0; sb[1] = (long32*)__data->sb1;
357: sb[2] = (long32*)__data->sb2; sb[3] = (long32*)__data->sb3;
358: #endif
359: #ifdef _UFC_64_
360: long64 *sb[4];
361: sb[0] = (long64*)__data->sb0; sb[1] = (long64*)__data->sb1;
362: sb[2] = (long64*)__data->sb2; sb[3] = (long64*)__data->sb3;
363: #endif
364:
365: if(small_tables_initialized == 0) {
366: #ifdef __GNU_LIBRARY__
367: __libc_lock_lock (_ufc_tables_lock);
368: if(small_tables_initialized)
369: goto small_tables_done;
370: #endif
371:
372:
373:
374:
375:
376:
377: _ufc_clearmem((char*)do_pc1, (int)sizeof(do_pc1));
378: for(bit = 0; bit < 56; bit++) {
379: comes_from_bit = pc1[bit] - 1;
380: mask1 = bytemask[comes_from_bit % 8 + 1];
381: mask2 = longmask[bit % 28 + 4];
382: for(j = 0; j < 128; j++) {
383: if(j & mask1)
384: do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2;
385: }
386: }
387:
388:
389:
390:
391:
392:
393: _ufc_clearmem((char*)do_pc2, (int)sizeof(do_pc2));
394: for(bit = 0; bit < 48; bit++) {
395: comes_from_bit = pc2[bit] - 1;
396: mask1 = bytemask[comes_from_bit % 7 + 1];
397: mask2 = BITMASK[bit % 24];
398: for(j = 0; j < 128; j++) {
399: if(j & mask1)
400: do_pc2[comes_from_bit / 7][j] |= mask2;
401: }
402: }
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416: _ufc_clearmem((char*)eperm32tab, (int)sizeof(eperm32tab));
417: for(bit = 0; bit < 48; bit++) {
418: ufc_long mask1,comes_from;
419: comes_from = perm32[esel[bit]-1]-1;
420: mask1 = bytemask[comes_from % 8];
421: for(j = 256; j--;) {
422: if(j & mask1)
423: eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK[bit % 24];
424: }
425: }
426:
427:
428:
429:
430:
431: for(bit=48; bit--;) {
432: e_inverse[esel[bit] - 1 ] = bit;
433: e_inverse[esel[bit] - 1 + 32] = bit + 48;
434: }
435:
436:
437:
438:
439:
440: _ufc_clearmem((char*)efp, (int)sizeof efp);
441: for(bit = 0; bit < 64; bit++) {
442: int o_bit, o_long;
443: ufc_long word_value, mask1, mask2;
444: int comes_from_f_bit, comes_from_e_bit;
445: int comes_from_word, bit_within_word;
446:
447:
448: o_long = bit / 32;
449: o_bit = bit % 32;
450:
451:
452:
453:
454:
455:
456:
457:
458: comes_from_f_bit = final_perm[bit] - 1;
459: comes_from_e_bit = e_inverse[comes_from_f_bit];
460: comes_from_word = comes_from_e_bit / 6;
461: bit_within_word = comes_from_e_bit % 6;
462:
463: mask1 = longmask[bit_within_word + 26];
464: mask2 = longmask[o_bit];
465:
466: for(word_value = 64; word_value--;) {
467: if(word_value & mask1)
468: efp[comes_from_word][word_value][o_long] |= mask2;
469: }
470: }
471: small_tables_initialized = 1;
472: #ifdef __GNU_LIBRARY__
473: small_tables_done:
474: __libc_lock_unlock(_ufc_tables_lock);
475: #endif
476: }
477:
478:
479:
480: