source: trunk/src/testing/app/vnc/d3des.cpp @ 4

Revision 4, 16.2 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1/*
2 * This is D3DES (V5.09) by Richard Outerbridge with the double and
3 * triple-length support removed for use in VNC.  Also the bytebit[] array
4 * has been reversed so that the most significant bit in each byte of the
5 * key is ignored, not the least significant.
6 *
7 * These changes are:
8 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
9 *
10 * This software is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 */
14
15/* D3DES (V5.09) -
16 *
17 * A portable, public domain, version of the Data Encryption Standard.
18 *
19 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
20 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
21 * code;  Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
22 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
23 * for humouring me on.
24 *
25 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
26 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
27 */
28
29/* March 3, 2006
30   Modified by Ratko Jagodic
31   Added a method for using normal DES decryption where the bits of
32   every byte of the password are not mirrored.
33*/
34
35#include "d3des.h"
36
37static void scrunch(unsigned char *, unsigned long *);
38static void unscrun(unsigned long *, unsigned char *);
39static void desfunc(unsigned long *, unsigned long *);
40static void cookey(unsigned long *);
41
42static unsigned long KnL[32] = { 0L };
43static unsigned long KnR[32] = { 0L };
44static unsigned long Kn3[32] = { 0L };
45static unsigned char Df_Key[24] = {
46        0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
47        0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
48        0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 };
49
50// Ratko Jagodic changed so that bytebit can be changed later
51static unsigned short bytebitArray[8]   = {
52        01, 02, 04, 010, 020, 040, 0100, 0200 };
53static unsigned short *bytebit = bytebitArray;
54
55
56static unsigned long bigbyte[24] = {
57        0x800000L,      0x400000L,      0x200000L,      0x100000L,
58        0x80000L,       0x40000L,       0x20000L,       0x10000L,
59        0x8000L,        0x4000L,        0x2000L,        0x1000L,
60        0x800L,         0x400L,         0x200L,         0x100L,
61        0x80L,          0x40L,          0x20L,          0x10L,
62        0x8L,           0x4L,           0x2L,           0x1L    };
63
64/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
65
66static unsigned char pc1[56] = {
67        56, 48, 40, 32, 24, 16,  8,      0, 57, 49, 41, 33, 25, 17,
68         9,  1, 58, 50, 42, 34, 26,     18, 10,  2, 59, 51, 43, 35,
69        62, 54, 46, 38, 30, 22, 14,      6, 61, 53, 45, 37, 29, 21,
70        13,  5, 60, 52, 44, 36, 28,     20, 12,  4, 27, 19, 11,  3 };
71
72static unsigned char totrot[16] = {
73        1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
74
75static unsigned char pc2[48] = {
76        13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
77        22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
78        40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
79        43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
80
81
82
83/* Ratko Jagodic added to support normal decryption
84   (without flipping the bits of every byte of a password)
85   more explanation here:
86   http://www.vidarholen.net/contents/junk/vnc.html
87*/
88extern void decryptUIpass(unsigned char *outpass, unsigned char *inpass, unsigned char *key);
89void decryptUIpass(unsigned char *outpass, unsigned char *inpass, unsigned char *key)
90{
91  // set the correct bit order of the password
92  unsigned short bytebitArray2[] = { 0200, 0100, 040, 020, 010, 04, 02, 01 };
93  bytebit = bytebitArray2;
94
95  // perform decryption
96  deskey(key, DE1);
97  des(inpass, outpass);
98 
99  // put back the flipped bit order for vnc usage
100  bytebit = bytebitArray;
101
102  return;
103}
104/* end edit, Ratko Jagodic */
105
106
107
108void deskey(unsigned char *key, int edf)
109        /* Thanks to James Gillogly & Phil Karn! */
110{
111        register int i, j, l, m, n;
112        unsigned char pc1m[56], pcr[56];
113        unsigned long kn[32];
114
115        for ( j = 0; j < 56; j++ ) {
116                l = pc1[j];
117                m = l & 07;
118                pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
119    }
120        for( i = 0; i < 16; i++ ) {
121                if( edf == DE1 ) m = (15 - i) << 1;
122                else m = i << 1;
123                n = m + 1;
124                kn[m] = kn[n] = 0L;
125                for( j = 0; j < 28; j++ ) {
126                        l = j + totrot[i];
127                        if( l < 28 ) pcr[j] = pc1m[l];
128                        else pcr[j] = pc1m[l - 28];
129        }
130                for( j = 28; j < 56; j++ ) {
131                    l = j + totrot[i];
132                    if( l < 56 ) pcr[j] = pc1m[l];
133                    else pcr[j] = pc1m[l - 28];
134        }
135                for( j = 0; j < 24; j++ ) {
136                        if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
137                        if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
138        }
139    }
140        cookey(kn);
141        return;
142}
143
144static void cookey(register unsigned long *raw1)
145{
146        register unsigned long *cook, *raw0;
147        unsigned long dough[32];
148        register int i;
149
150        cook = dough;
151        for( i = 0; i < 16; i++, raw1++ ) {
152                raw0 = raw1++;
153                *cook    = (*raw0 & 0x00fc0000L) << 6;
154                *cook   |= (*raw0 & 0x00000fc0L) << 10;
155                *cook   |= (*raw1 & 0x00fc0000L) >> 10;
156                *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
157                *cook    = (*raw0 & 0x0003f000L) << 12;
158                *cook   |= (*raw0 & 0x0000003fL) << 16;
159                *cook   |= (*raw1 & 0x0003f000L) >> 4;
160                *cook++ |= (*raw1 & 0x0000003fL);
161    }
162        usekey(dough);
163        return;
164}
165
166void cpkey(register unsigned long *into)
167{
168        register unsigned long *from, *endp;
169
170        from = KnL, endp = &KnL[32];
171        while( from < endp ) *into++ = *from++;
172        return;
173}
174
175void usekey(register unsigned long *from)
176{
177        register unsigned long *to, *endp;
178
179        to = KnL, endp = &KnL[32];
180        while( to < endp ) *to++ = *from++;
181        return;
182}
183
184void des(unsigned char *inblock, unsigned char *outblock)
185{
186        unsigned long work[2];
187
188        scrunch(inblock, work);
189        desfunc(work, KnL);
190        unscrun(work, outblock);
191        return;
192}
193
194static void scrunch(register unsigned char *outof, register unsigned long *into)
195{
196        *into    = (*outof++ & 0xffL) << 24;
197        *into   |= (*outof++ & 0xffL) << 16;
198        *into   |= (*outof++ & 0xffL) << 8;
199        *into++ |= (*outof++ & 0xffL);
200        *into    = (*outof++ & 0xffL) << 24;
201        *into   |= (*outof++ & 0xffL) << 16;
202        *into   |= (*outof++ & 0xffL) << 8;
203        *into   |= (*outof   & 0xffL);
204        return;
205}
206
207static void unscrun(register unsigned long *outof, register unsigned char *into)
208{
209        *into++ = (unsigned char) ( (*outof >> 24) & 0xffL );
210        *into++ = (unsigned char) ( (*outof >> 16) & 0xffL );
211        *into++ = (unsigned char) ( (*outof >>  8) & 0xffL );
212        *into++ = (unsigned char) (  *outof++    & 0xffL );
213        *into++ = (unsigned char) (  (*outof >> 24) & 0xffL );
214        *into++ = (unsigned char) (  (*outof >> 16) & 0xffL );
215        *into++ = (unsigned char) (  (*outof >>  8) & 0xffL );
216        *into   = (unsigned char) (   *outof     & 0xffL );
217        return;
218}
219
220static unsigned long SP1[64] = {
221        0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
222        0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
223        0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
224        0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
225        0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
226        0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
227        0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
228        0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
229        0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
230        0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
231        0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
232        0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
233        0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
234        0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
235        0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
236        0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
237
238static unsigned long SP2[64] = {
239        0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
240        0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
241        0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
242        0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
243        0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
244        0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
245        0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
246        0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
247        0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
248        0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
249        0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
250        0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
251        0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
252        0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
253        0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
254        0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
255
256static unsigned long SP3[64] = {
257        0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
258        0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
259        0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
260        0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
261        0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
262        0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
263        0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
264        0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
265        0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
266        0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
267        0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
268        0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
269        0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
270        0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
271        0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
272        0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
273
274static unsigned long SP4[64] = {
275        0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
276        0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
277        0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
278        0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
279        0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
280        0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
281        0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
282        0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
283        0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
284        0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
285        0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
286        0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
287        0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
288        0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
289        0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
290        0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
291
292static unsigned long SP5[64] = {
293        0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
294        0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
295        0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
296        0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
297        0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
298        0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
299        0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
300        0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
301        0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
302        0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
303        0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
304        0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
305        0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
306        0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
307        0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
308        0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
309
310static unsigned long SP6[64] = {
311        0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
312        0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
313        0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
314        0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
315        0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
316        0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
317        0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
318        0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
319        0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
320        0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
321        0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
322        0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
323        0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
324        0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
325        0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
326        0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
327
328static unsigned long SP7[64] = {
329        0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
330        0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
331        0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
332        0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
333        0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
334        0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
335        0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
336        0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
337        0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
338        0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
339        0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
340        0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
341        0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
342        0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
343        0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
344        0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
345
346static unsigned long SP8[64] = {
347        0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
348        0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
349        0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
350        0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
351        0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
352        0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
353        0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
354        0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
355        0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
356        0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
357        0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
358        0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
359        0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
360        0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
361        0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
362        0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
363
364static void desfunc(register unsigned long *block, register unsigned long *keys)
365{
366        register unsigned long fval, work, right, leftt;
367        register int round;
368
369        leftt = block[0];
370        right = block[1];
371        work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
372        right ^= work;
373        leftt ^= (work << 4);
374        work = ((leftt >> 16) ^ right) & 0x0000ffffL;
375        right ^= work;
376        leftt ^= (work << 16);
377        work = ((right >> 2) ^ leftt) & 0x33333333L;
378        leftt ^= work;
379        right ^= (work << 2);
380        work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
381        leftt ^= work;
382        right ^= (work << 8);
383        right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
384        work = (leftt ^ right) & 0xaaaaaaaaL;
385        leftt ^= work;
386        right ^= work;
387        leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
388
389        for( round = 0; round < 8; round++ ) {
390                work  = (right << 28) | (right >> 4);
391                work ^= *keys++;
392                fval  = SP7[ work                & 0x3fL];
393                fval |= SP5[(work >>  8) & 0x3fL];
394                fval |= SP3[(work >> 16) & 0x3fL];
395                fval |= SP1[(work >> 24) & 0x3fL];
396                work  = right ^ *keys++;
397                fval |= SP8[ work                & 0x3fL];
398                fval |= SP6[(work >>  8) & 0x3fL];
399                fval |= SP4[(work >> 16) & 0x3fL];
400                fval |= SP2[(work >> 24) & 0x3fL];
401                leftt ^= fval;
402                work  = (leftt << 28) | (leftt >> 4);
403                work ^= *keys++;
404                fval  = SP7[ work                & 0x3fL];
405                fval |= SP5[(work >>  8) & 0x3fL];
406                fval |= SP3[(work >> 16) & 0x3fL];
407                fval |= SP1[(work >> 24) & 0x3fL];
408                work  = leftt ^ *keys++;
409                fval |= SP8[ work                & 0x3fL];
410                fval |= SP6[(work >>  8) & 0x3fL];
411                fval |= SP4[(work >> 16) & 0x3fL];
412                fval |= SP2[(work >> 24) & 0x3fL];
413                right ^= fval;
414    }
415
416        right = (right << 31) | (right >> 1);
417        work = (leftt ^ right) & 0xaaaaaaaaL;
418        leftt ^= work;
419        right ^= work;
420        leftt = (leftt << 31) | (leftt >> 1);
421        work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
422        right ^= work;
423        leftt ^= (work << 8);
424        work = ((leftt >> 2) ^ right) & 0x33333333L;
425        right ^= work;
426        leftt ^= (work << 2);
427        work = ((right >> 16) ^ leftt) & 0x0000ffffL;
428        leftt ^= work;
429        right ^= (work << 16);
430        work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
431        leftt ^= work;
432        right ^= (work << 4);
433        *block++ = right;
434        *block = leftt;
435        return;
436}
437
438/* Validation sets:
439 *
440 * Single-length key, single-length plaintext -
441 * Key    : 0123 4567 89ab cdef
442 * Plain  : 0123 4567 89ab cde7
443 * Cipher : c957 4425 6a5e d31d
444 *
445 * Double-length key, single-length plaintext -
446 * Key    : 0123 4567 89ab cdef fedc ba98 7654 3210
447 * Plain  : 0123 4567 89ab cde7
448 * Cipher : 7f1d 0a77 826b 8aff
449 *
450 * Double-length key, double-length plaintext -
451 * Key    : 0123 4567 89ab cdef fedc ba98 7654 3210
452 * Plain  : 0123 4567 89ab cdef 0123 4567 89ab cdff
453 * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
454 *
455 * Triple-length key, single-length plaintext -
456 * Key    : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
457 * Plain  : 0123 4567 89ab cde7
458 * Cipher : de0b 7c06 ae5e 0ed5
459 *
460 * Triple-length key, double-length plaintext -
461 * Key    : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
462 * Plain  : 0123 4567 89ab cdef 0123 4567 89ab cdff
463 * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5
464 *
465 * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
466 **********************************************************************/
Note: See TracBrowser for help on using the repository browser.