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"
77 #include <des/stats.h>
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.
84 #define UNROLL_LOOPS 1
86 * Inline assembler gives a boost only to fc_keysched.
87 * On the pentium expect ca 28%.
89 /*#define GNU_ASM 1 (now autoconfed) */
91 #if !defined(inline) && !defined(__GNUC__)
96 * There is usually no memcpy in kernels but gcc will inline all
97 * calls to memcpy in this code anyway.
99 #if defined(KERNEL) && !defined(__GNUC__)
100 #define memcpy(to, from, n) bcopy((from), (to), (n))
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))
110 #define NTOH(x) bswap32(x)
114 * Try to use a good function for ntohl-ing.
116 * The choice is done by autoconf setting EFF_NTOHL to one of:
124 #define EFF_NTOHL(x) ntohl(x)
127 #if defined(__GNUC__) && (defined(i386) || defined(__i386__))
128 static inline afs_uint32
131 asm("bswap %0": "=r"(x):"0"(x));
138 * Sboxes for Feistel network derived from
139 * /afs/transarc.com/public/afsps/afs.rel31b.export-src/rxkad/sboxes.h
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)
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)
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)
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)
351 * This is a 16 round Feistel network with permutation F_ENCRYPT
354 #define F_ENCRYPT(R, L, sched) { \
355 union lc4 { afs_uint32 l; unsigned char c[4]; } un; \
357 L ^= sbox0[un.c[0]] ^ sbox1[un.c[1]] ^ sbox2[un.c[2]] ^ sbox3[un.c[3]]; }
359 #ifndef WORDS_BIGENDIAN
360 /* BEWARE: this code is endian dependent.
361 * This should really be inline assembler on the x86.
364 #define FF(y, shiftN) (((y) >> shiftN) & 0xFF)
365 #define F_ENCRYPT(R, L, sched) { \
368 L ^= sbox0[FF(un, 0)] ^ sbox1[FF(un, 8)] ^ sbox2[FF(un, 16)] ^ sbox3[FF(un, 24)];}
372 fc_ecb_enc(afs_uint32 l, afs_uint32 r, afs_uint32 out[2],
373 const afs_int32 sched[MAXROUNDS])
375 #if !defined(UNROLL_LOOPS)
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++);
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 */
409 fc_ecb_dec(afs_uint32 l, afs_uint32 r, afs_uint32 out[2],
410 const afs_int32 sched[MAXROUNDS])
412 sched = &sched[MAXROUNDS - 1];
414 #if !defined(UNROLL_LOOPS)
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--);
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 */
448 fc_cbc_enc(const afs_uint32 * in, afs_uint32 * out, afs_int32 length,
449 const afs_int32 sched[MAXROUNDS], afs_uint32 * iv)
451 afs_int32 xor0 = iv[0], xor1 = iv[1];
453 for (; length > 0; length -= 8) {
455 /* If length < 8 we read to much, usally ok */
458 fc_ecb_enc(xor0, xor1, b8, sched);
459 xor0 = in[0] ^ b8[0];
460 xor1 = in[1] ^ b8[1];
462 /* Out is always a multiple of 8 */
472 fc_cbc_dec(const afs_uint32 * in, afs_uint32 * out, afs_int32 length,
473 const afs_int32 sched[MAXROUNDS], afs_uint32 * iv)
475 afs_int32 xor0 = iv[0], xor1 = iv[1];
477 for (; length > 0; length -= 8) {
479 /* In is always a multiple of 8 */
480 fc_ecb_dec(in[0], in[1], b8, sched);
483 xor0 = in[0] ^ b8[0];
484 xor1 = in[1] ^ b8[1];
490 memcpy(out, b8, length); /* Don't write to much when length < 8 */
492 /* If length < 8 we write to much, this is not always ok */
503 fc_ecb_encrypt(afs_uint32 * in, afs_uint32 * out, fc_KeySchedule sched,
506 INC_RXKAD_STATS(fc_encrypts[encrypt]);
508 fc_ecb_enc(in[0], in[1], out, sched);
510 fc_ecb_dec(in[0], in[1], out, sched);
515 fc_cbc_encrypt(afs_uint32 * in, afs_uint32 * out, afs_int32 length,
516 fc_KeySchedule sched, afs_uint32 * iv, int encrypt)
519 fc_cbc_enc(in, out, length, sched, iv);
521 fc_cbc_dec(in, out, length, sched, iv);
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)); }
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)); }
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.
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!
548 fc_keysched(void *key_, fc_KeySchedule sched)
550 const unsigned char *key = key_;
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 */
556 /* Compress out parity bits */
573 /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
574 *sched++ = EFF_NTOHL((afs_uint32) k);
576 *sched++ = EFF_NTOHL((afs_uint32) k);
578 *sched++ = EFF_NTOHL((afs_uint32) k);
580 *sched++ = EFF_NTOHL((afs_uint32) k);
583 *sched++ = EFF_NTOHL((afs_uint32) k);
585 *sched++ = EFF_NTOHL((afs_uint32) k);
587 *sched++ = EFF_NTOHL((afs_uint32) k);
589 *sched++ = EFF_NTOHL((afs_uint32) k);
592 *sched++ = EFF_NTOHL((afs_uint32) k);
594 *sched++ = EFF_NTOHL((afs_uint32) k);
596 *sched++ = EFF_NTOHL((afs_uint32) k);
598 *sched++ = EFF_NTOHL((afs_uint32) k);
601 *sched++ = EFF_NTOHL((afs_uint32) k);
603 *sched++ = EFF_NTOHL((afs_uint32) k);
605 *sched++ = EFF_NTOHL((afs_uint32) k);
607 *sched++ = EFF_NTOHL((afs_uint32) k);
609 afs_uint32 hi, lo; /* hi is upper 24 bits and lo lower 32, total 56 */
611 /* Compress out parity bits */
630 /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
631 *sched++ = EFF_NTOHL(lo);
633 *sched++ = EFF_NTOHL(lo);
635 *sched++ = EFF_NTOHL(lo);
637 *sched++ = EFF_NTOHL(lo);
640 *sched++ = EFF_NTOHL(lo);
642 *sched++ = EFF_NTOHL(lo);
644 *sched++ = EFF_NTOHL(lo);
646 *sched++ = EFF_NTOHL(lo);
649 *sched++ = EFF_NTOHL(lo);
651 *sched++ = EFF_NTOHL(lo);
653 *sched++ = EFF_NTOHL(lo);
655 *sched++ = EFF_NTOHL(lo);
658 *sched++ = EFF_NTOHL(lo);
660 *sched++ = EFF_NTOHL(lo);
662 *sched++ = EFF_NTOHL(lo);
664 *sched++ = EFF_NTOHL(lo);
666 INC_RXKAD_STATS(fc_key_scheds);
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.
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)
682 struct rx_securityClass *obj;
683 struct rxkad_cprivate *tp; /* s & c have type at same offset */
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);
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!
693 afs_uint32 *t = (afs_uint32 *) packet->wirevec[1].iov_base;
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;
702 return RXKADDATALEN; /* Length mismatch */
704 iov_len = len; /* Don't process to much data */
705 fc_cbc_enc(iov_bas, iov_bas, iov_len, sched, ivec);
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)
718 struct rx_securityClass *obj;
719 struct rxkad_cprivate *tp; /* s & c have type at same offset */
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;
729 return RXKADDATALEN; /* Length mismatch */
731 iov_len = len; /* Don't process to much data */
732 fc_cbc_dec(iov_bas, iov_bas, iov_len, sched, ivec);
738 #if defined(TEST) || defined(TEST_KERNEL)
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.
749 const char the_quick[] = "The quick brown fox jumps over the lazy dogs.\0\0";
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
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
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
786 afs_int32 sched[MAXROUNDS];
787 char ciph[100], clear[100], tmp[100];
790 struct rx_packet packet;
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");
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");
810 * Use key2 and key1 as iv
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");
823 * Test Encrypt- and Decrypt-Packet, use key1 and key2 as iv
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;
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);
839 if (strcmp(the_quick, clear) != 0)
840 fprintf(stderr, "rxkad_EncryptPacket/rxkad_DecryptPacket FAILED\n");
843 struct timeval start, stop;
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);
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);
864 fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv,
866 gettimeofday(&start, 0);
867 for (i = 0; i < 100000; i++)
868 fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv,
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);