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