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