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