viced-sane-acls-bit-20060802
[openafs.git] / src / rxkad / bg-fcrypt.c
1 /*
2  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  * 
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 #include <afsconfig.h>
34 #ifdef KERNEL
35 #include "afs/param.h"
36 #else
37 #include <afs/param.h>
38 #endif
39
40 RCSID
41     ("$Header$");
42
43 #define DEBUG 0
44 #ifdef KERNEL
45 #ifndef UKERNEL
46 #include "afs/stds.h"
47 #include "h/types.h"
48 #if !defined(AFS_LINUX20_ENV) && !defined(AFS_OBSD_ENV)
49 #include "netinet/in.h"
50 #endif
51 #else /* UKERNEL */
52 #include "afs/sysincludes.h"
53 #include "afs/stds.h"
54 #endif /* UKERNEL */
55 #ifdef AFS_LINUX22_ENV
56 #include <asm/byteorder.h>
57 #endif
58
59 #include "afs/longc_procs.h"
60
61 #else /* KERNEL */
62
63 #include <afs/stds.h>
64 #include <sys/types.h>
65 #ifdef AFS_NT40_ENV
66 #include <winsock2.h>
67 #else
68 #include <netinet/in.h>
69 #endif
70 #include <rx/rx.h>
71 #endif /* KERNEL */
72
73 #include "fcrypt.h"
74 #include "rxkad.h"
75 #include "fcrypt.h"
76 #include "private_data.h"
77 #include <des/stats.h>
78
79 #undef WORDS_BIGENDIAN
80 #ifdef AFSBIG_ENDIAN
81 #define WORDS_BIGENDIAN 1
82 #endif
83
84 /*
85  * Unrolling of the inner loops helps the most on pentium chips
86  * (ca 18%). On risc machines only expect a modest improvement (ca 5%).
87  * The cost for this is rougly 4k bytes.
88  */
89 #define UNROLL_LOOPS 1
90 /*
91  * Inline assembler gives a boost only to fc_keysched.
92  * On the pentium expect ca 28%.
93  */
94 /*#define GNU_ASM 1 (now autoconfed) */
95
96 #if !defined(inline) && !defined(__GNUC__)
97 #define inline
98 #endif
99
100 /*
101  * There is usually no memcpy in kernels but gcc will inline all
102  * calls to memcpy in this code anyway.
103  */
104 #if defined(KERNEL) && !defined(__GNUC__)
105 #define memcpy(to, from, n) bcopy((from), (to), (n))
106 #endif
107
108 /* Rotate 32 bit word left */
109 #define ROT32L(x, n) ((((afs_uint32) x) << (n)) | (((afs_uint32) x) >> (32-(n))))
110 #define bswap32(x) (((ROT32L(x, 16) & 0x00ff00ff)<<8) | ((ROT32L(x, 16)>>8) & 0x00ff00ff))
111
112 #if WORDS_BIGENDIAN
113 #define NTOH(x) (x)
114 #else
115 #define NTOH(x) bswap32(x)
116 #endif
117
118 /*
119  * Try to use a good function for ntohl-ing.
120  *
121  * The choice is done by autoconf setting EFF_NTOHL to one of:
122  * CPU          function
123  * i386         ntohl
124  * i[4-9]86     bswap
125  * alpha        bswap32
126  * all else     ntohl
127  */
128
129 #define EFF_NTOHL(x) ntohl(x)
130
131 #if 0
132 #if defined(__GNUC__) && (defined(i386) || defined(__i386__))
133 static inline afs_uint32
134 bswap(afs_uint32 x)
135 {
136   asm("bswap %0": "=r"(x):"0"(x));
137     return x;
138 }
139 #endif
140 #endif
141
142 /*
143  * Sboxes for Feistel network derived from
144  * /afs/transarc.com/public/afsps/afs.rel31b.export-src/rxkad/sboxes.h
145  */
146
147 #undef Z
148 #define Z(x) NTOH(x << 3)
149 static const afs_uint32 sbox0[256] = {
150     Z(0xea), Z(0x7f), Z(0xb2), Z(0x64), Z(0x9d), Z(0xb0), Z(0xd9), Z(0x11),
151     Z(0xcd), Z(0x86), Z(0x86),
152     Z(0x91), Z(0x0a), Z(0xb2), Z(0x93), Z(0x06), Z(0x0e), Z(0x06), Z(0xd2),
153     Z(0x65), Z(0x73), Z(0xc5),
154     Z(0x28), Z(0x60), Z(0xf2), Z(0x20), Z(0xb5), Z(0x38), Z(0x7e), Z(0xda),
155     Z(0x9f), Z(0xe3), Z(0xd2),
156     Z(0xcf), Z(0xc4), Z(0x3c), Z(0x61), Z(0xff), Z(0x4a), Z(0x4a), Z(0x35),
157     Z(0xac), Z(0xaa), Z(0x5f),
158     Z(0x2b), Z(0xbb), Z(0xbc), Z(0x53), Z(0x4e), Z(0x9d), Z(0x78), Z(0xa3),
159     Z(0xdc), Z(0x09), Z(0x32),
160     Z(0x10), Z(0xc6), Z(0x6f), Z(0x66), Z(0xd6), Z(0xab), Z(0xa9), Z(0xaf),
161     Z(0xfd), Z(0x3b), Z(0x95),
162     Z(0xe8), Z(0x34), Z(0x9a), Z(0x81), Z(0x72), Z(0x80), Z(0x9c), Z(0xf3),
163     Z(0xec), Z(0xda), Z(0x9f),
164     Z(0x26), Z(0x76), Z(0x15), Z(0x3e), Z(0x55), Z(0x4d), Z(0xde), Z(0x84),
165     Z(0xee), Z(0xad), Z(0xc7),
166     Z(0xf1), Z(0x6b), Z(0x3d), Z(0xd3), Z(0x04), Z(0x49), Z(0xaa), Z(0x24),
167     Z(0x0b), Z(0x8a), Z(0x83),
168     Z(0xba), Z(0xfa), Z(0x85), Z(0xa0), Z(0xa8), Z(0xb1), Z(0xd4), Z(0x01),
169     Z(0xd8), Z(0x70), Z(0x64),
170     Z(0xf0), Z(0x51), Z(0xd2), Z(0xc3), Z(0xa7), Z(0x75), Z(0x8c), Z(0xa5),
171     Z(0x64), Z(0xef), Z(0x10),
172     Z(0x4e), Z(0xb7), Z(0xc6), Z(0x61), Z(0x03), Z(0xeb), Z(0x44), Z(0x3d),
173     Z(0xe5), Z(0xb3), Z(0x5b),
174     Z(0xae), Z(0xd5), Z(0xad), Z(0x1d), Z(0xfa), Z(0x5a), Z(0x1e), Z(0x33),
175     Z(0xab), Z(0x93), Z(0xa2),
176     Z(0xb7), Z(0xe7), Z(0xa8), Z(0x45), Z(0xa4), Z(0xcd), Z(0x29), Z(0x63),
177     Z(0x44), Z(0xb6), Z(0x69),
178     Z(0x7e), Z(0x2e), Z(0x62), Z(0x03), Z(0xc8), Z(0xe0), Z(0x17), Z(0xbb),
179     Z(0xc7), Z(0xf3), Z(0x3f),
180     Z(0x36), Z(0xba), Z(0x71), Z(0x8e), Z(0x97), Z(0x65), Z(0x60), Z(0x69),
181     Z(0xb6), Z(0xf6), Z(0xe6),
182     Z(0x6e), Z(0xe0), Z(0x81), Z(0x59), Z(0xe8), Z(0xaf), Z(0xdd), Z(0x95),
183     Z(0x22), Z(0x99), Z(0xfd),
184     Z(0x63), Z(0x19), Z(0x74), Z(0x61), Z(0xb1), Z(0xb6), Z(0x5b), Z(0xae),
185     Z(0x54), Z(0xb3), Z(0x70),
186     Z(0xff), Z(0xc6), Z(0x3b), Z(0x3e), Z(0xc1), Z(0xd7), Z(0xe1), Z(0x0e),
187     Z(0x76), Z(0xe5), Z(0x36),
188     Z(0x4f), Z(0x59), Z(0xc7), Z(0x08), Z(0x6e), Z(0x82), Z(0xa6), Z(0x93),
189     Z(0xc4), Z(0xaa), Z(0x26),
190     Z(0x49), Z(0xe0), Z(0x21), Z(0x64), Z(0x07), Z(0x9f), Z(0x64), Z(0x81),
191     Z(0x9c), Z(0xbf), Z(0xf9),
192     Z(0xd1), Z(0x43), Z(0xf8), Z(0xb6), Z(0xb9), Z(0xf1), Z(0x24), Z(0x75),
193     Z(0x03), Z(0xe4), Z(0xb0),
194     Z(0x99), Z(0x46), Z(0x3d), Z(0xf5), Z(0xd1), Z(0x39), Z(0x72), Z(0x12),
195     Z(0xf6), Z(0xba), Z(0x0c),
196     Z(0x0d), Z(0x42), Z(0x2e)
197 };
198
199 #undef Z
200 #define Z(x) NTOH((x << 27) | (x >> 5))
201 static const afs_uint32 sbox1[256] = {
202     Z(0x77), Z(0x14), Z(0xa6), Z(0xfe), Z(0xb2), Z(0x5e), Z(0x8c), Z(0x3e),
203     Z(0x67), Z(0x6c), Z(0xa1),
204     Z(0x0d), Z(0xc2), Z(0xa2), Z(0xc1), Z(0x85), Z(0x6c), Z(0x7b), Z(0x67),
205     Z(0xc6), Z(0x23), Z(0xe3),
206     Z(0xf2), Z(0x89), Z(0x50), Z(0x9c), Z(0x03), Z(0xb7), Z(0x73), Z(0xe6),
207     Z(0xe1), Z(0x39), Z(0x31),
208     Z(0x2c), Z(0x27), Z(0x9f), Z(0xa5), Z(0x69), Z(0x44), Z(0xd6), Z(0x23),
209     Z(0x83), Z(0x98), Z(0x7d),
210     Z(0x3c), Z(0xb4), Z(0x2d), Z(0x99), Z(0x1c), Z(0x1f), Z(0x8c), Z(0x20),
211     Z(0x03), Z(0x7c), Z(0x5f),
212     Z(0xad), Z(0xf4), Z(0xfa), Z(0x95), Z(0xca), Z(0x76), Z(0x44), Z(0xcd),
213     Z(0xb6), Z(0xb8), Z(0xa1),
214     Z(0xa1), Z(0xbe), Z(0x9e), Z(0x54), Z(0x8f), Z(0x0b), Z(0x16), Z(0x74),
215     Z(0x31), Z(0x8a), Z(0x23),
216     Z(0x17), Z(0x04), Z(0xfa), Z(0x79), Z(0x84), Z(0xb1), Z(0xf5), Z(0x13),
217     Z(0xab), Z(0xb5), Z(0x2e),
218     Z(0xaa), Z(0x0c), Z(0x60), Z(0x6b), Z(0x5b), Z(0xc4), Z(0x4b), Z(0xbc),
219     Z(0xe2), Z(0xaf), Z(0x45),
220     Z(0x73), Z(0xfa), Z(0xc9), Z(0x49), Z(0xcd), Z(0x00), Z(0x92), Z(0x7d),
221     Z(0x97), Z(0x7a), Z(0x18),
222     Z(0x60), Z(0x3d), Z(0xcf), Z(0x5b), Z(0xde), Z(0xc6), Z(0xe2), Z(0xe6),
223     Z(0xbb), Z(0x8b), Z(0x06),
224     Z(0xda), Z(0x08), Z(0x15), Z(0x1b), Z(0x88), Z(0x6a), Z(0x17), Z(0x89),
225     Z(0xd0), Z(0xa9), Z(0xc1),
226     Z(0xc9), Z(0x70), Z(0x6b), Z(0xe5), Z(0x43), Z(0xf4), Z(0x68), Z(0xc8),
227     Z(0xd3), Z(0x84), Z(0x28),
228     Z(0x0a), Z(0x52), Z(0x66), Z(0xa3), Z(0xca), Z(0xf2), Z(0xe3), Z(0x7f),
229     Z(0x7a), Z(0x31), Z(0xf7),
230     Z(0x88), Z(0x94), Z(0x5e), Z(0x9c), Z(0x63), Z(0xd5), Z(0x24), Z(0x66),
231     Z(0xfc), Z(0xb3), Z(0x57),
232     Z(0x25), Z(0xbe), Z(0x89), Z(0x44), Z(0xc4), Z(0xe0), Z(0x8f), Z(0x23),
233     Z(0x3c), Z(0x12), Z(0x52),
234     Z(0xf5), Z(0x1e), Z(0xf4), Z(0xcb), Z(0x18), Z(0x33), Z(0x1f), Z(0xf8),
235     Z(0x69), Z(0x10), Z(0x9d),
236     Z(0xd3), Z(0xf7), Z(0x28), Z(0xf8), Z(0x30), Z(0x05), Z(0x5e), Z(0x32),
237     Z(0xc0), Z(0xd5), Z(0x19),
238     Z(0xbd), Z(0x45), Z(0x8b), Z(0x5b), Z(0xfd), Z(0xbc), Z(0xe2), Z(0x5c),
239     Z(0xa9), Z(0x96), Z(0xef),
240     Z(0x70), Z(0xcf), Z(0xc2), Z(0x2a), Z(0xb3), Z(0x61), Z(0xad), Z(0x80),
241     Z(0x48), Z(0x81), Z(0xb7),
242     Z(0x1d), Z(0x43), Z(0xd9), Z(0xd7), Z(0x45), Z(0xf0), Z(0xd8), Z(0x8a),
243     Z(0x59), Z(0x7c), Z(0x57),
244     Z(0xc1), Z(0x79), Z(0xc7), Z(0x34), Z(0xd6), Z(0x43), Z(0xdf), Z(0xe4),
245     Z(0x78), Z(0x16), Z(0x06),
246     Z(0xda), Z(0x92), Z(0x76), Z(0x51), Z(0xe1), Z(0xd4), Z(0x70), Z(0x03),
247     Z(0xe0), Z(0x2f), Z(0x96),
248     Z(0x91), Z(0x82), Z(0x80)
249 };
250
251 #undef Z
252 #define Z(x) NTOH(x << 11)
253 static const afs_uint32 sbox2[256] = {
254     Z(0xf0), Z(0x37), Z(0x24), Z(0x53), Z(0x2a), Z(0x03), Z(0x83), Z(0x86),
255     Z(0xd1), Z(0xec), Z(0x50),
256     Z(0xf0), Z(0x42), Z(0x78), Z(0x2f), Z(0x6d), Z(0xbf), Z(0x80), Z(0x87),
257     Z(0x27), Z(0x95), Z(0xe2),
258     Z(0xc5), Z(0x5d), Z(0xf9), Z(0x6f), Z(0xdb), Z(0xb4), Z(0x65), Z(0x6e),
259     Z(0xe7), Z(0x24), Z(0xc8),
260     Z(0x1a), Z(0xbb), Z(0x49), Z(0xb5), Z(0x0a), Z(0x7d), Z(0xb9), Z(0xe8),
261     Z(0xdc), Z(0xb7), Z(0xd9),
262     Z(0x45), Z(0x20), Z(0x1b), Z(0xce), Z(0x59), Z(0x9d), Z(0x6b), Z(0xbd),
263     Z(0x0e), Z(0x8f), Z(0xa3),
264     Z(0xa9), Z(0xbc), Z(0x74), Z(0xa6), Z(0xf6), Z(0x7f), Z(0x5f), Z(0xb1),
265     Z(0x68), Z(0x84), Z(0xbc),
266     Z(0xa9), Z(0xfd), Z(0x55), Z(0x50), Z(0xe9), Z(0xb6), Z(0x13), Z(0x5e),
267     Z(0x07), Z(0xb8), Z(0x95),
268     Z(0x02), Z(0xc0), Z(0xd0), Z(0x6a), Z(0x1a), Z(0x85), Z(0xbd), Z(0xb6),
269     Z(0xfd), Z(0xfe), Z(0x17),
270     Z(0x3f), Z(0x09), Z(0xa3), Z(0x8d), Z(0xfb), Z(0xed), Z(0xda), Z(0x1d),
271     Z(0x6d), Z(0x1c), Z(0x6c),
272     Z(0x01), Z(0x5a), Z(0xe5), Z(0x71), Z(0x3e), Z(0x8b), Z(0x6b), Z(0xbe),
273     Z(0x29), Z(0xeb), Z(0x12),
274     Z(0x19), Z(0x34), Z(0xcd), Z(0xb3), Z(0xbd), Z(0x35), Z(0xea), Z(0x4b),
275     Z(0xd5), Z(0xae), Z(0x2a),
276     Z(0x79), Z(0x5a), Z(0xa5), Z(0x32), Z(0x12), Z(0x7b), Z(0xdc), Z(0x2c),
277     Z(0xd0), Z(0x22), Z(0x4b),
278     Z(0xb1), Z(0x85), Z(0x59), Z(0x80), Z(0xc0), Z(0x30), Z(0x9f), Z(0x73),
279     Z(0xd3), Z(0x14), Z(0x48),
280     Z(0x40), Z(0x07), Z(0x2d), Z(0x8f), Z(0x80), Z(0x0f), Z(0xce), Z(0x0b),
281     Z(0x5e), Z(0xb7), Z(0x5e),
282     Z(0xac), Z(0x24), Z(0x94), Z(0x4a), Z(0x18), Z(0x15), Z(0x05), Z(0xe8),
283     Z(0x02), Z(0x77), Z(0xa9),
284     Z(0xc7), Z(0x40), Z(0x45), Z(0x89), Z(0xd1), Z(0xea), Z(0xde), Z(0x0c),
285     Z(0x79), Z(0x2a), Z(0x99),
286     Z(0x6c), Z(0x3e), Z(0x95), Z(0xdd), Z(0x8c), Z(0x7d), Z(0xad), Z(0x6f),
287     Z(0xdc), Z(0xff), Z(0xfd),
288     Z(0x62), Z(0x47), Z(0xb3), Z(0x21), Z(0x8a), Z(0xec), Z(0x8e), Z(0x19),
289     Z(0x18), Z(0xb4), Z(0x6e),
290     Z(0x3d), Z(0xfd), Z(0x74), Z(0x54), Z(0x1e), Z(0x04), Z(0x85), Z(0xd8),
291     Z(0xbc), Z(0x1f), Z(0x56),
292     Z(0xe7), Z(0x3a), Z(0x56), Z(0x67), Z(0xd6), Z(0xc8), Z(0xa5), Z(0xf3),
293     Z(0x8e), Z(0xde), Z(0xae),
294     Z(0x37), Z(0x49), Z(0xb7), Z(0xfa), Z(0xc8), Z(0xf4), Z(0x1f), Z(0xe0),
295     Z(0x2a), Z(0x9b), Z(0x15),
296     Z(0xd1), Z(0x34), Z(0x0e), Z(0xb5), Z(0xe0), Z(0x44), Z(0x78), Z(0x84),
297     Z(0x59), Z(0x56), Z(0x68),
298     Z(0x77), Z(0xa5), Z(0x14), Z(0x06), Z(0xf5), Z(0x2f), Z(0x8c), Z(0x8a),
299     Z(0x73), Z(0x80), Z(0x76),
300     Z(0xb4), Z(0x10), Z(0x86)
301 };
302
303 #undef Z
304 #define Z(x) NTOH(x << 19)
305 static const afs_uint32 sbox3[256] = {
306     Z(0xa9), Z(0x2a), Z(0x48), Z(0x51), Z(0x84), Z(0x7e), Z(0x49), Z(0xe2),
307     Z(0xb5), Z(0xb7), Z(0x42),
308     Z(0x33), Z(0x7d), Z(0x5d), Z(0xa6), Z(0x12), Z(0x44), Z(0x48), Z(0x6d),
309     Z(0x28), Z(0xaa), Z(0x20),
310     Z(0x6d), Z(0x57), Z(0xd6), Z(0x6b), Z(0x5d), Z(0x72), Z(0xf0), Z(0x92),
311     Z(0x5a), Z(0x1b), Z(0x53),
312     Z(0x80), Z(0x24), Z(0x70), Z(0x9a), Z(0xcc), Z(0xa7), Z(0x66), Z(0xa1),
313     Z(0x01), Z(0xa5), Z(0x41),
314     Z(0x97), Z(0x41), Z(0x31), Z(0x82), Z(0xf1), Z(0x14), Z(0xcf), Z(0x53),
315     Z(0x0d), Z(0xa0), Z(0x10),
316     Z(0xcc), Z(0x2a), Z(0x7d), Z(0xd2), Z(0xbf), Z(0x4b), Z(0x1a), Z(0xdb),
317     Z(0x16), Z(0x47), Z(0xf6),
318     Z(0x51), Z(0x36), Z(0xed), Z(0xf3), Z(0xb9), Z(0x1a), Z(0xa7), Z(0xdf),
319     Z(0x29), Z(0x43), Z(0x01),
320     Z(0x54), Z(0x70), Z(0xa4), Z(0xbf), Z(0xd4), Z(0x0b), Z(0x53), Z(0x44),
321     Z(0x60), Z(0x9e), Z(0x23),
322     Z(0xa1), Z(0x18), Z(0x68), Z(0x4f), Z(0xf0), Z(0x2f), Z(0x82), Z(0xc2),
323     Z(0x2a), Z(0x41), Z(0xb2),
324     Z(0x42), Z(0x0c), Z(0xed), Z(0x0c), Z(0x1d), Z(0x13), Z(0x3a), Z(0x3c),
325     Z(0x6e), Z(0x35), Z(0xdc),
326     Z(0x60), Z(0x65), Z(0x85), Z(0xe9), Z(0x64), Z(0x02), Z(0x9a), Z(0x3f),
327     Z(0x9f), Z(0x87), Z(0x96),
328     Z(0xdf), Z(0xbe), Z(0xf2), Z(0xcb), Z(0xe5), Z(0x6c), Z(0xd4), Z(0x5a),
329     Z(0x83), Z(0xbf), Z(0x92),
330     Z(0x1b), Z(0x94), Z(0x00), Z(0x42), Z(0xcf), Z(0x4b), Z(0x00), Z(0x75),
331     Z(0xba), Z(0x8f), Z(0x76),
332     Z(0x5f), Z(0x5d), Z(0x3a), Z(0x4d), Z(0x09), Z(0x12), Z(0x08), Z(0x38),
333     Z(0x95), Z(0x17), Z(0xe4),
334     Z(0x01), Z(0x1d), Z(0x4c), Z(0xa9), Z(0xcc), Z(0x85), Z(0x82), Z(0x4c),
335     Z(0x9d), Z(0x2f), Z(0x3b),
336     Z(0x66), Z(0xa1), Z(0x34), Z(0x10), Z(0xcd), Z(0x59), Z(0x89), Z(0xa5),
337     Z(0x31), Z(0xcf), Z(0x05),
338     Z(0xc8), Z(0x84), Z(0xfa), Z(0xc7), Z(0xba), Z(0x4e), Z(0x8b), Z(0x1a),
339     Z(0x19), Z(0xf1), Z(0xa1),
340     Z(0x3b), Z(0x18), Z(0x12), Z(0x17), Z(0xb0), Z(0x98), Z(0x8d), Z(0x0b),
341     Z(0x23), Z(0xc3), Z(0x3a),
342     Z(0x2d), Z(0x20), Z(0xdf), Z(0x13), Z(0xa0), Z(0xa8), Z(0x4c), Z(0x0d),
343     Z(0x6c), Z(0x2f), Z(0x47),
344     Z(0x13), Z(0x13), Z(0x52), Z(0x1f), Z(0x2d), Z(0xf5), Z(0x79), Z(0x3d),
345     Z(0xa2), Z(0x54), Z(0xbd),
346     Z(0x69), Z(0xc8), Z(0x6b), Z(0xf3), Z(0x05), Z(0x28), Z(0xf1), Z(0x16),
347     Z(0x46), Z(0x40), Z(0xb0),
348     Z(0x11), Z(0xd3), Z(0xb7), Z(0x95), Z(0x49), Z(0xcf), Z(0xc3), Z(0x1d),
349     Z(0x8f), Z(0xd8), Z(0xe1),
350     Z(0x73), Z(0xdb), Z(0xad), Z(0xc8), Z(0xc9), Z(0xa9), Z(0xa1), Z(0xc2),
351     Z(0xc5), Z(0xe3), Z(0xba),
352     Z(0xfc), Z(0x0e), Z(0x25)
353 };
354
355 /*
356  * This is a 16 round Feistel network with permutation F_ENCRYPT
357  */
358
359 #define F_ENCRYPT(R, L, sched) { \
360  union lc4 { afs_uint32 l; unsigned char c[4]; } un; \
361  un.l = sched ^ R; \
362  L ^= sbox0[un.c[0]] ^ sbox1[un.c[1]] ^ sbox2[un.c[2]] ^ sbox3[un.c[3]]; }
363
364 #ifndef WORDS_BIGENDIAN
365 /* BEWARE: this code is endian dependent.
366  * This should really be inline assembler on the x86.
367  */
368 #undef F_ENCRYPT
369 #define FF(y, shiftN) (((y) >> shiftN) & 0xFF)
370 #define F_ENCRYPT(R, L, sched) { \
371  afs_uint32 un; \
372  un = sched ^ R; \
373  L ^= sbox0[FF(un, 0)] ^ sbox1[FF(un, 8)] ^ sbox2[FF(un, 16)] ^ sbox3[FF(un, 24)];}
374 #endif
375
376 static inline void
377 fc_ecb_enc(afs_uint32 l, afs_uint32 r, afs_uint32 out[2],
378            const afs_int32 sched[MAXROUNDS])
379 {
380 #if !defined(UNROLL_LOOPS)
381     {
382         int i;
383         for (i = 0; i < (MAXROUNDS / 4); i++) {
384             F_ENCRYPT(r, l, *sched++);
385             F_ENCRYPT(l, r, *sched++);
386             F_ENCRYPT(r, l, *sched++);
387             F_ENCRYPT(l, r, *sched++);
388         }
389     }
390 #else
391     F_ENCRYPT(r, l, *sched++);
392     F_ENCRYPT(l, r, *sched++);
393     F_ENCRYPT(r, l, *sched++);
394     F_ENCRYPT(l, r, *sched++);
395     F_ENCRYPT(r, l, *sched++);
396     F_ENCRYPT(l, r, *sched++);
397     F_ENCRYPT(r, l, *sched++);
398     F_ENCRYPT(l, r, *sched++);
399     F_ENCRYPT(r, l, *sched++);
400     F_ENCRYPT(l, r, *sched++);
401     F_ENCRYPT(r, l, *sched++);
402     F_ENCRYPT(l, r, *sched++);
403     F_ENCRYPT(r, l, *sched++);
404     F_ENCRYPT(l, r, *sched++);
405     F_ENCRYPT(r, l, *sched++);
406     F_ENCRYPT(l, r, *sched++);
407 #endif /* UNROLL_LOOPS */
408
409     out[0] = l;
410     out[1] = r;
411 }
412
413 static inline void
414 fc_ecb_dec(afs_uint32 l, afs_uint32 r, afs_uint32 out[2],
415            const afs_int32 sched[MAXROUNDS])
416 {
417     sched = &sched[MAXROUNDS - 1];
418
419 #if !defined(UNROLL_LOOPS)
420     {
421         int i;
422         for (i = 0; i < (MAXROUNDS / 4); i++) {
423             F_ENCRYPT(l, r, *sched--);
424             F_ENCRYPT(r, l, *sched--);
425             F_ENCRYPT(l, r, *sched--);
426             F_ENCRYPT(r, l, *sched--);
427         }
428     }
429 #else
430     F_ENCRYPT(l, r, *sched--);
431     F_ENCRYPT(r, l, *sched--);
432     F_ENCRYPT(l, r, *sched--);
433     F_ENCRYPT(r, l, *sched--);
434     F_ENCRYPT(l, r, *sched--);
435     F_ENCRYPT(r, l, *sched--);
436     F_ENCRYPT(l, r, *sched--);
437     F_ENCRYPT(r, l, *sched--);
438     F_ENCRYPT(l, r, *sched--);
439     F_ENCRYPT(r, l, *sched--);
440     F_ENCRYPT(l, r, *sched--);
441     F_ENCRYPT(r, l, *sched--);
442     F_ENCRYPT(l, r, *sched--);
443     F_ENCRYPT(r, l, *sched--);
444     F_ENCRYPT(l, r, *sched--);
445     F_ENCRYPT(r, l, *sched--);
446 #endif /* UNROLL_LOOPS */
447
448     out[0] = l;
449     out[1] = r;
450 }
451
452 static inline void
453 fc_cbc_enc(const afs_uint32 * in, afs_uint32 * out, afs_int32 length,
454            const afs_int32 sched[MAXROUNDS], afs_uint32 * iv)
455 {
456     afs_int32 xor0 = iv[0], xor1 = iv[1];
457
458     for (; length > 0; length -= 8) {
459         afs_uint32 b8[2];
460         /* If length < 8 we read to much, usally ok */
461         xor0 ^= in[0];
462         xor1 ^= in[1];
463         fc_ecb_enc(xor0, xor1, b8, sched);
464         xor0 = in[0] ^ b8[0];
465         xor1 = in[1] ^ b8[1];
466
467         /* Out is always a multiple of 8 */
468         memcpy(out, b8, 8);
469         out += 2;
470         in += 2;
471     }
472     iv[0] = xor0;
473     iv[1] = xor1;
474 }
475
476 static inline void
477 fc_cbc_dec(const afs_uint32 * in, afs_uint32 * out, afs_int32 length,
478            const afs_int32 sched[MAXROUNDS], afs_uint32 * iv)
479 {
480     afs_int32 xor0 = iv[0], xor1 = iv[1];
481
482     for (; length > 0; length -= 8) {
483         afs_uint32 b8[2];
484         /* In is always a multiple of 8 */
485         fc_ecb_dec(in[0], in[1], b8, sched);
486         b8[0] ^= xor0;
487         b8[1] ^= xor1;
488         xor0 = in[0] ^ b8[0];
489         xor1 = in[1] ^ b8[1];
490
491 #if 0
492         if (length >= 8)
493             memcpy(out, b8, 8);
494         else
495             memcpy(out, b8, length);    /* Don't write to much when length < 8 */
496 #else
497         /* If length < 8 we write to much, this is not always ok */
498         memcpy(out, b8, 8);
499 #endif
500         out += 2;
501         in += 2;
502     }
503     iv[0] = xor0;
504     iv[1] = xor1;
505 }
506
507 afs_int32
508 fc_ecb_encrypt(afs_uint32 * in, afs_uint32 * out, fc_KeySchedule sched,
509                int encrypt)
510 {
511     INC_RXKAD_STATS(fc_encrypts[encrypt]);
512     if (encrypt)
513         fc_ecb_enc(in[0], in[1], out, sched);
514     else
515         fc_ecb_dec(in[0], in[1], out, sched);
516     return 0;
517 }
518
519 afs_int32
520 fc_cbc_encrypt(afs_uint32 * in, afs_uint32 * out, afs_int32 length,
521                fc_KeySchedule sched, afs_uint32 * iv, int encrypt)
522 {
523     if (encrypt)
524         fc_cbc_enc(in, out, length, sched, iv);
525     else
526         fc_cbc_dec(in, out, length, sched, iv);
527     return 0;
528 }
529
530 /* Rotate two 32 bit numbers as a 56 bit number */
531 #define ROT56R(hi, lo, n) { \
532   afs_uint32 t = lo & ((1<<n)-1); \
533   lo = (lo >> n) | ((hi & ((1<<n)-1)) << (32-n)); \
534   hi = (hi >> n) | (t << (24-n)); }
535
536 /* Rotate one 64 bit number as a 56 bit number */
537 #define ROT56R64(k, n) { \
538   k = (k >> n) | ((k & ((1<<n) - 1)) << (56-n)); }
539
540 /*
541  * Generate a key schedule from key, the least significant bit in each
542  * key byte is parity and shall be ignored. This leaves 56 significant
543  * bits in the key to scatter over the 16 key schedules. For each
544  * schedule extract the low order 32 bits and use as schedule, then
545  * rotate right by 11 bits.
546  *
547  * Note that this fc_keysched() generates a schedule in natural byte
548  * order, the Transarc function does not. Therefore it's *not*
549  * possible to mix fc_keysched, fc_ecb_encrypt and fc_cbc_encrypt
550  * from different implementations. Keep them in the same module!
551  */
552 int
553 fc_keysched(void *key_, fc_KeySchedule sched)
554 {
555     const unsigned char *key = key_;
556
557     /* Do we have 56 bit longs or even longer longs? */
558 #if ((1ul << 31) << 1) && defined(ULONG_MAX) && ((ULONG_MAX >> 55) != 0) && ((1ul << 55) != 0)
559     unsigned long k;            /* k holds all 56 non parity bits */
560
561     /* Compress out parity bits */
562     k = (*key++) >> 1;
563     k <<= 7;
564     k |= (*key++) >> 1;
565     k <<= 7;
566     k |= (*key++) >> 1;
567     k <<= 7;
568     k |= (*key++) >> 1;
569     k <<= 7;
570     k |= (*key++) >> 1;
571     k <<= 7;
572     k |= (*key++) >> 1;
573     k <<= 7;
574     k |= (*key++) >> 1;
575     k <<= 7;
576     k |= (*key) >> 1;
577
578     /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
579     *sched++ = EFF_NTOHL((afs_uint32) k);
580     ROT56R64(k, 11);
581     *sched++ = EFF_NTOHL((afs_uint32) k);
582     ROT56R64(k, 11);
583     *sched++ = EFF_NTOHL((afs_uint32) k);
584     ROT56R64(k, 11);
585     *sched++ = EFF_NTOHL((afs_uint32) k);
586     ROT56R64(k, 11);
587
588     *sched++ = EFF_NTOHL((afs_uint32) k);
589     ROT56R64(k, 11);
590     *sched++ = EFF_NTOHL((afs_uint32) k);
591     ROT56R64(k, 11);
592     *sched++ = EFF_NTOHL((afs_uint32) k);
593     ROT56R64(k, 11);
594     *sched++ = EFF_NTOHL((afs_uint32) k);
595     ROT56R64(k, 11);
596
597     *sched++ = EFF_NTOHL((afs_uint32) k);
598     ROT56R64(k, 11);
599     *sched++ = EFF_NTOHL((afs_uint32) k);
600     ROT56R64(k, 11);
601     *sched++ = EFF_NTOHL((afs_uint32) k);
602     ROT56R64(k, 11);
603     *sched++ = EFF_NTOHL((afs_uint32) k);
604     ROT56R64(k, 11);
605
606     *sched++ = EFF_NTOHL((afs_uint32) k);
607     ROT56R64(k, 11);
608     *sched++ = EFF_NTOHL((afs_uint32) k);
609     ROT56R64(k, 11);
610     *sched++ = EFF_NTOHL((afs_uint32) k);
611     ROT56R64(k, 11);
612     *sched++ = EFF_NTOHL((afs_uint32) k);
613 #else
614     afs_uint32 hi, lo;          /* hi is upper 24 bits and lo lower 32, total 56 */
615
616     /* Compress out parity bits */
617     lo = (*key++) >> 1;
618     lo <<= 7;
619     lo |= (*key++) >> 1;
620     lo <<= 7;
621     lo |= (*key++) >> 1;
622     lo <<= 7;
623     lo |= (*key++) >> 1;
624     hi = lo >> 4;
625     lo &= 0xf;
626     lo <<= 7;
627     lo |= (*key++) >> 1;
628     lo <<= 7;
629     lo |= (*key++) >> 1;
630     lo <<= 7;
631     lo |= (*key++) >> 1;
632     lo <<= 7;
633     lo |= (*key) >> 1;
634
635     /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
636     *sched++ = EFF_NTOHL(lo);
637     ROT56R(hi, lo, 11);
638     *sched++ = EFF_NTOHL(lo);
639     ROT56R(hi, lo, 11);
640     *sched++ = EFF_NTOHL(lo);
641     ROT56R(hi, lo, 11);
642     *sched++ = EFF_NTOHL(lo);
643     ROT56R(hi, lo, 11);
644
645     *sched++ = EFF_NTOHL(lo);
646     ROT56R(hi, lo, 11);
647     *sched++ = EFF_NTOHL(lo);
648     ROT56R(hi, lo, 11);
649     *sched++ = EFF_NTOHL(lo);
650     ROT56R(hi, lo, 11);
651     *sched++ = EFF_NTOHL(lo);
652     ROT56R(hi, lo, 11);
653
654     *sched++ = EFF_NTOHL(lo);
655     ROT56R(hi, lo, 11);
656     *sched++ = EFF_NTOHL(lo);
657     ROT56R(hi, lo, 11);
658     *sched++ = EFF_NTOHL(lo);
659     ROT56R(hi, lo, 11);
660     *sched++ = EFF_NTOHL(lo);
661     ROT56R(hi, lo, 11);
662
663     *sched++ = EFF_NTOHL(lo);
664     ROT56R(hi, lo, 11);
665     *sched++ = EFF_NTOHL(lo);
666     ROT56R(hi, lo, 11);
667     *sched++ = EFF_NTOHL(lo);
668     ROT56R(hi, lo, 11);
669     *sched++ = EFF_NTOHL(lo);
670 #endif
671     INC_RXKAD_STATS(fc_key_scheds);
672     return 0;
673 }
674
675 /*
676  * Encryption/decryption of Rx packets is pretty straight forward. Run
677  * fc_cbc_encrypt over the packet fragments until len bytes have been
678  * processed. Skip the Rx packet header but not the security header.
679  */
680 afs_int32
681 rxkad_EncryptPacket(const struct rx_connection * rx_connection_not_used,
682                     const fc_KeySchedule * sched, const afs_uint32 * iv,
683                     int len, struct rx_packet * packet)
684 {
685     afs_uint32 ivec[2];
686     struct iovec *frag;
687     struct rx_securityClass *obj;
688     struct rxkad_cprivate *tp;  /* s & c have type at same offset */
689
690     obj = rx_SecurityObjectOf(rx_connection_not_used);
691     tp = (struct rxkad_cprivate *)obj->privateData;
692     ADD_RXKAD_STATS(bytesEncrypted[rxkad_TypeIndex(tp->type)],len);
693     {
694         /* What is this good for?
695          * It turns out that the security header for auth_enc is of
696          * size 8 bytes and the last 4 bytes are defined to be 0!
697          */
698         afs_uint32 *t = (afs_uint32 *) packet->wirevec[1].iov_base;
699         t[1] = 0;
700     }
701
702     memcpy(ivec, iv, sizeof(ivec));     /* Must use copy of iv */
703     for (frag = &packet->wirevec[1]; len; frag++) {
704         int iov_len = frag->iov_len;
705         afs_uint32 *iov_bas = (afs_uint32 *) frag->iov_base;
706         if (iov_len == 0)
707             return RXKADDATALEN;        /* Length mismatch */
708         if (len < iov_len)
709             iov_len = len;      /* Don't process to much data */
710         fc_cbc_enc(iov_bas, iov_bas, iov_len, sched, ivec);
711         len -= iov_len;
712     }
713     return 0;
714 }
715
716 afs_int32
717 rxkad_DecryptPacket(const struct rx_connection * rx_connection_not_used,
718                     const fc_KeySchedule * sched, const afs_uint32 * iv,
719                     int len, struct rx_packet * packet)
720 {
721     afs_uint32 ivec[2];
722     struct iovec *frag;
723     struct rx_securityClass *obj;
724     struct rxkad_cprivate *tp;  /* s & c have type at same offset */
725
726     obj = rx_SecurityObjectOf(rx_connection_not_used);
727     tp = (struct rxkad_cprivate *)obj->privateData;
728     ADD_RXKAD_STATS(bytesDecrypted[rxkad_TypeIndex(tp->type)],len);
729     memcpy(ivec, iv, sizeof(ivec));     /* Must use copy of iv */
730     for (frag = &packet->wirevec[1]; len > 0; frag++) {
731         int iov_len = frag->iov_len;
732         afs_uint32 *iov_bas = (afs_uint32 *) frag->iov_base;
733         if (iov_len == 0)
734             return RXKADDATALEN;        /* Length mismatch */
735         if (len < iov_len)
736             iov_len = len;      /* Don't process to much data */
737         fc_cbc_dec(iov_bas, iov_bas, iov_len, sched, ivec);
738         len -= iov_len;
739     }
740     return 0;
741 }
742
743 #if defined(TEST) || defined(TEST_KERNEL)
744 /*
745  * It is possible to link with the client kernel libafs.a to verify
746  * the test case. Use TEST_KERNEL to get the mangled names.
747  */
748
749 #include <stdio.h>
750 #include <string.h>
751
752 #include <time.h>
753
754 const char the_quick[] = "The quick brown fox jumps over the lazy dogs.\0\0";
755
756 const unsigned char key1[8] =
757     { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 };
758 const char ciph1[] = {
759     0x00, 0xf0, 0xe, 0x11, 0x75, 0xe6, 0x23, 0x82, 0xee, 0xac, 0x98, 0x62,
760     0x44, 0x51, 0xe4, 0x84, 0xc3, 0x59, 0xd8, 0xaa, 0x64, 0x60, 0xae, 0xf7,
761     0xd2, 0xd9, 0x13, 0x79, 0x72, 0xa3, 0x45, 0x03, 0x23, 0xb5, 0x62, 0xd7,
762     0xc, 0xf5, 0x27, 0xd1, 0xf8, 0x91, 0x3c, 0xac, 0x44, 0x22, 0x92, 0xef
763 };
764
765 const unsigned char key2[8] =
766     { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 };
767 const char ciph2[] = {
768     0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c, 0x01, 0x88, 0x7f, 0x3e,
769     0x31, 0x6e, 0x62, 0x9d, 0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58,
770     0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0, 0x19, 0x89, 0x09, 0x1c,
771     0x2a, 0x8e, 0x8c, 0x94, 0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f
772 };
773
774 #ifdef TEST_KERNEL
775 #define fc_keysched    _afs_QTKrFdpoFL
776 #define fc_ecb_encrypt _afs_sDLThwNLok
777 #define fc_cbc_encrypt _afs_fkyCWTvfRS
778 #define rxkad_DecryptPacket _afs_SRWEeqTXrS
779 #define rxkad_EncryptPacket _afs_bpwQbdoghO
780 #endif
781
782 int
783 rx_SlowPutInt32()
784 {
785     abort();
786 }
787
788 int
789 main()
790 {
791     afs_int32 sched[MAXROUNDS];
792     char ciph[100], clear[100], tmp[100];
793     afs_uint32 data[2];
794     afs_uint32 iv[2];
795     struct rx_packet packet;
796
797     if (sizeof(afs_int32) != 4)
798         fprintf(stderr, "error: sizeof(afs_int32) != 4\n");
799     if (sizeof(afs_uint32) != 4)
800         fprintf(stderr, "error: sizeof(afs_uint32) != 4\n");
801
802     /*
803      * Use key1 and key2 as iv */
804     fc_keysched(key1, sched);
805     memcpy(iv, key2, sizeof(iv));
806     fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT);
807     if (memcmp(ciph1, ciph, sizeof(ciph1)) != 0)
808         fprintf(stderr, "encrypt FAILED\n");
809     memcpy(iv, key2, sizeof(iv));
810     fc_cbc_encrypt(ciph, clear, sizeof(the_quick), sched, iv, DECRYPT);
811     if (strcmp(the_quick, clear) != 0)
812         fprintf(stderr, "crypt decrypt FAILED\n");
813
814     /*
815      * Use key2 and key1 as iv
816      */
817     fc_keysched(key2, sched);
818     memcpy(iv, key1, sizeof(iv));
819     fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT);
820     if (memcmp(ciph2, ciph, sizeof(ciph2)) != 0)
821         fprintf(stderr, "encrypt FAILED\n");
822     memcpy(iv, key1, sizeof(iv));
823     fc_cbc_encrypt(ciph, clear, sizeof(the_quick), sched, iv, DECRYPT);
824     if (strcmp(the_quick, clear) != 0)
825         fprintf(stderr, "crypt decrypt FAILED\n");
826
827     /*
828      * Test Encrypt- and Decrypt-Packet, use key1 and key2 as iv
829      */
830     fc_keysched(key1, sched);
831     memcpy(iv, key2, sizeof(iv));
832     strcpy(clear, the_quick);
833     packet.wirevec[1].iov_base = clear;
834     packet.wirevec[1].iov_len = sizeof(the_quick);
835     packet.wirevec[2].iov_len = 0;
836
837     /* For unknown reasons bytes 4-7 are zeroed in rxkad_EncryptPacket */
838     rxkad_EncryptPacket(tmp, sched, iv, sizeof(the_quick), &packet);
839     rxkad_DecryptPacket(tmp, sched, iv, sizeof(the_quick), &packet);
840     clear[4] ^= 'q';
841     clear[5] ^= 'u';
842     clear[6] ^= 'i';
843     clear[7] ^= 'c';
844     if (strcmp(the_quick, clear) != 0)
845         fprintf(stderr, "rxkad_EncryptPacket/rxkad_DecryptPacket FAILED\n");
846
847     {
848         struct timeval start, stop;
849         int i;
850
851         fc_keysched(key1, sched);
852         gettimeofday(&start, 0);
853         for (i = 0; i < 1000000; i++)
854             fc_keysched(key1, sched);
855         gettimeofday(&stop, 0);
856         printf("fc_keysched    = %2.2f us\n",
857                (stop.tv_sec - start.tv_sec +
858                 (stop.tv_usec - start.tv_usec) / 1e6) * 1);
859
860         fc_ecb_encrypt(data, data, sched, ENCRYPT);
861         gettimeofday(&start, 0);
862         for (i = 0; i < 1000000; i++)
863             fc_ecb_encrypt(data, data, sched, ENCRYPT);
864         gettimeofday(&stop, 0);
865         printf("fc_ecb_encrypt = %2.2f us\n",
866                (stop.tv_sec - start.tv_sec +
867                 (stop.tv_usec - start.tv_usec) / 1e6) * 1);
868
869         fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv,
870                        ENCRYPT);
871         gettimeofday(&start, 0);
872         for (i = 0; i < 100000; i++)
873             fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv,
874                            ENCRYPT);
875         gettimeofday(&stop, 0);
876         printf("fc_cbc_encrypt = %2.2f us\n",
877                (stop.tv_sec - start.tv_sec +
878                 (stop.tv_usec - start.tv_usec) / 1e6) * 10);
879
880     }
881
882     exit(0);
883 }
884 #endif /* TEST */