]> andersk Git - moira.git/blob - util/gdss/lib/crypto/algorithm/DEScrypto.h
initial import of gdss from the Athena source tree
[moira.git] / util / gdss / lib / crypto / algorithm / DEScrypto.h
1 /* DEScrypto.h */
2 /*
3  * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
4  * ALL RIGHTS RESERVED
5  *
6  * "Digital Equipment Corporation authorizes the reproduction,
7  * distribution and modification of this software subject to the following
8  * restrictions:
9  * 
10  * 1.  Any partial or whole copy of this software, or any modification
11  * thereof, must include this copyright notice in its entirety.
12  *
13  * 2.  This software is supplied "as is" with no warranty of any kind,
14  * expressed or implied, for any purpose, including any warranty of fitness 
15  * or merchantibility.  DIGITAL assumes no responsibility for the use or
16  * reliability of this software, nor promises to provide any form of 
17  * support for it on any basis.
18  *
19  * 3.  Distribution of this software is authorized only if no profit or
20  * remuneration of any kind is received in exchange for such distribution.
21  * 
22  * 4.  This software produces public key authentication certificates
23  * bearing an expiration date established by DIGITAL and RSA Data
24  * Security, Inc.  It may cease to generate certificates after the expiration
25  * date.  Any modification of this software that changes or defeats
26  * the expiration date or its effect is unauthorized.
27  * 
28  * 5.  Software that will renew or extend the expiration date of
29  * authentication certificates produced by this software may be obtained
30  * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
31  * 94065, (415)595-8782, or from DIGITAL"
32  *
33  */
34
35 /* In-line include file for DES routines */
36
37 #ifndef SPHINX_DESCRYPTO
38 #define SPHINX_DESCRYPTO
39
40 /*
41  *********************************************************************
42  *********************************************************************
43  **                                                                 **
44  **                       W A R N I N G                             **
45  **                                                                 **
46  **  This software is subject to export restrictions under the      **
47  **  U.S. Department of State's International Traffic in Arms       **
48  **  Regulations (ITAR).  This software must not be transmitted     **
49  **  in source form outside the United States or to a foreign       **
50  **  national in the United States without a valid U.S. State       **
51  **  Department export license.                                     **
52  **                                                                 **
53  *********************************************************************
54  *********************************************************************
55 */
56
57 #ifndef SPHINX_ITAR
58 #define SPHINX_ITAR
59 static char copyright[] = "\n Copyright, 1989, 1990, Digital Equipment Corporation \n";
60 static char warning[]= "\n  This software is subject to export restrictions under \
61 \n  the U.S. Department of State's International Traffic in Arms \
62 \n  Regulations (ITAR).  This software must not be transmitted \
63 \n  in source form outside the United States or to a foreign \
64 \n  national in the United States without a valid U.S. State \
65 \n  Department export license. ";
66 #endif
67
68 #include "endian.h"
69 #include "hashes.h"
70 #include "random.h"
71 #include "tables.h"
72
73 static DESdecrypt_local();
74 static DESencrypt_local();
75 static void DES_load_key_local();
76 static int DES_CBC_encrypt_local ();
77 static int DES_CBC_decrypt_local ();
78
79 typedef struct 
80 {                                       /* DES key schedule */
81     unsigned char       subkey[16][8];  /* 8 6-bit subkeys per round */
82 } KEYschedule;
83
84 /*
85  * The following macros perform the initial and final permutations on a
86  * DES block. The output is accessed as 32-bit units and the input as 8-bit
87  * units.
88  *
89  * Note: These macros reference 2 permutation arrays (iperm and fperm) which
90  *       are machine generated and must be included with any program using
91  *       these macros.
92  */
93
94 #define INITIAL(out, in) \
95     out[0] = iperma[in[0]] \
96              | (iperma[in[1]] << 1) \
97              | (iperma[in[2]] << 2) \
98              | (iperma[in[3]] << 3) \
99              | (iperma[in[4]] << 4) \
100              | (iperma[in[5]] << 5) \
101              | (iperma[in[6]] << 6) \
102              | (iperma[in[7]] << 7); \
103     out[1] = ipermb[in[0]] \
104              | (ipermb[in[1]] << 1) \
105              | (ipermb[in[2]] << 2) \
106              | (ipermb[in[3]] << 3) \
107              | (ipermb[in[4]] << 4) \
108              | (ipermb[in[5]] << 5) \
109              | (ipermb[in[6]] << 6) \
110              | (ipermb[in[7]] << 7)
111
112 #if SPHINX_ENDIAN
113 #define FINAL(out, in) \
114     out[0] = fperma[in[0]] \
115              | (fperma[in[4]] << 1) \
116              | (fperma[in[1]] << 2) \
117              | (fperma[in[5]] << 3) \
118              | (fperma[in[2]] << 4) \
119              | (fperma[in[6]] << 5) \
120              | (fperma[in[3]] << 6) \
121              | (fperma[in[7]] << 7); \
122     out[1] = fpermb[in[0]] \
123              | (fpermb[in[4]] << 1) \
124              | (fpermb[in[1]] << 2) \
125              | (fpermb[in[5]] << 3) \
126              | (fpermb[in[2]] << 4) \
127              | (fpermb[in[6]] << 5) \
128              | (fpermb[in[3]] << 6) \
129              | (fpermb[in[7]] << 7);
130 #else
131 #define FINAL(out, in) \
132     out[0] = fperma[in[3]] \
133              | (fperma[in[7]] << 1) \
134              | (fperma[in[2]] << 2) \
135              | (fperma[in[6]] << 3) \
136              | (fperma[in[1]] << 4) \
137              | (fperma[in[5]] << 5) \
138              | (fperma[in[0]] << 6) \
139              | (fperma[in[4]] << 7); \
140     out[1] = fpermb[in[3]] \
141              | (fpermb[in[7]] << 1) \
142              | (fpermb[in[2]] << 2) \
143              | (fpermb[in[6]] << 3) \
144              | (fpermb[in[1]] << 4) \
145              | (fpermb[in[5]] << 5) \
146              | (fpermb[in[0]] << 6) \
147              | (fpermb[in[4]] << 7);
148
149 #endif  /* SPHINX_ENDIAN */
150
151 /*
152  * The following tables are taken directly from FIPS PUB 46 (Specifications
153  * for the Data Encryption Standard).
154  */
155
156 /*
157  * Number of left rotations of pc1
158  */
159 static char totrot[] = {
160         1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
161 };
162
163 /*
164  * Permuted choice key (table)
165  */
166 static char pc2[] = {
167         14, 17, 11, 24,  1,  5,
168          3, 28, 15,  6, 21, 10,
169         23, 19, 12,  4, 26,  8,
170         16,  7, 27, 20, 13,  2,
171         41, 52, 31, 37, 47, 55,
172         30, 40, 51, 45, 33, 48,
173         44, 49, 39, 56, 34, 53,
174         46, 42, 50, 36, 29, 32
175 };
176
177 /*
178  * Note that the Standard is written in Big Endian terms so bit 1 is the
179  * high bit of the byte.
180  */
181 static int bytebit[] = {
182     0200, 0100, 040, 020, 010, 04, 02, 01
183 };
184
185 /*
186  * Declare external and forward routines.
187  */
188
189 \f
190 /*
191  *
192  * Functional Description:
193  *
194  *      Perform a DES decryption of a single 8-byte block producing
195  *      another 8-byte block.
196  *
197  * Inputs:
198  *
199  *      indata  - Pointer to the input data
200  *
201  * Outputs:
202  *
203  *      outdata - Pointer to the output data
204  *
205  * Return Value:
206  *
207  *      None
208  *
209  */
210 static DESdecrypt_local( indata,outdata,key_schedule )
211 KEYschedule *key_schedule ;
212 DESblock *indata,*outdata;
213 {
214     register int i;
215     register INT32 er,out;
216     register unsigned char *subkey;
217     INT32 index;
218     DESblock temp;
219     
220     /*
221      * Perform the initial transformation.
222      */
223     INITIAL(temp.longwords, indata->bytes);
224
225     /*
226      * Now swap halves of the working block.
227      */
228     out = temp.longwords[0];
229     temp.longwords[0] = temp.longwords[1];
230     temp.longwords[1] = out;
231     
232     /*
233      * Perform the decryption operation.
234      */
235     for (i = 15; i >= 0; i--)
236     {
237         /*
238          * Select the subkey for this round.
239          */
240         subkey = key_schedule->subkey[i];
241
242         /*
243          * Compute the index value to be used for the first 7 subkeys.
244          */
245         index = temp.longwords[1 - (i & 1)];
246         er = (index >> 1) | ((index & 1) ? 0x80000000 : 0);
247         
248         /*
249          * Perform one round of E(input) ^ K through the combined S and
250          * P boxes.
251          */
252         out  = sp[0][((er >> 26) & 0x3F) ^ *subkey++];
253         out |= sp[1][((er >> 22) & 0x3F) ^ *subkey++];
254         out |= sp[2][((er >> 18) & 0x3F) ^ *subkey++];
255         out |= sp[3][((er >> 14) & 0x3F) ^ *subkey++];
256         out |= sp[4][((er >> 10) & 0x3F) ^ *subkey++];
257         out |= sp[5][((er >> 6) & 0x3F) ^ *subkey++];
258         out |= sp[6][((er >> 2) & 0x3F) ^ *subkey++];
259         er = (index << 1) | ((index & 0x80000000) ? 1 : 0);
260         out |= sp[7][(er & 0x3F) ^ *subkey];
261
262         temp.longwords[i & 1] ^= out;
263     }
264     
265     /*
266      * Perform the final transformation.
267      */
268     FINAL(outdata->longwords, temp.bytes);
269 }
270
271 \f
272 /*
273  *
274  * Functional Description:
275  *
276  *      Perform a DES encryption of a single 8-byte block producing
277  *      another 8-byte block.
278  *
279  * Inputs:
280  *
281  *      indata  - Pointer to the input data
282  *
283  * Outputs:
284  *
285  *      outdata - Pointer to the output data
286  *
287  * Return Value:
288  *
289  *      None
290  *
291  */
292 static DESencrypt_local( indata,outdata,key_schedule )
293 DESblock *indata,*outdata;
294 KEYschedule *key_schedule ;
295 {
296     register int i;
297     register INT32 er,out;
298     register unsigned char *subkey;
299     INT32 index;
300     DESblock temp;
301     
302     /*
303      * Perform the initial transformation.
304      */
305     INITIAL(temp.longwords, indata->bytes);
306     
307     /*
308      * Perform the encryption operation.
309      */
310     for (i = 0; i < 16; i++)
311     {
312         /*
313          * Select the subkey for this round.
314          */
315         subkey = key_schedule->subkey[i];
316
317         /*
318          * Compute the index value to be used for the first 7 subkeys.
319          */
320         index = temp.longwords[1 - (i & 1)];
321         er = (index >> 1) | ((index & 1) ? 0x80000000 : 0);
322         
323         /*
324          * Perform one round of E(input) ^ K through the combined S and
325          * P boxes.
326          */
327         out  = sp[0][((er >> 26) & 0x3F) ^ *subkey++];
328         out |= sp[1][((er >> 22) & 0x3F) ^ *subkey++];
329         out |= sp[2][((er >> 18) & 0x3F) ^ *subkey++];
330         out |= sp[3][((er >> 14) & 0x3F) ^ *subkey++];
331         out |= sp[4][((er >> 10) & 0x3F) ^ *subkey++];
332         out |= sp[5][((er >> 6) & 0x3F) ^ *subkey++];
333         out |= sp[6][((er >> 2) & 0x3F) ^ *subkey++];
334         er = (index << 1) | ((index & 0x80000000) ? 1 : 0);
335         out |= sp[7][(er & 0x3F) ^ *subkey];
336
337         temp.longwords[i & 1] ^= out;
338     }
339     
340     /*
341      * Now swap halves of the working block.
342      */
343     out = temp.longwords[0];
344     temp.longwords[0] = temp.longwords[1];
345     temp.longwords[1] = out;
346
347     /*
348      * Perform the final transformation.
349      */
350     FINAL(outdata->longwords, temp.bytes);
351 }
352 \f
353 /*
354  *
355  * Functional Description:
356  *
357  *      Expand a DES key from an 8-byte array into a key schedule. This
358  *      expansion allows the later encryption routines to operate faster.
359  *
360  * Inputs:
361  *
362  *      inkey   - Pointer to an 8-byte input key
363  *
364  * Outputs:
365  *
366  * Return Value:
367  *
368  *      None
369  *
370  */
371 static void DES_load_key_local( key, key_schedule )
372 register unsigned char *key;
373 KEYschedule *key_schedule ;
374 {
375     register int i,j,k;
376     unsigned char k1[56],k2[56];
377
378     /*
379      * Clear out the key schedule, in case it isn't already
380      */
381     memset(key_schedule, 0, sizeof(KEYschedule));
382     
383     /*
384      * Compute the key for the first round as an array of 56 bits (k1).
385      */
386     for (i = 0; i < 56; i++)
387         k1[i] = (key[pc1byte[i]] & pc1bit[i]) ? 1 : 0;
388
389     /*
390      * Build the subkeys by rotating and selecting the bits from each
391      * iteration.
392      */
393     for (i = 0; i < 16; i++)
394     {
395         /*
396          * Rotate the initial key permutation the correct amount for
397          * this subkey, rotating each half independently.
398          */
399         for (j = 0; j < 56; j++)
400             k2[j] = k1[(k = j + totrot[i]) < (j < 28 ? 28 : 56) ? k : k - 28];
401
402         /*
403          * Select the final values for each subkey.
404          */
405         for (j = 0; j < 48; j++)
406             if (k2[pc2[j] - 1] != 0)
407                 key_schedule->subkey[i][j/6] |= bytebit[j % 6] >> 2;
408     }
409 }
410
411
412 \f
413 /*
414  *
415  *                      D E S _ C B C _ e n c r y p t
416  *
417  *      Encrypt a buffer using DES in Cipher Block Chaining mode.
418  *
419  * Inputs:
420  *      iv      - Pointer to initialization vector or zero
421  *      inbuf   - Pointer to the input buffer
422  *      isize   - Size of the input buffer
423  *      outbuf  - Pointer to the output buffer (can be same as input)
424  *
425  * Outputs:
426  *      outbuf  - contains encrypted data
427  *
428  * Return Value:
429  *      0       - Buffer is not a multiple of 8 bytes
430  *      1       - Success
431  */
432 static int DES_CBC_encrypt_local (iv , inbuf, isize, outbuf,key_schedule)
433 unsigned char * iv, * inbuf, * outbuf ;
434 int isize;
435 KEYschedule *key_schedule ;
436 {
437         unsigned long temp1[2] ;
438         unsigned long * inptr = (unsigned long *) inbuf;
439         unsigned long * outptr = (unsigned long *) outbuf;
440     
441         /*
442          * Check that we have a good buffer size.
443          */
444         if ((isize & 0x7) != 0) return (0);
445
446         if (iv!=0) memcpy(temp1,iv,sizeof(temp1)); /* copy over initialization vector */
447         else    memset(temp1,0,sizeof(temp1));
448
449         while (isize > 0) {
450
451                 temp1[0] ^= * inptr ++ ; /* XOR previous ciphertext with next data */
452                 temp1[1] ^= * inptr ++ ;
453                 
454                 DESencrypt_local(temp1,temp1,key_schedule); /* encrypt */
455                 
456                 * outptr ++ = temp1 [0]; /* copy out data */
457                 * outptr ++ = temp1 [1];
458
459                 isize -= 8;
460         }
461         return(1);
462 }
463 \f
464 /*
465  *
466  *                      D E S _ C B C _ d e c r y p t
467  *
468  *      Decrypt a buffer using DES in Cipher Block Chaining mode.
469  *
470  * Inputs:
471  *      iv      - Pointer to initialization vector or zero
472  *      inbuf   - Pointer to the input buffer
473  *      isize   - Size of the input buffer
474  *      outbuf  - Pointer to the output buffer  (can be same as input)
475  *
476  * Outputs:
477  *      outbuf  - contains encrypted data
478  *
479  * Return Value:
480  *      0       - Buffer is not a multiple of 8 bytes
481  *      1       - Success
482  */
483 static int DES_CBC_decrypt_local (iv , inbuf, isize, outbuf,key_schedule)
484 char * iv, * inbuf, * outbuf ;
485 int isize;
486 KEYschedule *key_schedule ;
487 {
488         unsigned long temp1[2], temp2[2];
489         unsigned long * inptr = (unsigned long *) inbuf;
490         unsigned long * outptr = (unsigned long *) outbuf;
491     
492         /*
493          * Check that we have a good buffer size.
494          */
495         if ((isize & 0x7) != 0) return (0);
496
497         if (iv!=0) memcpy(temp1,iv,sizeof(temp1)); /* copy over initialization vector */
498         else    memset(temp1,0,sizeof(temp1));
499
500         while (isize > 0) {
501                 DESdecrypt_local(inptr,temp2,key_schedule); /* decrypt to temporary */
502
503                 temp2[0] ^= temp1 [0]; /* XOR previous ciphertext with data */
504                 temp2[1] ^= temp1 [1];
505                 
506                 temp1[0] = * inptr ++ ; /* copy in ciphertext for next block XOR */
507                 temp1[1] = * inptr ++ ;
508
509                 * outptr ++ = temp2 [0]; /* copy out data */
510                 * outptr ++ = temp2 [1];
511
512                 isize -= 8;
513         }
514         return(1);
515 }
516
517 #endif
This page took 0.0781 seconds and 5 git commands to generate.