Print this page
5007142 Add ntohll and htonll to sys/byteorder.h
6717509 Need to use bswap/bswapq for byte swap of 64-bit integer on x32/x64
PSARC 2008/474

@@ -21,12 +21,10 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident   "%Z%%M% %I%     %E% SMI"
-
 /*
  * Blowfish encryption/decryption and keyschedule code.
  */
 
 #include <sys/types.h>

@@ -48,13 +46,17 @@
 #else /* !_KERNEL */
 
 #include <strings.h>
 #include <stdlib.h>
 #define BLOWFISH_ASSERT(x)
-
 #endif /* _KERNEL */
 
+#if defined(__i386) || defined(__amd64)
+#include <sys/byteorder.h>
+#define UNALIGNED_POINTERS_PERMITTED
+#endif
+
 /* EXPORT DELETE START */
 
 /*
  * Blowfish initial P box and S boxes, derived from the hex digits of PI.
  *

@@ -388,26 +390,30 @@
         if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
                 /* LINTED:  pointer alignment */
                 b32 = (uint32_t *)block;
                 left = b32[0];
                 right = b32[1];
-        } else {
+        } else
 #endif
+        {
         /*
          * Read input block and place in left/right in big-endian order.
          */
+#ifdef UNALIGNED_POINTERS_PERMITTED
+        left = htonl(*(uint32_t *)&block[0]);
+        right = htonl(*(uint32_t *)&block[4]);
+#else
         left = ((uint32_t)block[0] << 24)
             | ((uint32_t)block[1] << 16)
             | ((uint32_t)block[2] << 8)
             | (uint32_t)block[3];
         right = ((uint32_t)block[4] << 24)
             | ((uint32_t)block[5] << 16)
             | ((uint32_t)block[6] << 8)
             | (uint32_t)block[7];
-#ifdef _BIG_ENDIAN
+#endif  /* UNALIGNED_POINTERS_PERMITTED */
         }
-#endif
 
         ROUND(left, right, 0);
         ROUND(left, right, 1);
         ROUND(left, right, 2);
         ROUND(left, right, 3);

@@ -434,24 +440,28 @@
         if (IS_P2ALIGNED(out_block, sizeof (uint32_t))) {
                 /* LINTED:  pointer alignment */
                 b32 = (uint32_t *)out_block;
                 b32[0] = left;
                 b32[1] = right;
-        } else {
+        } else
 #endif
+        {
         /* Put the block back into the user's block with final swap */
+#ifdef UNALIGNED_POINTERS_PERMITTED
+                *(uint32_t *)&out_block[0] = htonl(left);
+                *(uint32_t *)&out_block[4] = htonl(right);
+#else
         out_block[0] = left >> 24;
         out_block[1] = left >> 16;
         out_block[2] = left >> 8;
         out_block[3] = left;
         out_block[4] = right >> 24;
         out_block[5] = right >> 16;
         out_block[6] = right >> 8;
         out_block[7] = right;
-#ifdef _BIG_ENDIAN
+#endif  /* UNALIGNED_POINTERS_PERMITTED */
         }
-#endif
 /* EXPORT DELETE END */
         return (CRYPTO_SUCCESS);
 }
 
 /*

@@ -477,26 +487,30 @@
         if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
                 /* LINTED:  pointer alignment */
                 b32 = (uint32_t *)block;
                 left = b32[0];
                 right = b32[1];
-        } else {
+        } else
 #endif
+        {
         /*
          * Read input block and place in left/right in big-endian order.
          */
+#ifdef UNALIGNED_POINTERS_PERMITTED
+        left = htonl(*(uint32_t *)&block[0]);
+        right = htonl(*(uint32_t *)&block[4]);
+#else
         left = ((uint32_t)block[0] << 24)
             | ((uint32_t)block[1] << 16)
             | ((uint32_t)block[2] << 8)
             | (uint32_t)block[3];
         right = ((uint32_t)block[4] << 24)
             | ((uint32_t)block[5] << 16)
             | ((uint32_t)block[6] << 8)
             | (uint32_t)block[7];
-#ifdef _BIG_ENDIAN
+#endif  /* UNALIGNED_POINTERS_PERMITTED */
         }
-#endif
 
         ROUND(left, right, 17);
         ROUND(left, right, 16);
         ROUND(left, right, 15);
         ROUND(left, right, 14);

@@ -523,24 +537,28 @@
         if (IS_P2ALIGNED(out_block, sizeof (uint32_t))) {
                 /* LINTED:  pointer alignment */
                 b32 = (uint32_t *)out_block;
                 b32[0] = left;
                 b32[1] = right;
-        } else {
+        } else
 #endif
+        {
         /* Put the block back into the user's block with final swap */
+#ifdef UNALIGNED_POINTERS_PERMITTED
+                *(uint32_t *)&out_block[0] = htonl(left);
+                *(uint32_t *)&out_block[4] = htonl(right);
+#else
         out_block[0] = left >> 24;
         out_block[1] = left >> 16;
         out_block[2] = left >> 8;
         out_block[3] = left;
         out_block[4] = right >> 24;
         out_block[5] = right >> 16;
         out_block[6] = right >> 8;
         out_block[7] = right;
-#ifdef _BIG_ENDIAN
+#endif  /* UNALIGNED_POINTERS_PERMITTED */
         }
-#endif
 /* EXPORT DELETE END */
         return (CRYPTO_SUCCESS);
 }
 
 static void