source: trunk/third/moira/util/rsaref/desc.c @ 23095

Revision 23095, 20.8 KB checked in by ghudson, 16 years ago (diff)
Import the moira package from SIPB Debathena.
Line 
1/* DESC.C - Data Encryption Standard routines for RSAREF
2     Based on "Karn/Hoey/Outerbridge" implementation (KHODES)
3 */
4
5#include "global.h"
6#include "rsaref.h"
7#include "des.h"
8
9static UINT2 BYTE_BIT[8] = {
10  0200, 0100, 040, 020, 010, 04, 02, 01
11};
12
13static UINT4 BIG_BYTE[24] = {
14  0x800000L, 0x400000L, 0x200000L, 0x100000L,
15  0x80000L,  0x40000L,  0x20000L,  0x10000L,
16  0x8000L,   0x4000L,   0x2000L,   0x1000L,
17  0x800L,    0x400L,    0x200L,    0x100L,
18  0x80L,     0x40L,     0x20L,     0x10L,
19  0x8L,      0x4L,      0x2L,      0x1L
20};
21
22static unsigned char PC1[56] = {
23  56, 48, 40, 32, 24, 16,  8,      0, 57, 49, 41, 33, 25, 17,
24   9,  1, 58, 50, 42, 34, 26,     18, 10,  2, 59, 51, 43, 35,
25  62, 54, 46, 38, 30, 22, 14,      6, 61, 53, 45, 37, 29, 21,
26  13,  5, 60, 52, 44, 36, 28,     20, 12,  4, 27, 19, 11,  3
27};
28
29static unsigned char TOTAL_ROTATIONS[16] = {
30  1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
31};
32
33static unsigned char PC2[48] = {
34  13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
35  22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
36  40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
37  43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
38};
39
40static UINT4 SP1[64] = {
41  0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
42  0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
43  0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
44  0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
45  0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
46  0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
47  0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
48  0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
49  0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
50  0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
51  0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
52  0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
53  0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
54  0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
55  0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
56  0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L
57};
58
59static UINT4 SP2[64] = {
60  0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
61  0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
62  0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
63  0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
64  0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
65  0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
66  0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
67  0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
68  0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
69  0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
70  0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
71  0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
72  0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
73  0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
74  0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
75  0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L
76};
77
78static UINT4 SP3[64] = {
79  0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
80  0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
81  0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
82  0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
83  0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
84  0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
85  0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
86  0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
87  0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
88  0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
89  0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
90  0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
91  0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
92  0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
93  0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
94  0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L
95};
96
97static UINT4 SP4[64] = {
98  0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
99  0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
100  0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
101  0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
102  0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
103  0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
104  0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
105  0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
106  0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
107  0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
108  0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
109  0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
110  0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
111  0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
112  0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
113  0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L
114};
115
116static UINT4 SP5[64] = {
117  0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
118  0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
119  0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
120  0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
121  0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
122  0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
123  0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
124  0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
125  0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
126  0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
127  0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
128  0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
129  0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
130  0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
131  0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
132  0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L
133};
134
135static UINT4 SP6[64] = {
136  0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
137  0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
138  0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
139  0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
140  0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
141  0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
142  0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
143  0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
144  0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
145  0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
146  0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
147  0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
148  0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
149  0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
150  0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
151  0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L
152};
153
154static UINT4 SP7[64] = {
155  0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
156  0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
157  0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
158  0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
159  0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
160  0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
161  0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
162  0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
163  0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
164  0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
165  0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
166  0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
167  0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
168  0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
169  0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
170  0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L
171};
172
173static UINT4 SP8[64] = {
174  0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
175  0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
176  0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
177  0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
178  0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
179  0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
180  0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
181  0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
182  0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
183  0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
184  0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
185  0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
186  0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
187  0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
188  0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
189  0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L
190};
191
192static void Unpack PROTO_LIST ((unsigned char *, UINT4 *));
193static void Pack PROTO_LIST ((UINT4 *, unsigned char *));
194static void DESKey PROTO_LIST ((UINT4 *, unsigned char *, int));
195static void CookKey PROTO_LIST ((UINT4 *, UINT4 *, int));
196static void DESFunction PROTO_LIST ((UINT4 *, UINT4 *));
197
198/* Initialize context.  Caller must zeroize the context when finished.
199 */
200void DES_CBCInit (context, key, iv, encrypt)
201DES_CBC_CTX *context;                                            /* context */
202unsigned char key[8];                                                /* key */
203unsigned char iv[8];                                 /* initializing vector */
204int encrypt;                     /* encrypt flag (1 = encrypt, 0 = decrypt) */
205
206  /* Copy encrypt flag to context.
207   */
208  context->encrypt = encrypt;
209
210  /* Pack initializing vector into context.
211   */
212  Pack (context->iv, iv);
213
214  /* Save the IV for use in Restart */
215  context->originalIV[0] = context->iv[0];
216  context->originalIV[1] = context->iv[1];
217
218  /* Precompute key schedule
219   */
220  DESKey (context->subkeys, key, encrypt);
221}
222
223/* DES-CBC block update operation. Continues a DES-CBC encryption
224   operation, processing eight-byte message blocks, and updating
225   the context.
226 */
227int DES_CBCUpdate (context, output, input, len)
228DES_CBC_CTX *context;                                            /* context */
229unsigned char *output;                                      /* output block */
230unsigned char *input;                                        /* input block */
231unsigned int len;                      /* length of input and output blocks */
232{
233  UINT4 inputBlock[2], work[2];
234  unsigned int i;
235 
236  if (len % 8)
237    return (RE_LEN);
238
239  for (i = 0; i < len/8; i++) {
240    Pack (inputBlock, &input[8*i]);
241       
242    /* Chain if encrypting.
243     */
244    if (context->encrypt) {
245      work[0] = inputBlock[0] ^ context->iv[0];
246      work[1] = inputBlock[1] ^ context->iv[1];
247    }
248    else {
249      work[0] = inputBlock[0];
250      work[1] = inputBlock[1];         
251    }
252
253    DESFunction (work, context->subkeys);
254
255    /* Chain if decrypting, then update IV.
256     */
257    if (context->encrypt) {
258      context->iv[0] = work[0];
259      context->iv[1] = work[1];
260    }
261    else {
262      work[0] ^= context->iv[0];
263      work[1] ^= context->iv[1];
264      context->iv[0] = inputBlock[0];
265      context->iv[1] = inputBlock[1];
266    }
267    Unpack (&output[8*i], work);
268  }
269 
270  /* Zeroize sensitive information.
271   */
272  R_memset ((POINTER)inputBlock, 0, sizeof (inputBlock));
273  R_memset ((POINTER)work, 0, sizeof (work));
274 
275  return (0);
276}
277
278void DES_CBCRestart (context)
279DES_CBC_CTX *context;
280{
281  /* Reset to the original IV */
282  context->iv[0] = context->originalIV[0];
283  context->iv[1] = context->originalIV[1];
284}
285
286/* Initialize context.  Caller must zeroize the context when finished.
287   The key has the DES key, input whitener and output whitener concatenated.
288 */
289void DESX_CBCInit (context, key, iv, encrypt)
290DESX_CBC_CTX *context;
291unsigned char key[24];                              /* DES key and whiteners */
292unsigned char iv[8];                              /* DES initializing vector */
293int encrypt;                      /* encrypt flag (1 = encrypt, 0 = decrypt) */
294
295  /* Copy encrypt flag to context.
296   */
297  context->encrypt = encrypt;
298
299  /* Pack initializing vector and whiteners into context.
300   */
301  Pack (context->iv, iv);
302  Pack (context->inputWhitener, key + 8);
303  Pack (context->outputWhitener, key + 16);
304
305  /* Save the IV for use in Restart */
306  context->originalIV[0] = context->iv[0];
307  context->originalIV[1] = context->iv[1];
308
309  /* Precompute key schedule.
310   */
311  DESKey (context->subkeys, key, encrypt);
312}
313
314/* DESX-CBC block update operation. Continues a DESX-CBC encryption
315   operation, processing eight-byte message blocks, and updating
316   the context.
317 */
318int DESX_CBCUpdate (context, output, input, len)
319DESX_CBC_CTX *context;                                           /* context */
320unsigned char *output;                                      /* output block */
321unsigned char *input;                                        /* input block */
322unsigned int len;                      /* length of input and output blocks */
323{
324  UINT4 inputBlock[2], work[2];
325  unsigned int i;
326 
327  if (len % 8)
328    return (RE_LEN);
329
330  for (i = 0; i < len/8; i++)  {
331    Pack (inputBlock, &input[8*i]);
332       
333    /* Chain if encrypting, and xor with whitener.
334     */
335    if (context->encrypt) {
336      work[0] =
337        inputBlock[0] ^ context->iv[0] ^ context->inputWhitener[0];
338      work[1] =
339        inputBlock[1] ^ context->iv[1] ^ context->inputWhitener[1];
340    }
341    else {
342      work[0] = inputBlock[0] ^ context->outputWhitener[0];
343      work[1] = inputBlock[1] ^ context->outputWhitener[1];         
344    }
345
346    DESFunction (work, context->subkeys);
347
348    /* Xor with whitener, chain if decrypting, then update IV.
349     */
350    if (context->encrypt) {
351      work[0] ^= context->outputWhitener[0];
352      work[1] ^= context->outputWhitener[1];
353      context->iv[0] = work[0];
354      context->iv[1] = work[1];
355    }
356    else {
357      work[0] ^= context->iv[0] ^ context->inputWhitener[0];
358      work[1] ^= context->iv[1] ^ context->inputWhitener[1];
359      context->iv[0] = inputBlock[0];
360      context->iv[1] = inputBlock[1];
361    }
362    Unpack (&output[8*i], work);
363  }
364 
365  /* Zeroize sensitive information.
366   */
367  R_memset ((POINTER)inputBlock, 0, sizeof (inputBlock));
368  R_memset ((POINTER)work, 0, sizeof (work));
369 
370  return (0);
371}
372
373void DESX_CBCRestart (context)
374DESX_CBC_CTX *context;
375{
376  /* Reset to the original IV */
377  context->iv[0] = context->originalIV[0];
378  context->iv[1] = context->originalIV[1];
379}
380
381/* Initialize context.  Caller must zeroize the context when finished.
382 */
383void DES3_CBCInit(context, key, iv, encrypt)
384DES3_CBC_CTX *context;                                           /* context */
385unsigned char key[24];                                               /* key */
386unsigned char iv[8];                                 /* initializing vector */
387int encrypt;                     /* encrypt flag (1 = encrypt, 0 = decrypt) */
388
389  /* Copy encrypt flag to context.
390   */
391  context->encrypt = encrypt;
392
393  /* Pack initializing vector into context.
394   */
395  Pack (context->iv, iv);
396
397  /* Save the IV for use in Restart */
398  context->originalIV[0] = context->iv[0];
399  context->originalIV[1] = context->iv[1];
400
401  /* Precompute key schedules.
402   */
403  DESKey (context->subkeys[0], encrypt ? key : &key[16], encrypt);
404  DESKey (context->subkeys[1], &key[8], !encrypt);
405  DESKey (context->subkeys[2], encrypt ? &key[16] : key, encrypt);
406}
407
408int DES3_CBCUpdate (context, output, input, len)
409DES3_CBC_CTX *context;                                           /* context */
410unsigned char *output;                                      /* output block */
411unsigned char *input;                                        /* input block */
412unsigned int len;                      /* length of input and output blocks */
413{
414  UINT4 inputBlock[2], work[2];
415  unsigned int i;
416 
417  if (len % 8)
418    return (RE_LEN);
419
420  for (i = 0; i < len/8; i++) {
421    Pack (inputBlock, &input[8*i]);
422       
423    /* Chain if encrypting.
424     */
425    if (context->encrypt) {
426      work[0] = inputBlock[0] ^ context->iv[0];
427      work[1] = inputBlock[1] ^ context->iv[1];
428    }
429    else {
430      work[0] = inputBlock[0];
431      work[1] = inputBlock[1];         
432    }
433
434    DESFunction (work, context->subkeys[0]);
435    DESFunction (work, context->subkeys[1]);
436    DESFunction (work, context->subkeys[2]);
437
438    /* Chain if decrypting, then update IV.
439     */
440    if (context->encrypt) {
441      context->iv[0] = work[0];
442      context->iv[1] = work[1];
443    }
444    else {
445      work[0] ^= context->iv[0];
446      work[1] ^= context->iv[1];
447      context->iv[0] = inputBlock[0];
448      context->iv[1] = inputBlock[1];
449    }
450    Unpack (&output[8*i], work);
451  }
452 
453  /* Zeroize sensitive information.
454   */
455  R_memset ((POINTER)inputBlock, 0, sizeof (inputBlock));
456  R_memset ((POINTER)work, 0, sizeof (work));
457 
458  return (0);
459}
460
461void DES3_CBCRestart (context)
462DES3_CBC_CTX *context;
463{
464  /* Reset to the original IV */
465  context->iv[0] = context->originalIV[0];
466  context->iv[1] = context->originalIV[1];
467}
468
469static void Pack (into, outof)
470UINT4 *into;
471unsigned char *outof;
472{
473  *into    = (*outof++ & 0xffL) << 24;
474  *into   |= (*outof++ & 0xffL) << 16;
475  *into   |= (*outof++ & 0xffL) << 8;
476  *into++ |= (*outof++ & 0xffL);
477  *into    = (*outof++ & 0xffL) << 24;
478  *into   |= (*outof++ & 0xffL) << 16;
479  *into   |= (*outof++ & 0xffL) << 8;
480  *into   |= (*outof   & 0xffL);
481}
482
483static void Unpack (into, outof)
484unsigned char *into;
485UINT4 *outof;
486{
487  *into++ = (unsigned char)((*outof >> 24) & 0xffL);
488  *into++ = (unsigned char)((*outof >> 16) & 0xffL);
489  *into++ = (unsigned char)((*outof >>  8) & 0xffL);
490  *into++ = (unsigned char)( *outof++      & 0xffL);
491  *into++ = (unsigned char)((*outof >> 24) & 0xffL);
492  *into++ = (unsigned char)((*outof >> 16) & 0xffL);
493  *into++ = (unsigned char)((*outof >>  8) & 0xffL);
494  *into   = (unsigned char)( *outof        & 0xffL);
495}
496
497static void DESKey (subkeys, key, encrypt)
498UINT4 subkeys[32];
499unsigned char key[8];
500int encrypt;
501{
502  UINT4 kn[32];
503  int i, j, l, m, n;
504  unsigned char pc1m[56], pcr[56];
505
506  for (j = 0; j < 56; j++) {
507    l = PC1[j];
508    m = l & 07;
509    pc1m[j] = (unsigned char)((key[l >> 3] & BYTE_BIT[m]) ? 1 : 0);
510  }
511  for (i = 0; i < 16; i++) {
512    m = i << 1;
513    n = m + 1;
514    kn[m] = kn[n] = 0L;
515    for (j = 0; j < 28; j++) {
516      l = j + TOTAL_ROTATIONS[i];
517      if (l < 28)
518        pcr[j] = pc1m[l];
519      else
520        pcr[j] = pc1m[l - 28];
521    }
522    for (j = 28; j < 56; j++) {
523      l = j + TOTAL_ROTATIONS[i];
524      if (l < 56)
525        pcr[j] = pc1m[l];
526      else
527        pcr[j] = pc1m[l - 28];
528    }
529    for (j = 0; j < 24; j++) {
530      if (pcr[PC2[j]])
531        kn[m] |= BIG_BYTE[j];
532      if (pcr[PC2[j+24]])
533        kn[n] |= BIG_BYTE[j];
534    }
535  }
536  CookKey (subkeys, kn, encrypt);
537
538  /* Zeroize sensitive information.
539   */
540  R_memset ((POINTER)pc1m, 0, sizeof (pc1m));
541  R_memset ((POINTER)pcr, 0, sizeof (pcr));
542  R_memset ((POINTER)kn, 0, sizeof (kn));
543}
544
545static void CookKey (subkeys, kn, encrypt)
546UINT4 *subkeys;
547UINT4 *kn;
548int encrypt;
549{
550  UINT4 *cooked, *raw0, *raw1;
551  int increment;
552  unsigned int i;
553
554  raw1 = kn;
555  cooked = encrypt ? subkeys : &subkeys[30];
556  increment = encrypt ? 1 : -3;
557
558  for (i = 0; i < 16; i++, raw1++) {
559    raw0 = raw1++;
560    *cooked    = (*raw0 & 0x00fc0000L) << 6;
561    *cooked   |= (*raw0 & 0x00000fc0L) << 10;
562    *cooked   |= (*raw1 & 0x00fc0000L) >> 10;
563    *cooked++ |= (*raw1 & 0x00000fc0L) >> 6;
564    *cooked    = (*raw0 & 0x0003f000L) << 12;
565    *cooked   |= (*raw0 & 0x0000003fL) << 16;
566    *cooked   |= (*raw1 & 0x0003f000L) >> 4;
567    *cooked   |= (*raw1 & 0x0000003fL);
568    cooked += increment;
569  }
570}
571
572static void DESFunction (block, subkeys)
573UINT4 *block;
574UINT4 *subkeys;
575{
576  register UINT4 fval, work, right, left;
577  register int round;
578 
579  left = block[0];
580  right = block[1];
581  work = ((left >> 4) ^ right) & 0x0f0f0f0fL;
582  right ^= work;
583  left ^= (work << 4);
584  work = ((left >> 16) ^ right) & 0x0000ffffL;
585  right ^= work;
586  left ^= (work << 16);
587  work = ((right >> 2) ^ left) & 0x33333333L;
588  left ^= work;
589  right ^= (work << 2);
590  work = ((right >> 8) ^ left) & 0x00ff00ffL;
591  left ^= work;
592  right ^= (work << 8);
593  right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
594  work = (left ^ right) & 0xaaaaaaaaL;
595  left ^= work;
596  right ^= work;
597  left = ((left << 1) | ((left >> 31) & 1L)) & 0xffffffffL;
598 
599  for (round = 0; round < 8; round++) {
600    work  = (right << 28) | (right >> 4);
601    work ^= *subkeys++;
602    fval  = SP7[ work        & 0x3fL];
603    fval |= SP5[(work >>  8) & 0x3fL];
604    fval |= SP3[(work >> 16) & 0x3fL];
605    fval |= SP1[(work >> 24) & 0x3fL];
606    work  = right ^ *subkeys++;
607    fval |= SP8[ work        & 0x3fL];
608    fval |= SP6[(work >>  8) & 0x3fL];
609    fval |= SP4[(work >> 16) & 0x3fL];
610    fval |= SP2[(work >> 24) & 0x3fL];
611    left ^= fval;
612    work  = (left << 28) | (left >> 4);
613    work ^= *subkeys++;
614    fval  = SP7[ work        & 0x3fL];
615    fval |= SP5[(work >>  8) & 0x3fL];
616    fval |= SP3[(work >> 16) & 0x3fL];
617    fval |= SP1[(work >> 24) & 0x3fL];
618    work  = left ^ *subkeys++;
619    fval |= SP8[ work        & 0x3fL];
620    fval |= SP6[(work >>  8) & 0x3fL];
621    fval |= SP4[(work >> 16) & 0x3fL];
622    fval |= SP2[(work >> 24) & 0x3fL];
623    right ^= fval;
624  }
625 
626  right = (right << 31) | (right >> 1);
627  work = (left ^ right) & 0xaaaaaaaaL;
628  left ^= work;
629  right ^= work;
630  left = (left << 31) | (left >> 1);
631  work = ((left >> 8) ^ right) & 0x00ff00ffL;
632  right ^= work;
633  left ^= (work << 8);
634  work = ((left >> 2) ^ right) & 0x33333333L;
635  right ^= work;
636  left ^= (work << 2);
637  work = ((right >> 16) ^ left) & 0x0000ffffL;
638  left ^= work;
639  right ^= (work << 16);
640  work = ((right >> 4) ^ left) & 0x0f0f0f0fL;
641  left ^= work;
642  right ^= (work << 4);
643  *block++ = right;
644  *block = left;
645}
Note: See TracBrowser for help on using the repository browser.