2 * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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
33 #include <afsconfig.h>
35 #include "afs/param.h"
37 #include <afs/param.h>
48 #if !defined(AFS_LINUX20_ENV) && !defined(AFS_OBSD_ENV)
49 #include "netinet/in.h"
52 #include "afs/sysincludes.h"
55 #ifdef AFS_LINUX22_ENV
56 #include <asm/byteorder.h>
59 #include "afs/longc_procs.h"
64 #include <sys/types.h>
68 #include <netinet/in.h>
76 #include "private_data.h"
78 #undef WORDS_BIGENDIAN
80 #define WORDS_BIGENDIAN 1
84 * Unrolling of the inner loops helps the most on pentium chips
85 * (ca 18%). On risc machines only expect a modest improvement (ca 5%).
86 * The cost for this is rougly 4k bytes.
88 #define UNROLL_LOOPS 1
90 * Inline assembler gives a boost only to fc_keysched.
91 * On the pentium expect ca 28%.
93 /*#define GNU_ASM 1 (now autoconfed) */
95 #if !defined(inline) && !defined(__GNUC__)
100 * There is usually no memcpy in kernels but gcc will inline all
101 * calls to memcpy in this code anyway.
103 #if defined(KERNEL) && !defined(__GNUC__)
104 #define memcpy(to, from, n) bcopy((from), (to), (n))
107 /* Rotate 32 bit word left */
108 #define ROT32L(x, n) ((((afs_uint32) x) << (n)) | (((afs_uint32) x) >> (32-(n))))
109 #define bswap32(x) (((ROT32L(x, 16) & 0x00ff00ff)<<8) | ((ROT32L(x, 16)>>8) & 0x00ff00ff))
114 #define NTOH(x) bswap32(x)
118 * Try to use a good function for ntohl-ing.
120 * The choice is done by autoconf setting EFF_NTOHL to one of:
128 #define EFF_NTOHL(x) ntohl(x)
131 #if defined(__GNUC__) && (defined(i386) || defined(__i386__))
132 static inline afs_uint32
135 asm("bswap %0": "=r"(x):"0"(x));
142 * Sboxes for Feistel network derived from
143 * /afs/transarc.com/public/afsps/afs.rel31b.export-src/rxkad/sboxes.h
147 #define Z(x) NTOH(x << 3)
148 static const afs_uint32 sbox0[256] = {
149 Z(0xea), Z(0x7f), Z(0xb2), Z(0x64), Z(0x9d), Z(0xb0), Z(0xd9), Z(0x11),
150 Z(0xcd), Z(0x86), Z(0x86),
151 Z(0x91), Z(0x0a), Z(0xb2), Z(0x93), Z(0x06), Z(0x0e), Z(0x06), Z(0xd2),
152 Z(0x65), Z(0x73), Z(0xc5),
153 Z(0x28), Z(0x60), Z(0xf2), Z(0x20), Z(0xb5), Z(0x38), Z(0x7e), Z(0xda),
154 Z(0x9f), Z(0xe3), Z(0xd2),
155 Z(0xcf), Z(0xc4), Z(0x3c), Z(0x61), Z(0xff), Z(0x4a), Z(0x4a), Z(0x35),
156 Z(0xac), Z(0xaa), Z(0x5f),
157 Z(0x2b), Z(0xbb), Z(0xbc), Z(0x53), Z(0x4e), Z(0x9d), Z(0x78), Z(0xa3),
158 Z(0xdc), Z(0x09), Z(0x32),
159 Z(0x10), Z(0xc6), Z(0x6f), Z(0x66), Z(0xd6), Z(0xab), Z(0xa9), Z(0xaf),
160 Z(0xfd), Z(0x3b), Z(0x95),
161 Z(0xe8), Z(0x34), Z(0x9a), Z(0x81), Z(0x72), Z(0x80), Z(0x9c), Z(0xf3),
162 Z(0xec), Z(0xda), Z(0x9f),
163 Z(0x26), Z(0x76), Z(0x15), Z(0x3e), Z(0x55), Z(0x4d), Z(0xde), Z(0x84),
164 Z(0xee), Z(0xad), Z(0xc7),
165 Z(0xf1), Z(0x6b), Z(0x3d), Z(0xd3), Z(0x04), Z(0x49), Z(0xaa), Z(0x24),
166 Z(0x0b), Z(0x8a), Z(0x83),
167 Z(0xba), Z(0xfa), Z(0x85), Z(0xa0), Z(0xa8), Z(0xb1), Z(0xd4), Z(0x01),
168 Z(0xd8), Z(0x70), Z(0x64),
169 Z(0xf0), Z(0x51), Z(0xd2), Z(0xc3), Z(0xa7), Z(0x75), Z(0x8c), Z(0xa5),
170 Z(0x64), Z(0xef), Z(0x10),
171 Z(0x4e), Z(0xb7), Z(0xc6), Z(0x61), Z(0x03), Z(0xeb), Z(0x44), Z(0x3d),
172 Z(0xe5), Z(0xb3), Z(0x5b),
173 Z(0xae), Z(0xd5), Z(0xad), Z(0x1d), Z(0xfa), Z(0x5a), Z(0x1e), Z(0x33),
174 Z(0xab), Z(0x93), Z(0xa2),
175 Z(0xb7), Z(0xe7), Z(0xa8), Z(0x45), Z(0xa4), Z(0xcd), Z(0x29), Z(0x63),
176 Z(0x44), Z(0xb6), Z(0x69),
177 Z(0x7e), Z(0x2e), Z(0x62), Z(0x03), Z(0xc8), Z(0xe0), Z(0x17), Z(0xbb),
178 Z(0xc7), Z(0xf3), Z(0x3f),
179 Z(0x36), Z(0xba), Z(0x71), Z(0x8e), Z(0x97), Z(0x65), Z(0x60), Z(0x69),
180 Z(0xb6), Z(0xf6), Z(0xe6),
181 Z(0x6e), Z(0xe0), Z(0x81), Z(0x59), Z(0xe8), Z(0xaf), Z(0xdd), Z(0x95),
182 Z(0x22), Z(0x99), Z(0xfd),
183 Z(0x63), Z(0x19), Z(0x74), Z(0x61), Z(0xb1), Z(0xb6), Z(0x5b), Z(0xae),
184 Z(0x54), Z(0xb3), Z(0x70),
185 Z(0xff), Z(0xc6), Z(0x3b), Z(0x3e), Z(0xc1), Z(0xd7), Z(0xe1), Z(0x0e),
186 Z(0x76), Z(0xe5), Z(0x36),
187 Z(0x4f), Z(0x59), Z(0xc7), Z(0x08), Z(0x6e), Z(0x82), Z(0xa6), Z(0x93),
188 Z(0xc4), Z(0xaa), Z(0x26),
189 Z(0x49), Z(0xe0), Z(0x21), Z(0x64), Z(0x07), Z(0x9f), Z(0x64), Z(0x81),
190 Z(0x9c), Z(0xbf), Z(0xf9),
191 Z(0xd1), Z(0x43), Z(0xf8), Z(0xb6), Z(0xb9), Z(0xf1), Z(0x24), Z(0x75),
192 Z(0x03), Z(0xe4), Z(0xb0),
193 Z(0x99), Z(0x46), Z(0x3d), Z(0xf5), Z(0xd1), Z(0x39), Z(0x72), Z(0x12),
194 Z(0xf6), Z(0xba), Z(0x0c),
195 Z(0x0d), Z(0x42), Z(0x2e)
199 #define Z(x) NTOH((x << 27) | (x >> 5))
200 static const afs_uint32 sbox1[256] = {
201 Z(0x77), Z(0x14), Z(0xa6), Z(0xfe), Z(0xb2), Z(0x5e), Z(0x8c), Z(0x3e),
202 Z(0x67), Z(0x6c), Z(0xa1),
203 Z(0x0d), Z(0xc2), Z(0xa2), Z(0xc1), Z(0x85), Z(0x6c), Z(0x7b), Z(0x67),
204 Z(0xc6), Z(0x23), Z(0xe3),
205 Z(0xf2), Z(0x89), Z(0x50), Z(0x9c), Z(0x03), Z(0xb7), Z(0x73), Z(0xe6),
206 Z(0xe1), Z(0x39), Z(0x31),
207 Z(0x2c), Z(0x27), Z(0x9f), Z(0xa5), Z(0x69), Z(0x44), Z(0xd6), Z(0x23),
208 Z(0x83), Z(0x98), Z(0x7d),
209 Z(0x3c), Z(0xb4), Z(0x2d), Z(0x99), Z(0x1c), Z(0x1f), Z(0x8c), Z(0x20),
210 Z(0x03), Z(0x7c), Z(0x5f),
211 Z(0xad), Z(0xf4), Z(0xfa), Z(0x95), Z(0xca), Z(0x76), Z(0x44), Z(0xcd),
212 Z(0xb6), Z(0xb8), Z(0xa1),
213 Z(0xa1), Z(0xbe), Z(0x9e), Z(0x54), Z(0x8f), Z(0x0b), Z(0x16), Z(0x74),
214 Z(0x31), Z(0x8a), Z(0x23),
215 Z(0x17), Z(0x04), Z(0xfa), Z(0x79), Z(0x84), Z(0xb1), Z(0xf5), Z(0x13),
216 Z(0xab), Z(0xb5), Z(0x2e),
217 Z(0xaa), Z(0x0c), Z(0x60), Z(0x6b), Z(0x5b), Z(0xc4), Z(0x4b), Z(0xbc),
218 Z(0xe2), Z(0xaf), Z(0x45),
219 Z(0x73), Z(0xfa), Z(0xc9), Z(0x49), Z(0xcd), Z(0x00), Z(0x92), Z(0x7d),
220 Z(0x97), Z(0x7a), Z(0x18),
221 Z(0x60), Z(0x3d), Z(0xcf), Z(0x5b), Z(0xde), Z(0xc6), Z(0xe2), Z(0xe6),
222 Z(0xbb), Z(0x8b), Z(0x06),
223 Z(0xda), Z(0x08), Z(0x15), Z(0x1b), Z(0x88), Z(0x6a), Z(0x17), Z(0x89),
224 Z(0xd0), Z(0xa9), Z(0xc1),
225 Z(0xc9), Z(0x70), Z(0x6b), Z(0xe5), Z(0x43), Z(0xf4), Z(0x68), Z(0xc8),
226 Z(0xd3), Z(0x84), Z(0x28),
227 Z(0x0a), Z(0x52), Z(0x66), Z(0xa3), Z(0xca), Z(0xf2), Z(0xe3), Z(0x7f),
228 Z(0x7a), Z(0x31), Z(0xf7),
229 Z(0x88), Z(0x94), Z(0x5e), Z(0x9c), Z(0x63), Z(0xd5), Z(0x24), Z(0x66),
230 Z(0xfc), Z(0xb3), Z(0x57),
231 Z(0x25), Z(0xbe), Z(0x89), Z(0x44), Z(0xc4), Z(0xe0), Z(0x8f), Z(0x23),
232 Z(0x3c), Z(0x12), Z(0x52),
233 Z(0xf5), Z(0x1e), Z(0xf4), Z(0xcb), Z(0x18), Z(0x33), Z(0x1f), Z(0xf8),
234 Z(0x69), Z(0x10), Z(0x9d),
235 Z(0xd3), Z(0xf7), Z(0x28), Z(0xf8), Z(0x30), Z(0x05), Z(0x5e), Z(0x32),
236 Z(0xc0), Z(0xd5), Z(0x19),
237 Z(0xbd), Z(0x45), Z(0x8b), Z(0x5b), Z(0xfd), Z(0xbc), Z(0xe2), Z(0x5c),
238 Z(0xa9), Z(0x96), Z(0xef),
239 Z(0x70), Z(0xcf), Z(0xc2), Z(0x2a), Z(0xb3), Z(0x61), Z(0xad), Z(0x80),
240 Z(0x48), Z(0x81), Z(0xb7),
241 Z(0x1d), Z(0x43), Z(0xd9), Z(0xd7), Z(0x45), Z(0xf0), Z(0xd8), Z(0x8a),
242 Z(0x59), Z(0x7c), Z(0x57),
243 Z(0xc1), Z(0x79), Z(0xc7), Z(0x34), Z(0xd6), Z(0x43), Z(0xdf), Z(0xe4),
244 Z(0x78), Z(0x16), Z(0x06),
245 Z(0xda), Z(0x92), Z(0x76), Z(0x51), Z(0xe1), Z(0xd4), Z(0x70), Z(0x03),
246 Z(0xe0), Z(0x2f), Z(0x96),
247 Z(0x91), Z(0x82), Z(0x80)
251 #define Z(x) NTOH(x << 11)
252 static const afs_uint32 sbox2[256] = {
253 Z(0xf0), Z(0x37), Z(0x24), Z(0x53), Z(0x2a), Z(0x03), Z(0x83), Z(0x86),
254 Z(0xd1), Z(0xec), Z(0x50),
255 Z(0xf0), Z(0x42), Z(0x78), Z(0x2f), Z(0x6d), Z(0xbf), Z(0x80), Z(0x87),
256 Z(0x27), Z(0x95), Z(0xe2),
257 Z(0xc5), Z(0x5d), Z(0xf9), Z(0x6f), Z(0xdb), Z(0xb4), Z(0x65), Z(0x6e),
258 Z(0xe7), Z(0x24), Z(0xc8),
259 Z(0x1a), Z(0xbb), Z(0x49), Z(0xb5), Z(0x0a), Z(0x7d), Z(0xb9), Z(0xe8),
260 Z(0xdc), Z(0xb7), Z(0xd9),
261 Z(0x45), Z(0x20), Z(0x1b), Z(0xce), Z(0x59), Z(0x9d), Z(0x6b), Z(0xbd),
262 Z(0x0e), Z(0x8f), Z(0xa3),
263 Z(0xa9), Z(0xbc), Z(0x74), Z(0xa6), Z(0xf6), Z(0x7f), Z(0x5f), Z(0xb1),
264 Z(0x68), Z(0x84), Z(0xbc),
265 Z(0xa9), Z(0xfd), Z(0x55), Z(0x50), Z(0xe9), Z(0xb6), Z(0x13), Z(0x5e),
266 Z(0x07), Z(0xb8), Z(0x95),
267 Z(0x02), Z(0xc0), Z(0xd0), Z(0x6a), Z(0x1a), Z(0x85), Z(0xbd), Z(0xb6),
268 Z(0xfd), Z(0xfe), Z(0x17),
269 Z(0x3f), Z(0x09), Z(0xa3), Z(0x8d), Z(0xfb), Z(0xed), Z(0xda), Z(0x1d),
270 Z(0x6d), Z(0x1c), Z(0x6c),
271 Z(0x01), Z(0x5a), Z(0xe5), Z(0x71), Z(0x3e), Z(0x8b), Z(0x6b), Z(0xbe),
272 Z(0x29), Z(0xeb), Z(0x12),
273 Z(0x19), Z(0x34), Z(0xcd), Z(0xb3), Z(0xbd), Z(0x35), Z(0xea), Z(0x4b),
274 Z(0xd5), Z(0xae), Z(0x2a),
275 Z(0x79), Z(0x5a), Z(0xa5), Z(0x32), Z(0x12), Z(0x7b), Z(0xdc), Z(0x2c),
276 Z(0xd0), Z(0x22), Z(0x4b),
277 Z(0xb1), Z(0x85), Z(0x59), Z(0x80), Z(0xc0), Z(0x30), Z(0x9f), Z(0x73),
278 Z(0xd3), Z(0x14), Z(0x48),
279 Z(0x40), Z(0x07), Z(0x2d), Z(0x8f), Z(0x80), Z(0x0f), Z(0xce), Z(0x0b),
280 Z(0x5e), Z(0xb7), Z(0x5e),
281 Z(0xac), Z(0x24), Z(0x94), Z(0x4a), Z(0x18), Z(0x15), Z(0x05), Z(0xe8),
282 Z(0x02), Z(0x77), Z(0xa9),
283 Z(0xc7), Z(0x40), Z(0x45), Z(0x89), Z(0xd1), Z(0xea), Z(0xde), Z(0x0c),
284 Z(0x79), Z(0x2a), Z(0x99),
285 Z(0x6c), Z(0x3e), Z(0x95), Z(0xdd), Z(0x8c), Z(0x7d), Z(0xad), Z(0x6f),
286 Z(0xdc), Z(0xff), Z(0xfd),
287 Z(0x62), Z(0x47), Z(0xb3), Z(0x21), Z(0x8a), Z(0xec), Z(0x8e), Z(0x19),
288 Z(0x18), Z(0xb4), Z(0x6e),
289 Z(0x3d), Z(0xfd), Z(0x74), Z(0x54), Z(0x1e), Z(0x04), Z(0x85), Z(0xd8),
290 Z(0xbc), Z(0x1f), Z(0x56),
291 Z(0xe7), Z(0x3a), Z(0x56), Z(0x67), Z(0xd6), Z(0xc8), Z(0xa5), Z(0xf3),
292 Z(0x8e), Z(0xde), Z(0xae),
293 Z(0x37), Z(0x49), Z(0xb7), Z(0xfa), Z(0xc8), Z(0xf4), Z(0x1f), Z(0xe0),
294 Z(0x2a), Z(0x9b), Z(0x15),
295 Z(0xd1), Z(0x34), Z(0x0e), Z(0xb5), Z(0xe0), Z(0x44), Z(0x78), Z(0x84),
296 Z(0x59), Z(0x56), Z(0x68),
297 Z(0x77), Z(0xa5), Z(0x14), Z(0x06), Z(0xf5), Z(0x2f), Z(0x8c), Z(0x8a),
298 Z(0x73), Z(0x80), Z(0x76),
299 Z(0xb4), Z(0x10), Z(0x86)
303 #define Z(x) NTOH(x << 19)
304 static const afs_uint32 sbox3[256] = {
305 Z(0xa9), Z(0x2a), Z(0x48), Z(0x51), Z(0x84), Z(0x7e), Z(0x49), Z(0xe2),
306 Z(0xb5), Z(0xb7), Z(0x42),
307 Z(0x33), Z(0x7d), Z(0x5d), Z(0xa6), Z(0x12), Z(0x44), Z(0x48), Z(0x6d),
308 Z(0x28), Z(0xaa), Z(0x20),
309 Z(0x6d), Z(0x57), Z(0xd6), Z(0x6b), Z(0x5d), Z(0x72), Z(0xf0), Z(0x92),
310 Z(0x5a), Z(0x1b), Z(0x53),
311 Z(0x80), Z(0x24), Z(0x70), Z(0x9a), Z(0xcc), Z(0xa7), Z(0x66), Z(0xa1),
312 Z(0x01), Z(0xa5), Z(0x41),
313 Z(0x97), Z(0x41), Z(0x31), Z(0x82), Z(0xf1), Z(0x14), Z(0xcf), Z(0x53),
314 Z(0x0d), Z(0xa0), Z(0x10),
315 Z(0xcc), Z(0x2a), Z(0x7d), Z(0xd2), Z(0xbf), Z(0x4b), Z(0x1a), Z(0xdb),
316 Z(0x16), Z(0x47), Z(0xf6),
317 Z(0x51), Z(0x36), Z(0xed), Z(0xf3), Z(0xb9), Z(0x1a), Z(0xa7), Z(0xdf),
318 Z(0x29), Z(0x43), Z(0x01),
319 Z(0x54), Z(0x70), Z(0xa4), Z(0xbf), Z(0xd4), Z(0x0b), Z(0x53), Z(0x44),
320 Z(0x60), Z(0x9e), Z(0x23),
321 Z(0xa1), Z(0x18), Z(0x68), Z(0x4f), Z(0xf0), Z(0x2f), Z(0x82), Z(0xc2),
322 Z(0x2a), Z(0x41), Z(0xb2),
323 Z(0x42), Z(0x0c), Z(0xed), Z(0x0c), Z(0x1d), Z(0x13), Z(0x3a), Z(0x3c),
324 Z(0x6e), Z(0x35), Z(0xdc),
325 Z(0x60), Z(0x65), Z(0x85), Z(0xe9), Z(0x64), Z(0x02), Z(0x9a), Z(0x3f),
326 Z(0x9f), Z(0x87), Z(0x96),
327 Z(0xdf), Z(0xbe), Z(0xf2), Z(0xcb), Z(0xe5), Z(0x6c), Z(0xd4), Z(0x5a),
328 Z(0x83), Z(0xbf), Z(0x92),
329 Z(0x1b), Z(0x94), Z(0x00), Z(0x42), Z(0xcf), Z(0x4b), Z(0x00), Z(0x75),
330 Z(0xba), Z(0x8f), Z(0x76),
331 Z(0x5f), Z(0x5d), Z(0x3a), Z(0x4d), Z(0x09), Z(0x12), Z(0x08), Z(0x38),
332 Z(0x95), Z(0x17), Z(0xe4),
333 Z(0x01), Z(0x1d), Z(0x4c), Z(0xa9), Z(0xcc), Z(0x85), Z(0x82), Z(0x4c),
334 Z(0x9d), Z(0x2f), Z(0x3b),
335 Z(0x66), Z(0xa1), Z(0x34), Z(0x10), Z(0xcd), Z(0x59), Z(0x89), Z(0xa5),
336 Z(0x31), Z(0xcf), Z(0x05),
337 Z(0xc8), Z(0x84), Z(0xfa), Z(0xc7), Z(0xba), Z(0x4e), Z(0x8b), Z(0x1a),
338 Z(0x19), Z(0xf1), Z(0xa1),
339 Z(0x3b), Z(0x18), Z(0x12), Z(0x17), Z(0xb0), Z(0x98), Z(0x8d), Z(0x0b),
340 Z(0x23), Z(0xc3), Z(0x3a),
341 Z(0x2d), Z(0x20), Z(0xdf), Z(0x13), Z(0xa0), Z(0xa8), Z(0x4c), Z(0x0d),
342 Z(0x6c), Z(0x2f), Z(0x47),
343 Z(0x13), Z(0x13), Z(0x52), Z(0x1f), Z(0x2d), Z(0xf5), Z(0x79), Z(0x3d),
344 Z(0xa2), Z(0x54), Z(0xbd),
345 Z(0x69), Z(0xc8), Z(0x6b), Z(0xf3), Z(0x05), Z(0x28), Z(0xf1), Z(0x16),
346 Z(0x46), Z(0x40), Z(0xb0),
347 Z(0x11), Z(0xd3), Z(0xb7), Z(0x95), Z(0x49), Z(0xcf), Z(0xc3), Z(0x1d),
348 Z(0x8f), Z(0xd8), Z(0xe1),
349 Z(0x73), Z(0xdb), Z(0xad), Z(0xc8), Z(0xc9), Z(0xa9), Z(0xa1), Z(0xc2),
350 Z(0xc5), Z(0xe3), Z(0xba),
351 Z(0xfc), Z(0x0e), Z(0x25)
355 * This is a 16 round Feistel network with permutation F_ENCRYPT
358 #define F_ENCRYPT(R, L, sched) { \
359 union lc4 { afs_uint32 l; unsigned char c[4]; } un; \
361 L ^= sbox0[un.c[0]] ^ sbox1[un.c[1]] ^ sbox2[un.c[2]] ^ sbox3[un.c[3]]; }
363 #ifndef WORDS_BIGENDIAN
364 /* BEWARE: this code is endian dependent.
365 * This should really be inline assembler on the x86.
368 #define FF(y, shiftN) (((y) >> shiftN) & 0xFF)
369 #define F_ENCRYPT(R, L, sched) { \
372 L ^= sbox0[FF(un, 0)] ^ sbox1[FF(un, 8)] ^ sbox2[FF(un, 16)] ^ sbox3[FF(un, 24)];}
376 fc_ecb_enc(afs_uint32 l, afs_uint32 r, afs_uint32 out[2],
377 const afs_int32 sched[MAXROUNDS])
379 #if !defined(UNROLL_LOOPS)
382 for (i = 0; i < (MAXROUNDS / 4); i++) {
383 F_ENCRYPT(r, l, *sched++);
384 F_ENCRYPT(l, r, *sched++);
385 F_ENCRYPT(r, l, *sched++);
386 F_ENCRYPT(l, r, *sched++);
390 F_ENCRYPT(r, l, *sched++);
391 F_ENCRYPT(l, r, *sched++);
392 F_ENCRYPT(r, l, *sched++);
393 F_ENCRYPT(l, r, *sched++);
394 F_ENCRYPT(r, l, *sched++);
395 F_ENCRYPT(l, r, *sched++);
396 F_ENCRYPT(r, l, *sched++);
397 F_ENCRYPT(l, r, *sched++);
398 F_ENCRYPT(r, l, *sched++);
399 F_ENCRYPT(l, r, *sched++);
400 F_ENCRYPT(r, l, *sched++);
401 F_ENCRYPT(l, r, *sched++);
402 F_ENCRYPT(r, l, *sched++);
403 F_ENCRYPT(l, r, *sched++);
404 F_ENCRYPT(r, l, *sched++);
405 F_ENCRYPT(l, r, *sched++);
406 #endif /* UNROLL_LOOPS */
413 fc_ecb_dec(afs_uint32 l, afs_uint32 r, afs_uint32 out[2],
414 const afs_int32 sched[MAXROUNDS])
416 sched = &sched[MAXROUNDS - 1];
418 #if !defined(UNROLL_LOOPS)
421 for (i = 0; i < (MAXROUNDS / 4); i++) {
422 F_ENCRYPT(l, r, *sched--);
423 F_ENCRYPT(r, l, *sched--);
424 F_ENCRYPT(l, r, *sched--);
425 F_ENCRYPT(r, l, *sched--);
429 F_ENCRYPT(l, r, *sched--);
430 F_ENCRYPT(r, l, *sched--);
431 F_ENCRYPT(l, r, *sched--);
432 F_ENCRYPT(r, l, *sched--);
433 F_ENCRYPT(l, r, *sched--);
434 F_ENCRYPT(r, l, *sched--);
435 F_ENCRYPT(l, r, *sched--);
436 F_ENCRYPT(r, l, *sched--);
437 F_ENCRYPT(l, r, *sched--);
438 F_ENCRYPT(r, l, *sched--);
439 F_ENCRYPT(l, r, *sched--);
440 F_ENCRYPT(r, l, *sched--);
441 F_ENCRYPT(l, r, *sched--);
442 F_ENCRYPT(r, l, *sched--);
443 F_ENCRYPT(l, r, *sched--);
444 F_ENCRYPT(r, l, *sched--);
445 #endif /* UNROLL_LOOPS */
452 fc_cbc_enc(const afs_uint32 * in, afs_uint32 * out, afs_int32 length,
453 const afs_int32 sched[MAXROUNDS], afs_uint32 * iv)
455 afs_int32 xor0 = iv[0], xor1 = iv[1];
457 for (; length > 0; length -= 8) {
459 /* If length < 8 we read to much, usally ok */
462 fc_ecb_enc(xor0, xor1, b8, sched);
463 xor0 = in[0] ^ b8[0];
464 xor1 = in[1] ^ b8[1];
466 /* Out is always a multiple of 8 */
476 fc_cbc_dec(const afs_uint32 * in, afs_uint32 * out, afs_int32 length,
477 const afs_int32 sched[MAXROUNDS], afs_uint32 * iv)
479 afs_int32 xor0 = iv[0], xor1 = iv[1];
481 for (; length > 0; length -= 8) {
483 /* In is always a multiple of 8 */
484 fc_ecb_dec(in[0], in[1], b8, sched);
487 xor0 = in[0] ^ b8[0];
488 xor1 = in[1] ^ b8[1];
494 memcpy(out, b8, length); /* Don't write to much when length < 8 */
496 /* If length < 8 we write to much, this is not always ok */
507 fc_ecb_encrypt(afs_uint32 * in, afs_uint32 * out, fc_KeySchedule sched,
510 LOCK_RXKAD_STATS rxkad_stats.fc_encrypts[encrypt]++;
511 UNLOCK_RXKAD_STATS if (encrypt)
512 fc_ecb_enc(in[0], in[1], out, sched);
514 fc_ecb_dec(in[0], in[1], out, sched);
519 fc_cbc_encrypt(afs_uint32 * in, afs_uint32 * out, afs_int32 length,
520 fc_KeySchedule sched, afs_uint32 * iv, int encrypt)
523 fc_cbc_enc(in, out, length, sched, iv);
525 fc_cbc_dec(in, out, length, sched, iv);
529 /* Rotate two 32 bit numbers as a 56 bit number */
530 #define ROT56R(hi, lo, n) { \
531 afs_uint32 t = lo & ((1<<n)-1); \
532 lo = (lo >> n) | ((hi & ((1<<n)-1)) << (32-n)); \
533 hi = (hi >> n) | (t << (24-n)); }
535 /* Rotate one 64 bit number as a 56 bit number */
536 #define ROT56R64(k, n) { \
537 k = (k >> n) | ((k & ((1<<n) - 1)) << (56-n)); }
540 * Generate a key schedule from key, the least significant bit in each
541 * key byte is parity and shall be ignored. This leaves 56 significant
542 * bits in the key to scatter over the 16 key schedules. For each
543 * schedule extract the low order 32 bits and use as schedule, then
544 * rotate right by 11 bits.
546 * Note that this fc_keysched() generates a schedule in natural byte
547 * order, the Transarc function does not. Therefore it's *not*
548 * possible to mix fc_keysched, fc_ecb_encrypt and fc_cbc_encrypt
549 * from different implementations. Keep them in the same module!
552 fc_keysched(void *key_, fc_KeySchedule sched)
554 const unsigned char *key = key_;
556 /* Do we have 56 bit longs or even longer longs? */
557 #if ((1ul << 31) << 1) && defined(ULONG_MAX) && ((ULONG_MAX >> 55) != 0) && ((1ul << 55) != 0)
558 unsigned long k; /* k holds all 56 non parity bits */
560 /* Compress out parity bits */
577 /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
578 *sched++ = EFF_NTOHL((afs_uint32) k);
580 *sched++ = EFF_NTOHL((afs_uint32) k);
582 *sched++ = EFF_NTOHL((afs_uint32) k);
584 *sched++ = EFF_NTOHL((afs_uint32) k);
587 *sched++ = EFF_NTOHL((afs_uint32) k);
589 *sched++ = EFF_NTOHL((afs_uint32) k);
591 *sched++ = EFF_NTOHL((afs_uint32) k);
593 *sched++ = EFF_NTOHL((afs_uint32) k);
596 *sched++ = EFF_NTOHL((afs_uint32) k);
598 *sched++ = EFF_NTOHL((afs_uint32) k);
600 *sched++ = EFF_NTOHL((afs_uint32) k);
602 *sched++ = EFF_NTOHL((afs_uint32) k);
605 *sched++ = EFF_NTOHL((afs_uint32) k);
607 *sched++ = EFF_NTOHL((afs_uint32) k);
609 *sched++ = EFF_NTOHL((afs_uint32) k);
611 *sched++ = EFF_NTOHL((afs_uint32) k);
613 afs_uint32 hi, lo; /* hi is upper 24 bits and lo lower 32, total 56 */
615 /* Compress out parity bits */
634 /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
635 *sched++ = EFF_NTOHL(lo);
637 *sched++ = EFF_NTOHL(lo);
639 *sched++ = EFF_NTOHL(lo);
641 *sched++ = EFF_NTOHL(lo);
644 *sched++ = EFF_NTOHL(lo);
646 *sched++ = EFF_NTOHL(lo);
648 *sched++ = EFF_NTOHL(lo);
650 *sched++ = EFF_NTOHL(lo);
653 *sched++ = EFF_NTOHL(lo);
655 *sched++ = EFF_NTOHL(lo);
657 *sched++ = EFF_NTOHL(lo);
659 *sched++ = EFF_NTOHL(lo);
662 *sched++ = EFF_NTOHL(lo);
664 *sched++ = EFF_NTOHL(lo);
666 *sched++ = EFF_NTOHL(lo);
668 *sched++ = EFF_NTOHL(lo);
670 LOCK_RXKAD_STATS rxkad_stats.fc_key_scheds++;
671 UNLOCK_RXKAD_STATS return 0;
675 * Encryption/decryption of Rx packets is pretty straight forward. Run
676 * fc_cbc_encrypt over the packet fragments until len bytes have been
677 * processed. Skip the Rx packet header but not the security header.
680 rxkad_EncryptPacket(const struct rx_connection * rx_connection_not_used,
681 const fc_KeySchedule * sched, const afs_uint32 * iv,
682 int len, struct rx_packet * packet)
686 struct rx_securityClass *obj;
687 struct rxkad_cprivate *tp; /* s & c have type at same offset */
689 obj = rx_SecurityObjectOf(rx_connection_not_used);
690 tp = (struct rxkad_cprivate *)obj->privateData;
691 LOCK_RXKAD_STATS rxkad_stats.bytesEncrypted[rxkad_TypeIndex(tp->type)] +=
694 /* What is this good for?
695 * It turns out that the security header for auth_enc is of
696 * size 8 bytes and the last 4 bytes are defined to be 0!
698 afs_uint32 *t = (afs_uint32 *) packet->wirevec[1].iov_base;
702 memcpy(ivec, iv, sizeof(ivec)); /* Must use copy of iv */
703 for (frag = &packet->wirevec[1]; len; frag++) {
704 int iov_len = frag->iov_len;
705 afs_uint32 *iov_bas = (afs_uint32 *) frag->iov_base;
707 return RXKADDATALEN; /* Length mismatch */
709 iov_len = len; /* Don't process to much data */
710 fc_cbc_enc(iov_bas, iov_bas, iov_len, sched, ivec);
717 rxkad_DecryptPacket(const struct rx_connection * rx_connection_not_used,
718 const fc_KeySchedule * sched, const afs_uint32 * iv,
719 int len, struct rx_packet * packet)
723 struct rx_securityClass *obj;
724 struct rxkad_cprivate *tp; /* s & c have type at same offset */
726 obj = rx_SecurityObjectOf(rx_connection_not_used);
727 tp = (struct rxkad_cprivate *)obj->privateData;
728 LOCK_RXKAD_STATS rxkad_stats.bytesDecrypted[rxkad_TypeIndex(tp->type)] +=
730 UNLOCK_RXKAD_STATS memcpy(ivec, iv, sizeof(ivec)); /* Must use copy of iv */
731 for (frag = &packet->wirevec[1]; len > 0; frag++) {
732 int iov_len = frag->iov_len;
733 afs_uint32 *iov_bas = (afs_uint32 *) frag->iov_base;
735 return RXKADDATALEN; /* Length mismatch */
737 iov_len = len; /* Don't process to much data */
738 fc_cbc_dec(iov_bas, iov_bas, iov_len, sched, ivec);
744 #if defined(TEST) || defined(TEST_KERNEL)
746 * It is possible to link with the client kernel libafs.a to verify
747 * the test case. Use TEST_KERNEL to get the mangled names.
755 const char the_quick[] = "The quick brown fox jumps over the lazy dogs.\0\0";
757 const unsigned char key1[8] =
758 { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 };
759 const char ciph1[] = {
760 0x00, 0xf0, 0xe, 0x11, 0x75, 0xe6, 0x23, 0x82, 0xee, 0xac, 0x98, 0x62,
761 0x44, 0x51, 0xe4, 0x84, 0xc3, 0x59, 0xd8, 0xaa, 0x64, 0x60, 0xae, 0xf7,
762 0xd2, 0xd9, 0x13, 0x79, 0x72, 0xa3, 0x45, 0x03, 0x23, 0xb5, 0x62, 0xd7,
763 0xc, 0xf5, 0x27, 0xd1, 0xf8, 0x91, 0x3c, 0xac, 0x44, 0x22, 0x92, 0xef
766 const unsigned char key2[8] =
767 { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 };
768 const char ciph2[] = {
769 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c, 0x01, 0x88, 0x7f, 0x3e,
770 0x31, 0x6e, 0x62, 0x9d, 0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58,
771 0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0, 0x19, 0x89, 0x09, 0x1c,
772 0x2a, 0x8e, 0x8c, 0x94, 0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f
776 #define fc_keysched _afs_QTKrFdpoFL
777 #define fc_ecb_encrypt _afs_sDLThwNLok
778 #define fc_cbc_encrypt _afs_fkyCWTvfRS
779 #define rxkad_DecryptPacket _afs_SRWEeqTXrS
780 #define rxkad_EncryptPacket _afs_bpwQbdoghO
792 afs_int32 sched[MAXROUNDS];
793 char ciph[100], clear[100], tmp[100];
796 struct rx_packet packet;
798 if (sizeof(afs_int32) != 4)
799 fprintf(stderr, "error: sizeof(afs_int32) != 4\n");
800 if (sizeof(afs_uint32) != 4)
801 fprintf(stderr, "error: sizeof(afs_uint32) != 4\n");
804 * Use key1 and key2 as iv */
805 fc_keysched(key1, sched);
806 memcpy(iv, key2, sizeof(iv));
807 fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT);
808 if (memcmp(ciph1, ciph, sizeof(ciph1)) != 0)
809 fprintf(stderr, "encrypt FAILED\n");
810 memcpy(iv, key2, sizeof(iv));
811 fc_cbc_encrypt(ciph, clear, sizeof(the_quick), sched, iv, DECRYPT);
812 if (strcmp(the_quick, clear) != 0)
813 fprintf(stderr, "crypt decrypt FAILED\n");
816 * Use key2 and key1 as iv
818 fc_keysched(key2, sched);
819 memcpy(iv, key1, sizeof(iv));
820 fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT);
821 if (memcmp(ciph2, ciph, sizeof(ciph2)) != 0)
822 fprintf(stderr, "encrypt FAILED\n");
823 memcpy(iv, key1, sizeof(iv));
824 fc_cbc_encrypt(ciph, clear, sizeof(the_quick), sched, iv, DECRYPT);
825 if (strcmp(the_quick, clear) != 0)
826 fprintf(stderr, "crypt decrypt FAILED\n");
829 * Test Encrypt- and Decrypt-Packet, use key1 and key2 as iv
831 fc_keysched(key1, sched);
832 memcpy(iv, key2, sizeof(iv));
833 strcpy(clear, the_quick);
834 packet.wirevec[1].iov_base = clear;
835 packet.wirevec[1].iov_len = sizeof(the_quick);
836 packet.wirevec[2].iov_len = 0;
838 /* For unknown reasons bytes 4-7 are zeroed in rxkad_EncryptPacket */
839 rxkad_EncryptPacket(tmp, sched, iv, sizeof(the_quick), &packet);
840 rxkad_DecryptPacket(tmp, sched, iv, sizeof(the_quick), &packet);
845 if (strcmp(the_quick, clear) != 0)
846 fprintf(stderr, "rxkad_EncryptPacket/rxkad_DecryptPacket FAILED\n");
849 struct timeval start, stop;
852 fc_keysched(key1, sched);
853 gettimeofday(&start, 0);
854 for (i = 0; i < 1000000; i++)
855 fc_keysched(key1, sched);
856 gettimeofday(&stop, 0);
857 printf("fc_keysched = %2.2f us\n",
858 (stop.tv_sec - start.tv_sec +
859 (stop.tv_usec - start.tv_usec) / 1e6) * 1);
861 fc_ecb_encrypt(data, data, sched, ENCRYPT);
862 gettimeofday(&start, 0);
863 for (i = 0; i < 1000000; i++)
864 fc_ecb_encrypt(data, data, sched, ENCRYPT);
865 gettimeofday(&stop, 0);
866 printf("fc_ecb_encrypt = %2.2f us\n",
867 (stop.tv_sec - start.tv_sec +
868 (stop.tv_usec - start.tv_usec) / 1e6) * 1);
870 fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv,
872 gettimeofday(&start, 0);
873 for (i = 0; i < 100000; i++)
874 fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv,
876 gettimeofday(&stop, 0);
877 printf("fc_cbc_encrypt = %2.2f us\n",
878 (stop.tv_sec - start.tv_sec +
879 (stop.tv_usec - start.tv_usec) / 1e6) * 10);