Resync with broadcom drivers 5.100.138.20 and utilities.
[tomato.git] / release / src-rt / bcmcrypto / des.c
blobf59233b4c81b207e8407cfd448d9cd0b61c300e7
1 /*
2 * DES functions
3 * Copied from des-ka9q-1.0-portable, a public domain DES implementation,
4 * and diddled with only enough to compile without warnings and link
5 * with our driver.
7 * Copyright (C) 2010, Broadcom Corporation
8 * All Rights Reserved.
9 *
10 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
11 * the contents of this file may not be disclosed to third parties, copied
12 * or duplicated in any form, in whole or in part, without the prior
13 * written permission of Broadcom Corporation.
15 * $Id: des.c,v 1.12 2009-10-21 23:12:36 Exp $
18 /* Portable C code to create DES key schedules from user-provided keys
19 * This doesn't have to be fast unless you're cracking keys or UNIX
20 * passwords
23 #include <typedefs.h>
24 #ifdef BCMDRIVER
25 #include <osl.h>
26 #else
27 #include <stddef.h> /* for size_t */
28 #if defined(__GNUC__)
29 #include <strings.h>
30 #else
31 #include <memory.h>
32 #define bcopy(src, dst, len) memcpy((dst), (src), (len))
33 #define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
34 #define bzero(b, len) memset((b), 0, (len))
35 #endif /* __GNUC__ */
36 #endif /* BCMDRIVER */
37 #include <bcmcrypto/des.h>
39 const unsigned long BCMROMDATA(Spbox)[8][64] = {
41 0x01010400, 0x00000000, 0x00010000, 0x01010404,
42 0x01010004, 0x00010404, 0x00000004, 0x00010000,
43 0x00000400, 0x01010400, 0x01010404, 0x00000400,
44 0x01000404, 0x01010004, 0x01000000, 0x00000004,
45 0x00000404, 0x01000400, 0x01000400, 0x00010400,
46 0x00010400, 0x01010000, 0x01010000, 0x01000404,
47 0x00010004, 0x01000004, 0x01000004, 0x00010004,
48 0x00000000, 0x00000404, 0x00010404, 0x01000000,
49 0x00010000, 0x01010404, 0x00000004, 0x01010000,
50 0x01010400, 0x01000000, 0x01000000, 0x00000400,
51 0x01010004, 0x00010000, 0x00010400, 0x01000004,
52 0x00000400, 0x00000004, 0x01000404, 0x00010404,
53 0x01010404, 0x00010004, 0x01010000, 0x01000404,
54 0x01000004, 0x00000404, 0x00010404, 0x01010400,
55 0x00000404, 0x01000400, 0x01000400, 0x00000000,
56 0x00010004, 0x00010400, 0x00000000, 0x01010004
59 0x80108020, 0x80008000, 0x00008000, 0x00108020,
60 0x00100000, 0x00000020, 0x80100020, 0x80008020,
61 0x80000020, 0x80108020, 0x80108000, 0x80000000,
62 0x80008000, 0x00100000, 0x00000020, 0x80100020,
63 0x00108000, 0x00100020, 0x80008020, 0x00000000,
64 0x80000000, 0x00008000, 0x00108020, 0x80100000,
65 0x00100020, 0x80000020, 0x00000000, 0x00108000,
66 0x00008020, 0x80108000, 0x80100000, 0x00008020,
67 0x00000000, 0x00108020, 0x80100020, 0x00100000,
68 0x80008020, 0x80100000, 0x80108000, 0x00008000,
69 0x80100000, 0x80008000, 0x00000020, 0x80108020,
70 0x00108020, 0x00000020, 0x00008000, 0x80000000,
71 0x00008020, 0x80108000, 0x00100000, 0x80000020,
72 0x00100020, 0x80008020, 0x80000020, 0x00100020,
73 0x00108000, 0x00000000, 0x80008000, 0x00008020,
74 0x80000000, 0x80100020, 0x80108020, 0x00108000
77 0x00000208, 0x08020200, 0x00000000, 0x08020008,
78 0x08000200, 0x00000000, 0x00020208, 0x08000200,
79 0x00020008, 0x08000008, 0x08000008, 0x00020000,
80 0x08020208, 0x00020008, 0x08020000, 0x00000208,
81 0x08000000, 0x00000008, 0x08020200, 0x00000200,
82 0x00020200, 0x08020000, 0x08020008, 0x00020208,
83 0x08000208, 0x00020200, 0x00020000, 0x08000208,
84 0x00000008, 0x08020208, 0x00000200, 0x08000000,
85 0x08020200, 0x08000000, 0x00020008, 0x00000208,
86 0x00020000, 0x08020200, 0x08000200, 0x00000000,
87 0x00000200, 0x00020008, 0x08020208, 0x08000200,
88 0x08000008, 0x00000200, 0x00000000, 0x08020008,
89 0x08000208, 0x00020000, 0x08000000, 0x08020208,
90 0x00000008, 0x00020208, 0x00020200, 0x08000008,
91 0x08020000, 0x08000208, 0x00000208, 0x08020000,
92 0x00020208, 0x00000008, 0x08020008, 0x00020200
95 0x00802001, 0x00002081, 0x00002081, 0x00000080,
96 0x00802080, 0x00800081, 0x00800001, 0x00002001,
97 0x00000000, 0x00802000, 0x00802000, 0x00802081,
98 0x00000081, 0x00000000, 0x00800080, 0x00800001,
99 0x00000001, 0x00002000, 0x00800000, 0x00802001,
100 0x00000080, 0x00800000, 0x00002001, 0x00002080,
101 0x00800081, 0x00000001, 0x00002080, 0x00800080,
102 0x00002000, 0x00802080, 0x00802081, 0x00000081,
103 0x00800080, 0x00800001, 0x00802000, 0x00802081,
104 0x00000081, 0x00000000, 0x00000000, 0x00802000,
105 0x00002080, 0x00800080, 0x00800081, 0x00000001,
106 0x00802001, 0x00002081, 0x00002081, 0x00000080,
107 0x00802081, 0x00000081, 0x00000001, 0x00002000,
108 0x00800001, 0x00002001, 0x00802080, 0x00800081,
109 0x00002001, 0x00002080, 0x00800000, 0x00802001,
110 0x00000080, 0x00800000, 0x00002000, 0x00802080
113 0x00000100, 0x02080100, 0x02080000, 0x42000100,
114 0x00080000, 0x00000100, 0x40000000, 0x02080000,
115 0x40080100, 0x00080000, 0x02000100, 0x40080100,
116 0x42000100, 0x42080000, 0x00080100, 0x40000000,
117 0x02000000, 0x40080000, 0x40080000, 0x00000000,
118 0x40000100, 0x42080100, 0x42080100, 0x02000100,
119 0x42080000, 0x40000100, 0x00000000, 0x42000000,
120 0x02080100, 0x02000000, 0x42000000, 0x00080100,
121 0x00080000, 0x42000100, 0x00000100, 0x02000000,
122 0x40000000, 0x02080000, 0x42000100, 0x40080100,
123 0x02000100, 0x40000000, 0x42080000, 0x02080100,
124 0x40080100, 0x00000100, 0x02000000, 0x42080000,
125 0x42080100, 0x00080100, 0x42000000, 0x42080100,
126 0x02080000, 0x00000000, 0x40080000, 0x42000000,
127 0x00080100, 0x02000100, 0x40000100, 0x00080000,
128 0x00000000, 0x40080000, 0x02080100, 0x40000100
131 0x20000010, 0x20400000, 0x00004000, 0x20404010,
132 0x20400000, 0x00000010, 0x20404010, 0x00400000,
133 0x20004000, 0x00404010, 0x00400000, 0x20000010,
134 0x00400010, 0x20004000, 0x20000000, 0x00004010,
135 0x00000000, 0x00400010, 0x20004010, 0x00004000,
136 0x00404000, 0x20004010, 0x00000010, 0x20400010,
137 0x20400010, 0x00000000, 0x00404010, 0x20404000,
138 0x00004010, 0x00404000, 0x20404000, 0x20000000,
139 0x20004000, 0x00000010, 0x20400010, 0x00404000,
140 0x20404010, 0x00400000, 0x00004010, 0x20000010,
141 0x00400000, 0x20004000, 0x20000000, 0x00004010,
142 0x20000010, 0x20404010, 0x00404000, 0x20400000,
143 0x00404010, 0x20404000, 0x00000000, 0x20400010,
144 0x00000010, 0x00004000, 0x20400000, 0x00404010,
145 0x00004000, 0x00400010, 0x20004010, 0x00000000,
146 0x20404000, 0x20000000, 0x00400010, 0x20004010
149 0x00200000, 0x04200002, 0x04000802, 0x00000000,
150 0x00000800, 0x04000802, 0x00200802, 0x04200800,
151 0x04200802, 0x00200000, 0x00000000, 0x04000002,
152 0x00000002, 0x04000000, 0x04200002, 0x00000802,
153 0x04000800, 0x00200802, 0x00200002, 0x04000800,
154 0x04000002, 0x04200000, 0x04200800, 0x00200002,
155 0x04200000, 0x00000800, 0x00000802, 0x04200802,
156 0x00200800, 0x00000002, 0x04000000, 0x00200800,
157 0x04000000, 0x00200800, 0x00200000, 0x04000802,
158 0x04000802, 0x04200002, 0x04200002, 0x00000002,
159 0x00200002, 0x04000000, 0x04000800, 0x00200000,
160 0x04200800, 0x00000802, 0x00200802, 0x04200800,
161 0x00000802, 0x04000002, 0x04200802, 0x04200000,
162 0x00200800, 0x00000000, 0x00000002, 0x04200802,
163 0x00000000, 0x00200802, 0x04200000, 0x00000800,
164 0x04000002, 0x04000800, 0x00000800, 0x00200002
167 0x10001040, 0x00001000, 0x00040000, 0x10041040,
168 0x10000000, 0x10001040, 0x00000040, 0x10000000,
169 0x00040040, 0x10040000, 0x10041040, 0x00041000,
170 0x10041000, 0x00041040, 0x00001000, 0x00000040,
171 0x10040000, 0x10000040, 0x10001000, 0x00001040,
172 0x00041000, 0x00040040, 0x10040040, 0x10041000,
173 0x00001040, 0x00000000, 0x00000000, 0x10040040,
174 0x10000040, 0x10001000, 0x00041040, 0x00040000,
175 0x00041040, 0x00040000, 0x10041000, 0x00001000,
176 0x00000040, 0x10040040, 0x00001000, 0x00041040,
177 0x10001000, 0x00000040, 0x10000040, 0x10040000,
178 0x10040040, 0x10000000, 0x00040000, 0x10001040,
179 0x00000000, 0x10041040, 0x00040040, 0x10000040,
180 0x10040000, 0x10001000, 0x10001040, 0x00000000,
181 0x10041040, 0x00041000, 0x00041000, 0x00001040,
182 0x00001040, 0x00040040, 0x10000000, 0x10041000
187 /* Key schedule-related tables from FIPS-46 */
189 /* permuted choice table (key) */
190 static const unsigned char pc1[] = {
191 57, 49, 41, 33, 25, 17, 9,
192 01, 58, 50, 42, 34, 26, 18,
193 10, 2, 59, 51, 43, 35, 27,
194 19, 11, 3, 60, 52, 44, 36,
196 63, 55, 47, 39, 31, 23, 15,
197 07, 62, 54, 46, 38, 30, 22,
198 14, 6, 61, 53, 45, 37, 29,
199 21, 13, 5, 28, 20, 12, 4
202 /* number left rotations of pc1 */
203 static const unsigned char totrot[] = {
204 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
207 /* permuted choice key (table) */
208 static const unsigned char pc2[] = {
209 14, 17, 11, 24, 1, 5,
210 03, 28, 15, 6, 21, 10,
211 23, 19, 12, 4, 26, 8,
212 16, 7, 27, 20, 13, 2,
213 41, 52, 31, 37, 47, 55,
214 30, 40, 51, 45, 33, 48,
215 44, 49, 39, 56, 34, 53,
216 46, 42, 50, 36, 29, 32
219 /* End of DES-defined tables */
222 /* int Asmversion = 0; */
223 #define Asmversion 0
225 /* bit 0 is left-most in byte */
226 static const int bytebit[] = {
227 0200, 0100, 040, 020, 010, 04, 02, 01
231 /* Generate key schedule for encryption or decryption
232 * depending on the value of "decrypt"
234 void
235 BCMROMFN(deskey)(DES_KS k, /* Key schedule array */
236 unsigned char *key, /* 64 bits (will use only 56) */
237 int decrypt) /* 0 = encrypt, 1 = decrypt */
239 unsigned char pc1m[56]; /* place to modify pc1 into */
240 unsigned char pcr[56]; /* place to rotate pc1 into */
241 register int i, j, l;
242 int m;
243 unsigned char ks[8];
245 for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */
246 l = pc1[j] - 1; /* integer bit location */
247 m = l & 07; /* find bit */
248 pc1m[j] = (key[l >> 3] & /* find which key byte l is in */
249 bytebit[m]) /* and which bit of that byte */
250 ? 1 : 0; /* and store 1-bit result */
252 for (i = 0; i < 16; i++) { /* key chunk for each iteration */
253 bzero(ks, sizeof(ks)); /* Clear key schedule */
254 for (j = 0; j < 56; j++) /* rotate pc1 the right amount */
255 pcr[j] = pc1m[(l = j + totrot[decrypt ? 15 - i : i]) <
256 (j < 28 ? 28 : 56) ? l : l - 28];
257 /* rotate left and right halves independently */
258 for (j = 0; j < 48; j++) { /* select bits individually */
259 /* check bit that goes to ks[j] */
260 if (pcr[pc2[j] - 1]) {
261 /* mask it in if it's there */
262 l = j % 6;
263 ks[j/6] |= bytebit[l] >> 2;
266 /* Now convert to packed odd/even interleaved form */
267 k[i][0] = (((long)ks[0] << 24) |
268 ((long)ks[2] << 16) |
269 ((long)ks[4] << 8) |
270 ((long)ks[6]));
271 k[i][1] = (((long)ks[1] << 24) |
272 ((long)ks[3] << 16) |
273 ((long)ks[5] << 8) |
274 ((long)ks[7]));
275 if (Asmversion) {
276 /* The assembler versions pre-shift each subkey 2 bits
277 * so the Spbox indexes are already computed
279 k[i][0] <<= 2;
280 k[i][1] <<= 2;
285 /* Portable C version of des() function */
287 /* Tables defined in the Data Encryption Standard documents
288 * Three of these tables, the initial permutation, the final
289 * permutation and the expansion operator, are regular enough that
290 * for speed, we hard-code them. They're here for reference only.
291 * Also, the S and P boxes are used by a separate program, gensp.c,
292 * to build the combined SP box, Spbox[]. They're also here just
293 * for reference.
295 #ifdef notdef
296 /* initial permutation IP */
297 static unsigned char ip[] = {
298 58, 50, 42, 34, 26, 18, 10, 2,
299 60, 52, 44, 36, 28, 20, 12, 4,
300 62, 54, 46, 38, 30, 22, 14, 6,
301 64, 56, 48, 40, 32, 24, 16, 8,
302 57, 49, 41, 33, 25, 17, 9, 1,
303 59, 51, 43, 35, 27, 19, 11, 3,
304 61, 53, 45, 37, 29, 21, 13, 5,
305 63, 55, 47, 39, 31, 23, 15, 7
308 /* final permutation IP^-1 */
309 static unsigned char fp[] = {
310 40, 8, 48, 16, 56, 24, 64, 32,
311 39, 7, 47, 15, 55, 23, 63, 31,
312 38, 6, 46, 14, 54, 22, 62, 30,
313 37, 5, 45, 13, 53, 21, 61, 29,
314 36, 4, 44, 12, 52, 20, 60, 28,
315 35, 3, 43, 11, 51, 19, 59, 27,
316 34, 2, 42, 10, 50, 18, 58, 26,
317 33, 1, 41, 9, 49, 17, 57, 25
319 /* expansion operation matrix */
320 static unsigned char ei[] = {
321 32, 1, 2, 3, 4, 5,
322 4, 5, 6, 7, 8, 9,
323 8, 9, 10, 11, 12, 13,
324 12, 13, 14, 15, 16, 17,
325 16, 17, 18, 19, 20, 21,
326 20, 21, 22, 23, 24, 25,
327 24, 25, 26, 27, 28, 29,
328 28, 29, 30, 31, 32, 1
330 /* The (in)famous S-boxes */
331 static unsigned char sbox[8][64] = {
332 /* S1 */
333 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
334 00, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
335 04, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
336 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
338 /* S2 */
339 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
340 03, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
341 00, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
342 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
344 /* S3 */
345 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
346 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
347 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
348 01, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
350 /* S4 */
351 07, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
352 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
353 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
354 03, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
356 /* S5 */
357 02, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
358 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
359 04, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
360 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
362 /* S6 */
363 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
364 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
365 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
366 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
368 /* S7 */
369 04, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
370 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
371 01, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
372 06, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
374 /* S8 */
375 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
376 01, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
377 07, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
378 02, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
381 /* 32-bit permutation function P used on the output of the S-boxes */
382 static unsigned char p32i[] = {
383 16, 7, 20, 21,
384 29, 12, 28, 17,
385 01, 15, 23, 26,
386 05, 18, 31, 10,
387 02, 8, 24, 14,
388 32, 27, 3, 9,
389 19, 13, 30, 6,
390 22, 11, 4, 25
392 #endif /* notdef */
394 /* Combined SP lookup table, linked in
395 * For best results, ensure that this is aligned on a 32-bit boundary;
396 * Borland C++ 3.1 doesn't guarantee this!
399 /* Primitive function F.
400 * Input is r, subkey array in keys, output is XORed into l.
401 * Each round consumes eight 6-bit subkeys, one for
402 * each of the 8 S-boxes, 2 longs for each round.
403 * Each long contains four 6-bit subkeys, each taking up a byte.
404 * The first long contains, from high to low end, the subkeys for
405 * S-boxes 1, 3, 5 & 7; the second contains the subkeys for S-boxes
406 * 2, 4, 6 & 8 (using the origin-1 S-box numbering in the standard,
407 * not the origin-0 numbering used elsewhere in this code)
408 * See comments elsewhere about the pre-rotated values of r and Spbox.
410 #define F(l, r, key) { \
411 work = ((r >> 4) | (r << 28)) ^ key[0]; \
412 l ^= Spbox[6][work & 0x3f]; \
413 l ^= Spbox[4][(work >> 8) & 0x3f]; \
414 l ^= Spbox[2][(work >> 16) & 0x3f]; \
415 l ^= Spbox[0][(work >> 24) & 0x3f]; \
416 work = r ^ key[1]; \
417 l ^= Spbox[7][work & 0x3f]; \
418 l ^= Spbox[5][(work >> 8) & 0x3f]; \
419 l ^= Spbox[3][(work >> 16) & 0x3f]; \
420 l ^= Spbox[1][(work >> 24) & 0x3f]; \
422 /* Encrypt or decrypt a block of data in ECB mode */
423 void
424 BCMROMFN(des)(unsigned long ks[16][2], /* Key schedule */
425 unsigned char block[8]) /* Data block */
427 unsigned long left, right, work;
428 #if defined(BCMROMBUILD)
429 int round;
430 #endif
432 /* Read input block and place in left/right in big-endian order */
433 left = (((unsigned long)block[0] << 24) |
434 ((unsigned long)block[1] << 16) |
435 ((unsigned long)block[2] << 8) |
436 (unsigned long)block[3]);
437 right = (((unsigned long)block[4] << 24) |
438 ((unsigned long)block[5] << 16) |
439 ((unsigned long)block[6] << 8) |
440 (unsigned long)block[7]);
442 /* Hoey's clever initial permutation algorithm, from Outerbridge
443 * (see Schneier p 478)
445 * The convention here is the same as Outerbridge: rotate each
446 * register left by 1 bit, i.e., so that "left" contains permuted
447 * input bits 2, 3, 4, ... 1 and "right" contains 33, 34, 35, ... 32
448 * (using origin-1 numbering as in the FIPS). This allows us to avoid
449 * one of the two rotates that would otherwise be required in each of
450 * the 16 rounds.
452 work = ((left >> 4) ^ right) & 0x0f0f0f0f;
453 right ^= work;
454 left ^= work << 4;
455 work = ((left >> 16) ^ right) & 0xffff;
456 right ^= work;
457 left ^= work << 16;
458 work = ((right >> 2) ^ left) & 0x33333333;
459 left ^= work;
460 right ^= (work << 2);
461 work = ((right >> 8) ^ left) & 0xff00ff;
462 left ^= work;
463 right ^= (work << 8);
464 right = (right << 1) | (right >> 31);
465 work = (left ^ right) & 0xaaaaaaaa;
466 left ^= work;
467 right ^= work;
468 left = (left << 1) | (left >> 31);
470 /* Now do the 16 rounds.
471 * Fully unrolling generates 4x larger ARM code for this function
473 #if defined(BCMROMBUILD)
474 for (round = 0; round < 16; round += 2) {
475 F(left, right, ks[round + 0]);
476 F(right, left, ks[round + 1]);
478 #else /* !BCMROMBUILD */
479 F(left, right, ks[0]);
480 F(right, left, ks[1]);
481 F(left, right, ks[2]);
482 F(right, left, ks[3]);
483 F(left, right, ks[4]);
484 F(right, left, ks[5]);
485 F(left, right, ks[6]);
486 F(right, left, ks[7]);
487 F(left, right, ks[8]);
488 F(right, left, ks[9]);
489 F(left, right, ks[10]);
490 F(right, left, ks[11]);
491 F(left, right, ks[12]);
492 F(right, left, ks[13]);
493 F(left, right, ks[14]);
494 F(right, left, ks[15]);
495 #endif /* !BCMROMBUILD */
497 /* Inverse permutation, also from Hoey via Outerbridge and Schneier */
498 right = (right << 31) | (right >> 1);
499 work = (left ^ right) & 0xaaaaaaaa;
500 left ^= work;
501 right ^= work;
502 left = (left >> 1) | (left << 31);
503 work = ((left >> 8) ^ right) & 0xff00ff;
504 right ^= work;
505 left ^= work << 8;
506 work = ((left >> 2) ^ right) & 0x33333333;
507 right ^= work;
508 left ^= work << 2;
509 work = ((right >> 16) ^ left) & 0xffff;
510 left ^= work;
511 right ^= work << 16;
512 work = ((right >> 4) ^ left) & 0x0f0f0f0f;
513 left ^= work;
514 right ^= work << 4;
516 /* Put the block back into the user's buffer with final swap */
517 block[0] = (unsigned char)(right >> 24);
518 block[1] = (unsigned char)(right >> 16);
519 block[2] = (unsigned char)(right >> 8);
520 block[3] = (unsigned char)right;
521 block[4] = (unsigned char)(left >> 24);
522 block[5] = (unsigned char)(left >> 16);
523 block[6] = (unsigned char)(left >> 8);
524 block[7] = (unsigned char)left;
527 #ifdef DES_TEST_STANDALONE
528 #include <stdio.h>
529 #include <unistd.h>
530 #include <time.h>
532 static unsigned long
533 randlong(void)
535 static unsigned long r = 0;
536 if (r == 0)
537 r = getpid() * time(0) * 153846157;
538 r = (r + 7180351) * 74449801;
539 return r;
542 static void
543 dumpit(int sample, unsigned long ks[16][2], unsigned char in[8], unsigned char out[8])
545 int i;
547 printf("unsigned long sample%d_ks[16][2] = {\n", sample);
548 for (i = 0; i < 16; i++)
549 printf("\t{ 0x%08lx, 0x%08lx },\n", ks[i][0], ks[i][1]);
550 printf("};\n\n");
551 printf("unsigned char sample%d_in[8] = {\n\t", sample);
552 for (i = 0; i < 8; i++)
553 printf("%s0x%02x,", i > 0 ? " " : "", in[i]);
554 printf("\n};\n\n");
555 printf("unsigned char sample%d_out[8] = {\n\t", sample);
556 for (i = 0; i < 8; i++)
557 printf("%s0x%02x,", i > 0 ? " " : "", out[i]);
558 printf("\n};\n\n");
561 void
562 gensample(int sample)
564 unsigned long ks[16][2];
565 unsigned char in[8], out[8];
566 int i, j;
568 for (i = 0; i < 16; i++)
569 for (j = 0; j < 2; j++)
570 ks[i][j] = randlong();
572 for (i = 0; i < 8; i++)
573 in[i] = out[i] = randlong() & 0xff;
575 des(ks, out);
577 dumpit(sample, ks, in, out);
581 checksample(unsigned long ks[16][2], unsigned char in[8], unsigned char expected_out[8])
583 des(ks, in);
584 return (bcmp(in, expected_out, 8) == 0);
587 unsigned long sample1_ks[16][2] = {
588 { 0xe75fea2c, 0xb035c443 },
589 { 0x7245bf92, 0xab5529d9 },
590 { 0xfde3ded8, 0x03f1b84f },
591 { 0x6af77dfe, 0xd6ef55a5 },
592 { 0x7b28b304, 0x5f83c7db },
593 { 0x1f9073ea, 0x8eecb4f1 },
594 { 0xcb1e96b0, 0x5705a2e7 },
595 { 0x1edfd156, 0xadbdf7bd },
596 { 0x2623b9dc, 0x2f6ef973 },
597 { 0x3882c642, 0x2611ce09 },
598 { 0x77c44c88, 0x9b557b7f },
599 { 0xbfa482ae, 0xfb94e7d5 },
600 { 0xbd7a7eb4, 0xafacd90b },
601 { 0xc5be369a, 0xf3b1f521 },
602 { 0xdd6e8060, 0x1086c217 },
603 { 0x4d571206, 0xfe51a5ed },
606 unsigned char sample1_in[8] = {
607 0x8c, 0xa3, 0xf2, 0x39, 0x38, 0xaf, 0x5e, 0x05,
610 unsigned char sample1_out[8] = {
611 0x0e, 0x38, 0x62, 0x0a, 0x72, 0x93, 0xc8, 0x25,
614 unsigned long sample2_ks[16][2] = {
615 { 0xf130845c, 0x97a6d7f3 },
616 { 0xfe0458c2, 0x7520b489 },
617 { 0xcb712708, 0x0165e9ff },
618 { 0xe7bb252e, 0xcb995e55 },
619 { 0xf5416934, 0x75dfd78b },
620 { 0xc803e91a, 0x1415fba1 },
621 { 0x37097ae0, 0x6d665097 },
622 { 0xf7a5d486, 0x26bf3c6d },
623 { 0xb89f8c0c, 0xbc290523 },
624 { 0x93361772, 0x0efbd0b9 },
625 { 0xc807ccb8, 0x2ef5a52f },
626 { 0x9dd7e1de, 0xe4306885 },
627 { 0x18346ce4, 0x5ff7e0bb },
628 { 0x1bfc63ca, 0x5a7fb3d1 },
629 { 0x77c59c90, 0xc37967c7 },
630 { 0x2622cd36, 0x0b8a629d },
633 unsigned char sample2_in[8] = {
634 0xbc, 0x53, 0x22, 0xe9, 0x68, 0x5f, 0x8e, 0xb5,
637 unsigned char sample2_out[8] = {
638 0x76, 0xb9, 0xdf, 0xb8, 0x2a, 0x5b, 0x50, 0x48,
642 main(int argc, char **argv)
645 if (!checksample(sample1_ks, sample1_in, sample1_out))
646 printf("sample1 bad\n");
647 else if (!checksample(sample2_ks, sample2_in, sample2_out))
648 printf("sample2 bad\n");
649 else
650 printf("pass\n");
652 return 0;
655 #endif /* DES_TEST_STANDALONE */