c4f2d992 |
1 | /* -*-c-*- |
2 | * |
3c45ef4a |
3 | * $Id: blowfish.c,v 1.5 1998/01/12 16:43:48 mdw Exp $ |
c4f2d992 |
4 | * |
5 | * Blowfish encryption routines |
6 | * |
3c45ef4a |
7 | * (c) 1998 Mark Wooding |
c4f2d992 |
8 | */ |
40fb5440 |
9 | |
c4f2d992 |
10 | /*----- Licencing notice --------------------------------------------------* |
11 | * |
12 | * This file is part of `become' |
13 | * |
14 | * `Become' is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License as published by |
16 | * the Free Software Foundation; either version 2 of the License, or |
17 | * (at your option) any later version. |
18 | * |
19 | * `Become' is distributed in the hope that it will be useful, |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22 | * GNU General Public License for more details. |
23 | * |
24 | * You should have received a copy of the GNU General Public License |
a37d956f |
25 | * along with `become'; if not, write to the Free Software Foundation, |
26 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
c4f2d992 |
27 | */ |
40fb5440 |
28 | |
c4f2d992 |
29 | /*----- Revision history --------------------------------------------------* |
30 | * |
31 | * $Log: blowfish.c,v $ |
3c45ef4a |
32 | * Revision 1.5 1998/01/12 16:43:48 mdw |
33 | * Include required header files. Fix copyright date. |
34 | * |
40fb5440 |
35 | * Revision 1.4 1997/12/08 15:29:50 mdw |
36 | * Formatting fixes. Very boring. |
37 | * |
a37d956f |
38 | * Revision 1.3 1997/08/07 09:42:58 mdw |
39 | * Fix address of the FSF. |
40 | * |
03f996bd |
41 | * Revision 1.2 1997/08/04 10:24:20 mdw |
42 | * Sources placed under CVS control. |
43 | * |
44 | * Revision 1.1 1997/07/21 13:47:53 mdw |
c4f2d992 |
45 | * Initial revision |
46 | * |
47 | */ |
48 | |
49 | /*----- Header files ------------------------------------------------------*/ |
50 | |
51 | /* --- ANSI headers --- */ |
52 | |
53 | #include <stdio.h> |
3c45ef4a |
54 | #include <stdlib.h> |
55 | #include <string.h> |
c4f2d992 |
56 | |
57 | /* --- Local headers --- */ |
58 | |
59 | #include "config.h" |
60 | #include "blowfish.h" |
61 | #include "utils.h" |
62 | |
63 | /*----- Define the initial S-box values -----------------------------------*/ |
64 | |
65 | #include "blowfish-sbox.h" |
66 | |
67 | /*----- Useful macros -----------------------------------------------------*/ |
68 | |
69 | /* --- The Blowfish round function --- * |
70 | * |
71 | * This is why I like this cipher. The round function is microscopic. And |
72 | * very fast. |
73 | */ |
74 | |
75 | #define ROUND(L, R, K) \ |
76 | ((L) ^= k->p[K], \ |
77 | (R) ^= ((((k->s0[((L) >> 24) & 0xFF]) + \ |
78 | k->s1[((L) >> 16) & 0xFF]) ^ \ |
79 | k->s2[((L) >> 8) & 0xFF]) + \ |
80 | k->s3[((L) >> 0) & 0xFF])) |
81 | |
82 | /*----- Main code ---------------------------------------------------------*/ |
83 | |
84 | /* --- @blowfish_encrypt@ --- * |
85 | * |
86 | * Arguments: @const blowfish_key *k@ = pointer to key block |
87 | * @const void *from@ = block to encrypt from |
88 | * @void *to@ = block to encrypt to |
89 | * |
90 | * Returns: --- |
91 | * |
92 | * Use: Encrypts a block using the Blowfish algorithm. |
93 | */ |
94 | |
95 | void blowfish_encrypt(const blowfish_key *k, const void *from, void *to) |
96 | { |
97 | uint_32 l, r; |
98 | const unsigned char *f = from; |
99 | unsigned char *t = to; |
100 | |
101 | /* --- Extract left and right block halves --- */ |
102 | |
103 | l = load32(f + 0); |
104 | r = load32(f + 4); |
105 | |
106 | /* --- Now run the round function on these values --- */ |
107 | |
108 | ROUND(l, r, 0); |
109 | ROUND(r, l, 1); |
110 | ROUND(l, r, 2); |
111 | ROUND(r, l, 3); |
112 | ROUND(l, r, 4); |
113 | ROUND(r, l, 5); |
114 | ROUND(l, r, 6); |
115 | ROUND(r, l, 7); |
116 | ROUND(l, r, 8); |
117 | ROUND(r, l, 9); |
118 | ROUND(l, r, 10); |
119 | ROUND(r, l, 11); |
120 | ROUND(l, r, 12); |
121 | ROUND(r, l, 13); |
122 | ROUND(l, r, 14); |
123 | ROUND(r, l, 15); |
124 | |
125 | /* --- Final transformation --- */ |
126 | |
127 | l ^= k->p[16]; |
128 | r ^= k->p[17]; |
129 | |
130 | /* --- Store the encrypted value --- */ |
131 | |
132 | store32(t + 0, r); |
133 | store32(t + 4, l); |
134 | } |
135 | |
136 | /* --- @blowfish_decrypt@ --- * |
137 | * |
138 | * Arguments: @const blowfish_key *k@ = pointer to key block |
139 | * @const void *from@ = block to decrypt from |
140 | * @void *to@ = block to decrypt to |
141 | * |
142 | * Returns: --- |
143 | * |
144 | * Use: Decrypts a block using the Blowfish algorithm. |
145 | */ |
146 | |
147 | void blowfish_decrypt(const blowfish_key *k, const void *from, void *to) |
148 | { |
149 | uint_32 l, r; |
150 | const unsigned char *f = from; |
151 | unsigned char *t = to; |
152 | |
153 | /* --- Extract left and right block halves --- */ |
154 | |
155 | l = load32(f + 0); |
156 | r = load32(f + 4); |
157 | |
158 | /* --- Now run the round function on these values --- */ |
159 | |
160 | ROUND(l, r, 17); |
161 | ROUND(r, l, 16); |
162 | ROUND(l, r, 15); |
163 | ROUND(r, l, 14); |
164 | ROUND(l, r, 13); |
165 | ROUND(r, l, 12); |
166 | ROUND(l, r, 11); |
167 | ROUND(r, l, 10); |
168 | ROUND(l, r, 9); |
169 | ROUND(r, l, 8); |
170 | ROUND(l, r, 7); |
171 | ROUND(r, l, 6); |
172 | ROUND(l, r, 5); |
173 | ROUND(r, l, 4); |
174 | ROUND(l, r, 3); |
175 | ROUND(r, l, 2); |
176 | |
177 | /* --- Final transformation --- */ |
178 | |
179 | l ^= k->p[1]; |
180 | r ^= k->p[0]; |
181 | |
182 | /* --- Store the decrypted value --- */ |
183 | |
184 | store32(t + 0, r); |
185 | store32(t + 4, l); |
186 | } |
187 | |
188 | /* --- @blowfish__qcrypt@ --- * |
189 | * |
190 | * Arguments: @const blowfish_key *k@ = pointer to a key block |
191 | * @uint_32 *p@ = pointer to block to mangle |
192 | * |
193 | * Returns: --- |
194 | * |
195 | * Use: Mangles a block using the Blowfish algorithm. |
196 | */ |
197 | |
198 | static void blowfish__qcrypt(blowfish_key *k, uint_32 *p) |
199 | { |
200 | uint_32 l = p[0], r = p[1]; |
201 | |
202 | /* --- Run the round function --- */ |
203 | |
204 | ROUND(l, r, 0); |
205 | ROUND(r, l, 1); |
206 | ROUND(l, r, 2); |
207 | ROUND(r, l, 3); |
208 | ROUND(l, r, 4); |
209 | ROUND(r, l, 5); |
210 | ROUND(l, r, 6); |
211 | ROUND(r, l, 7); |
212 | ROUND(l, r, 8); |
213 | ROUND(r, l, 9); |
214 | ROUND(l, r, 10); |
215 | ROUND(r, l, 11); |
216 | ROUND(l, r, 12); |
217 | ROUND(r, l, 13); |
218 | ROUND(l, r, 14); |
219 | ROUND(r, l, 15); |
220 | |
221 | /* --- Output transformation --- */ |
222 | |
223 | l ^= k->p[16]; |
224 | r ^= k->p[17]; |
225 | |
226 | /* --- Store the new values --- */ |
227 | |
228 | p[0] = r; |
229 | p[1] = l; |
230 | } |
231 | |
232 | /* --- @blowfish__buildKey@ --- * |
233 | * |
234 | * Arguments: @blowfish_key *k@ = pointer to a key block to set up |
235 | * |
236 | * Returns: --- |
237 | * |
238 | * Use: Sets up the P-array and S-boxes once a key has been mixed |
239 | * into the P-array. Use a local copy of the Blowfish |
240 | * encryption routine, to avoid penalising the main code too |
241 | * much with having to veneer onto a general args-in-words |
242 | * function, and to avoid me messing about with transforming |
243 | * values backwards and forwards between char arrays and |
244 | * integers. |
245 | */ |
246 | |
247 | static void blowfish__buildKey(blowfish_key *k) |
248 | { |
249 | uint_32 b[2] = { 0, 0 }; |
250 | int i; |
251 | |
252 | /* --- First, run through the P-array --- */ |
253 | |
254 | for (i = 0; i < 18; i += 2) { |
255 | blowfish__qcrypt(k, b); |
256 | k->p[i] = b[0]; |
257 | k->p[i + 1] = b[1]; |
258 | } |
259 | |
260 | /* --- Now do the S-boxes --- */ |
261 | |
262 | for (i = 0; i < 256; i += 2) { |
263 | blowfish__qcrypt(k, b); |
264 | k->s0[i] = b[0]; |
265 | k->s0[i + 1] = b[1]; |
266 | } |
267 | |
268 | for (i = 0; i < 256; i += 2) { |
269 | blowfish__qcrypt(k, b); |
270 | k->s1[i] = b[0]; |
271 | k->s1[i + 1] = b[1]; |
272 | } |
273 | |
274 | for (i = 0; i < 256; i += 2) { |
275 | blowfish__qcrypt(k, b); |
276 | k->s2[i] = b[0]; |
277 | k->s2[i + 1] = b[1]; |
278 | } |
279 | |
280 | for (i = 0; i < 256; i += 2) { |
281 | blowfish__qcrypt(k, b); |
282 | k->s3[i] = b[0]; |
283 | k->s3[i + 1] = b[1]; |
284 | } |
285 | } |
286 | |
287 | /* --- @blowfish_setKey@ --- * |
288 | * |
289 | * Arguments: @blowfish_key *kb@ = pointer to key block to fill |
290 | * @void *k@ = pointer to key data |
291 | * @size_t sz@ = length of data in bytes |
292 | * |
293 | * Returns: --- |
294 | * |
295 | * Use: Expands a key which isn't represented as a number of whole |
296 | * words. This is a nonstandard extension, although it can be |
297 | * used to support 40-bit keys, which some governments might |
298 | * find more palatable than 160-bit (or 448-bit!) keys. |
299 | */ |
300 | |
301 | void blowfish_setKey(blowfish_key *kb, const void *k, size_t sz) |
302 | { |
303 | int i, j, l; |
304 | const unsigned char *p = k; |
305 | uint_32 a; |
306 | |
307 | memcpy(kb, &blowfish__init, sizeof(blowfish__init)); |
308 | |
309 | j = 0; |
310 | for (i = 0; i < 18; i++) { |
311 | a = 0; |
312 | for (l = 0; l < 4; l++) { |
313 | a = (a << 8) | p[j]; |
314 | j++; |
315 | if (j >= sz) |
316 | j = 0; |
317 | } |
318 | kb->p[i] ^= a; |
319 | } |
320 | |
321 | blowfish__buildKey(kb); |
322 | } |
323 | |
324 | /*----- Test rig ----------------------------------------------------------*/ |
325 | |
326 | #ifdef TEST_RIG |
327 | |
328 | int main(void) |
329 | { |
330 | /* --- Stage one: ECB tests --- */ |
331 | |
332 | { |
333 | static struct { |
334 | uint_32 k[2]; |
335 | uint_32 p[2]; |
336 | uint_32 c[2]; |
337 | } table[] = { |
338 | { { 0x00000000u, 0x00000000u }, |
339 | { 0x00000000u, 0x00000000u }, |
340 | { 0x4EF99745u, 0x6198DD78u } }, |
341 | |
342 | { { 0xFFFFFFFFu, 0xFFFFFFFFu }, |
343 | { 0xFFFFFFFFu, 0xFFFFFFFFu }, |
344 | { 0x51866FD5u, 0xB85ECB8Au } }, |
345 | |
346 | { { 0x30000000u, 0x00000000u }, |
347 | { 0x10000000u, 0x00000001u }, |
348 | { 0x7D856F9Au, 0x613063F2u } }, |
349 | |
350 | { { 0x11111111u, 0x11111111u }, |
351 | { 0x11111111u, 0x11111111u }, |
352 | { 0x2466DD87u, 0x8B963C9Du } }, |
353 | |
354 | { { 0x01234567u, 0x89ABCDEFu }, |
355 | { 0x11111111u, 0x11111111u }, |
356 | { 0x61F9C380u, 0x2281B096u } }, |
357 | |
358 | { { 0x11111111u, 0x11111111u }, |
359 | { 0x01234567u, 0x89ABCDEFu }, |
360 | { 0x7D0CC630u, 0xAFDA1EC7u } }, |
361 | |
362 | { { 0x00000000u, 0x00000000u }, |
363 | { 0x00000000u, 0x00000000u }, |
364 | { 0x4EF99745u, 0x6198DD78u } }, |
365 | |
366 | { { 0xFEDCBA98u, 0x76543210u }, |
367 | { 0x01234567u, 0x89ABCDEFu }, |
368 | { 0x0ACEAB0Fu, 0xC6A0A28Du } }, |
369 | |
370 | { { 0x7CA11045u, 0x4A1A6E57u }, |
371 | { 0x01A1D6D0u, 0x39776742u }, |
372 | { 0x59C68245u, 0xEB05282Bu } }, |
373 | |
374 | { { 0x0131D961u, 0x9DC1376Eu }, |
375 | { 0x5CD54CA8u, 0x3DEF57DAu }, |
376 | { 0xB1B8CC0Bu, 0x250F09A0u } }, |
377 | |
378 | { { 0x07A1133Eu, 0x4A0B2686u }, |
379 | { 0x0248D438u, 0x06F67172u }, |
380 | { 0x1730E577u, 0x8BEA1DA4u } }, |
381 | |
382 | { { 0x3849674Cu, 0x2602319Eu }, |
383 | { 0x51454B58u, 0x2DDF440Au }, |
384 | { 0xA25E7856u, 0xCF2651EBu } }, |
385 | |
386 | { { 0x04B915BAu, 0x43FEB5B6u }, |
387 | { 0x42FD4430u, 0x59577FA2u }, |
388 | { 0x353882B1u, 0x09CE8F1Au } }, |
389 | |
390 | { { 0x0113B970u, 0xFD34F2CEu }, |
391 | { 0x059B5E08u, 0x51CF143Au }, |
392 | { 0x48F4D088u, 0x4C379918u } }, |
393 | |
394 | { { 0x0170F175u, 0x468FB5E6u }, |
395 | { 0x0756D8E0u, 0x774761D2u }, |
396 | { 0x432193B7u, 0x8951FC98u } }, |
397 | |
398 | { { 0x43297FADu, 0x38E373FEu }, |
399 | { 0x762514B8u, 0x29BF486Au }, |
400 | { 0x13F04154u, 0xD69D1AE5u } }, |
401 | |
402 | { { 0x07A71370u, 0x45DA2A16u }, |
403 | { 0x3BDD1190u, 0x49372802u }, |
404 | { 0x2EEDDA93u, 0xFFD39C79u } }, |
405 | |
406 | { { 0x04689104u, 0xC2FD3B2Fu }, |
407 | { 0x26955F68u, 0x35AF609Au }, |
408 | { 0xD887E039u, 0x3C2DA6E3u } }, |
409 | |
410 | { { 0x37D06BB5u, 0x16CB7546u }, |
411 | { 0x164D5E40u, 0x4F275232u }, |
412 | { 0x5F99D04Fu, 0x5B163969u } }, |
413 | |
414 | { { 0x1F08260Du, 0x1AC2465Eu }, |
415 | { 0x6B056E18u, 0x759F5CCAu }, |
416 | { 0x4A057A3Bu, 0x24D3977Bu } }, |
417 | |
418 | { { 0x58402364u, 0x1ABA6176u }, |
419 | { 0x004BD6EFu, 0x09176062u }, |
420 | { 0x452031C1u, 0xE4FADA8Eu } }, |
421 | |
422 | { { 0x02581616u, 0x4629B007u }, |
423 | { 0x480D3900u, 0x6EE762F2u }, |
424 | { 0x7555AE39u, 0xF59B87BDu } }, |
425 | |
426 | { { 0x49793EBCu, 0x79B3258Fu }, |
427 | { 0x437540C8u, 0x698F3CFAu }, |
428 | { 0x53C55F9Cu, 0xB49FC019u } }, |
429 | |
430 | { { 0x4FB05E15u, 0x15AB73A7u }, |
431 | { 0x072D43A0u, 0x77075292u }, |
432 | { 0x7A8E7BFAu, 0x937E89A3u } }, |
433 | |
434 | { { 0x49E95D6Du, 0x4CA229BFu }, |
435 | { 0x02FE5577u, 0x8117F12Au }, |
436 | { 0xCF9C5D7Au, 0x4986ADB5u } }, |
437 | |
438 | { { 0x018310DCu, 0x409B26D6u }, |
439 | { 0x1D9D5C50u, 0x18F728C2u }, |
440 | { 0xD1ABB290u, 0x658BC778u } }, |
441 | |
442 | { { 0x1C587F1Cu, 0x13924FEFu }, |
443 | { 0x30553228u, 0x6D6F295Au }, |
444 | { 0x55CB3774u, 0xD13EF201u } }, |
445 | |
446 | { { 0x01010101u, 0x01010101u }, |
447 | { 0x01234567u, 0x89ABCDEFu }, |
448 | { 0xFA34EC48u, 0x47B268B2u } }, |
449 | |
450 | { { 0x1F1F1F1Fu, 0x0E0E0E0Eu }, |
451 | { 0x01234567u, 0x89ABCDEFu }, |
452 | { 0xA7907951u, 0x08EA3CAEu } }, |
453 | |
454 | { { 0xE0FEE0FEu, 0xF1FEF1FEu }, |
455 | { 0x01234567u, 0x89ABCDEFu }, |
456 | { 0xC39E072Du, 0x9FAC631Du } }, |
457 | |
458 | { { 0x00000000u, 0x00000000u }, |
459 | { 0xFFFFFFFFu, 0xFFFFFFFFu }, |
460 | { 0x014933E0u, 0xCDAFF6E4u } }, |
461 | |
462 | { { 0xFFFFFFFFu, 0xFFFFFFFFu }, |
463 | { 0x00000000u, 0x00000000u }, |
464 | { 0xF21E9A77u, 0xB71C49BCu } }, |
465 | |
466 | { { 0x01234567u, 0x89ABCDEFu }, |
467 | { 0x00000000u, 0x00000000u }, |
468 | { 0x24594688u, 0x5754369Au } }, |
469 | |
470 | { { 0xFEDCBA98u, 0x76543210u }, |
471 | { 0xFFFFFFFFu, 0xFFFFFFFFu }, |
472 | { 0x6B5C5A9Cu, 0x5D9E0A5Au } } |
473 | }; |
474 | |
475 | int f = 1; |
476 | int i; |
477 | |
478 | printf("*** stage one: "); |
479 | fflush(stdout); |
480 | |
481 | for (i = 0; i < sizeof(table) / sizeof(table[0]); i++) { |
482 | char kb[8], p[8], c[8]; |
483 | blowfish_key k; |
484 | |
485 | store32(kb + 0, table[i].k[0]); |
486 | store32(kb + 4, table[i].k[1]); |
487 | blowfish_setKey(&k, kb, 8); |
488 | |
489 | store32(p + 0, table[i].p[0]); |
490 | store32(p + 4, table[i].p[1]); |
491 | blowfish_encrypt(&k, p, c); |
492 | |
493 | if (load32(c + 0) != table[i].c[0] || |
494 | load32(c + 4) != table[i].c[1]) { |
495 | printf("\n" |
496 | "!!! bad encryption\n" |
497 | " key = %08lx-%08lx\n" |
498 | " plaintext = %08lx-%08lx\n" |
499 | " expected ciphertext = %08lx-%08lx\n" |
500 | " calculated ciphertext = %08lx-%08lx\n", |
501 | (unsigned long)table[i].k[0], |
502 | (unsigned long)table[i].k[1], |
503 | (unsigned long)table[i].p[0], |
504 | (unsigned long)table[i].p[1], |
505 | (unsigned long)table[i].c[0], |
506 | (unsigned long)table[i].c[1], |
507 | (unsigned long)load32(c + 0), |
508 | (unsigned long)load32(c + 4)); |
509 | f = 0; |
510 | } |
511 | |
512 | blowfish_decrypt(&k, c, p); |
513 | if (load32(p + 0) != table[i].p[0] || |
514 | load32(p + 4) != table[i].p[1]) { |
515 | printf("\n" |
516 | "!!! bad decryption\n" |
517 | " key = %08lx-%08lx\n" |
518 | " ciphertext = %08lx-%08lx\n" |
519 | " expected plaintext = %08lx-%08lx\n" |
520 | " calculated plaintext = %08lx-%08lx\n", |
521 | (unsigned long)table[i].k[0], |
522 | (unsigned long)table[i].k[1], |
523 | (unsigned long)table[i].c[0], |
524 | (unsigned long)table[i].c[1], |
525 | (unsigned long)table[i].p[0], |
526 | (unsigned long)table[i].p[1], |
527 | (unsigned long)load32(p + 0), |
528 | (unsigned long)load32(p + 4)); |
529 | f = 0; |
530 | } |
531 | |
532 | putchar('.'); |
533 | fflush(stdout); |
534 | } |
535 | putchar('\n'); |
536 | if (f) |
537 | printf("*** stage one ok\n"); |
538 | } |
539 | |
540 | /* --- Stage 2: key scheduling --- */ |
541 | |
542 | { |
543 | static struct { |
544 | uint_32 c[2]; |
545 | } table[] = { |
546 | {{ 0xF9AD597Cu, 0x49DB005Eu }}, |
547 | {{ 0xE91D21C1u, 0xD961A6D6u }}, |
548 | {{ 0xE9C2B70Au, 0x1BC65CF3u }}, |
549 | {{ 0xBE1E6394u, 0x08640F05u }}, |
550 | {{ 0xB39E4448u, 0x1BDB1E6Eu }}, |
551 | {{ 0x9457AA83u, 0xB1928C0Du }}, |
552 | {{ 0x8BB77032u, 0xF960629Du }}, |
553 | {{ 0xE87A244Eu, 0x2CC85E82u }}, |
554 | {{ 0x15750E7Au, 0x4F4EC577u }}, |
555 | {{ 0x122BA70Bu, 0x3AB64AE0u }}, |
556 | {{ 0x3A833C9Au, 0xFFC537F6u }}, |
557 | {{ 0x9409DA87u, 0xA90F6BF2u }}, |
558 | {{ 0x884F8062u, 0x5060B8B4u }}, |
559 | {{ 0x1F85031Cu, 0x19E11968u }}, |
560 | {{ 0x79D9373Au, 0x714CA34Fu }}, |
561 | {{ 0x93142887u, 0xEE3BE15Cu }}, |
562 | {{ 0x03429E83u, 0x8CE2D14Bu }}, |
563 | {{ 0xA4299E27u, 0x469FF67Bu }}, |
564 | {{ 0xAFD5AED1u, 0xC1BC96A8u }}, |
565 | {{ 0x10851C0Eu, 0x3858DA9Fu }}, |
566 | {{ 0xE6F51ED7u, 0x9B9DB21Fu }}, |
567 | {{ 0x64A6E14Au, 0xFD36B46Fu }}, |
568 | {{ 0x80C7D7D4u, 0x5A5479ADu }}, |
569 | {{ 0x05044B62u, 0xFA52D080u }}, |
570 | }; |
571 | |
572 | unsigned char kk[] = { |
573 | 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, |
574 | 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F, |
575 | 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 |
576 | }; |
577 | |
578 | int i; |
579 | int f = 1; |
580 | |
581 | printf("*** stage two: "); |
582 | fflush(stdout); |
583 | |
584 | for (i = 0; i < sizeof(kk); i++) { |
585 | blowfish_key k; |
586 | unsigned char p[8] = { 0xFE, 0xDC, 0xBA, 0x98, |
587 | 0x76, 0x54, 0x32, 0x10 }; |
588 | |
589 | blowfish_setKey(&k, kk, i + 1); |
590 | blowfish_encrypt(&k, p, p); |
591 | |
592 | if (load32(p + 0) != table[i].c[0] || |
593 | load32(p + 4) != table[i].c[1]) { |
594 | printf("!!! bad encryption\n" |
595 | " key length = %i\n" |
596 | " expected = %08lx-%08lx\n" |
597 | " calculated = %08lx-%08lx\n", |
598 | i + 1, |
599 | (unsigned long)table[i].c[0], |
600 | (unsigned long)table[i].c[1], |
601 | (unsigned long)load32(p + 0), |
602 | (unsigned long)load32(p + 4)); |
603 | f = 0; |
604 | } |
605 | |
606 | putchar('.'); |
607 | fflush(stdout); |
608 | } |
609 | |
610 | putchar('\n'); |
611 | |
612 | if (f) |
613 | printf("*** stage two ok\n"); |
614 | } |
615 | |
616 | return (0); |
617 | |
618 | } |
619 | |
620 | #endif |
621 | |
622 | /*----- That's all, folks -------------------------------------------------*/ |