Print this page
4896 Performance improvements for KCF AES modes


   5  * Common Development and Distribution License (the "License").
   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 2010 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)


 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
 717 blowfish_xor_block(uint8_t *data, uint8_t *dst)
 718 {
 719         if (IS_P2ALIGNED(dst, sizeof (uint32_t)) &&
 720             IS_P2ALIGNED(data, sizeof (uint32_t))) {
 721                 /* LINTED: pointer alignment */
 722                 *(uint32_t *)&dst[0] ^= *(uint32_t *)&data[0];
 723                 /* LINTED: pointer alignment */
 724                 *(uint32_t *)&dst[4] ^= *(uint32_t *)&data[4];
 725         } else {
 726                 BLOWFISH_XOR_BLOCK(data, dst);
 727         }
 728 }
 729 
 730 /*
 731  * Encrypt multiple blocks of data according to mode.
 732  */
 733 int
 734 blowfish_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
 735     crypto_data_t *out)
 736 {
 737         blowfish_ctx_t *blowfish_ctx = ctx;
 738         int rv;
 739 
 740         if (blowfish_ctx->bc_flags & CBC_MODE) {
 741                 rv = cbc_encrypt_contiguous_blocks(ctx, data, length, out,
 742                     BLOWFISH_BLOCK_LEN, blowfish_encrypt_block,
 743                     blowfish_copy_block, blowfish_xor_block);
 744         } else {
 745                 rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
 746                     BLOWFISH_BLOCK_LEN, blowfish_encrypt_block);
 747         }
 748         return (rv);
 749 }
 750 
 751 /*
 752  * Decrypt multiple blocks of data according to mode.
 753  */
 754 int
 755 blowfish_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
 756     crypto_data_t *out)
 757 {
 758         blowfish_ctx_t *blowfish_ctx = ctx;
 759         int rv;
 760 
 761         if (blowfish_ctx->bc_flags & CBC_MODE) {
 762                 rv = cbc_decrypt_contiguous_blocks(ctx, data, length, out,
 763                     BLOWFISH_BLOCK_LEN, blowfish_decrypt_block,
 764                     blowfish_copy_block, blowfish_xor_block);
 765         } else {
 766                 rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
 767                     BLOWFISH_BLOCK_LEN, blowfish_decrypt_block);
 768                 if (rv == CRYPTO_DATA_LEN_RANGE)
 769                         rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
 770         }
 771         return (rv);
 772 }


   5  * Common Development and Distribution License (the "License").
   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 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright 2015 by Saso Kiselkov. All rights reserved.
  27  */
  28 
  29 /*
  30  * Blowfish encryption/decryption and keyschedule code.
  31  */
  32 
  33 #include <sys/types.h>
  34 #include <sys/systm.h>
  35 #include <sys/ddi.h>
  36 #include <sys/sysmacros.h>
  37 #include <sys/strsun.h>
  38 #include <sys/note.h>
  39 #include <sys/byteorder.h>
  40 #include <sys/crypto/spi.h>
  41 #include <modes/modes.h>
  42 #include <sys/crypto/common.h>
  43 #include "blowfish_impl.h"
  44 
  45 #ifdef _KERNEL
  46 
  47 #define BLOWFISH_ASSERT(x)      ASSERT(x)


 685 /* ARGSUSED */
 686 void *
 687 blowfish_alloc_keysched(size_t *size, int kmflag)
 688 {
 689         keysched_t *keysched;
 690 
 691 #ifdef _KERNEL
 692         keysched = (keysched_t *)kmem_alloc(sizeof (keysched_t), kmflag);
 693 #else
 694         keysched = (keysched_t *)malloc(sizeof (keysched_t));
 695 #endif /* _KERNEL */
 696         if (keysched != NULL) {
 697                 *size = sizeof (keysched_t);
 698                 return (keysched);
 699         }
 700 
 701         return (NULL);
 702 }
 703 
 704 void
 705 blowfish_copy_block(const uint8_t *in, uint8_t *out)
 706 {
 707         if (IS_P2ALIGNED(in, sizeof (uint32_t)) &&
 708             IS_P2ALIGNED(out, sizeof (uint32_t))) {
 709                 /* LINTED: pointer alignment */
 710                 *(uint32_t *)&out[0] = *(uint32_t *)&in[0];
 711                 /* LINTED: pointer alignment */
 712                 *(uint32_t *)&out[4] = *(uint32_t *)&in[4];
 713         } else {
 714                 BLOWFISH_COPY_BLOCK(in, out);
 715         }
 716 }
 717 
 718 /* XOR block of data into dest */
 719 void
 720 blowfish_xor_block(const uint8_t *data, uint8_t *dst)
 721 {
 722         if (IS_P2ALIGNED(dst, sizeof (uint32_t)) &&
 723             IS_P2ALIGNED(data, sizeof (uint32_t))) {
 724                 /* LINTED: pointer alignment */
 725                 *(uint32_t *)&dst[0] ^= *(uint32_t *)&data[0];
 726                 /* LINTED: pointer alignment */
 727                 *(uint32_t *)&dst[4] ^= *(uint32_t *)&data[4];
 728         } else {
 729                 BLOWFISH_XOR_BLOCK(data, dst);
 730         }
 731 }
 732 
 733 /*
 734  * Encrypt multiple blocks of data according to mode.
 735  */
 736 int
 737 blowfish_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
 738     crypto_data_t *out)
 739 {
 740         blowfish_ctx_t *blowfish_ctx = ctx;
 741         int rv;
 742 
 743         if (blowfish_ctx->bc_flags & CBC_MODE) {
 744                 rv = cbc_encrypt_contiguous_blocks(ctx, data, length, out,
 745                     BLOWFISH_BLOCK_LEN, blowfish_encrypt_block,
 746                     blowfish_copy_block, blowfish_xor_block, NULL);
 747         } else {
 748                 rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
 749                     BLOWFISH_BLOCK_LEN, blowfish_encrypt_block, NULL);
 750         }
 751         return (rv);
 752 }
 753 
 754 /*
 755  * Decrypt multiple blocks of data according to mode.
 756  */
 757 int
 758 blowfish_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
 759     crypto_data_t *out)
 760 {
 761         blowfish_ctx_t *blowfish_ctx = ctx;
 762         int rv;
 763 
 764         if (blowfish_ctx->bc_flags & CBC_MODE) {
 765                 rv = cbc_decrypt_contiguous_blocks(ctx, data, length, out,
 766                     BLOWFISH_BLOCK_LEN, blowfish_decrypt_block,
 767                     blowfish_copy_block, blowfish_xor_block, NULL, NULL);
 768         } else {
 769                 rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
 770                     BLOWFISH_BLOCK_LEN, blowfish_decrypt_block, NULL);
 771                 if (rv == CRYPTO_DATA_LEN_RANGE)
 772                         rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
 773         }
 774         return (rv);
 775 }