Print this page
3882 remove xmod & friends


  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,
  78         0x24a19947U, 0xb3916cf7U, 0x0801f2e2U, 0x858efc16U,
  79         0x636920d8U, 0x71574e69U, 0xa458fea3U, 0xf4933d7eU,


 350  *      uint32_t *P;
 351  *      uint32_t *S;
 352  *      uint32_t tmp;
 353  *
 354  *
 355  * And to Microsoft interview survivors out there, perhaps I should do the
 356  * XOR swap trick, or at least #ifdef (__i386) the tmp = ... = tmp; stuff.
 357  */
 358 
 359 #define F(word) \
 360         (((S[(word >> 24) & 0xff] + S[256 + ((word >> 16) & 0xff)]) ^ \
 361                 S[512 + ((word >> 8) & 0xff)]) + S[768 + (word & 0xff)])
 362 
 363 #define ROUND(left, right, i) \
 364         (left) ^= P[i]; \
 365         (right) ^= F((left)); \
 366         tmp = (left); \
 367         (left) = (right); \
 368         (right) = tmp;
 369 
 370 /* EXPORT DELETE END */
 371 
 372 /*
 373  * Encrypt a block of data.  Because of addition operations, convert blocks
 374  * to their big-endian representation, even on Intel boxen.
 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


 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 *)(void *)&out_block[0] = htonl(left);
 451                 *(uint32_t *)(void *)&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


 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 *)(void *)&out_block[0] = htonl(left);
 548                 *(uint32_t *)(void *)&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 = CRYPTO_BYTES2BITS(dst_len_bytes);
 571         uint_t bitoffset = 0;
 572         uint_t currentbits;
 573         int i;
 574 
 575         BLOWFISH_ASSERT(CRYPTO_BITS2BYTES(len_bits) == len_bytes);
 576 
 577         bzero(dst, dst_len_bytes);
 578 
 579         while (bitsleft != 0) {
 580                 if (bitsleft >= len_bits) {
 581                         currentbits = len_bits;
 582 
 583                         for (i = 0; i < len_bytes; i++) {
 584                                 if (currentbits >= 8) {
 585                                         *current++ |= pattern[i] >> bitoffset;
 586                                         *current |= pattern[i] << 8 - bitoffset;
 587                                         currentbits -= 8;
 588                                 } else {


 600                         for (i = 0; i < len_bytes && bitsleft != 0; i++) {
 601                                 if (currentbits >= 8 &&
 602                                     current < dst + dst_len_bytes) {
 603                                         *current++ |= pattern[i] >> bitoffset;
 604                                         *current |= pattern[i] << 8 - bitoffset;
 605                                         currentbits -= 8;
 606                                         bitsleft -= 8;
 607                                 } else {
 608                                         *current |= pattern[i] >> bitoffset;
 609                                         bitsleft -= bitoffset;
 610                                         bitoffset = bitoffset + currentbits;
 611                                         bitoffset &= 0x7;
 612                                         if (bitoffset == 0)
 613                                                 current++;
 614                                         currentbits = 0;
 615                                 }
 616                         }
 617                         bitsleft = 0;
 618                 }
 619         }
 620 /* EXPORT DELETE END */
 621 }
 622 
 623 /*
 624  * Initialize key schedules for Blowfish.
 625  */
 626 void
 627 blowfish_init_keysched(uint8_t *key, uint_t bits, void *keysched)
 628 {
 629 /* EXPORT DELETE START */
 630         keysched_t *newbie = keysched;
 631         uint32_t *P = newbie->ksch_P;
 632         uint32_t *S = newbie->ksch_S;
 633         uint32_t *initp;
 634         uint32_t tmpblock[] = {0, 0};
 635         uint8_t *rawkeybytes = (uint8_t *)P;
 636         int i, slop, copylen;
 637         uintptr_t bytesleft;
 638         uint_t len;
 639 
 640         len = CRYPTO_BITS2BYTES(bits);
 641 
 642         if ((bits & 0x7) != 0) {
 643                 /*
 644                  * Really slow case, bits aren't on a byte boundary.
 645                  * Keep track of individual bits copied over.  :-P
 646                  */
 647                 bitrepeat(key, len, bits, rawkeybytes, 72);
 648         } else {
 649                 slop = 72 % len;


 668          * When initializing P and S boxes, store the results of a single
 669          * encrypt-block operation in "host order", which on little-endian
 670          * means byte-swapping.  Fortunately, the ntohl() function does this
 671          * quite nicely, and it a NOP on big-endian machine.
 672          */
 673         initp = P;
 674         for (i = 0; i < 9; i++) {
 675                 (void) blowfish_encrypt_block(newbie, (uint8_t *)tmpblock,
 676                     (uint8_t *)tmpblock);
 677                 *initp++ = ntohl(tmpblock[0]);
 678                 *initp++ = ntohl(tmpblock[1]);
 679         }
 680 
 681         initp = S;
 682         for (i = 0; i < 512; i++) {
 683                 (void) blowfish_encrypt_block(newbie, (uint8_t *)tmpblock,
 684                     (uint8_t *)tmpblock);
 685                 *initp++ = ntohl(tmpblock[0]);
 686                 *initp++ = ntohl(tmpblock[1]);
 687         }
 688 /* EXPORT DELETE END */
 689 }
 690 
 691 /*
 692  * Allocate key schedule for Blowfish.
 693  */
 694 /* ARGSUSED */
 695 void *
 696 blowfish_alloc_keysched(size_t *size, int kmflag)
 697 {
 698 /* EXPORT DELETE START */
 699         keysched_t *keysched;
 700 
 701 #ifdef _KERNEL
 702         keysched = (keysched_t *)kmem_alloc(sizeof (keysched_t), kmflag);
 703 #else
 704         keysched = (keysched_t *)malloc(sizeof (keysched_t));
 705 #endif /* _KERNEL */
 706         if (keysched != NULL) {
 707                 *size = sizeof (keysched_t);
 708                 return (keysched);
 709         }
 710 /* EXPORT DELETE END */
 711 
 712         return (NULL);
 713 }
 714 
 715 void
 716 blowfish_copy_block(uint8_t *in, uint8_t *out)
 717 {
 718         if (IS_P2ALIGNED(in, sizeof (uint32_t)) &&
 719             IS_P2ALIGNED(out, sizeof (uint32_t))) {
 720                 /* LINTED: pointer alignment */
 721                 *(uint32_t *)&out[0] = *(uint32_t *)&in[0];
 722                 /* LINTED: pointer alignment */
 723                 *(uint32_t *)&out[4] = *(uint32_t *)&in[4];
 724         } else {
 725                 BLOWFISH_COPY_BLOCK(in, out);
 726         }
 727 }
 728 
 729 /* XOR block of data into dest */
 730 void




  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 /*
  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,
  76         0x24a19947U, 0xb3916cf7U, 0x0801f2e2U, 0x858efc16U,
  77         0x636920d8U, 0x71574e69U, 0xa458fea3U, 0xf4933d7eU,


 348  *      uint32_t *P;
 349  *      uint32_t *S;
 350  *      uint32_t tmp;
 351  *
 352  *
 353  * And to Microsoft interview survivors out there, perhaps I should do the
 354  * XOR swap trick, or at least #ifdef (__i386) the tmp = ... = tmp; stuff.
 355  */
 356 
 357 #define F(word) \
 358         (((S[(word >> 24) & 0xff] + S[256 + ((word >> 16) & 0xff)]) ^ \
 359                 S[512 + ((word >> 8) & 0xff)]) + S[768 + (word & 0xff)])
 360 
 361 #define ROUND(left, right, i) \
 362         (left) ^= P[i]; \
 363         (right) ^= F((left)); \
 364         tmp = (left); \
 365         (left) = (right); \
 366         (right) = tmp;
 367 


 368 /*
 369  * Encrypt a block of data.  Because of addition operations, convert blocks
 370  * to their big-endian representation, even on Intel boxen.
 371  */
 372 /* ARGSUSED */
 373 int
 374 blowfish_encrypt_block(const void *cookie, const uint8_t *block,
 375     uint8_t *out_block)
 376 {

 377         keysched_t *ksch = (keysched_t *)cookie;
 378 
 379         uint32_t left, right, tmp;
 380         uint32_t *P = ksch->ksch_P;
 381         uint32_t *S = ksch->ksch_S;
 382 #ifdef _BIG_ENDIAN
 383         uint32_t *b32;
 384 
 385         if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
 386                 /* LINTED:  pointer alignment */
 387                 b32 = (uint32_t *)block;
 388                 left = b32[0];
 389                 right = b32[1];
 390         } else
 391 #endif
 392         {
 393         /*
 394          * Read input block and place in left/right in big-endian order.
 395          */
 396 #ifdef UNALIGNED_POINTERS_PERMITTED


 438                 b32[0] = left;
 439                 b32[1] = right;
 440         } else
 441 #endif
 442         {
 443                 /* Put the block back into the user's block with final swap */
 444 #ifdef UNALIGNED_POINTERS_PERMITTED
 445                 *(uint32_t *)(void *)&out_block[0] = htonl(left);
 446                 *(uint32_t *)(void *)&out_block[4] = htonl(right);
 447 #else
 448                 out_block[0] = left >> 24;
 449                 out_block[1] = left >> 16;
 450                 out_block[2] = left >> 8;
 451                 out_block[3] = left;
 452                 out_block[4] = right >> 24;
 453                 out_block[5] = right >> 16;
 454                 out_block[6] = right >> 8;
 455                 out_block[7] = right;
 456 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 457         }

 458         return (CRYPTO_SUCCESS);
 459 }
 460 
 461 /*
 462  * Decrypt a block of data.  Because of addition operations, convert blocks
 463  * to their big-endian representation, even on Intel boxen.
 464  * It should look like the blowfish_encrypt_block() operation
 465  * except for the order in which the S/P boxes are accessed.
 466  */
 467 /* ARGSUSED */
 468 int
 469 blowfish_decrypt_block(const void *cookie, const uint8_t *block,
 470     uint8_t *out_block)
 471 {

 472         keysched_t *ksch = (keysched_t *)cookie;
 473 
 474         uint32_t left, right, tmp;
 475         uint32_t *P = ksch->ksch_P;
 476         uint32_t *S = ksch->ksch_S;
 477 #ifdef _BIG_ENDIAN
 478         uint32_t *b32;
 479 
 480         if (IS_P2ALIGNED(block, sizeof (uint32_t))) {
 481                 /* LINTED:  pointer alignment */
 482                 b32 = (uint32_t *)block;
 483                 left = b32[0];
 484                 right = b32[1];
 485         } else
 486 #endif
 487         {
 488         /*
 489          * Read input block and place in left/right in big-endian order.
 490          */
 491 #ifdef UNALIGNED_POINTERS_PERMITTED


 533                 b32[0] = left;
 534                 b32[1] = right;
 535         } else
 536 #endif
 537         {
 538         /* Put the block back into the user's block with final swap */
 539 #ifdef UNALIGNED_POINTERS_PERMITTED
 540                 *(uint32_t *)(void *)&out_block[0] = htonl(left);
 541                 *(uint32_t *)(void *)&out_block[4] = htonl(right);
 542 #else
 543                 out_block[0] = left >> 24;
 544                 out_block[1] = left >> 16;
 545                 out_block[2] = left >> 8;
 546                 out_block[3] = left;
 547                 out_block[4] = right >> 24;
 548                 out_block[5] = right >> 16;
 549                 out_block[6] = right >> 8;
 550                 out_block[7] = right;
 551 #endif  /* UNALIGNED_POINTERS_PERMITTED */
 552         }

 553         return (CRYPTO_SUCCESS);
 554 }
 555 
 556 static void
 557 bitrepeat(uint8_t *pattern, uint_t len_bytes, uint_t len_bits, uint8_t *dst,
 558     uint_t dst_len_bytes)
 559 {

 560         uint8_t *current = dst;
 561         uint_t bitsleft = CRYPTO_BYTES2BITS(dst_len_bytes);
 562         uint_t bitoffset = 0;
 563         uint_t currentbits;
 564         int i;
 565 
 566         BLOWFISH_ASSERT(CRYPTO_BITS2BYTES(len_bits) == len_bytes);
 567 
 568         bzero(dst, dst_len_bytes);
 569 
 570         while (bitsleft != 0) {
 571                 if (bitsleft >= len_bits) {
 572                         currentbits = len_bits;
 573 
 574                         for (i = 0; i < len_bytes; i++) {
 575                                 if (currentbits >= 8) {
 576                                         *current++ |= pattern[i] >> bitoffset;
 577                                         *current |= pattern[i] << 8 - bitoffset;
 578                                         currentbits -= 8;
 579                                 } else {


 591                         for (i = 0; i < len_bytes && bitsleft != 0; i++) {
 592                                 if (currentbits >= 8 &&
 593                                     current < dst + dst_len_bytes) {
 594                                         *current++ |= pattern[i] >> bitoffset;
 595                                         *current |= pattern[i] << 8 - bitoffset;
 596                                         currentbits -= 8;
 597                                         bitsleft -= 8;
 598                                 } else {
 599                                         *current |= pattern[i] >> bitoffset;
 600                                         bitsleft -= bitoffset;
 601                                         bitoffset = bitoffset + currentbits;
 602                                         bitoffset &= 0x7;
 603                                         if (bitoffset == 0)
 604                                                 current++;
 605                                         currentbits = 0;
 606                                 }
 607                         }
 608                         bitsleft = 0;
 609                 }
 610         }

 611 }
 612 
 613 /*
 614  * Initialize key schedules for Blowfish.
 615  */
 616 void
 617 blowfish_init_keysched(uint8_t *key, uint_t bits, void *keysched)
 618 {

 619         keysched_t *newbie = keysched;
 620         uint32_t *P = newbie->ksch_P;
 621         uint32_t *S = newbie->ksch_S;
 622         uint32_t *initp;
 623         uint32_t tmpblock[] = {0, 0};
 624         uint8_t *rawkeybytes = (uint8_t *)P;
 625         int i, slop, copylen;
 626         uintptr_t bytesleft;
 627         uint_t len;
 628 
 629         len = CRYPTO_BITS2BYTES(bits);
 630 
 631         if ((bits & 0x7) != 0) {
 632                 /*
 633                  * Really slow case, bits aren't on a byte boundary.
 634                  * Keep track of individual bits copied over.  :-P
 635                  */
 636                 bitrepeat(key, len, bits, rawkeybytes, 72);
 637         } else {
 638                 slop = 72 % len;


 657          * When initializing P and S boxes, store the results of a single
 658          * encrypt-block operation in "host order", which on little-endian
 659          * means byte-swapping.  Fortunately, the ntohl() function does this
 660          * quite nicely, and it a NOP on big-endian machine.
 661          */
 662         initp = P;
 663         for (i = 0; i < 9; i++) {
 664                 (void) blowfish_encrypt_block(newbie, (uint8_t *)tmpblock,
 665                     (uint8_t *)tmpblock);
 666                 *initp++ = ntohl(tmpblock[0]);
 667                 *initp++ = ntohl(tmpblock[1]);
 668         }
 669 
 670         initp = S;
 671         for (i = 0; i < 512; i++) {
 672                 (void) blowfish_encrypt_block(newbie, (uint8_t *)tmpblock,
 673                     (uint8_t *)tmpblock);
 674                 *initp++ = ntohl(tmpblock[0]);
 675                 *initp++ = ntohl(tmpblock[1]);
 676         }

 677 }
 678 
 679 /*
 680  * Allocate key schedule for Blowfish.
 681  */
 682 /* ARGSUSED */
 683 void *
 684 blowfish_alloc_keysched(size_t *size, int kmflag)
 685 {

 686         keysched_t *keysched;
 687 
 688 #ifdef _KERNEL
 689         keysched = (keysched_t *)kmem_alloc(sizeof (keysched_t), kmflag);
 690 #else
 691         keysched = (keysched_t *)malloc(sizeof (keysched_t));
 692 #endif /* _KERNEL */
 693         if (keysched != NULL) {
 694                 *size = sizeof (keysched_t);
 695                 return (keysched);
 696         }

 697 
 698         return (NULL);
 699 }
 700 
 701 void
 702 blowfish_copy_block(uint8_t *in, uint8_t *out)
 703 {
 704         if (IS_P2ALIGNED(in, sizeof (uint32_t)) &&
 705             IS_P2ALIGNED(out, sizeof (uint32_t))) {
 706                 /* LINTED: pointer alignment */
 707                 *(uint32_t *)&out[0] = *(uint32_t *)&in[0];
 708                 /* LINTED: pointer alignment */
 709                 *(uint32_t *)&out[4] = *(uint32_t *)&in[4];
 710         } else {
 711                 BLOWFISH_COPY_BLOCK(in, out);
 712         }
 713 }
 714 
 715 /* XOR block of data into dest */
 716 void