6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 /*
29 * Blowfish encryption/decryption and keyschedule code.
30 */
31
32 #include <sys/types.h>
33 #include <sys/systm.h>
34 #include <sys/ddi.h>
35 #include <sys/sysmacros.h>
36 #include <sys/strsun.h>
37 #include <sys/note.h>
38 #include <sys/byteorder.h>
39 #include <sys/crypto/spi.h>
40 #include <modes/modes.h>
41 #include <sys/crypto/common.h>
42 #include "blowfish_impl.h"
43
44 #ifdef _KERNEL
45
46 #define BLOWFISH_ASSERT(x) ASSERT(x)
47
48 #else /* !_KERNEL */
49
50 #include <strings.h>
51 #include <stdlib.h>
52 #define BLOWFISH_ASSERT(x)
53
54 #endif /* _KERNEL */
55
56 /* EXPORT DELETE START */
57
58 /*
59 * Blowfish initial P box and S boxes, derived from the hex digits of PI.
60 *
61 * NOTE: S boxes are placed into one large array.
62 */
63 static const uint32_t init_P[] = {
64 0x243f6a88U, 0x85a308d3U, 0x13198a2eU,
65 0x03707344U, 0xa4093822U, 0x299f31d0U,
66 0x082efa98U, 0xec4e6c89U, 0x452821e6U,
67 0x38d01377U, 0xbe5466cfU, 0x34e90c6cU,
68 0xc0ac29b7U, 0xc97c50ddU, 0x3f84d5b5U,
69 0xb5470917U, 0x9216d5d9U, 0x8979fb1bU
70 };
71
72 static const uint32_t init_S[] = {
73 /* S-Box 0. */
74 0xd1310ba6U, 0x98dfb5acU, 0x2ffd72dbU, 0xd01adfb7U,
75 0xb8e1afedU, 0x6a267e96U, 0xba7c9045U, 0xf12c7f99U,
373 */
374 /* ARGSUSED */
375 int
376 blowfish_encrypt_block(const void *cookie, const uint8_t *block,
377 uint8_t *out_block)
378 {
379 /* EXPORT DELETE START */
380 keysched_t *ksch = (keysched_t *)cookie;
381
382 uint32_t left, right, tmp;
383 uint32_t *P = ksch->ksch_P;
384 uint32_t *S = ksch->ksch_S;
385 #ifdef _BIG_ENDIAN
386 uint32_t *b32;
387
388 if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
389 /* LINTED: pointer alignment */
390 b32 = (uint32_t *)block;
391 left = b32[0];
392 right = b32[1];
393 } else {
394 #endif
395 /*
396 * Read input block and place in left/right in big-endian order.
397 */
398 left = ((uint32_t)block[0] << 24)
399 | ((uint32_t)block[1] << 16)
400 | ((uint32_t)block[2] << 8)
401 | (uint32_t)block[3];
402 right = ((uint32_t)block[4] << 24)
403 | ((uint32_t)block[5] << 16)
404 | ((uint32_t)block[6] << 8)
405 | (uint32_t)block[7];
406 #ifdef _BIG_ENDIAN
407 }
408 #endif
409
410 ROUND(left, right, 0);
411 ROUND(left, right, 1);
412 ROUND(left, right, 2);
413 ROUND(left, right, 3);
414 ROUND(left, right, 4);
415 ROUND(left, right, 5);
416 ROUND(left, right, 6);
417 ROUND(left, right, 7);
418 ROUND(left, right, 8);
419 ROUND(left, right, 9);
420 ROUND(left, right, 10);
421 ROUND(left, right, 11);
422 ROUND(left, right, 12);
423 ROUND(left, right, 13);
424 ROUND(left, right, 14);
425 ROUND(left, right, 15);
426
427 tmp = left;
428 left = right;
429 right = tmp;
430 right ^= P[16];
431 left ^= P[17];
432
433 #ifdef _BIG_ENDIAN
434 if (IS_P2ALIGNED(out_block, sizeof (uint32_t))) {
435 /* LINTED: pointer alignment */
436 b32 = (uint32_t *)out_block;
437 b32[0] = left;
438 b32[1] = right;
439 } else {
440 #endif
441 /* Put the block back into the user's block with final swap */
442 out_block[0] = left >> 24;
443 out_block[1] = left >> 16;
444 out_block[2] = left >> 8;
445 out_block[3] = left;
446 out_block[4] = right >> 24;
447 out_block[5] = right >> 16;
448 out_block[6] = right >> 8;
449 out_block[7] = right;
450 #ifdef _BIG_ENDIAN
451 }
452 #endif
453 /* EXPORT DELETE END */
454 return (CRYPTO_SUCCESS);
455 }
456
457 /*
458 * Decrypt a block of data. Because of addition operations, convert blocks
459 * to their big-endian representation, even on Intel boxen.
460 * It should look like the blowfish_encrypt_block() operation
461 * except for the order in which the S/P boxes are accessed.
462 */
463 /* ARGSUSED */
464 int
465 blowfish_decrypt_block(const void *cookie, const uint8_t *block,
466 uint8_t *out_block)
467 {
468 /* EXPORT DELETE START */
469 keysched_t *ksch = (keysched_t *)cookie;
470
471 uint32_t left, right, tmp;
472 uint32_t *P = ksch->ksch_P;
473 uint32_t *S = ksch->ksch_S;
474 #ifdef _BIG_ENDIAN
475 uint32_t *b32;
476
477 if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
478 /* LINTED: pointer alignment */
479 b32 = (uint32_t *)block;
480 left = b32[0];
481 right = b32[1];
482 } else {
483 #endif
484 /*
485 * Read input block and place in left/right in big-endian order.
486 */
487 left = ((uint32_t)block[0] << 24)
488 | ((uint32_t)block[1] << 16)
489 | ((uint32_t)block[2] << 8)
490 | (uint32_t)block[3];
491 right = ((uint32_t)block[4] << 24)
492 | ((uint32_t)block[5] << 16)
493 | ((uint32_t)block[6] << 8)
494 | (uint32_t)block[7];
495 #ifdef _BIG_ENDIAN
496 }
497 #endif
498
499 ROUND(left, right, 17);
500 ROUND(left, right, 16);
501 ROUND(left, right, 15);
502 ROUND(left, right, 14);
503 ROUND(left, right, 13);
504 ROUND(left, right, 12);
505 ROUND(left, right, 11);
506 ROUND(left, right, 10);
507 ROUND(left, right, 9);
508 ROUND(left, right, 8);
509 ROUND(left, right, 7);
510 ROUND(left, right, 6);
511 ROUND(left, right, 5);
512 ROUND(left, right, 4);
513 ROUND(left, right, 3);
514 ROUND(left, right, 2);
515
516 tmp = left;
517 left = right;
518 right = tmp;
519 right ^= P[1];
520 left ^= P[0];
521
522 #ifdef _BIG_ENDIAN
523 if (IS_P2ALIGNED(out_block, sizeof (uint32_t))) {
524 /* LINTED: pointer alignment */
525 b32 = (uint32_t *)out_block;
526 b32[0] = left;
527 b32[1] = right;
528 } else {
529 #endif
530 /* Put the block back into the user's block with final swap */
531 out_block[0] = left >> 24;
532 out_block[1] = left >> 16;
533 out_block[2] = left >> 8;
534 out_block[3] = left;
535 out_block[4] = right >> 24;
536 out_block[5] = right >> 16;
537 out_block[6] = right >> 8;
538 out_block[7] = right;
539 #ifdef _BIG_ENDIAN
540 }
541 #endif
542 /* EXPORT DELETE END */
543 return (CRYPTO_SUCCESS);
544 }
545
546 static void
547 bitrepeat(uint8_t *pattern, uint_t len_bytes, uint_t len_bits, uint8_t *dst,
548 uint_t dst_len_bytes)
549 {
550 /* EXPORT DELETE START */
551 uint8_t *current = dst;
552 uint_t bitsleft = dst_len_bytes << 3;
553 uint_t bitoffset = 0;
554 uint_t currentbits;
555 int i;
556
557 BLOWFISH_ASSERT(((len_bits + 7) >> 3) == len_bytes);
558
559 bzero(dst, dst_len_bytes);
560
561 while (bitsleft != 0) {
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * Blowfish encryption/decryption and keyschedule code.
28 */
29
30 #include <sys/types.h>
31 #include <sys/systm.h>
32 #include <sys/ddi.h>
33 #include <sys/sysmacros.h>
34 #include <sys/strsun.h>
35 #include <sys/note.h>
36 #include <sys/byteorder.h>
37 #include <sys/crypto/spi.h>
38 #include <modes/modes.h>
39 #include <sys/crypto/common.h>
40 #include "blowfish_impl.h"
41
42 #ifdef _KERNEL
43
44 #define BLOWFISH_ASSERT(x) ASSERT(x)
45
46 #else /* !_KERNEL */
47
48 #include <strings.h>
49 #include <stdlib.h>
50 #define BLOWFISH_ASSERT(x)
51 #endif /* _KERNEL */
52
53 #if defined(__i386) || defined(__amd64)
54 #include <sys/byteorder.h>
55 #define UNALIGNED_POINTERS_PERMITTED
56 #endif
57
58 /* EXPORT DELETE START */
59
60 /*
61 * Blowfish initial P box and S boxes, derived from the hex digits of PI.
62 *
63 * NOTE: S boxes are placed into one large array.
64 */
65 static const uint32_t init_P[] = {
66 0x243f6a88U, 0x85a308d3U, 0x13198a2eU,
67 0x03707344U, 0xa4093822U, 0x299f31d0U,
68 0x082efa98U, 0xec4e6c89U, 0x452821e6U,
69 0x38d01377U, 0xbe5466cfU, 0x34e90c6cU,
70 0xc0ac29b7U, 0xc97c50ddU, 0x3f84d5b5U,
71 0xb5470917U, 0x9216d5d9U, 0x8979fb1bU
72 };
73
74 static const uint32_t init_S[] = {
75 /* S-Box 0. */
76 0xd1310ba6U, 0x98dfb5acU, 0x2ffd72dbU, 0xd01adfb7U,
77 0xb8e1afedU, 0x6a267e96U, 0xba7c9045U, 0xf12c7f99U,
375 */
376 /* ARGSUSED */
377 int
378 blowfish_encrypt_block(const void *cookie, const uint8_t *block,
379 uint8_t *out_block)
380 {
381 /* EXPORT DELETE START */
382 keysched_t *ksch = (keysched_t *)cookie;
383
384 uint32_t left, right, tmp;
385 uint32_t *P = ksch->ksch_P;
386 uint32_t *S = ksch->ksch_S;
387 #ifdef _BIG_ENDIAN
388 uint32_t *b32;
389
390 if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
391 /* LINTED: pointer alignment */
392 b32 = (uint32_t *)block;
393 left = b32[0];
394 right = b32[1];
395 } else
396 #endif
397 {
398 /*
399 * Read input block and place in left/right in big-endian order.
400 */
401 #ifdef UNALIGNED_POINTERS_PERMITTED
402 left = htonl(*(uint32_t *)&block[0]);
403 right = htonl(*(uint32_t *)&block[4]);
404 #else
405 left = ((uint32_t)block[0] << 24)
406 | ((uint32_t)block[1] << 16)
407 | ((uint32_t)block[2] << 8)
408 | (uint32_t)block[3];
409 right = ((uint32_t)block[4] << 24)
410 | ((uint32_t)block[5] << 16)
411 | ((uint32_t)block[6] << 8)
412 | (uint32_t)block[7];
413 #endif /* UNALIGNED_POINTERS_PERMITTED */
414 }
415
416 ROUND(left, right, 0);
417 ROUND(left, right, 1);
418 ROUND(left, right, 2);
419 ROUND(left, right, 3);
420 ROUND(left, right, 4);
421 ROUND(left, right, 5);
422 ROUND(left, right, 6);
423 ROUND(left, right, 7);
424 ROUND(left, right, 8);
425 ROUND(left, right, 9);
426 ROUND(left, right, 10);
427 ROUND(left, right, 11);
428 ROUND(left, right, 12);
429 ROUND(left, right, 13);
430 ROUND(left, right, 14);
431 ROUND(left, right, 15);
432
433 tmp = left;
434 left = right;
435 right = tmp;
436 right ^= P[16];
437 left ^= P[17];
438
439 #ifdef _BIG_ENDIAN
440 if (IS_P2ALIGNED(out_block, sizeof (uint32_t))) {
441 /* LINTED: pointer alignment */
442 b32 = (uint32_t *)out_block;
443 b32[0] = left;
444 b32[1] = right;
445 } else
446 #endif
447 {
448 /* Put the block back into the user's block with final swap */
449 #ifdef UNALIGNED_POINTERS_PERMITTED
450 *(uint32_t *)&out_block[0] = htonl(left);
451 *(uint32_t *)&out_block[4] = htonl(right);
452 #else
453 out_block[0] = left >> 24;
454 out_block[1] = left >> 16;
455 out_block[2] = left >> 8;
456 out_block[3] = left;
457 out_block[4] = right >> 24;
458 out_block[5] = right >> 16;
459 out_block[6] = right >> 8;
460 out_block[7] = right;
461 #endif /* UNALIGNED_POINTERS_PERMITTED */
462 }
463 /* EXPORT DELETE END */
464 return (CRYPTO_SUCCESS);
465 }
466
467 /*
468 * Decrypt a block of data. Because of addition operations, convert blocks
469 * to their big-endian representation, even on Intel boxen.
470 * It should look like the blowfish_encrypt_block() operation
471 * except for the order in which the S/P boxes are accessed.
472 */
473 /* ARGSUSED */
474 int
475 blowfish_decrypt_block(const void *cookie, const uint8_t *block,
476 uint8_t *out_block)
477 {
478 /* EXPORT DELETE START */
479 keysched_t *ksch = (keysched_t *)cookie;
480
481 uint32_t left, right, tmp;
482 uint32_t *P = ksch->ksch_P;
483 uint32_t *S = ksch->ksch_S;
484 #ifdef _BIG_ENDIAN
485 uint32_t *b32;
486
487 if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
488 /* LINTED: pointer alignment */
489 b32 = (uint32_t *)block;
490 left = b32[0];
491 right = b32[1];
492 } else
493 #endif
494 {
495 /*
496 * Read input block and place in left/right in big-endian order.
497 */
498 #ifdef UNALIGNED_POINTERS_PERMITTED
499 left = htonl(*(uint32_t *)&block[0]);
500 right = htonl(*(uint32_t *)&block[4]);
501 #else
502 left = ((uint32_t)block[0] << 24)
503 | ((uint32_t)block[1] << 16)
504 | ((uint32_t)block[2] << 8)
505 | (uint32_t)block[3];
506 right = ((uint32_t)block[4] << 24)
507 | ((uint32_t)block[5] << 16)
508 | ((uint32_t)block[6] << 8)
509 | (uint32_t)block[7];
510 #endif /* UNALIGNED_POINTERS_PERMITTED */
511 }
512
513 ROUND(left, right, 17);
514 ROUND(left, right, 16);
515 ROUND(left, right, 15);
516 ROUND(left, right, 14);
517 ROUND(left, right, 13);
518 ROUND(left, right, 12);
519 ROUND(left, right, 11);
520 ROUND(left, right, 10);
521 ROUND(left, right, 9);
522 ROUND(left, right, 8);
523 ROUND(left, right, 7);
524 ROUND(left, right, 6);
525 ROUND(left, right, 5);
526 ROUND(left, right, 4);
527 ROUND(left, right, 3);
528 ROUND(left, right, 2);
529
530 tmp = left;
531 left = right;
532 right = tmp;
533 right ^= P[1];
534 left ^= P[0];
535
536 #ifdef _BIG_ENDIAN
537 if (IS_P2ALIGNED(out_block, sizeof (uint32_t))) {
538 /* LINTED: pointer alignment */
539 b32 = (uint32_t *)out_block;
540 b32[0] = left;
541 b32[1] = right;
542 } else
543 #endif
544 {
545 /* Put the block back into the user's block with final swap */
546 #ifdef UNALIGNED_POINTERS_PERMITTED
547 *(uint32_t *)&out_block[0] = htonl(left);
548 *(uint32_t *)&out_block[4] = htonl(right);
549 #else
550 out_block[0] = left >> 24;
551 out_block[1] = left >> 16;
552 out_block[2] = left >> 8;
553 out_block[3] = left;
554 out_block[4] = right >> 24;
555 out_block[5] = right >> 16;
556 out_block[6] = right >> 8;
557 out_block[7] = right;
558 #endif /* UNALIGNED_POINTERS_PERMITTED */
559 }
560 /* EXPORT DELETE END */
561 return (CRYPTO_SUCCESS);
562 }
563
564 static void
565 bitrepeat(uint8_t *pattern, uint_t len_bytes, uint_t len_bits, uint8_t *dst,
566 uint_t dst_len_bytes)
567 {
568 /* EXPORT DELETE START */
569 uint8_t *current = dst;
570 uint_t bitsleft = dst_len_bytes << 3;
571 uint_t bitoffset = 0;
572 uint_t currentbits;
573 int i;
574
575 BLOWFISH_ASSERT(((len_bits + 7) >> 3) == len_bytes);
576
577 bzero(dst, dst_len_bytes);
578
579 while (bitsleft != 0) {
|