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

Split Close
Expand all
Collapse all
          --- old/usr/src/common/crypto/blowfish/blowfish_impl.c
          +++ new/usr/src/common/crypto/blowfish/blowfish_impl.c
↓ open down ↓ 15 lines elided ↑ open up ↑
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  
  26      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  27      -
  28   26  /*
  29   27   * Blowfish encryption/decryption and keyschedule code.
  30   28   */
  31   29  
  32   30  #include <sys/types.h>
  33   31  #include <sys/systm.h>
  34   32  #include <sys/ddi.h>
  35   33  #include <sys/sysmacros.h>
  36   34  #include <sys/strsun.h>
  37   35  #include <sys/note.h>
↓ open down ↓ 5 lines elided ↑ open up ↑
  43   41  
  44   42  #ifdef _KERNEL
  45   43  
  46   44  #define BLOWFISH_ASSERT(x)      ASSERT(x)
  47   45  
  48   46  #else /* !_KERNEL */
  49   47  
  50   48  #include <strings.h>
  51   49  #include <stdlib.h>
  52   50  #define BLOWFISH_ASSERT(x)
  53      -
  54   51  #endif /* _KERNEL */
  55   52  
       53 +#if defined(__i386) || defined(__amd64)
       54 +#include <sys/byteorder.h>
       55 +#define UNALIGNED_POINTERS_PERMITTED
       56 +#endif
       57 +
  56   58  /* EXPORT DELETE START */
  57   59  
  58   60  /*
  59   61   * Blowfish initial P box and S boxes, derived from the hex digits of PI.
  60   62   *
  61   63   * NOTE:  S boxes are placed into one large array.
  62   64   */
  63   65  static const uint32_t init_P[] = {
  64   66          0x243f6a88U, 0x85a308d3U, 0x13198a2eU,
  65   67          0x03707344U, 0xa4093822U, 0x299f31d0U,
↓ open down ↓ 317 lines elided ↑ open up ↑
 383  385          uint32_t *P = ksch->ksch_P;
 384  386          uint32_t *S = ksch->ksch_S;
 385  387  #ifdef _BIG_ENDIAN
 386  388          uint32_t *b32;
 387  389  
 388  390          if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
 389  391                  /* LINTED:  pointer alignment */
 390  392                  b32 = (uint32_t *)block;
 391  393                  left = b32[0];
 392  394                  right = b32[1];
 393      -        } else {
      395 +        } else
 394  396  #endif
      397 +        {
 395  398          /*
 396  399           * Read input block and place in left/right in big-endian order.
 397  400           */
      401 +#ifdef UNALIGNED_POINTERS_PERMITTED
      402 +        left = htonl(*(uint32_t *)&block[0]);
      403 +        right = htonl(*(uint32_t *)&block[4]);
      404 +#else
 398  405          left = ((uint32_t)block[0] << 24)
 399  406              | ((uint32_t)block[1] << 16)
 400  407              | ((uint32_t)block[2] << 8)
 401  408              | (uint32_t)block[3];
 402  409          right = ((uint32_t)block[4] << 24)
 403  410              | ((uint32_t)block[5] << 16)
 404  411              | ((uint32_t)block[6] << 8)
 405  412              | (uint32_t)block[7];
 406      -#ifdef _BIG_ENDIAN
      413 +#endif  /* UNALIGNED_POINTERS_PERMITTED */
 407  414          }
 408      -#endif
 409  415  
 410  416          ROUND(left, right, 0);
 411  417          ROUND(left, right, 1);
 412  418          ROUND(left, right, 2);
 413  419          ROUND(left, right, 3);
 414  420          ROUND(left, right, 4);
 415  421          ROUND(left, right, 5);
 416  422          ROUND(left, right, 6);
 417  423          ROUND(left, right, 7);
 418  424          ROUND(left, right, 8);
