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>
62 #include <sys/types.h>
66 #include <netinet/in.h>
74 #include "private_data.h"
75 #include <des/stats.h>
78 * Unrolling of the inner loops helps the most on pentium chips
79 * (ca 18%). On risc machines only expect a modest improvement (ca 5%).
80 * The cost for this is rougly 4k bytes.
82 #define UNROLL_LOOPS 1
84 * Inline assembler gives a boost only to fc_keysched.
85 * On the pentium expect ca 28%.
87 /*#define GNU_ASM 1 (now autoconfed) */
89 #if !defined(inline) && !defined(__GNUC__)
94 * There is usually no memcpy in kernels but gcc will inline all
95 * calls to memcpy in this code anyway.
97 #if defined(KERNEL) && !defined(__GNUC__)
98 #define memcpy(to, from, n) bcopy((from), (to), (n))
101 /* Rotate 32 bit word left */
102 #define ROT32L(x, n) ((((afs_uint32) x) << (n)) | (((afs_uint32) x) >> (32-(n))))
103 #define bswap32(x) (((ROT32L(x, 16) & 0x00ff00ff)<<8) | ((ROT32L(x, 16)>>8) & 0x00ff00ff))
108 #define NTOH(x) bswap32(x)
112 * Try to use a good function for ntohl-ing.
114 * The choice is done by autoconf setting EFF_NTOHL to one of:
122 #define EFF_NTOHL(x) ntohl(x)
125 #if defined(__GNUC__) && (defined(i386) || defined(__i386__))
126 static inline afs_uint32
129 asm("bswap %0": "=r"(x):"0"(x));
136 * Sboxes for Feistel network derived from
137 * /afs/transarc.com/public/afsps/afs.rel31b.export-src/rxkad/sboxes.h
141 #define Z(x) NTOH(x << 3)
142 static const afs_uint32 sbox0[256] = {
143 Z(0xea), Z(0x7f), Z(0xb2), Z(0x64), Z(0x9d), Z(0xb0), Z(0xd9), Z(0x11),
144 Z(0xcd), Z(0x86), Z(0x86),
145 Z(0x91), Z(0x0a), Z(0xb2), Z(0x93), Z(0x06), Z(0x0e), Z(0x06), Z(0xd2),
146 Z(0x65), Z(0x73), Z(0xc5),
147 Z(0x28), Z(0x60), Z(0xf2), Z(0x20), Z(0xb5), Z(0x38), Z(0x7e), Z(0xda),
148 Z(0x9f), Z(0xe3), Z(0xd2),
149 Z(0xcf), Z(0xc4), Z(0x3c), Z(0x61), Z(0xff), Z(0x4a), Z(0x4a), Z(0x35),
150 Z(0xac), Z(0xaa), Z(0x5f),
151 Z(0x2b), Z(0xbb), Z(0xbc), Z(0x53), Z(0x4e), Z(0x9d), Z(0x78), Z(0xa3),
152 Z(0xdc), Z(0x09), Z(0x32),
153 Z(0x10), Z(0xc6), Z(0x6f), Z(0x66), Z(0xd6), Z(0xab), Z(0xa9), Z(0xaf),
154 Z(0xfd), Z(0x3b), Z(0x95),
155 Z(0xe8), Z(0x34), Z(0x9a), Z(0x81), Z(0x72), Z(0x80), Z(0x9c), Z(0xf3),
156 Z(0xec), Z(0xda), Z(0x9f),
157 Z(0x26), Z(0x76), Z(0x15), Z(0x3e), Z(0x55), Z(0x4d), Z(0xde), Z(0x84),
158 Z(0xee), Z(0xad), Z(0xc7),
159 Z(0xf1), Z(0x6b), Z(0x3d), Z(0xd3), Z(0x04), Z(0x49), Z(0xaa), Z(0x24),
160 Z(0x0b), Z(0x8a), Z(0x83),
161 Z(0xba), Z(0xfa), Z(0x85), Z(0xa0), Z(0xa8), Z(0xb1), Z(0xd4), Z(0x01),
162 Z(0xd8), Z(0x70), Z(0x64),
163 Z(0xf0), Z(0x51), Z(0xd2), Z(0xc3), Z(0xa7), Z(0x75), Z(0x8c), Z(0xa5),
164 Z(0x64), Z(0xef), Z(0x10),
165 Z(0x4e), Z(0xb7), Z(0xc6), Z(0x61), Z(0x03), Z(0xeb), Z(0x44), Z(0x3d),
166 Z(0xe5), Z(0xb3), Z(0x5b),
167 Z(0xae), Z(0xd5), Z(0xad), Z(0x1d), Z(0xfa), Z(0x5a), Z(0x1e), Z(0x33),
168 Z(0xab), Z(0x93), Z(0xa2),
169 Z(0xb7), Z(0xe7), Z(0xa8), Z(0x45), Z(0xa4), Z(0xcd), Z(0x29), Z(0x63),
170 Z(0x44), Z(0xb6), Z(0x69),
171 Z(0x7e), Z(0x2e), Z(0x62), Z(0x03), Z(0xc8), Z(0xe0), Z(0x17), Z(0xbb),
172 Z(0xc7), Z(0xf3), Z(0x3f),
173 Z(0x36), Z(0xba), Z(0x71), Z(0x8e), Z(0x97), Z(0x65), Z(0x60), Z(0x69),
174 Z(0xb6), Z(0xf6), Z(0xe6),
175 Z(0x6e), Z(0xe0), Z(0x81), Z(0x59), Z(0xe8), Z(0xaf), Z(0xdd), Z(0x95),
176 Z(0x22), Z(0x99), Z(0xfd),
177 Z(0x63), Z(0x19), Z(0x74), Z(0x61), Z(0xb1), Z(0xb6), Z(0x5b), Z(0xae),
178 Z(0x54), Z(0xb3), Z(0x70),
179 Z(0xff), Z(0xc6), Z(0x3b), Z(0x3e), Z(0xc1), Z(0xd7), Z(0xe1), Z(0x0e),
180 Z(0x76), Z(0xe5), Z(0x36),
181 Z(0x4f), Z(0x59), Z(0xc7), Z(0x08), Z(0x6e), Z(0x82), Z(0xa6), Z(0x93),
182 Z(0xc4), Z(0xaa), Z(0x26),
183 Z(0x49), Z(0xe0), Z(0x21), Z(0x64), Z(0x07), Z(0x9f), Z(0x64), Z(0x81),
184 Z(0x9c), Z(0xbf), Z(0xf9),
185 Z(0xd1), Z(0x43), Z(0xf8), Z(0xb6), Z(0xb9), Z(0xf1), Z(0x24), Z(0x75),
186 Z(0x03), Z(0xe4), Z(0xb0),
187 Z(0x99), Z(0x46), Z(0x3d), Z(0xf5), Z(0xd1), Z(0x39), Z(0x72), Z(0x12),
188 Z(0xf6), Z(0xba), Z(0x0c),
189 Z(0x0d), Z(0x42), Z(0x2e)
193 #define Z(x) NTOH((x << 27) | (x >> 5))
194 static const afs_uint32 sbox1[256] = {
195 Z(0x77), Z(0x14), Z(0xa6), Z(0xfe), Z(0xb2), Z(0x5e), Z(0x8c), Z(0x3e),
196 Z(0x67), Z(0x6c), Z(0xa1),
197 Z(0x0d), Z(0xc2), Z(0xa2), Z(0xc1), Z(0x85), Z(0x6c), Z(0x7b), Z(0x67),
198 Z(0xc6), Z(0x23), Z(0xe3),
199 Z(0xf2), Z(0x89), Z(0x50), Z(0x9c), Z(0x03), Z(0xb7), Z(0x73), Z(0xe6),
200 Z(0xe1), Z(0x39), Z(0x31),
201 Z(0x2c), Z(0x27), Z(0x9f), Z(0xa5), Z(0x69), Z(0x44), Z(0xd6), Z(0x23),
202 Z(0x83), Z(0x98), Z(0x7d),
203 Z(0x3c), Z(0xb4), Z(0x2d), Z(0x99), Z(0x1c), Z(0x1f), Z(0x8c), Z(0x20),
204 Z(0x03), Z(0x7c), Z(0x5f),
205 Z(0xad), Z(0xf4), Z(0xfa), Z(0x95), Z(0xca), Z(0x76), Z(0x44), Z(0xcd),
206 Z(0xb6), Z(0xb8), Z(0xa1),
207 Z(0xa1), Z(0xbe), Z(0x9e), Z(0x54), Z(0x8f), Z(0x0b), Z(0x16), Z(0x74),
208 Z(0x31), Z(0x8a), Z(0x23),
209 Z(0x17), Z(0x04), Z(0xfa), Z(0x79), Z(0x84), Z(0xb1), Z(0xf5), Z(0x13),
210 Z(0xab), Z(0xb5), Z(0x2e),
211 Z(0xaa), Z(0x0c), Z(0x60), Z(0x6b), Z(0x5b), Z(0xc4), Z(0x4b), Z(0xbc),
212 Z(0xe2), Z(0xaf), Z(0x45),
213 Z(0x73), Z(0xfa), Z(0xc9), Z(0x49), Z(0xcd), Z(0x00), Z(0x92), Z(0x7d),
214 Z(0x97), Z(0x7a), Z(0x18),
215 Z(0x60), Z(0x3d), Z(0xcf), Z(0x5b), Z(0xde), Z(0xc6), Z(0xe2), Z(0xe6),
216 Z(0xbb), Z(0x8b), Z(0x06),
217 Z(0xda), Z(0x08), Z(0x15), Z(0x1b), Z(0x88), Z(0x6a), Z(0x17), Z(0x89),
218 Z(0xd0), Z(0xa9), Z(0xc1),
219 Z(0xc9), Z(0x70), Z(0x6b), Z(0xe5), Z(0x43), Z(0xf4), Z(0x68), Z(0xc8),
220 Z(0xd3), Z(0x84), Z(0x28),
221 Z(0x0a), Z(0x52), Z(0x66), Z(0xa3), Z(0xca), Z(0xf2), Z(0xe3), Z(0x7f),
222 Z(0x7a), Z(0x31), Z(0xf7),
223 Z(0x88), Z(0x94), Z(0x5e), Z(0x9c), Z(0x63), Z(0xd5), Z(0x24), Z(0x66),
224 Z(0xfc), Z(0xb3), Z(0x57),
225 Z(0x25), Z(0xbe), Z(0x89), Z(0x44), Z(0xc4), Z(0xe0), Z(0x8f), Z(0x23),
226 Z(0x3c), Z(0x12), Z(0x52),
227 Z(0xf5), Z(0x1e), Z(0xf4), Z(0xcb), Z(0x18), Z(0x33), Z(0x1f), Z(0xf8),
228 Z(0x69), Z(0x10), Z(0x9d),
229 Z(0xd3), Z(0xf7), Z(0x28), Z(0xf8), Z(0x30), Z(0x05), Z(0x5e), Z(0x32),
230 Z(0xc0), Z(0xd5), Z(0x19),
231 Z(0xbd), Z(0x45), Z(0x8b), Z(0x5b), Z(0xfd), Z(0xbc), Z(0xe2), Z(0x5c),
232 Z(0xa9), Z(0x96), Z(0xef),
233 Z(0x70), Z(0xcf), Z(0xc2), Z(0x2a), Z(0xb3), Z(0x61), Z(0xad), Z(0x80),
234 Z(0x48), Z(0x81), Z(0xb7),
235 Z(0x1d), Z(0x43), Z(0xd9), Z(0xd7), Z(0x45), Z(0xf0), Z(0xd8), Z(0x8a),
236 Z(0x59), Z(0x7c), Z(0x57),
237 Z(0xc1), Z(0x79), Z(0xc7), Z(0x34), Z(0xd6), Z(0x43), Z(0xdf), Z(0xe4),
238 Z(0x78), Z(0x16), Z(0x06),
239 Z(0xda), Z(0x92), Z(0x76), Z(0x51), Z(0xe1), Z(0xd4), Z(0x70), Z(0x03),
240 Z(0xe0), Z(0x2f), Z(0x96),
241 Z(0x91), Z(0x82), Z(0x80)
245 #define Z(x) NTOH(x << 11)
246 static const afs_uint32 sbox2[256] = {
247 Z(0xf0), Z(0x37), Z(0x24), Z(0x53), Z(0x2a), Z(0x03), Z(0x83), Z(0x86),
248 Z(0xd1), Z(0xec), Z(0x50),
249 Z(0xf0), Z(0x42), Z(0x78), Z(0x2f), Z(0x6d), Z(0xbf), Z(0x80), Z(0x87),
250 Z(0x27), Z(0x95), Z(0xe2),
251 Z(0xc5), Z(0x5d), Z(0xf9), Z(0x6f), Z(0xdb), Z(0xb4), Z(0x65), Z(0x6e),
252 Z(0xe7), Z(0x24), Z(0xc8),
253 Z(0x1a), Z(0xbb), Z(0x49), Z(0xb5), Z(0x0a), Z(0x7d), Z(0xb9), Z(0xe8),
254 Z(0xdc), Z(0xb7), Z(0xd9),
255 Z(0x45), Z(0x20), Z(0x1b), Z(0xce), Z(0x59), Z(0x9d), Z(0x6b), Z(0xbd),
256 Z(0x0e), Z(0x8f), Z(0xa3),
257 Z(0xa9), Z(0xbc), Z(0x74), Z(0xa6), Z(0xf6), Z(0x7f), Z(0x5f), Z(0xb1),
258 Z(0x68), Z(0x84), Z(0xbc),
259 Z(0xa9), Z(0xfd), Z(0x55), Z(0x50), Z(0xe9), Z(0xb6), Z(0x13), Z(0x5e),
260 Z(0x07), Z(0xb8), Z(0x95),
261 Z(0x02), Z(0xc0), Z(0xd0), Z(0x6a), Z(0x1a), Z(0x85), Z(0xbd), Z(0xb6),
262 Z(0xfd), Z(0xfe), Z(0x17),
263 Z(0x3f), Z(0x09), Z(0xa3), Z(0x8d), Z(0xfb), Z(0xed), Z(0xda), Z(0x1d),
264 Z(0x6d), Z(0x1c), Z(0x6c),
265 Z(0x01), Z(0x5a), Z(0xe5), Z(0x71), Z(0x3e), Z(0x8b), Z(0x6b), Z(0xbe),
266 Z(0x29), Z(0xeb), Z(0x12),
267 Z(0x19), Z(0x34), Z(0xcd), Z(0xb3), Z(0xbd), Z(0x35), Z(0xea), Z(0x4b),
268 Z(0xd5), Z(0xae), Z(0x2a),
269 Z(0x79), Z(0x5a), Z(0xa5), Z(0x32), Z(0x12), Z(0x7b), Z(0xdc), Z(0x2c),
270 Z(0xd0), Z(0x22), Z(0x4b),
271 Z(0xb1), Z(0x85), Z(0x59), Z(0x80), Z(0xc0), Z(0x30), Z(0x9f), Z(0x73),
272 Z(0xd3), Z(0x14), Z(0x48),
273 Z(0x40), Z(0x07), Z(0x2d), Z(0x8f), Z(0x80), Z(0x0f), Z(0xce), Z(0x0b),
274 Z(0x5e), Z(0xb7), Z(0x5e),
275 Z(0xac), Z(0x24), Z(0x94), Z(0x4a), Z(0x18), Z(0x15), Z(0x05), Z(0xe8),
276 Z(0x02), Z(0x77), Z(0xa9),
277 Z(0xc7), Z(0x40), Z(0x45), Z(0x89), Z(0xd1), Z(0xea), Z(0xde), Z(0x0c),
278 Z(0x79), Z(0x2a), Z(0x99),
279 Z(0x6c), Z(0x3e), Z(0x95), Z(0xdd), Z(0x8c), Z(0x7d), Z(0xad), Z(0x6f),
280 Z(0xdc), Z(0xff), Z(0xfd),
281 Z(0x62), Z(0x47), Z(0xb3), Z(0x21), Z(0x8a), Z(0xec), Z(0x8e), Z(0x19),
282 Z(0x18), Z(0xb4), Z(0x6e),
283 Z(0x3d), Z(0xfd), Z(0x74), Z(0x54), Z(0x1e), Z(0x04), Z(0x85), Z(0xd8),
284 Z(0xbc), Z(0x1f), Z(0x56),
285 Z(0xe7), Z(0x3a), Z(0x56), Z(0x67), Z(0xd6), Z(0xc8), Z(0xa5), Z(0xf3),
286 Z(0x8e), Z(0xde), Z(0xae),
287 Z(0x37), Z(0x49), Z(0xb7), Z(0xfa), Z(0xc8), Z(0xf4), Z(0x1f), Z(0xe0),
288 Z(0x2a), Z(0x9b), Z(0x15),
289 Z(0xd1), Z(0x34), Z(0x0e), Z(0xb5), Z(0xe0), Z(0x44), Z(0x78), Z(0x84),
290 Z(0x59), Z(0x56), Z(0x68),
291 Z(0x77), Z(0xa5), Z(0x14), Z(0x06), Z(0xf5), Z(0x2f), Z(0x8c), Z(0x8a),
292 Z(0x73), Z(0x80), Z(0x76),
293 Z(0xb4), Z(0x10), Z(0x86)
297 #define Z(x) NTOH(x << 19)
298 static const afs_uint32 sbox3[256] = {
299 Z(0xa9), Z(0x2a), Z(0x48), Z(0x51), Z(0x84), Z(0x7e), Z(0x49), Z(0xe2),
300 Z(0xb5), Z(0xb7), Z(0x42),
301 Z(0x33), Z(0x7d), Z(0x5d), Z(0xa6), Z(0x12), Z(0x44), Z(0x48), Z(0x6d),
302 Z(0x28), Z(0xaa), Z(0x20),
303 Z(0x6d), Z(0x57), Z(0xd6), Z(0x6b), Z(0x5d), Z(0x72), Z(0xf0), Z(0x92),
304 Z(0x5a), Z(0x1b), Z(0x53),
305 Z(0x80), Z(0x24), Z(0x70), Z(0x9a), Z(0xcc), Z(0xa7), Z(0x66), Z(0xa1),
306 Z(0x01), Z(0xa5), Z(0x41),
307 Z(0x97), Z(0x41), Z(0x31), Z(0x82), Z(0xf1), Z(0x14), Z(0xcf), Z(0x53),
308 Z(0x0d), Z(0xa0), Z(0x10),
309 Z(0xcc), Z(0x2a), Z(0x7d), Z(0xd2), Z(0xbf), Z(0x4b), Z(0x1a), Z(0xdb),
310 Z(0x16), Z(0x47), Z(0xf6),
311 Z(0x51), Z(0x36), Z(0xed), Z(0xf3), Z(0xb9), Z(0x1a), Z(0xa7), Z(0xdf),
312 Z(0x29), Z(0x43), Z(0x01),
313 Z(0x54), Z(0x70), Z(0xa4), Z(0xbf), Z(0xd4), Z(0x0b), Z(0x53), Z(0x44),
314 Z(0x60), Z(0x9e), Z(0x23),
315 Z(0xa1), Z(0x18), Z(0x68), Z(0x4f), Z(0xf0), Z(0x2f), Z(0x82), Z(0xc2),
316 Z(0x2a), Z(0x41), Z(0xb2),
317 Z(0x42), Z(0x0c), Z(0xed), Z(0x0c), Z(0x1d), Z(0x13), Z(0x3a), Z(0x3c),
318 Z(0x6e), Z(0x35), Z(0xdc),
319 Z(0x60), Z(0x65), Z(0x85), Z(0xe9), Z(0x64), Z(0x02), Z(0x9a), Z(0x3f),
320 Z(0x9f), Z(0x87), Z(0x96),
321 Z(0xdf), Z(0xbe), Z(0xf2), Z(0xcb), Z(0xe5), Z(0x6c), Z(0xd4), Z(0x5a),
322 Z(0x83), Z(0xbf), Z(0x92),
323 Z(0x1b), Z(0x94), Z(0x00), Z(0x42), Z(0xcf), Z(0x4b), Z(0x00), Z(0x75),
324 Z(0xba), Z(0x8f), Z(0x76),
325 Z(0x5f), Z(0x5d), Z(0x3a), Z(0x4d), Z(0x09), Z(0x12), Z(0x08), Z(0x38),
326 Z(0x95), Z(0x17), Z(0xe4),
327 Z(0x01), Z(0x1d), Z(0x4c), Z(0xa9), Z(0xcc), Z(0x85), Z(0x82), Z(0x4c),
328 Z(0x9d), Z(0x2f), Z(0x3b),
329 Z(0x66), Z(0xa1), Z(0x34), Z(0x10), Z(0xcd), Z(0x59), Z(0x89), Z(0xa5),
330 Z(0x31), Z(0xcf), Z(0x05),
331 Z(0xc8), Z(0x84), Z(0xfa), Z(0xc7), Z(0xba), Z(0x4e), Z(0x8b), Z(0x1a),
332 Z(0x19), Z(0xf1), Z(0xa1),
333 Z(0x3b), Z(0x18), Z(0x12), Z(0x17), Z(0xb0), Z(0x98), Z(0x8d), Z(0x0b),
334 Z(0x23), Z(0xc3), Z(0x3a),
335 Z(0x2d), Z(0x20), Z(0xdf), Z(0x13), Z(0xa0), Z(0xa8), Z(0x4c), Z(0x0d),
336 Z(0x6c), Z(0x2f), Z(0x47),
337 Z(0x13), Z(0x13), Z(0x52), Z(0x1f), Z(0x2d), Z(0xf5), Z(0x79), Z(0x3d),
338 Z(0xa2), Z(0x54), Z(0xbd),
339 Z(0x69), Z(0xc8), Z(0x6b), Z(0xf3), Z(0x05), Z(0x28), Z(0xf1), Z(0x16),
340 Z(0x46), Z(0x40), Z(0xb0),
341 Z(0x11), Z(0xd3), Z(0xb7), Z(0x95), Z(0x49), Z(0xcf), Z(0xc3), Z(0x1d),
342 Z(0x8f), Z(0xd8), Z(0xe1),
343 Z(0x73), Z(0xdb), Z(0xad), Z(0xc8), Z(0xc9), Z(0xa9), Z(0xa1), Z(0xc2),
344 Z(0xc5), Z(0xe3), Z(0xba),
345 Z(0xfc), Z(0x0e), Z(0x25)
349 * This is a 16 round Feistel network with permutation F_ENCRYPT
352 #define F_ENCRYPT(R, L, sched) { \
353 union lc4 { afs_uint32 l; unsigned char c[4]; } un; \
355 L ^= sbox0[un.c[0]] ^ sbox1[un.c[1]] ^ sbox2[un.c[2]] ^ sbox3[un.c[3]]; }
357 #ifndef WORDS_BIGENDIAN
358 /* BEWARE: this code is endian dependent.
359 * This should really be inline assembler on the x86.
362 #define FF(y, shiftN) (((y) >> shiftN) & 0xFF)
363 #define F_ENCRYPT(R, L, sched) { \
366 L ^= sbox0[FF(un, 0)] ^ sbox1[FF(un, 8)] ^ sbox2[FF(un, 16)] ^ sbox3[FF(un, 24)];}
370 fc_ecb_enc(afs_uint32 l, afs_uint32 r, afs_uint32 out[2],
371 const afs_int32 sched[MAXROUNDS])
373 #if !defined(UNROLL_LOOPS)
376 for (i = 0; i < (MAXROUNDS / 4); i++) {
377 F_ENCRYPT(r, l, *sched++);
378 F_ENCRYPT(l, r, *sched++);
379 F_ENCRYPT(r, l, *sched++);
380 F_ENCRYPT(l, r, *sched++);
384 F_ENCRYPT(r, l, *sched++);
385 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 #endif /* UNROLL_LOOPS */
407 fc_ecb_dec(afs_uint32 l, afs_uint32 r, afs_uint32 out[2],
408 const afs_int32 sched[MAXROUNDS])
410 sched = &sched[MAXROUNDS - 1];
412 #if !defined(UNROLL_LOOPS)
415 for (i = 0; i < (MAXROUNDS / 4); i++) {
416 F_ENCRYPT(l, r, *sched--);
417 F_ENCRYPT(r, l, *sched--);
418 F_ENCRYPT(l, r, *sched--);
419 F_ENCRYPT(r, l, *sched--);
423 F_ENCRYPT(l, r, *sched--);
424 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 #endif /* UNROLL_LOOPS */
446 fc_cbc_enc(const afs_uint32 * in, afs_uint32 * out, afs_int32 length,
447 const afs_int32 sched[MAXROUNDS], afs_uint32 * iv)
449 afs_int32 xor0 = iv[0], xor1 = iv[1];
451 for (; length > 0; length -= 8) {
453 /* If length < 8 we read to much, usally ok */
456 fc_ecb_enc(xor0, xor1, b8, sched);
457 xor0 = in[0] ^ b8[0];
458 xor1 = in[1] ^ b8[1];
460 /* Out is always a multiple of 8 */
470 fc_cbc_dec(const afs_uint32 * in, afs_uint32 * out, afs_int32 length,
471 const afs_int32 sched[MAXROUNDS], afs_uint32 * iv)
473 afs_int32 xor0 = iv[0], xor1 = iv[1];
475 for (; length > 0; length -= 8) {
477 /* In is always a multiple of 8 */
478 fc_ecb_dec(in[0], in[1], b8, sched);
481 xor0 = in[0] ^ b8[0];
482 xor1 = in[1] ^ b8[1];
488 memcpy(out, b8, length); /* Don't write to much when length < 8 */
490 /* If length < 8 we write to much, this is not always ok */
501 fc_ecb_encrypt(afs_uint32 * in, afs_uint32 * out, fc_KeySchedule sched,
504 INC_RXKAD_STATS(fc_encrypts[encrypt]);
506 fc_ecb_enc(in[0], in[1], out, sched);
508 fc_ecb_dec(in[0], in[1], out, sched);
513 fc_cbc_encrypt(afs_uint32 * in, afs_uint32 * out, afs_int32 length,
514 fc_KeySchedule sched, afs_uint32 * iv, int encrypt)
517 fc_cbc_enc(in, out, length, sched, iv);
519 fc_cbc_dec(in, out, length, sched, iv);
523 /* Rotate two 32 bit numbers as a 56 bit number */
524 #define ROT56R(hi, lo, n) { \
525 afs_uint32 t = lo & ((1<<n)-1); \
526 lo = (lo >> n) | ((hi & ((1<<n)-1)) << (32-n)); \
527 hi = (hi >> n) | (t << (24-n)); }
529 /* Rotate one 64 bit number as a 56 bit number */
530 #define ROT56R64(k, n) { \
531 k = (k >> n) | ((k & ((1<<n) - 1)) << (56-n)); }
534 * Generate a key schedule from key, the least significant bit in each
535 * key byte is parity and shall be ignored. This leaves 56 significant
536 * bits in the key to scatter over the 16 key schedules. For each
537 * schedule extract the low order 32 bits and use as schedule, then
538 * rotate right by 11 bits.
540 * Note that this fc_keysched() generates a schedule in natural byte
541 * order, the Transarc function does not. Therefore it's *not*
542 * possible to mix fc_keysched, fc_ecb_encrypt and fc_cbc_encrypt
543 * from different implementations. Keep them in the same module!
546 fc_keysched(void *key_, fc_KeySchedule sched)
548 const unsigned char *key = key_;
550 /* Do we have 56 bit longs or even longer longs? */
552 afs_uint64 k; /* k holds all 56 non parity bits */
554 /* Compress out parity bits */
571 /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
572 *sched++ = EFF_NTOHL((afs_uint32) k);
574 *sched++ = EFF_NTOHL((afs_uint32) k);
576 *sched++ = EFF_NTOHL((afs_uint32) k);
578 *sched++ = EFF_NTOHL((afs_uint32) k);
581 *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);
590 *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);
599 *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 afs_uint32 hi, lo; /* hi is upper 24 bits and lo lower 32, total 56 */
609 /* Compress out parity bits */
628 /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */
629 *sched++ = EFF_NTOHL(lo);
631 *sched++ = EFF_NTOHL(lo);
633 *sched++ = EFF_NTOHL(lo);
635 *sched++ = EFF_NTOHL(lo);
638 *sched++ = EFF_NTOHL(lo);
640 *sched++ = EFF_NTOHL(lo);
642 *sched++ = EFF_NTOHL(lo);
644 *sched++ = EFF_NTOHL(lo);
647 *sched++ = EFF_NTOHL(lo);
649 *sched++ = EFF_NTOHL(lo);
651 *sched++ = EFF_NTOHL(lo);
653 *sched++ = EFF_NTOHL(lo);
656 *sched++ = EFF_NTOHL(lo);
658 *sched++ = EFF_NTOHL(lo);
660 *sched++ = EFF_NTOHL(lo);
662 *sched++ = EFF_NTOHL(lo);
664 INC_RXKAD_STATS(fc_key_scheds);
669 * Encryption/decryption of Rx packets is pretty straight forward. Run
670 * fc_cbc_encrypt over the packet fragments until len bytes have been
671 * processed. Skip the Rx packet header but not the security header.
674 rxkad_EncryptPacket(const struct rx_connection * rx_connection_not_used,
675 const fc_KeySchedule * sched, const afs_uint32 * iv,
676 int len, struct rx_packet * packet)
680 struct rx_securityClass *obj;
681 struct rxkad_cprivate *tp; /* s & c have type at same offset */
683 obj = rx_SecurityObjectOf(rx_connection_not_used);
684 tp = (struct rxkad_cprivate *)obj->privateData;
685 ADD_RXKAD_STATS(bytesEncrypted[rxkad_TypeIndex(tp->type)],len);
687 /* What is this good for?
688 * It turns out that the security header for auth_enc is of
689 * size 8 bytes and the last 4 bytes are defined to be 0!
691 afs_uint32 *t = (afs_uint32 *) packet->wirevec[1].iov_base;
695 memcpy(ivec, iv, sizeof(ivec)); /* Must use copy of iv */
696 for (frag = &packet->wirevec[1]; len; frag++) {
697 int iov_len = frag->iov_len;
698 afs_uint32 *iov_bas = (afs_uint32 *) frag->iov_base;
700 return RXKADDATALEN; /* Length mismatch */
702 iov_len = len; /* Don't process to much data */
703 fc_cbc_enc(iov_bas, iov_bas, iov_len, sched, ivec);
710 rxkad_DecryptPacket(const struct rx_connection * rx_connection_not_used,
711 const fc_KeySchedule * sched, const afs_uint32 * iv,
712 int len, struct rx_packet * packet)
716 struct rx_securityClass *obj;
717 struct rxkad_cprivate *tp; /* s & c have type at same offset */
719 obj = rx_SecurityObjectOf(rx_connection_not_used);
720 tp = (struct rxkad_cprivate *)obj->privateData;
721 ADD_RXKAD_STATS(bytesDecrypted[rxkad_TypeIndex(tp->type)],len);
722 memcpy(ivec, iv, sizeof(ivec)); /* Must use copy of iv */
723 for (frag = &packet->wirevec[1]; len > 0; frag++) {
724 int iov_len = frag->iov_len;
725 afs_uint32 *iov_bas = (afs_uint32 *) frag->iov_base;
727 return RXKADDATALEN; /* Length mismatch */
729 iov_len = len; /* Don't process to much data */
730 fc_cbc_dec(iov_bas, iov_bas, iov_len, sched, ivec);
736 #if defined(TEST) || defined(TEST_KERNEL)
738 * It is possible to link with the client kernel libafs.a to verify
739 * the test case. Use TEST_KERNEL to get the mangled names.
747 const char the_quick[] = "The quick brown fox jumps over the lazy dogs.\0\0";
749 const unsigned char key1[8] =
750 { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 };
751 const char ciph1[] = {
752 0x00, 0xf0, 0xe, 0x11, 0x75, 0xe6, 0x23, 0x82, 0xee, 0xac, 0x98, 0x62,
753 0x44, 0x51, 0xe4, 0x84, 0xc3, 0x59, 0xd8, 0xaa, 0x64, 0x60, 0xae, 0xf7,
754 0xd2, 0xd9, 0x13, 0x79, 0x72, 0xa3, 0x45, 0x03, 0x23, 0xb5, 0x62, 0xd7,
755 0xc, 0xf5, 0x27, 0xd1, 0xf8, 0x91, 0x3c, 0xac, 0x44, 0x22, 0x92, 0xef
758 const unsigned char key2[8] =
759 { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 };
760 const char ciph2[] = {
761 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c, 0x01, 0x88, 0x7f, 0x3e,
762 0x31, 0x6e, 0x62, 0x9d, 0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58,
763 0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0, 0x19, 0x89, 0x09, 0x1c,
764 0x2a, 0x8e, 0x8c, 0x94, 0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f
768 #define fc_keysched _afs_QTKrFdpoFL
769 #define fc_ecb_encrypt _afs_sDLThwNLok
770 #define fc_cbc_encrypt _afs_fkyCWTvfRS
771 #define rxkad_DecryptPacket _afs_SRWEeqTXrS
772 #define rxkad_EncryptPacket _afs_bpwQbdoghO
784 afs_int32 sched[MAXROUNDS];
785 char ciph[100], clear[100], tmp[100];
788 struct rx_packet packet;
790 if (sizeof(afs_int32) != 4)
791 fprintf(stderr, "error: sizeof(afs_int32) != 4\n");
792 if (sizeof(afs_uint32) != 4)
793 fprintf(stderr, "error: sizeof(afs_uint32) != 4\n");
796 * Use key1 and key2 as iv */
797 fc_keysched(key1, sched);
798 memcpy(iv, key2, sizeof(iv));
799 fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT);
800 if (memcmp(ciph1, ciph, sizeof(ciph1)) != 0)
801 fprintf(stderr, "encrypt FAILED\n");
802 memcpy(iv, key2, sizeof(iv));
803 fc_cbc_encrypt(ciph, clear, sizeof(the_quick), sched, iv, DECRYPT);
804 if (strcmp(the_quick, clear) != 0)
805 fprintf(stderr, "crypt decrypt FAILED\n");
808 * Use key2 and key1 as iv
810 fc_keysched(key2, sched);
811 memcpy(iv, key1, sizeof(iv));
812 fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv, ENCRYPT);
813 if (memcmp(ciph2, ciph, sizeof(ciph2)) != 0)
814 fprintf(stderr, "encrypt FAILED\n");
815 memcpy(iv, key1, sizeof(iv));
816 fc_cbc_encrypt(ciph, clear, sizeof(the_quick), sched, iv, DECRYPT);
817 if (strcmp(the_quick, clear) != 0)
818 fprintf(stderr, "crypt decrypt FAILED\n");
821 * Test Encrypt- and Decrypt-Packet, use key1 and key2 as iv
823 fc_keysched(key1, sched);
824 memcpy(iv, key2, sizeof(iv));
825 strcpy(clear, the_quick);
826 packet.wirevec[1].iov_base = clear;
827 packet.wirevec[1].iov_len = sizeof(the_quick);
828 packet.wirevec[2].iov_len = 0;
830 /* For unknown reasons bytes 4-7 are zeroed in rxkad_EncryptPacket */
831 rxkad_EncryptPacket(tmp, sched, iv, sizeof(the_quick), &packet);
832 rxkad_DecryptPacket(tmp, sched, iv, sizeof(the_quick), &packet);
837 if (strcmp(the_quick, clear) != 0)
838 fprintf(stderr, "rxkad_EncryptPacket/rxkad_DecryptPacket FAILED\n");
841 struct timeval start, stop;
844 fc_keysched(key1, sched);
845 gettimeofday(&start, 0);
846 for (i = 0; i < 1000000; i++)
847 fc_keysched(key1, sched);
848 gettimeofday(&stop, 0);
849 printf("fc_keysched = %2.2f us\n",
850 (stop.tv_sec - start.tv_sec +
851 (stop.tv_usec - start.tv_usec) / 1e6) * 1);
853 fc_ecb_encrypt(data, data, sched, ENCRYPT);
854 gettimeofday(&start, 0);
855 for (i = 0; i < 1000000; i++)
856 fc_ecb_encrypt(data, data, sched, ENCRYPT);
857 gettimeofday(&stop, 0);
858 printf("fc_ecb_encrypt = %2.2f us\n",
859 (stop.tv_sec - start.tv_sec +
860 (stop.tv_usec - start.tv_usec) / 1e6) * 1);
862 fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv,
864 gettimeofday(&start, 0);
865 for (i = 0; i < 100000; i++)
866 fc_cbc_encrypt(the_quick, ciph, sizeof(the_quick), sched, iv,
868 gettimeofday(&stop, 0);
869 printf("fc_cbc_encrypt = %2.2f us\n",
870 (stop.tv_sec - start.tv_sec +
871 (stop.tv_usec - start.tv_usec) / 1e6) * 10);