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