↓ open down ↓ 10 lines elided ↑ open up ↑
 429  435          right = tmp;
 430  436          right ^= P[16];
 431  437          left ^= P[17];
 432  438  
 433  439  #ifdef _BIG_ENDIAN
 434  440          if (IS_P2ALIGNED(out_block, sizeof (uint32_t))) {
 435  441                  /* LINTED:  pointer alignment */
 436  442                  b32 = (uint32_t *)out_block;
 437  443                  b32[0] = left;
 438  444                  b32[1] = right;
 439      -        } else {
      445 +        } else
 440  446  #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
      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 */
 451  462          }
 452      -#endif
 453  463  /* EXPORT DELETE END */
 454  464          return (CRYPTO_SUCCESS);
 455  465  }
 456  466  
 457  467  /*
 458  468   * Decrypt a block of data.  Because of addition operations, convert blocks
 459  469   * to their big-endian representation, even on Intel boxen.
 460  470   * It should look like the blowfish_encrypt_block() operation
 461  471   * except for the order in which the S/P boxes are accessed.
 462  472   */
↓ open down ↓ 9 lines elided ↑ open up ↑
 472  482          uint32_t *P = ksch->ksch_P;
 473  483          uint32_t *S = ksch->ksch_S;
 474  484  #ifdef _BIG_ENDIAN
 475  485          uint32_t *b32;
 476  486  
 477  487          if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
 478  488                  /* LINTED:  pointer alignment */
 479  489                  b32 = (uint32_t *)block;
 480  490                  left = b32[0];
 481  491                  right = b32[1];
 482      -        } else {
      492 +        } else
 483  493  #endif
      494 +        {
 484  495          /*
 485  496           * Read input block and place in left/right in big-endian order.
 486  497           */
      498 +#ifdef UNALIGNED_POINTERS_PERMITTED
      499 +        left = htonl(*(uint32_t *)&block[0]);
      500 +        right = htonl(*(uint32_t *)&block[4]);
      501 +#else
 487  502          left = ((uint32_t)block[0] << 24)
 488  503              | ((uint32_t)block[1] << 16)
 489  504              | ((uint32_t)block[2] << 8)
 490  505              | (uint32_t)block[3];
 491  506          right = ((uint32_t)block[4] << 24)
 492  507              | ((uint32_t)block[5] << 16)
 493  508              | ((uint32_t)block[6] << 8)
 494  509              | (uint32_t)block[7];
 495      -#ifdef _BIG_ENDIAN
      510 +#endif  /* UNALIGNED_POINTERS_PERMITTED */
 496  511          }
 497      -#endif
 498  512  
 499  513          ROUND(left, right, 17);
 500  514          ROUND(left, right, 16);
 501  515          ROUND(left, right, 15);
 502  516          ROUND(left, right, 14);
 503  517          ROUND(left, right, 13);
 504  518          ROUND(left, right, 12);
 505  519          ROUND(left, right, 11);
 506  520          ROUND(left, right, 10);
 507  521          ROUND(left, right, 9);
↓ open down ↓ 10 lines elided ↑ open up ↑
 518  532          right = tmp;
 519  533          right ^= P[1];
 520  534          left ^= P[0];
 521  535  
 522  536  #ifdef _BIG_ENDIAN
 523  537          if (IS_P2ALIGNED(out_block, sizeof (uint32_t))) {
 524  538                  /* LINTED:  pointer alignment */
 525  539                  b32 = (uint32_t *)out_block;
 526  540                  b32[0] = left;
 527  541                  b32[1] = right;
 528      -        } else {
      542 +        } else
 529  543  #endif
      544 +        {
 530  545          /* 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
      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 */
 540  559          }
 541      -#endif
 542  560  /* EXPORT DELETE END */
 543  561          return (CRYPTO_SUCCESS);
 544  562  }
 545  563  
 546  564  static void
 547  565  bitrepeat(uint8_t *pattern, uint_t len_bytes, uint_t len_bits, uint8_t *dst,
 548  566      uint_t dst_len_bytes)
 549  567  {
 550  568  /* EXPORT DELETE START */
 551  569          uint8_t *current = dst;
↓ open down ↓ 217 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX