Line data Source code
1 : /*
2 : * Copyright (C) 1998,1999,2000,2001 Nikos Mavroyanopoulos
3 : *
4 : * This library is free software; you can redistribute it and/or modify it
5 : * under the terms of the GNU Library General Public License as published
6 : * by the Free Software Foundation; either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This library 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 GNU
12 : * Library General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU Library General Public
15 : * License along with this library; if not, write to the
16 : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 : * Boston, MA 02111-1307, USA.
18 : */
19 :
20 : /* Sofware DES functions
21 : * written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from
22 : * the 1977 public-domain program by Jim Gillogly
23 : * Modified for additional speed - 6 December 1988 Phil Karn
24 : * Modified for parameterized key schedules - Jan 1991 Phil Karn
25 : * Callers now allocate a key schedule as follows:
26 : * kn = (char (*)[8])malloc(sizeof(char) * 8 * 16);
27 : * or
28 : * char kn[16][8];
29 : */
30 :
31 : /* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos
32 : * All modifications are placed under the license of libmcrypt.
33 : */
34 :
35 : #include <config.h>
36 :
37 : #if HAVE_STRING_H
38 : #include <string.h>
39 : #endif /* HAVE_STRING_H */
40 :
41 : #include <tds_sysdep_public.h>
42 : #include <freetds/bytes.h>
43 : #include <freetds/utils/des.h>
44 :
45 : void
46 0 : tds_des_set_odd_parity(des_cblock key)
47 : {
48 :
49 : int i;
50 : unsigned char parity;
51 :
52 0 : for (i = 0; i < 8; i++) {
53 0 : parity = key[i];
54 :
55 0 : parity ^= parity >> 4;
56 0 : parity ^= parity >> 2;
57 0 : parity ^= parity >> 1;
58 :
59 0 : key[i] = (key[i] & 0xfe) | (parity & 1);
60 : }
61 0 : }
62 :
63 : #ifndef HAVE_NETTLE
64 :
65 : static void permute_ip(const des_cblock inblock, const DES_KEY * key, des_cblock outblock);
66 : static void permute_fp(const des_cblock inblock, const DES_KEY * key, des_cblock outblock);
67 : static void perminit_ip(DES_KEY * key);
68 : static void spinit(DES_KEY * key);
69 : static void perminit_fp(DES_KEY * key);
70 : static uint32_t f(const DES_KEY * key, register uint32_t r, register const unsigned char *subkey);
71 :
72 : /* Tables defined in the Data Encryption Standard documents */
73 :
74 : /* initial permutation IP */
75 : static const char ip[] = {
76 : 58, 50, 42, 34, 26, 18, 10, 2,
77 : 60, 52, 44, 36, 28, 20, 12, 4,
78 : 62, 54, 46, 38, 30, 22, 14, 6,
79 : 64, 56, 48, 40, 32, 24, 16, 8,
80 : 57, 49, 41, 33, 25, 17, 9, 1,
81 : 59, 51, 43, 35, 27, 19, 11, 3,
82 : 61, 53, 45, 37, 29, 21, 13, 5,
83 : 63, 55, 47, 39, 31, 23, 15, 7
84 : };
85 :
86 : /* final permutation IP^-1 */
87 : static const char fp[] = {
88 : 40, 8, 48, 16, 56, 24, 64, 32,
89 : 39, 7, 47, 15, 55, 23, 63, 31,
90 : 38, 6, 46, 14, 54, 22, 62, 30,
91 : 37, 5, 45, 13, 53, 21, 61, 29,
92 : 36, 4, 44, 12, 52, 20, 60, 28,
93 : 35, 3, 43, 11, 51, 19, 59, 27,
94 : 34, 2, 42, 10, 50, 18, 58, 26,
95 : 33, 1, 41, 9, 49, 17, 57, 25
96 : };
97 :
98 : /* expansion operation matrix
99 : * This is for reference only; it is unused in the code
100 : * as the f() function performs it implicitly for speed
101 : */
102 : #ifdef notdef
103 : static char ei[] = {
104 : 32, 1, 2, 3, 4, 5,
105 : 4, 5, 6, 7, 8, 9,
106 : 8, 9, 10, 11, 12, 13,
107 : 12, 13, 14, 15, 16, 17,
108 : 16, 17, 18, 19, 20, 21,
109 : 20, 21, 22, 23, 24, 25,
110 : 24, 25, 26, 27, 28, 29,
111 : 28, 29, 30, 31, 32, 1
112 : };
113 : #endif
114 :
115 : /* permuted choice table (key) */
116 : static const char pc1[] = {
117 : 57, 49, 41, 33, 25, 17, 9,
118 : 1, 58, 50, 42, 34, 26, 18,
119 : 10, 2, 59, 51, 43, 35, 27,
120 : 19, 11, 3, 60, 52, 44, 36,
121 :
122 : 63, 55, 47, 39, 31, 23, 15,
123 : 7, 62, 54, 46, 38, 30, 22,
124 : 14, 6, 61, 53, 45, 37, 29,
125 : 21, 13, 5, 28, 20, 12, 4
126 : };
127 :
128 : /* number left rotations of pc1 */
129 : static const char totrot[] = {
130 : 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
131 : };
132 :
133 : /* permuted choice key (table) */
134 : static const char pc2[] = {
135 : 14, 17, 11, 24, 1, 5,
136 : 3, 28, 15, 6, 21, 10,
137 : 23, 19, 12, 4, 26, 8,
138 : 16, 7, 27, 20, 13, 2,
139 : 41, 52, 31, 37, 47, 55,
140 : 30, 40, 51, 45, 33, 48,
141 : 44, 49, 39, 56, 34, 53,
142 : 46, 42, 50, 36, 29, 32
143 : };
144 :
145 : /* The (in)famous S-boxes */
146 : static const char si[8][64] = {
147 : /* S1 */
148 : {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
149 : 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
150 : 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
151 : 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
152 :
153 : /* S2 */
154 : {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
155 : 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
156 : 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
157 : 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
158 :
159 : /* S3 */
160 : {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
161 : 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
162 : 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
163 : 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
164 :
165 : /* S4 */
166 : {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
167 : 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
168 : 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
169 : 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
170 :
171 : /* S5 */
172 : {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
173 : 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
174 : 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
175 : 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
176 :
177 : /* S6 */
178 : {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
179 : 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
180 : 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
181 : 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
182 :
183 : /* S7 */
184 : {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
185 : 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
186 : 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
187 : 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
188 :
189 : /* S8 */
190 : {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
191 : 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
192 : 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
193 : 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11},
194 :
195 : };
196 :
197 : #ifdef notdef
198 : /* 32-bit permutation function P used on the output of the S-boxes */
199 : static const char p32i[] = {
200 : 16, 7, 20, 21,
201 : 29, 12, 28, 17,
202 : 1, 15, 23, 26,
203 : 5, 18, 31, 10,
204 : 2, 8, 24, 14,
205 : 32, 27, 3, 9,
206 : 19, 13, 30, 6,
207 : 22, 11, 4, 25
208 : };
209 : #endif
210 :
211 : #define P32I_INDEX_ROW(n,i,a,b,c,d) \
212 : n==a ? 0+i : n==b ? 1+i : n==c ? 2+i : n==d ? 3+i
213 : #define P32I_INDEX(n) \
214 : (P32I_INDEX_ROW(n, 0, 16, 7, 20, 21) :\
215 : P32I_INDEX_ROW(n, 4, 29, 12, 28, 17) :\
216 : P32I_INDEX_ROW(n, 8, 1, 15, 23, 26) :\
217 : P32I_INDEX_ROW(n,12, 5, 18, 31, 10) :\
218 : P32I_INDEX_ROW(n,16, 2, 8, 24, 14) :\
219 : P32I_INDEX_ROW(n,20, 32, 27, 3, 9) :\
220 : P32I_INDEX_ROW(n,24, 19, 13, 30, 6) :\
221 : P32I_INDEX_ROW(n,28, 22, 11, 4, 25) : 0x7f)
222 :
223 : static const char pbox[32] = {
224 : P32I_INDEX( 1),
225 : P32I_INDEX( 2),
226 : P32I_INDEX( 3),
227 : P32I_INDEX( 4),
228 : P32I_INDEX( 5),
229 : P32I_INDEX( 6),
230 : P32I_INDEX( 7),
231 : P32I_INDEX( 8),
232 : P32I_INDEX( 9),
233 : P32I_INDEX(10),
234 : P32I_INDEX(11),
235 : P32I_INDEX(12),
236 : P32I_INDEX(13),
237 : P32I_INDEX(14),
238 : P32I_INDEX(15),
239 : P32I_INDEX(16),
240 : P32I_INDEX(17),
241 : P32I_INDEX(18),
242 : P32I_INDEX(19),
243 : P32I_INDEX(20),
244 : P32I_INDEX(21),
245 : P32I_INDEX(22),
246 : P32I_INDEX(23),
247 : P32I_INDEX(24),
248 : P32I_INDEX(25),
249 : P32I_INDEX(26),
250 : P32I_INDEX(27),
251 : P32I_INDEX(28),
252 : P32I_INDEX(29),
253 : P32I_INDEX(30),
254 : P32I_INDEX(31),
255 : P32I_INDEX(32),
256 : };
257 :
258 : /* End of DES-defined tables */
259 :
260 : /* Lookup tables initialized once only at startup by des_init() */
261 :
262 : /* bit 0 is left-most in byte */
263 : static const int bytebit[] = {
264 : 0200, 0100, 040, 020, 010, 04, 02, 01
265 : };
266 :
267 : static const int nibblebit[] = {
268 : 010, 04, 02, 01
269 : };
270 :
271 : /* Allocate space and initialize DES lookup arrays
272 : * mode == 0: standard Data Encryption Algorithm
273 : */
274 : static int
275 12 : des_init(DES_KEY * key)
276 : {
277 :
278 12 : spinit(key);
279 12 : perminit_ip(key);
280 12 : perminit_fp(key);
281 :
282 12 : return 0;
283 : }
284 :
285 :
286 : /* Set key (initialize key schedule array) */
287 : int
288 12 : tds_des_set_key(DES_KEY * dkey, const des_cblock user_key, int len)
289 : {
290 : char pc1m[56]; /* place to modify pc1 into */
291 : char pcr[56]; /* place to rotate pc1 into */
292 : register int i, j, l;
293 : int m;
294 :
295 12 : memset(dkey, '\0', sizeof(DES_KEY));
296 12 : des_init(dkey);
297 :
298 : /* Clear key schedule */
299 :
300 :
301 684 : for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */
302 672 : l = pc1[j] - 1; /* integer bit location */
303 672 : m = l & 07; /* find bit */
304 2016 : pc1m[j] = (user_key[l >> 3] & /* find which key byte l is in */
305 672 : bytebit[m]) /* and which bit of that byte */
306 672 : ? 1 : 0; /* and store 1-bit result */
307 :
308 : }
309 192 : for (i = 0; i < 16; i++) { /* key chunk for each iteration */
310 10752 : for (j = 0; j < 56; j++) /* rotate pc1 the right amount */
311 10752 : pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l - 28];
312 : /* rotate left and right halves independently */
313 9216 : for (j = 0; j < 48; j++) { /* select bits individually */
314 : /* check bit that goes to kn[j] */
315 9216 : if (pcr[pc2[j] - 1]) {
316 : /* mask it in if it's there */
317 2820 : l = j % 6;
318 2820 : dkey->kn[i][j / 6] |= bytebit[l] >> 2;
319 : }
320 : }
321 : }
322 12 : return 0;
323 : }
324 :
325 : /* In-place encryption of 64-bit block */
326 : void
327 28 : tds_des_encrypt(const DES_KEY * key, des_cblock block)
328 : {
329 : register uint32_t left, right;
330 : register const unsigned char *knp;
331 : uint32_t work[2]; /* Working data storage */
332 :
333 28 : permute_ip(block, key, (unsigned char *) work); /* Initial Permutation */
334 28 : left = TDS_GET_A4BE(&work[0]);
335 28 : right = TDS_GET_A4BE(&work[1]);
336 :
337 : /* Do the 16 rounds.
338 : * The rounds are numbered from 0 to 15. On even rounds
339 : * the right half is fed to f() and the result exclusive-ORs
340 : * the left half; on odd rounds the reverse is done.
341 : */
342 28 : knp = &key->kn[0][0];
343 28 : left ^= f(key, right, knp);
344 28 : knp += 8;
345 28 : right ^= f(key, left, knp);
346 28 : knp += 8;
347 28 : left ^= f(key, right, knp);
348 28 : knp += 8;
349 28 : right ^= f(key, left, knp);
350 28 : knp += 8;
351 28 : left ^= f(key, right, knp);
352 28 : knp += 8;
353 28 : right ^= f(key, left, knp);
354 28 : knp += 8;
355 28 : left ^= f(key, right, knp);
356 28 : knp += 8;
357 28 : right ^= f(key, left, knp);
358 28 : knp += 8;
359 28 : left ^= f(key, right, knp);
360 28 : knp += 8;
361 28 : right ^= f(key, left, knp);
362 28 : knp += 8;
363 28 : left ^= f(key, right, knp);
364 28 : knp += 8;
365 28 : right ^= f(key, left, knp);
366 28 : knp += 8;
367 28 : left ^= f(key, right, knp);
368 28 : knp += 8;
369 28 : right ^= f(key, left, knp);
370 28 : knp += 8;
371 28 : left ^= f(key, right, knp);
372 28 : knp += 8;
373 28 : right ^= f(key, left, knp);
374 :
375 : /* Left/right half swap, plus byte swap if little-endian */
376 28 : TDS_PUT_A4BE(&work[0], right);
377 28 : TDS_PUT_A4BE(&work[1], left);
378 28 : permute_fp((unsigned char *) work, key, block); /* Inverse initial permutation */
379 28 : }
380 :
381 : /* In-place decryption of 64-bit block. This function is the mirror
382 : * image of encryption; exactly the same steps are taken, but in
383 : * reverse order
384 : */
385 : #if 0
386 : void
387 : _mcrypt_decrypt(DES_KEY * key, unsigned char *block)
388 : {
389 : register uint32_t left, right;
390 : register unsigned char *knp;
391 : uint32_t work[2]; /* Working data storage */
392 :
393 : permute_ip(block, key, (unsigned char *) work); /* Initial permutation */
394 :
395 : /* Left/right half swap, plus byte swap if little-endian */
396 : right = TDS_GET_A4BE(&work[0]);
397 : left = TDS_GET_A4BE(&work[1]);
398 : /* Do the 16 rounds in reverse order.
399 : * The rounds are numbered from 15 to 0. On even rounds
400 : * the right half is fed to f() and the result exclusive-ORs
401 : * the left half; on odd rounds the reverse is done.
402 : */
403 : knp = &key->kn[15][0];
404 : right ^= f(key, left, knp);
405 : knp -= 8;
406 : left ^= f(key, right, knp);
407 : knp -= 8;
408 : right ^= f(key, left, knp);
409 : knp -= 8;
410 : left ^= f(key, right, knp);
411 : knp -= 8;
412 : right ^= f(key, left, knp);
413 : knp -= 8;
414 : left ^= f(key, right, knp);
415 : knp -= 8;
416 : right ^= f(key, left, knp);
417 : knp -= 8;
418 : left ^= f(key, right, knp);
419 : knp -= 8;
420 : right ^= f(key, left, knp);
421 : knp -= 8;
422 : left ^= f(key, right, knp);
423 : knp -= 8;
424 : right ^= f(key, left, knp);
425 : knp -= 8;
426 : left ^= f(key, right, knp);
427 : knp -= 8;
428 : right ^= f(key, left, knp);
429 : knp -= 8;
430 : left ^= f(key, right, knp);
431 : knp -= 8;
432 : right ^= f(key, left, knp);
433 : knp -= 8;
434 : left ^= f(key, right, knp);
435 :
436 : TDS_PUT_A4BE(&work[0], left);
437 : TDS_PUT_A4BE(&work[1], right);
438 : permute_fp((unsigned char *) work, key, block); /* Inverse initial permutation */
439 : }
440 : #endif
441 :
442 : /* Permute inblock with perm */
443 : static void
444 28 : permute_ip(const des_cblock inblock, const DES_KEY * key, des_cblock outblock)
445 : {
446 : register const unsigned char *ib; /* ptr to input block */
447 : register unsigned char *ob; /* ptr to output block */
448 : register const unsigned char *p, *q;
449 : register int j;
450 :
451 : /* Clear output block */
452 28 : memset(outblock, '\0', 8);
453 :
454 28 : ib = inblock;
455 252 : for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */
456 224 : ob = outblock;
457 224 : p = key->iperm[j][(*ib >> 4) & 0xf];
458 224 : q = key->iperm[j + 1][*ib & 0xf];
459 : /* and each output byte, OR the masks together */
460 224 : *ob++ |= *p++ | *q++;
461 224 : *ob++ |= *p++ | *q++;
462 224 : *ob++ |= *p++ | *q++;
463 224 : *ob++ |= *p++ | *q++;
464 224 : *ob++ |= *p++ | *q++;
465 224 : *ob++ |= *p++ | *q++;
466 224 : *ob++ |= *p++ | *q++;
467 224 : *ob++ |= *p++ | *q++;
468 : }
469 28 : }
470 :
471 : /* Permute inblock with perm */
472 : static void
473 28 : permute_fp(const des_cblock inblock, const DES_KEY * key, des_cblock outblock)
474 : {
475 : register const unsigned char *ib; /* ptr to input block */
476 : register unsigned char *ob; /* ptr to output block */
477 : register const unsigned char *p, *q;
478 : register int j;
479 :
480 : /* Clear output block */
481 28 : memset(outblock, '\0', 8);
482 :
483 28 : ib = inblock;
484 252 : for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */
485 224 : ob = outblock;
486 224 : p = key->fperm[j][(*ib >> 4) & 0xf];
487 224 : q = key->fperm[j + 1][*ib & 0xf];
488 : /* and each output byte, OR the masks together */
489 224 : *ob++ |= *p++ | *q++;
490 224 : *ob++ |= *p++ | *q++;
491 224 : *ob++ |= *p++ | *q++;
492 224 : *ob++ |= *p++ | *q++;
493 224 : *ob++ |= *p++ | *q++;
494 224 : *ob++ |= *p++ | *q++;
495 224 : *ob++ |= *p++ | *q++;
496 224 : *ob++ |= *p++ | *q++;
497 : }
498 28 : }
499 :
500 : /* The nonlinear function f(r,k), the heart of DES */
501 : static uint32_t
502 448 : f(const DES_KEY * key, register uint32_t r, register const unsigned char *subkey)
503 : {
504 : register const uint32_t *spp;
505 : register uint32_t rval, rt;
506 : register int er;
507 :
508 : #ifdef TRACE
509 : printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
510 : r, subkey[0], subkey[1], subkey[2], subkey[3], subkey[4], subkey[5], subkey[6], subkey[7]);
511 : #endif
512 : /* Run E(R) ^ K through the combined S & P boxes.
513 : * This code takes advantage of a convenient regularity in
514 : * E, namely that each group of 6 bits in E(R) feeding
515 : * a single S-box is a contiguous segment of R.
516 : */
517 448 : subkey += 7;
518 :
519 : /* Compute E(R) for each block of 6 bits, and run thru boxes */
520 448 : er = ((int) r << 1) | ((r & 0x80000000) ? 1 : 0);
521 448 : spp = &key->sp[7][0];
522 448 : rval = spp[(er ^ *subkey--) & 0x3f];
523 448 : spp -= 64;
524 448 : rt = (uint32_t) r >> 3;
525 448 : rval |= spp[((int) rt ^ *subkey--) & 0x3f];
526 448 : spp -= 64;
527 448 : rt >>= 4;
528 448 : rval |= spp[((int) rt ^ *subkey--) & 0x3f];
529 448 : spp -= 64;
530 448 : rt >>= 4;
531 448 : rval |= spp[((int) rt ^ *subkey--) & 0x3f];
532 448 : spp -= 64;
533 448 : rt >>= 4;
534 448 : rval |= spp[((int) rt ^ *subkey--) & 0x3f];
535 448 : spp -= 64;
536 448 : rt >>= 4;
537 448 : rval |= spp[((int) rt ^ *subkey--) & 0x3f];
538 448 : spp -= 64;
539 448 : rt >>= 4;
540 448 : rval |= spp[((int) rt ^ *subkey--) & 0x3f];
541 448 : spp -= 64;
542 448 : rt >>= 4;
543 448 : rt |= (r & 1) << 5;
544 448 : rval |= spp[((int) rt ^ *subkey) & 0x3f];
545 : #ifdef TRACE
546 : printf(" %08lx\n", rval);
547 : #endif
548 448 : return rval;
549 : }
550 :
551 : /* initialize a perm array */
552 : static void
553 12 : perminit_ip(DES_KEY * key)
554 : {
555 : register int l, j, k;
556 : int i, m;
557 :
558 : /* Clear the permutation array */
559 12 : memset(key->iperm, '\0', 16 * 16 * 8);
560 :
561 204 : for (i = 0; i < 16; i++) /* each input nibble position */
562 3072 : for (j = 0; j < 16; j++) /* each possible input nibble */
563 196608 : for (k = 0; k < 64; k++) { /* each output bit position */
564 196608 : l = ip[k] - 1; /* where does this bit come from */
565 196608 : if ((l >> 2) != i) /* does it come from input posn? */
566 184320 : continue; /* if not, bit k is 0 */
567 12288 : if (!(j & nibblebit[l & 3]))
568 6144 : continue; /* any such bit in input? */
569 6144 : m = k & 07; /* which bit is this in the byte */
570 6144 : key->iperm[i][j][k >> 3] |= bytebit[m];
571 : }
572 12 : }
573 :
574 : static void
575 12 : perminit_fp(DES_KEY * key)
576 : {
577 : register int l, j, k;
578 : int i, m;
579 :
580 : /* Clear the permutation array */
581 12 : memset(key->fperm, '\0', 16 * 16 * 8);
582 :
583 204 : for (i = 0; i < 16; i++) /* each input nibble position */
584 3072 : for (j = 0; j < 16; j++) /* each possible input nibble */
585 196608 : for (k = 0; k < 64; k++) { /* each output bit position */
586 196608 : l = fp[k] - 1; /* where does this bit come from */
587 196608 : if ((l >> 2) != i) /* does it come from input posn? */
588 184320 : continue; /* if not, bit k is 0 */
589 12288 : if (!(j & nibblebit[l & 3]))
590 6144 : continue; /* any such bit in input? */
591 6144 : m = k & 07; /* which bit is this in the byte */
592 6144 : key->fperm[i][j][k >> 3] |= bytebit[m];
593 : }
594 12 : }
595 :
596 : /* Initialize the lookup table for the combined S and P boxes */
597 : static void
598 12 : spinit(DES_KEY * key)
599 : {
600 : int i, s, j, rowcol;
601 : uint32_t val;
602 :
603 108 : for (s = 0; s < 8; s++) { /* For each S-box */
604 6144 : for (i = 0; i < 64; i++) { /* For each possible input */
605 6144 : val = 0;
606 : /* The row number is formed from the first and last
607 : * bits; the column number is from the middle 4
608 : */
609 6144 : rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf);
610 30720 : for (j = 0; j < 4; j++) { /* For each output bit */
611 24576 : if (si[s][rowcol] & (8 >> j)) {
612 12288 : val |= 1L << (31 - pbox[4 * s + j]);
613 : }
614 : }
615 6144 : key->sp[s][i] = val;
616 : }
617 : }
618 12 : }
619 :
620 : #endif
621 :
622 : /* ECB MODE */
623 :
624 : int
625 24 : tds_des_ecb_encrypt(const void *plaintext, int len, DES_KEY * akey, unsigned char *output)
626 : {
627 : int j;
628 24 : const unsigned char *plain = (const unsigned char *) plaintext;
629 :
630 80 : for (j = 0; j < len / 8; j++) {
631 56 : memcpy(&output[j * 8], &plain[j * 8], 8);
632 84 : tds_des_encrypt(akey, &output[j * 8]);
633 : }
634 24 : if (j == 0 && len != 0)
635 : return -1; /* no blocks were encrypted */
636 24 : return 0;
637 : }
|