]>
Commit | Line | Data |
---|---|---|
63b81f13 GS |
1 | /* encrypt.c - providing 56 bit DES encryption |
2 | * Copyright (C) 1991 Jochen Obalek | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2, or (at your option) | |
7 | * any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License | |
15 | * along with this program; if not, write to the Free Software | |
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
17 | ||
18 | #include <time.h> | |
19 | #include <string.h> | |
20 | #include <stdlib.h> | |
21 | ||
22 | #define BS 64 | |
23 | #define BS2 32 | |
24 | #define KS 48 | |
25 | #define KS2 24 | |
26 | #define IS 56 | |
27 | #define IS2 28 | |
28 | ||
29 | static char schluessel[16][KS]; | |
30 | ||
31 | ||
32 | static char PC1[] = | |
33 | { | |
34 | 56, 48, 40, 32, 24, 16, 8, 0, | |
35 | 57, 49, 41, 33, 25, 17, 9, 1, | |
36 | 58, 50, 42, 34, 26, 18, 10, 2, | |
37 | 59, 51, 43, 35, | |
38 | 62, 54, 46, 38, 30, 22, 14, 6, | |
39 | 61, 53, 45, 37, 29, 21, 13, 5, | |
40 | 60, 52, 44, 36, 28, 20, 12, 4, | |
41 | 27, 19, 11, 3 | |
42 | }; | |
43 | ||
44 | ||
45 | static char PC2[] = | |
46 | { | |
47 | 13, 16, 10, 23, 0, 4, 2, 27, | |
48 | 14, 5, 20, 9, 22, 18, 11, 3, | |
49 | 25, 7, 15, 6, 26, 19, 12, 1, | |
50 | 40, 51, 30, 36, 46, 54, 29, 39, | |
51 | 50, 44, 32, 47, 43, 48, 38, 55, | |
52 | 33, 52, 45, 41, 49, 35, 28, 31 | |
53 | }; | |
54 | ||
55 | ||
56 | static char IP[] = | |
57 | { | |
58 | 57, 49, 41, 33, 25, 17, 9, 1, | |
59 | 59, 51, 43, 35, 27, 19, 11, 3, | |
60 | 61, 53, 45, 37, 29, 21, 13, 5, | |
61 | 63, 55, 47, 39, 31, 23, 15, 7, | |
62 | 56, 48, 40, 32, 24, 16, 8, 0, | |
63 | 58, 50, 42, 34, 26, 18, 10, 2, | |
64 | 60, 52, 44, 36, 28, 20, 12, 4, | |
65 | 62, 54, 46, 38, 30, 22, 14, 6 | |
66 | }; | |
67 | ||
68 | ||
69 | static char EP[] = | |
70 | { | |
71 | 7, 39, 15, 47, 23, 55, 31, 63, | |
72 | 6, 38, 14, 46, 22, 54, 30, 62, | |
73 | 5, 37, 13, 45, 21, 53, 29, 61, | |
74 | 4, 36, 12, 44, 20, 52, 28, 60, | |
75 | 3, 35, 11, 43, 19, 51, 27, 59, | |
76 | 2, 34, 10, 42, 18, 50, 26, 58, | |
77 | 1, 33, 9, 41, 17, 49, 25, 57, | |
78 | 0, 32, 8, 40, 16, 48, 24, 56 | |
79 | }; | |
80 | ||
81 | ||
82 | static char E0[] = | |
83 | { | |
84 | 31, 0, 1, 2, 3, 4, 3, 4, | |
85 | 5, 6, 7, 8, 7, 8, 9, 10, | |
86 | 11, 12, 11, 12, 13, 14, 15, 16, | |
87 | 15, 16, 17, 18, 19, 20, 19, 20, | |
88 | 21, 22, 23, 24, 23, 24, 25, 26, | |
89 | 27, 28, 27, 28, 29, 30, 31, 0 | |
90 | }; | |
91 | ||
92 | ||
93 | static char E[KS]; | |
94 | ||
95 | ||
96 | static char PERM[] = | |
97 | { | |
98 | 15, 6, 19, 20, 28, 11, 27, 16, | |
99 | 0, 14, 22, 25, 4, 17, 30, 9, | |
100 | 1, 7, 23, 13, 31, 26, 2, 8, | |
101 | 18, 12, 29, 5, 21, 10, 3, 24 | |
102 | }; | |
103 | ||
104 | ||
105 | static char S_BOX[][64] = | |
106 | { | |
107 | { | |
108 | 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1, | |
109 | 3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8, | |
110 | 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7, | |
111 | 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13 | |
112 | }, | |
113 | { | |
114 | 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14, | |
115 | 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5, | |
116 | 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2, | |
117 | 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9 | |
118 | }, | |
119 | { | |
120 | 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10, | |
121 | 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1, | |
122 | 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7, | |
123 | 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12 | |
124 | }, | |
125 | { | |
126 | 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3, | |
127 | 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9, | |
128 | 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8, | |
129 | 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14 | |
130 | }, | |
131 | { | |
132 | 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1, | |
133 | 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6, | |
134 | 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13, | |
135 | 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3 | |
136 | }, | |
137 | { | |
138 | 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5, | |
139 | 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8, | |
140 | 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10, | |
141 | 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13 | |
142 | }, | |
143 | { | |
144 | 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10, | |
145 | 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6, | |
146 | 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7, | |
147 | 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12 | |
148 | }, | |
149 | { | |
150 | 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4, | |
151 | 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2, | |
152 | 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13, | |
153 | 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11 | |
154 | } | |
155 | }; | |
156 | ||
157 | static void | |
158 | perm(a, e, pc, n) | |
159 | register char *a, *e; | |
160 | register char *pc; | |
161 | int n; | |
162 | { | |
163 | for (; n--; pc++, a++) | |
164 | *a = e[*pc]; | |
165 | } | |
166 | ||
167 | static void | |
168 | crypt_main(nachr_l, nachr_r, schl) | |
169 | register char *nachr_l, *nachr_r; | |
170 | register char *schl; | |
171 | { | |
172 | char tmp[KS]; | |
173 | register int sbval; | |
174 | register char *tp = tmp; | |
175 | register char *e = E; | |
176 | register int i, j; | |
177 | ||
178 | for (i = 0; i < 8; i++) { | |
179 | for (j = 0, sbval = 0; j < 6; j++) | |
180 | sbval = (sbval << 1) | (nachr_r[*e++] ^ *schl++); | |
181 | sbval = S_BOX[i][sbval]; | |
182 | for (tp += 4, j = 4; j--; sbval >>= 1) | |
183 | *--tp = sbval & 1; | |
184 | tp += 4; | |
185 | } | |
186 | ||
187 | e = PERM; | |
188 | for (i = 0; i < BS2; i++) | |
189 | *nachr_l++ ^= tmp[*e++]; | |
190 | } | |
191 | ||
192 | void | |
193 | encrypt(char *nachr, int decr) | |
194 | { | |
195 | char (*schl)[KS] = decr ? schluessel + 15 : schluessel; | |
196 | char tmp[BS]; | |
197 | int i; | |
198 | ||
199 | perm(tmp, nachr, IP, BS); | |
200 | ||
201 | for (i = 8; i--;) { | |
202 | crypt_main(tmp, tmp + BS2, *schl); | |
203 | if (decr) | |
204 | schl--; | |
205 | else | |
206 | schl++; | |
207 | crypt_main(tmp + BS2, tmp, *schl); | |
208 | if (decr) | |
209 | schl--; | |
210 | else | |
211 | schl++; | |
212 | } | |
213 | ||
214 | perm(nachr, tmp, EP, BS); | |
215 | } | |
216 | ||
217 | void | |
218 | setkey(char *schl) | |
219 | { | |
220 | char tmp1[IS]; | |
221 | register unsigned int ls = 0x7efc; | |
222 | register int i, j, k; | |
223 | register int shval = 0; | |
224 | register char *akt_schl; | |
225 | ||
226 | memcpy(E, E0, KS); | |
227 | perm(tmp1, schl, PC1, IS); | |
228 | ||
229 | for (i = 0; i < 16; i++) { | |
230 | shval += 1 + (ls & 1); | |
231 | akt_schl = schluessel[i]; | |
232 | for (j = 0; j < KS; j++) { | |
233 | if ((k = PC2[j]) >= IS2) { | |
234 | if ((k += shval) >= IS) | |
235 | k = (k - IS2) % IS2 + IS2; | |
236 | } else if ((k += shval) >= IS2) | |
237 | k %= IS2; | |
238 | *akt_schl++ = tmp1[k]; | |
239 | } | |
240 | ls >>= 1; | |
241 | } | |
242 | } | |
243 | ||
244 | char * | |
245 | crypt(const char *wort, const char *salt) | |
246 | { | |
247 | static char retkey[14]; | |
248 | char key[BS + 2]; | |
249 | char *k; | |
250 | int tmp, keybyte; | |
251 | int i, j; | |
252 | ||
253 | memset(key, 0, BS + 2); | |
254 | ||
255 | for (k = key, i = 0; i < BS; i++) { | |
256 | if (!(keybyte = *wort++)) | |
257 | break; | |
258 | k += 7; | |
259 | for (j = 0; j < 7; j++, i++) { | |
260 | *--k = keybyte & 1; | |
261 | keybyte >>= 1; | |
262 | } | |
263 | k += 8; | |
264 | } | |
265 | ||
266 | setkey(key); | |
267 | memset(key, 0, BS + 2); | |
268 | ||
269 | for (k = E, i = 0; i < 2; i++) { | |
270 | retkey[i] = keybyte = *salt++; | |
271 | if (keybyte > 'Z') | |
272 | keybyte -= 'a' - 'Z' - 1; | |
273 | if (keybyte > '9') | |
274 | keybyte -= 'A' - '9' - 1; | |
275 | keybyte -= '.'; | |
276 | ||
277 | for (j = 0; j < 6; j++, keybyte >>= 1, k++) { | |
278 | if (!(keybyte & 1)) | |
279 | continue; | |
280 | tmp = *k; | |
281 | *k = k[24]; | |
282 | k[24] = tmp; | |
283 | } | |
284 | } | |
285 | ||
286 | for (i = 0; i < 25; i++) | |
287 | encrypt(key, 0); | |
288 | ||
289 | for (k = key, i = 0; i < 11; i++) { | |
290 | for (j = keybyte = 0; j < 6; j++) { | |
291 | keybyte <<= 1; | |
292 | keybyte |= *k++; | |
293 | } | |
294 | ||
295 | keybyte += '.'; | |
296 | if (keybyte > '9') | |
297 | keybyte += 'A' - '9' - 1; | |
298 | if (keybyte > 'Z') | |
299 | keybyte += 'a' - 'Z' - 1; | |
300 | retkey[i + 2] = keybyte; | |
301 | } | |
302 | ||
303 | retkey[i + 2] = 0; | |
304 | ||
305 | if (!retkey[1]) | |
306 | retkey[1] = *retkey; | |
307 | ||
308 | return retkey; | |
309 | } |