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 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */



  25 
  26 #include <sys/types.h>
  27 #include <sys/systm.h>
  28 #include <sys/ddi.h>
  29 #include <sys/sysmacros.h>
  30 #include <sys/strsun.h>
  31 #include <sys/crypto/spi.h>
  32 #include <modes/modes.h>
  33 #include <sys/crypto/common.h>
  34 #include "des_impl.h"
  35 #ifndef _KERNEL
  36 #include <strings.h>
  37 #include <stdlib.h>
  38 #endif  /* !_KERNEL */
  39 
  40 #if defined(__i386) || defined(__amd64)
  41 #include <sys/byteorder.h>
  42 #define UNALIGNED_POINTERS_PERMITTED
  43 #endif
  44 


 969         return (keysched);
 970 }
 971 
 972 /*
 973  * Replace the LSB of each byte by the xor of the other
 974  * 7 bits.  The tricky thing is that the original contents of the LSBs
 975  * are nullified by including them twice in the xor computation.
 976  */
 977 static void
 978 fix_des_parity(uint64_t *keyp)
 979 {
 980         uint64_t k = *keyp;
 981         k ^= k >> 1;
 982         k ^= k >> 2;
 983         k ^= k >> 4;
 984         *keyp ^= (k & 0x0101010101010101ULL);
 985         *keyp ^= 0x0101010101010101ULL;
 986 }
 987 
 988 void
 989 des_copy_block(uint8_t *in, uint8_t *out)
 990 {
 991         if (IS_P2ALIGNED(in, sizeof (uint32_t)) &&
 992             IS_P2ALIGNED(out, sizeof (uint32_t))) {
 993                 /* LINTED: pointer alignment */
 994                 *(uint32_t *)&out[0] = *(uint32_t *)&in[0];
 995                 /* LINTED: pointer alignment */
 996                 *(uint32_t *)&out[4] = *(uint32_t *)&in[4];
 997         } else {
 998                 DES_COPY_BLOCK(in, out);
 999         }
1000 }
1001 
1002 /* XOR block of data into dest */
1003 void
1004 des_xor_block(uint8_t *data, uint8_t *dst)
1005 {
1006         if (IS_P2ALIGNED(dst, sizeof (uint32_t)) &&
1007             IS_P2ALIGNED(data, sizeof (uint32_t))) {
1008                 /* LINTED: pointer alignment */
1009                 *(uint32_t *)&dst[0] ^=
1010                     /* LINTED: pointer alignment */
1011                     *(uint32_t *)&data[0];
1012                     /* LINTED: pointer alignment */
1013                 *(uint32_t *)&dst[4] ^=
1014                     /* LINTED: pointer alignment */
1015                     *(uint32_t *)&data[4];
1016         } else {
1017                 DES_XOR_BLOCK(data, dst);
1018         }
1019 }
1020 
1021 int
1022 des_encrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
1023 {
1024         return (des_crunch_block(keysched, in, out, B_FALSE));


1039 int
1040 des3_decrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
1041 {
1042         return (des3_crunch_block(keysched, in, out, B_TRUE));
1043 }
1044 
1045 /*
1046  * Encrypt multiple blocks of data according to mode.
1047  */
1048 int
1049 des_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
1050     crypto_data_t *out)
1051 {
1052         des_ctx_t *des_ctx = ctx;
1053         int rv;
1054 
1055         if (des_ctx->dc_flags & DES3_STRENGTH) {
1056                 if (des_ctx->dc_flags & CBC_MODE) {
1057                         rv = cbc_encrypt_contiguous_blocks(ctx, data,
1058                             length, out, DES_BLOCK_LEN, des3_encrypt_block,
1059                             des_copy_block, des_xor_block);
1060                 } else {
1061                         rv = ecb_cipher_contiguous_blocks(ctx, data, length,
1062                             out, DES_BLOCK_LEN, des3_encrypt_block);
1063                 }
1064         } else {
1065                 if (des_ctx->dc_flags & CBC_MODE) {
1066                         rv = cbc_encrypt_contiguous_blocks(ctx, data,
1067                             length, out, DES_BLOCK_LEN, des_encrypt_block,
1068                             des_copy_block, des_xor_block);
1069                 } else {
1070                         rv = ecb_cipher_contiguous_blocks(ctx, data, length,
1071                             out, DES_BLOCK_LEN, des_encrypt_block);
1072                 }
1073         }
1074         return (rv);
1075 }
1076 
1077 /*
1078  * Decrypt multiple blocks of data according to mode.
1079  */
1080 int
1081 des_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
1082     crypto_data_t *out)
1083 {
1084         des_ctx_t *des_ctx = ctx;
1085         int rv;
1086 
1087         if (des_ctx->dc_flags & DES3_STRENGTH) {
1088                 if (des_ctx->dc_flags & CBC_MODE) {
1089                         rv = cbc_decrypt_contiguous_blocks(ctx, data,
1090                             length, out, DES_BLOCK_LEN, des3_decrypt_block,
1091                             des_copy_block, des_xor_block);
1092                 } else {
1093                         rv = ecb_cipher_contiguous_blocks(ctx, data, length,
1094                             out, DES_BLOCK_LEN, des3_decrypt_block);
1095                         if (rv == CRYPTO_DATA_LEN_RANGE)
1096                                 rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
1097                 }
1098         } else {
1099                 if (des_ctx->dc_flags & CBC_MODE) {
1100                         rv = cbc_decrypt_contiguous_blocks(ctx, data,
1101                             length, out, DES_BLOCK_LEN, des_decrypt_block,
1102                             des_copy_block, des_xor_block);
1103                 } else {
1104                         rv = ecb_cipher_contiguous_blocks(ctx, data, length,
1105                             out, DES_BLOCK_LEN, des_decrypt_block);
1106                         if (rv == CRYPTO_DATA_LEN_RANGE)
1107                                 rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
1108                 }
1109         }
1110         return (rv);
1111 }


   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 2009 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 #include <sys/types.h>
  30 #include <sys/systm.h>
  31 #include <sys/ddi.h>
  32 #include <sys/sysmacros.h>
  33 #include <sys/strsun.h>
  34 #include <sys/crypto/spi.h>
  35 #include <modes/modes.h>
  36 #include <sys/crypto/common.h>
  37 #include "des_impl.h"
  38 #ifndef _KERNEL
  39 #include <strings.h>
  40 #include <stdlib.h>
  41 #endif  /* !_KERNEL */
  42 
  43 #if defined(__i386) || defined(__amd64)
  44 #include <sys/byteorder.h>
  45 #define UNALIGNED_POINTERS_PERMITTED
  46 #endif
  47 


 972         return (keysched);
 973 }
 974 
 975 /*
 976  * Replace the LSB of each byte by the xor of the other
 977  * 7 bits.  The tricky thing is that the original contents of the LSBs
 978  * are nullified by including them twice in the xor computation.
 979  */
 980 static void
 981 fix_des_parity(uint64_t *keyp)
 982 {
 983         uint64_t k = *keyp;
 984         k ^= k >> 1;
 985         k ^= k >> 2;
 986         k ^= k >> 4;
 987         *keyp ^= (k & 0x0101010101010101ULL);
 988         *keyp ^= 0x0101010101010101ULL;
 989 }
 990 
 991 void
 992 des_copy_block(const uint8_t *in, uint8_t *out)
 993 {
 994         if (IS_P2ALIGNED(in, sizeof (uint32_t)) &&
 995             IS_P2ALIGNED(out, sizeof (uint32_t))) {
 996                 /* LINTED: pointer alignment */
 997                 *(uint32_t *)&out[0] = *(uint32_t *)&in[0];
 998                 /* LINTED: pointer alignment */
 999                 *(uint32_t *)&out[4] = *(uint32_t *)&in[4];
1000         } else {
1001                 DES_COPY_BLOCK(in, out);
1002         }
1003 }
1004 
1005 /* XOR block of data into dest */
1006 void
1007 des_xor_block(const uint8_t *data, uint8_t *dst)
1008 {
1009         if (IS_P2ALIGNED(dst, sizeof (uint32_t)) &&
1010             IS_P2ALIGNED(data, sizeof (uint32_t))) {
1011                 /* LINTED: pointer alignment */
1012                 *(uint32_t *)&dst[0] ^=
1013                     /* LINTED: pointer alignment */
1014                     *(uint32_t *)&data[0];
1015                     /* LINTED: pointer alignment */
1016                 *(uint32_t *)&dst[4] ^=
1017                     /* LINTED: pointer alignment */
1018                     *(uint32_t *)&data[4];
1019         } else {
1020                 DES_XOR_BLOCK(data, dst);
1021         }
1022 }
1023 
1024 int
1025 des_encrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
1026 {
1027         return (des_crunch_block(keysched, in, out, B_FALSE));


1042 int
1043 des3_decrypt_block(const void *keysched, const uint8_t *in, uint8_t *out)
1044 {
1045         return (des3_crunch_block(keysched, in, out, B_TRUE));
1046 }
1047 
1048 /*
1049  * Encrypt multiple blocks of data according to mode.
1050  */
1051 int
1052 des_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
1053     crypto_data_t *out)
1054 {
1055         des_ctx_t *des_ctx = ctx;
1056         int rv;
1057 
1058         if (des_ctx->dc_flags & DES3_STRENGTH) {
1059                 if (des_ctx->dc_flags & CBC_MODE) {
1060                         rv = cbc_encrypt_contiguous_blocks(ctx, data,
1061                             length, out, DES_BLOCK_LEN, des3_encrypt_block,
1062                             des_copy_block, des_xor_block, NULL);
1063                 } else {
1064                         rv = ecb_cipher_contiguous_blocks(ctx, data, length,
1065                             out, DES_BLOCK_LEN, des3_encrypt_block, NULL);
1066                 }
1067         } else {
1068                 if (des_ctx->dc_flags & CBC_MODE) {
1069                         rv = cbc_encrypt_contiguous_blocks(ctx, data,
1070                             length, out, DES_BLOCK_LEN, des_encrypt_block,
1071                             des_copy_block, des_xor_block, NULL);
1072                 } else {
1073                         rv = ecb_cipher_contiguous_blocks(ctx, data, length,
1074                             out, DES_BLOCK_LEN, des_encrypt_block, NULL);
1075                 }
1076         }
1077         return (rv);
1078 }
1079 
1080 /*
1081  * Decrypt multiple blocks of data according to mode.
1082  */
1083 int
1084 des_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
1085     crypto_data_t *out)
1086 {
1087         des_ctx_t *des_ctx = ctx;
1088         int rv;
1089 
1090         if (des_ctx->dc_flags & DES3_STRENGTH) {
1091                 if (des_ctx->dc_flags & CBC_MODE) {
1092                         rv = cbc_decrypt_contiguous_blocks(ctx, data,
1093                             length, out, DES_BLOCK_LEN, des3_decrypt_block,
1094                             des_copy_block, des_xor_block, NULL, NULL);
1095                 } else {
1096                         rv = ecb_cipher_contiguous_blocks(ctx, data, length,
1097                             out, DES_BLOCK_LEN, des3_decrypt_block, NULL);
1098                         if (rv == CRYPTO_DATA_LEN_RANGE)
1099                                 rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
1100                 }
1101         } else {
1102                 if (des_ctx->dc_flags & CBC_MODE) {
1103                         rv = cbc_decrypt_contiguous_blocks(ctx, data,
1104                             length, out, DES_BLOCK_LEN, des_decrypt_block,
1105                             des_copy_block, des_xor_block, NULL, NULL);
1106                 } else {
1107                         rv = ecb_cipher_contiguous_blocks(ctx, data, length,
1108                             out, DES_BLOCK_LEN, des_decrypt_block, NULL);
1109                         if (rv == CRYPTO_DATA_LEN_RANGE)
1110                                 rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
1111                 }
1112         }
1113         return (rv);
1114 }