Print this page
5072963 Need an optimized AES implementation for amd64

Split Close
Expand all
Collapse all
          --- old/usr/src/common/crypto/aes/aes_impl.c
          +++ new/usr/src/common/crypto/aes/aes_impl.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5      - * Common Development and Distribution License, Version 1.0 only
   6      - * (the "License").  You may not use this file except in compliance
   7      - * with the License.
        5 + * Common Development and Distribution License (the "License").
        6 + * You may not use this file except in compliance with the License.
   8    7   *
   9    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10    9   * or http://www.opensolaris.org/os/licensing.
  11   10   * See the License for the specific language governing permissions
  12   11   * and limitations under the License.
  13   12   *
  14   13   * When distributing Covered Code, include this CDDL HEADER in each
  15   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16   15   * If applicable, add the following below this CDDL HEADER, with the
  17   16   * fields enclosed by brackets "[]" replaced with your own identifying
  18   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  19   18   *
  20   19   * CDDL HEADER END
  21   20   */
  22   21  /*
  23      - * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
       22 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24   23   * Use is subject to license terms.
  25   24   */
  26   25  
       26 +#pragma ident   "@(#)aes_impl.c 1.3     08/06/12 SMI"
       27 +
  27   28  #include <sys/types.h>
  28   29  #include <sys/systm.h>
  29   30  #include <sys/ddi.h>
  30   31  #include <sys/sysmacros.h>
  31   32  #include <sys/strsun.h>
  32   33  #include <netinet/in.h>
  33   34  #include "aes_impl.h"
  34   35  #ifndef _KERNEL
  35   36  #include <strings.h>
  36   37  #include <stdlib.h>
  37   38  #endif  /* !_KERNEL */
  38   39  
  39      -#pragma ident   "@(#)aes_impl.c 1.2     05/06/08 SMI"
  40   40  
  41   41  /*
  42   42   * This file is derived from the file  rijndael-alg-fst.c  taken from the
  43   43   * "optimized C code v3.0" on the "rijndael home page"
  44      - * (http://www.esat.kuleuven.ac.be/~rijmen/rijndael/)
  45      - * pointed by the NIST web-site (http://nist.gov)
       44 + * http://www.iaik.tu-graz.ac.at/research/krypto/AES/old/~rijmen/rijndael/
       45 + * pointed by the NIST web-site http://csrc.nist.gov/archive/aes/
  46   46   *
  47   47   * The following note is from the original file:
  48   48   */
  49   49  
  50   50  /*
  51   51   * rijndael-alg-fst.c
  52   52   *
  53   53   * @version 3.0 (December 2000)
  54   54   *
  55   55   * Optimised ANSI C code for the Rijndael cipher (now AES)
↓ open down ↓ 12 lines elided ↑ open up ↑
  68   68   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  69   69   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  70   70   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  71   71   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  72   72   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  73   73   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  74   74   */
  75   75  
  76   76  /* EXPORT DELETE START */
  77   77  
  78      -#ifndef _RIJNDAEL_TBL_H
  79      -#define _RIJNDAEL_TBL_H
       78 +#if defined(sun4u) || defined(__amd64)
       79 +/* External assembly functions: */
       80 +extern void aes_encrypt_impl(const uint32_t rk[], int Nr, const uint32_t pt[4],
       81 +        uint32_t ct[4]);
       82 +extern void aes_decrypt_impl(const uint32_t rk[], int Nr, const uint32_t ct[4],
       83 +        uint32_t pt[4]);
       84 +#define AES_ENCRYPT_IMPL                aes_encrypt_impl
       85 +#define AES_DECRYPT_IMPL                aes_decrypt_impl
  80   86  
       87 +#ifdef  __amd64
       88 +extern int rijndael_key_setup_enc(uint32_t rk[], const uint32_t cipherKey[],
       89 +        int keyBits);
       90 +extern int rijndael_key_setup_dec(uint32_t rk[], const uint32_t cipherKey[],
       91 +        int keyBits);
       92 +#endif
       93 +
       94 +#else
       95 +#define AES_ENCRYPT_IMPL                rijndael_encrypt
       96 +#define AES_DECRYPT_IMPL                rijndael_decrypt
       97 +#define rijndael_key_setup_enc_raw      rijndael_key_setup_enc
       98 +#endif  /* sun4u || __amd64 */
       99 +
      100 +#if defined(_LITTLE_ENDIAN) && !defined(__amd64)
      101 +#define AES_BYTE_SWAP
      102 +#endif
      103 +
      104 +#ifndef __amd64
  81  105  /*
  82  106   *  Constant tables
  83  107   */
  84  108  
  85  109  /*
  86  110   * Te0[x] = S [x].[02, 01, 01, 03];
  87  111   * Te1[x] = S [x].[03, 02, 01, 01];
  88  112   * Te2[x] = S [x].[01, 03, 02, 01];
  89  113   * Te3[x] = S [x].[01, 01, 03, 02];
  90  114   * Te4[x] = S [x].[01, 01, 01, 01];
  91  115   *
  92  116   * Td0[x] = Si[x].[0e, 09, 0d, 0b];
  93  117   * Td1[x] = Si[x].[0b, 0e, 09, 0d];
  94  118   * Td2[x] = Si[x].[0d, 0b, 0e, 09];
  95  119   * Td3[x] = Si[x].[09, 0d, 0b, 0e];
  96  120   * Td4[x] = Si[x].[01, 01, 01, 01];
  97  121   */
  98  122  
      123 +/* Encrypt Sbox constants (for the substitute bytes operation) */
  99  124  
 100  125  static const uint32_t Te0[256] =
 101  126  {
 102  127          0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
 103  128          0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
 104  129          0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
 105  130          0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
 106  131          0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
 107  132          0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
 108  133          0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
↓ open down ↓ 324 lines elided ↑ open up ↑
 433  458          0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
 434  459          0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
 435  460          0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
 436  461          0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
 437  462          0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
 438  463          0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
 439  464          0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
 440  465          0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U
 441  466  };
 442  467  
      468 +/* Decrypt Sbox constants (for the substitute bytes operation) */
      469 +
 443  470  static const uint32_t Td0[256] =
 444  471  {
 445  472          0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
 446  473          0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
 447  474          0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
 448  475          0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
 449  476          0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
 450  477          0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
 451  478          0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
 452  479          0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
↓ open down ↓ 321 lines elided ↑ open up ↑
 774  801          0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
 775  802          0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
 776  803          0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
 777  804          0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
 778  805          0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
 779  806          0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
 780  807          0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
 781  808          0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU
 782  809  };
 783  810  
 784      -static const uint32_t rcon[] =
      811 +/* Rcon is Round Constant; used for encryption key expansion */
      812 +static const uint32_t rcon[RC_LENGTH] =
 785  813  {
 786  814          /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
 787  815          0x01000000, 0x02000000, 0x04000000, 0x08000000,
 788  816          0x10000000, 0x20000000, 0x40000000, 0x80000000,
 789  817          0x1B000000, 0x36000000
 790  818  };
 791      -#endif
 792  819  
      820 +
 793  821  /*
 794      - *  Expand the cipher key into the encryption key schedule.
 795      - *  return  the number of rounds for the given cipher key size.
 796      - *  The size of the key schedule depends on the number of rounds
 797      - *  (which can be computed from the size of the key), i.e. 4*(Nr + 1).
      822 + * Expand the cipher key into the encryption key schedule.
      823 + *
      824 + * Return the number of rounds for the given cipher key size.
      825 + * The size of the key schedule depends on the number of rounds
      826 + * (which can be computed from the size of the key), i.e. 4*(Nr + 1).
      827 + *
      828 + * Parameters:
      829 + * rk           AES key schedule 32-bit array to be initialized
      830 + * cipherKey    User key
      831 + * keyBits      AES key size (128, 192, or 256 bits)
 798  832   */
 799  833  static int
 800  834  rijndael_key_setup_enc_raw(uint32_t rk[], const uint32_t cipherKey[],
 801  835      int keyBits)
 802  836  {
 803  837          int             i = 0;
 804  838          uint32_t        temp;
 805  839  
 806  840          rk[0] = cipherKey[0];
 807  841          rk[1] = cipherKey[1];
↓ open down ↓ 74 lines elided ↑ open up ↑
 882  916                          rk[13] = rk[5] ^ rk[12];
 883  917                          rk[14] = rk[6] ^ rk[13];
 884  918                          rk[15] = rk[7] ^ rk[14];
 885  919  
 886  920                          rk += 8;
 887  921                  }
 888  922          }
 889  923  
 890  924          return (0);
 891  925  }
      926 +#endif  /* !__amd64 */
 892  927  
 893  928  
 894      -#ifdef sun4u
      929 +#ifdef  sun4u
 895  930  
 896  931  /*
 897      - *  Expand the cipher key into the enryption key schedule as used
 898      - *  by the sun4u optimized assembly implementation.
 899      - *  return  the number of rounds for the given cipher key size.
 900      - *  The size of the key schedule depends on the number of rounds
 901      - *  (which can be computed from the size of the key), i.e. 4*(Nr + 1).
      932 + * Expand the cipher key into the encryption key schedule.
      933 + * by the sun4u optimized assembly implementation.
      934 + *
      935 + * Return the number of rounds for the given cipher key size.
      936 + * The size of the key schedule depends on the number of rounds
      937 + * (which can be computed from the size of the key), i.e. 4*(Nr + 1).
      938 + *
      939 + * Parameters:
      940 + * rk           AES key schedule 64-bit array to be initialized
      941 + * cipherKey    User key
      942 + * keyBits      AES key size (128, 192, or 256 bits)
 902  943   */
 903  944  static int
 904  945  rijndael_key_setup_enc(uint64_t rk[], const uint32_t cipherKey[], int keyBits)
 905  946  {
 906  947          uint32_t        rk1[4 * (MAX_AES_NR + 1)];
 907  948          uint64_t        *rk64 = (uint64_t *)rk;
 908  949          uint32_t        *rkt;
 909  950          uint64_t        t;
 910  951          int             i, Nr;
 911  952  
↓ open down ↓ 10 lines elided ↑ open up ↑
 922  963  
 923  964          for (i = 0; i < 4; i++) {
 924  965                  rkt[i] = rk1[4 * Nr+i];
 925  966          }
 926  967  
 927  968          return (Nr);
 928  969  }
 929  970  
 930  971  
 931  972  /*
 932      - *  Expand the cipher key into the decryption key schedule as used
 933      - *  by the sun4u optimized assembly implementation.
 934      - *  return  the number of rounds for the given cipher key size.
 935      - *  The size of the key schedule depends on the number of rounds
 936      - *  (which can be computed from the size of the key), i.e. 4*(Nr + 1).
      973 + * Expand the cipher key into the decryption key schedule as used
      974 + * by the sun4u optimized assembly implementation.
      975 + *
      976 + * Return the number of rounds for the given cipher key size.
      977 + * The size of the key schedule depends on the number of rounds
      978 + * (which can be computed from the size of the key), i.e. 4*(Nr + 1).
      979 + *
      980 + * Parameters:
      981 + * rk           AES key schedule 32-bit array to be initialized
      982 + * cipherKey    User key
      983 + * keyBits      AES key size (128, 192, or 256 bits)
 937  984   */
 938  985  static int
 939  986  rijndael_key_setup_dec_raw(uint32_t rk[], const uint32_t cipherKey[],
 940  987      int keyBits)
 941  988  {
 942  989          int             Nr, i;
 943  990          uint32_t        temp;
 944  991  
 945  992          /* expand the cipher key: */
 946  993          Nr = rijndael_key_setup_enc_raw(rk, cipherKey, keyBits);
↓ open down ↓ 28 lines elided ↑ open up ↑
 975 1022                      Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
 976 1023                      Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
 977 1024                      Td3[Te4[rk[3] & 0xff] & 0xff];
 978 1025          }
 979 1026  
 980 1027          return (Nr);
 981 1028  }
 982 1029  
 983 1030  
 984 1031  /*
 985      - *  The size of the key schedule depends on the number of rounds
 986      - *  (which can be computed from the size of the key), i.e. 4*(Nr + 1).
     1032 + * The size of the key schedule depends on the number of rounds
     1033 + * (which can be computed from the size of the key), i.e. 4*(Nr + 1).
     1034 + *
     1035 + * Parameters:
     1036 + * rk           AES key schedule 64-bit array to be initialized
     1037 + * cipherKey    User key
     1038 + * keyBits      AES key size (128, 192, or 256 bits)
 987 1039   */
 988      -int
     1040 +static int
 989 1041  rijndael_key_setup_dec(uint64_t rk[], const uint32_t cipherKey[], int keyBits)
 990 1042  {
 991 1043          uint32_t        rk1[4 * (MAX_AES_NR + 1)];
 992 1044          uint64_t        *rk64 = (uint64_t *)rk;
 993 1045          uint32_t        *rkt;
 994 1046          uint64_t        t;
 995 1047          int             i, Nr;
 996 1048  
 997 1049          Nr = rijndael_key_setup_dec_raw(rk1, cipherKey, keyBits);
 998 1050          for (i = 0; i < 4 * Nr; i++) {
↓ open down ↓ 6 lines elided ↑ open up ↑
1005 1057          rkt = (uint32_t *)(&(rk64[4 * Nr]));
1006 1058  
1007 1059          for (i = 0; i < 4; i++) {
1008 1060                  rkt[i] = rk1[4 * Nr + i];
1009 1061          }
1010 1062  
1011 1063          return (Nr);
1012 1064  }
1013 1065  
1014 1066  
     1067 +/*
     1068 + * Expand the 64-bit AES cipher key array into the encryption and decryption
     1069 + * key schedules.
     1070 + *
     1071 + * Parameters:
     1072 + * key          AES key schedule to be initialized
     1073 + * keyarr32     User key
     1074 + * keyBits      AES key size (128, 192, or 256 bits)
     1075 + */
1015 1076  static void
1016      -aes_setupkeys(aes_key_t *key, uint32_t *keyarr32, int keybits)
     1077 +aes_setupkeys(aes_key_t *key, const uint32_t *keyarr32, int keybits)
1017 1078  {
1018 1079          key->nr = rijndael_key_setup_enc(&(key->encr_ks.ks64[0]), keyarr32,
1019 1080              keybits);
1020 1081          key->nr = rijndael_key_setup_dec(&(key->decr_ks.ks64[0]), keyarr32,
1021 1082              keybits);
1022 1083          key->type = AES_64BIT_KS;
1023 1084  }
1024 1085  
1025      -#else /* !sun4u */
1026 1086  
1027      -/*
1028      - *  Expand the cipher key into the encryption key schedule.
1029      - *  return  the number of rounds for the given cipher key size.
1030      - *  The size of the key schedule depends on the number of rounds
1031      - *  (which can be computed from the size of the key), i.e. 4*(Nr + 1).
1032      - */
1033      -static int
1034      -rijndael_key_setup_enc(uint32_t rk[], const uint32_t cipherKey[], int keyBits)
1035      -{
1036      -        return (rijndael_key_setup_enc_raw(rk, cipherKey, keyBits));
1037      -}
     1087 +#elif !defined(__amd64)
1038 1088  
1039      -
1040 1089  /*
1041 1090   *  Expand the cipher key into the decryption key schedule.
1042      - *  @return  the number of rounds for the given cipher key size.
     1091 + *  Return the number of rounds for the given cipher key size.
1043 1092   *  The size of the key schedule depends on the number of rounds
1044 1093   *  (which can be computed from the size of the key), i.e. 4*(Nr + 1).
     1094 + *
     1095 + * Parameters:
     1096 + * rk           AES key schedule 32-bit array to be initialized
     1097 + * cipherKey    User key
     1098 + * keyBits      AES key size (128, 192, or 256 bits)
1045 1099   */
1046 1100  static int
1047 1101  rijndael_key_setup_dec(uint32_t rk[], const uint32_t cipherKey[], int keyBits)
1048 1102  {
1049 1103          int      Nr, i, j;
1050 1104          uint32_t temp;
1051 1105  
1052 1106          /* expand the cipher key: */
1053 1107          Nr = rijndael_key_setup_enc_raw(rk, cipherKey, keyBits);
1054 1108  
↓ open down ↓ 34 lines elided ↑ open up ↑
1089 1143                  rk[3] = Td0[Te4[rk[3] >> 24] & 0xff] ^
1090 1144                      Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
1091 1145                      Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
1092 1146                      Td3[Te4[rk[3] & 0xff] & 0xff];
1093 1147          }
1094 1148  
1095 1149          return (Nr);
1096 1150  }
1097 1151  
1098 1152  
1099      -static void
1100      -aes_setupkeys(aes_key_t *key, uint32_t *keyarr32, int keybits)
1101      -{
1102      -        key->nr = rijndael_key_setup_enc(&(key->encr_ks.ks32[0]), keyarr32,
1103      -            keybits);
1104      -        key->nr = rijndael_key_setup_dec(&(key->decr_ks.ks32[0]), keyarr32,
1105      -            keybits);
1106      -        key->type = AES_32BIT_KS;
1107      -}
1108      -
1109 1153  /*
1110 1154   * Encrypt one block of data. The block is assumed to be an array
1111 1155   * of four uint32_t values, so copy for alignment (and byte-order
1112 1156   * reversal for little endian systems might be necessary on the
1113 1157   * input and output byte streams.
1114 1158   * The size of the key schedule depends on the number of rounds
1115 1159   * (which can be computed from the size of the key), i.e. 4*(Nr + 1).
     1160 + *
     1161 + * Parameters:
     1162 + * rk   Key schedule, of aes_ks_t (60 32-bit integers)
     1163 + * Nr   Number of rounds
     1164 + * pt   Input block (plain text)
     1165 + * ct   Output block (crypto text).  Can overlap with pt
1116 1166   */
1117      -void
     1167 +static void
1118 1168  rijndael_encrypt(const uint32_t rk[], int Nr, const uint32_t pt[4],
1119 1169      uint32_t ct[4])
1120 1170  {
1121 1171          uint32_t        s0, s1, s2, s3, t0, t1, t2, t3;
1122 1172          int             r;
1123 1173  
1124 1174          /*
1125 1175           * map byte array block to cipher state
1126 1176           * and add initial round key:
1127 1177           */
↓ open down ↓ 100 lines elided ↑ open up ↑
1228 1278  }
1229 1279  
1230 1280  
1231 1281  /*
1232 1282   * Decrypt one block of data. The block is assumed to be an array
1233 1283   * of four uint32_t values, so copy for alignment (and byte-order
1234 1284   * reversal for little endian systems might be necessary on the
1235 1285   * input and output byte streams.
1236 1286   * The size of the key schedule depends on the number of rounds
1237 1287   * (which can be computed from the size of the key), i.e. 4*(Nr + 1).
     1288 + *
     1289 + * Parameters:
     1290 + * rk   Key schedule, of aes_ks_t (60 32-bit integers)
     1291 + * Nr   Number of rounds
     1292 + * ct   Input block (crypto text)
     1293 + * pt   Output block (plain text). Can overlap with pt
1238 1294   */
1239      -void
     1295 +static void
1240 1296  rijndael_decrypt(const uint32_t rk[], int Nr, const uint32_t ct[4],
1241 1297      uint32_t pt[4])
1242 1298  {
1243 1299          uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
1244 1300          int      r;
1245 1301  
1246 1302          /*
1247 1303           * map byte array block to cipher state
1248 1304           * and add initial round key:
1249 1305           */
↓ open down ↓ 90 lines elided ↑ open up ↑
1340 1396              rk[2];
1341 1397          pt[2] = s2;
1342 1398  
1343 1399          s3 = (Td4[t3 >> 24] & 0xff000000) ^
1344 1400              (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
1345 1401              (Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
1346 1402              (Td4[t0 & 0xff] & 0x000000ff) ^
1347 1403              rk[3];
1348 1404          pt[3] = s3;
1349 1405  }
     1406 +#endif  /* sun4u, !__amd64 */
1350 1407  
1351      -void
1352      -aes_encrypt_impl(const aes_ks_t *ks, int Nr, const uint32_t pt[4],
1353      -    uint32_t ct[4])
     1408 +#ifndef sun4u
     1409 +/*
     1410 + * Expand the 32-bit AES cipher key array into the encryption and decryption
     1411 + * key schedules.
     1412 + *
     1413 + * Parameters:
     1414 + * key          AES key schedule to be initialized
     1415 + * keyarr32     User key
     1416 + * keyBits      AES key size (128, 192, or 256 bits)
     1417 + */
     1418 +static void
     1419 +aes_setupkeys(aes_key_t *key, const uint32_t *keyarr32, int keybits)
1354 1420  {
1355      -        rijndael_encrypt(&(ks->ks32[0]), Nr, pt, ct);
     1421 +        key->nr = rijndael_key_setup_enc(&(key->encr_ks.ks32[0]), keyarr32,
     1422 +            keybits);
     1423 +        key->nr = rijndael_key_setup_dec(&(key->decr_ks.ks32[0]), keyarr32,
     1424 +            keybits);
     1425 +        key->type = AES_32BIT_KS;
1356 1426  }
1357      -
1358      -void
1359      -aes_decrypt_impl(const aes_ks_t *ks, int Nr, const uint32_t ct[4],
1360      -    uint32_t pt[4])
1361      -{
1362      -        rijndael_decrypt(&(ks->ks32[0]), Nr, ct, pt);
1363      -}
1364      -
1365      -#endif /* sun4u */
     1427 +#endif  /* sun4u */
1366 1428  /* EXPORT DELETE END */
1367 1429  
1368 1430  
1369 1431  /*
1370 1432   * Initialize key schedules for AES
     1433 + *
     1434 + * Parameters:
     1435 + * cipherKey    User key
     1436 + * keyBits      AES key size (128, 192, or 256 bits)
     1437 + * keysched     AES key schedule to be initialized, of type aes_key_t.
     1438 + *              Allocated by aes_alloc_keysched().
1371 1439   */
1372 1440  void
1373      -aes_init_keysched(uint8_t *cipherKey, uint_t keyBits, void *keysched)
     1441 +aes_init_keysched(const uint8_t *cipherKey, uint_t keyBits, void *keysched)
1374 1442  {
1375 1443  /* EXPORT DELETE START */
1376      -        aes_key_t *newbie = keysched;
1377      -        uint64_t keyarr64[4];
1378      -        uint32_t *keyarr32 = (uint32_t *)keyarr64;
1379      -        uint_t keysize, i, j;
     1444 +        aes_key_t       *newbie = keysched;
     1445 +        uint_t          keysize, i, j;
     1446 +        union {
     1447 +                uint64_t        ka64[4];
     1448 +                uint32_t        ka32[8];
     1449 +                } keyarr;
1380 1450  
1381 1451          switch (keyBits) {
1382 1452          case 128:
1383 1453                  newbie->nr = 10;
1384 1454                  break;
1385 1455  
1386 1456          case 192:
1387 1457                  newbie->nr = 12;
1388 1458                  break;
1389 1459  
↓ open down ↓ 1 lines elided ↑ open up ↑
1391 1461                  newbie->nr = 14;
1392 1462                  break;
1393 1463  
1394 1464          default:
1395 1465                  /* should never get here */
1396 1466                  return;
1397 1467          }
1398 1468          keysize = keyBits >> 3;
1399 1469  
1400 1470          /*
1401      -         * The code below, that is always executed on LITTLE_ENDIAN machines,
1402      -         * reverses every 4 bytes in the key.  On BIG_ENDIAN, the same code
1403      -         * copies the key without reversing bytes.
     1471 +         * For _LITTLE_ENDIAN machines (except AMD64), reverse every
     1472 +         * 4 bytes in the key.  On _BIG_ENDIAN and AMD64, copy the key
     1473 +         * without reversing bytes.
     1474 +         * For AMD64, do not byte swap for aes_setupkeys().
     1475 +         *
     1476 +         * SPARCv8/v9 uses a key schedule array with 64-bit elements.
     1477 +         * X86/AMD64  uses a key schedule array with 32-bit elements.
1404 1478           */
1405      -#ifdef _BIG_ENDIAN
     1479 +#ifndef AES_BYTE_SWAP
1406 1480          if (IS_P2ALIGNED(cipherKey, sizeof (uint64_t))) {
1407 1481                  for (i = 0, j = 0; j < keysize; i++, j += 8) {
1408 1482                          /* LINTED: pointer alignment */
1409      -                        keyarr64[i] = *((uint64_t *)&cipherKey[j]);
     1483 +                        keyarr.ka64[i] = *((uint64_t *)&cipherKey[j]);
1410 1484                  }
1411 1485          } else {
1412      -#endif
1413      -                for (i = 0, j = 0; j < keysize; i++, j += 4) {
1414      -                        keyarr32[i] = (((uint32_t)cipherKey[j] << 24) |
1415      -                            ((uint32_t)cipherKey[j + 1] << 16) |
1416      -                            ((uint32_t)cipherKey[j + 2] << 8) |
1417      -                            (uint32_t)cipherKey[j + 3]);
1418      -                }
1419      -#ifdef _BIG_ENDIAN
     1486 +                bcopy(cipherKey, keyarr.ka32, keysize);
1420 1487          }
     1488 +
     1489 +#else   /* byte swap */
     1490 +        for (i = 0, j = 0; j < keysize; i++, j += 4) {
     1491 +                keyarr.ka32[i] = (((uint32_t)cipherKey[j] << 24) |
     1492 +                    ((uint32_t)cipherKey[j + 1] << 16) |
     1493 +                    ((uint32_t)cipherKey[j + 2] << 8) |
     1494 +                    (uint32_t)cipherKey[j + 3]);
     1495 +        }
1421 1496  #endif
1422      -        aes_setupkeys(newbie, keyarr32, keyBits);
1423 1497  
     1498 +        aes_setupkeys(newbie, keyarr.ka32, keyBits);
1424 1499  /* EXPORT DELETE END */
1425 1500  }
1426 1501  
     1502 +
     1503 +/*
     1504 + * Encrypt one block using AES.
     1505 + * Align if needed and (for x86 32-bit only) byte-swap.
     1506 + *
     1507 + * Parameters:
     1508 + * ks   Key schedule, of type aes_key_t
     1509 + * pt   Input block (plain text)
     1510 + * ct   Output block (crypto text).  Can overlap with pt
     1511 + */
1427 1512  void
1428      -aes_encrypt_block(void *ks, uint8_t *pt, uint8_t *ct)
     1513 +aes_encrypt_block(const void *ks, const uint8_t *pt, uint8_t *ct)
1429 1514  {
1430 1515  /* EXPORT DELETE START */
     1516 +        aes_key_t       *ksch = (aes_key_t *)ks;
1431 1517  
1432      -        aes_key_t *ksch = (aes_key_t *)ks;
1433      -
1434      -#ifdef _BIG_ENDIAN
1435      -        if (IS_P2ALIGNED(pt, sizeof (uint32_t)) &&
1436      -            IS_P2ALIGNED(ct, sizeof (uint32_t))) {
1437      -                /* LINTED:  pointer alignment */
1438      -                aes_encrypt_impl(&ksch->encr_ks, ksch->nr, (uint32_t *)pt,
     1518 +#ifndef AES_BYTE_SWAP
     1519 +        if (IS_P2ALIGNED2(pt, ct, sizeof (uint32_t))) {
     1520 +                AES_ENCRYPT_IMPL(&ksch->encr_ks.ks32[0], ksch->nr,
1439 1521                      /* LINTED:  pointer alignment */
1440      -                    (uint32_t *)ct);
     1522 +                    (uint32_t *)pt, (uint32_t *)ct);
1441 1523          } else {
1442 1524  #endif
1443 1525                  uint32_t buffer[AES_BLOCK_LEN / sizeof (uint32_t)];
1444 1526  
     1527 +                /* Copy input block into buffer */
     1528 +#ifndef AES_BYTE_SWAP
     1529 +                bcopy(pt, &buffer, AES_BLOCK_LEN);
     1530 +
     1531 +#else   /* byte swap */
1445 1532                  buffer[0] = (((uint32_t)pt[0] << 24) | ((uint32_t)pt[1] << 16) |
1446 1533                      ((uint32_t)pt[2] << 8) | (uint32_t)pt[3]);
1447      -
1448 1534                  buffer[1] = (((uint32_t)pt[4] << 24) | ((uint32_t)pt[5] << 16) |
1449 1535                      ((uint32_t)pt[6] << 8) | (uint32_t)pt[7]);
1450      -
1451 1536                  buffer[2] = (((uint32_t)pt[8] << 24) | ((uint32_t)pt[9] << 16) |
1452 1537                      ((uint32_t)pt[10] << 8) | (uint32_t)pt[11]);
1453      -
1454 1538                  buffer[3] = (((uint32_t)pt[12] << 24) |
1455 1539                      ((uint32_t)pt[13] << 16) | ((uint32_t)pt[14] << 8) |
1456 1540                      (uint32_t)pt[15]);
     1541 +#endif
1457 1542  
1458      -                aes_encrypt_impl(&ksch->encr_ks, ksch->nr, buffer, buffer);
     1543 +                AES_ENCRYPT_IMPL(&ksch->encr_ks.ks32[0], ksch->nr,
     1544 +                    buffer, buffer);
1459 1545  
     1546 +                /* Copy result from buffer to output block */
     1547 +#ifndef AES_BYTE_SWAP
     1548 +                bcopy(&buffer, ct, AES_BLOCK_LEN);
     1549 +        }
     1550 +
     1551 +#else   /* byte swap */
1460 1552                  ct[0] = buffer[0] >> 24;
1461 1553                  ct[1] = buffer[0] >> 16;
1462 1554                  ct[2] = buffer[0] >> 8;
1463 1555                  ct[3] = (uint8_t)buffer[0];
1464 1556                  ct[4] = buffer[1] >> 24;
1465 1557                  ct[5] = buffer[1] >> 16;
1466 1558                  ct[6] = buffer[1] >> 8;
1467 1559                  ct[7] = (uint8_t)buffer[1];
1468 1560                  ct[8] = buffer[2] >> 24;
1469 1561                  ct[9] = buffer[2] >> 16;
1470 1562                  ct[10] = buffer[2] >> 8;
1471 1563                  ct[11] = (uint8_t)buffer[2];
1472 1564                  ct[12] = buffer[3] >> 24;
1473 1565                  ct[13] = buffer[3] >> 16;
1474 1566                  ct[14] = buffer[3] >> 8;
1475 1567                  ct[15] = (uint8_t)buffer[3];
1476      -#ifdef _BIG_ENDIAN
1477      -        }
1478 1568  #endif
1479      -
1480 1569  /* EXPORT DELETE END */
1481 1570  }
1482 1571  
     1572 +
     1573 +/*
     1574 + * Decrypt one block using AES.
     1575 + * Align and byte-swap if needed.
     1576 + *
     1577 + * Parameters:
     1578 + * ks   Key schedule, of type aes_key_t
     1579 + * ct   Input block (crypto text)
     1580 + * pt   Output block (plain text). Can overlap with pt
     1581 + */
1483 1582  void
1484      -aes_decrypt_block(void *ks, uint8_t *ct, uint8_t *pt)
     1583 +aes_decrypt_block(const void *ks, const uint8_t *ct, uint8_t *pt)
1485 1584  {
1486 1585  /* EXPORT DELETE START */
     1586 +        aes_key_t       *ksch = (aes_key_t *)ks;
1487 1587  
1488      -        aes_key_t *ksch = (aes_key_t *)ks;
1489      -
1490      -#ifdef _BIG_ENDIAN
1491      -        if (IS_P2ALIGNED(ct, sizeof (uint32_t)) &&
1492      -            IS_P2ALIGNED(pt, sizeof (uint32_t))) {
1493      -                /* LINTED:  pointer alignment */
1494      -                aes_decrypt_impl(&ksch->decr_ks, ksch->nr, (uint32_t *)ct,
     1588 +#ifndef AES_BYTE_SWAP
     1589 +        if (IS_P2ALIGNED2(ct, pt, sizeof (uint32_t))) {
     1590 +                AES_DECRYPT_IMPL(&ksch->decr_ks.ks32[0], ksch->nr,
1495 1591                      /* LINTED:  pointer alignment */
1496      -                    (uint32_t *)pt);
     1592 +                    (uint32_t *)ct, (uint32_t *)pt);
1497 1593          } else {
1498 1594  #endif
1499 1595                  uint32_t buffer[AES_BLOCK_LEN / sizeof (uint32_t)];
1500 1596  
     1597 +                /* Copy input block into buffer */
     1598 +#ifndef AES_BYTE_SWAP
     1599 +                bcopy(ct, &buffer, AES_BLOCK_LEN);
     1600 +
     1601 +#else   /* byte swap */
1501 1602                  buffer[0] = (((uint32_t)ct[0] << 24) | ((uint32_t)ct[1] << 16) |
1502 1603                      ((uint32_t)ct[2] << 8) | (uint32_t)ct[3]);
1503 1604  
1504 1605                  buffer[1] = (((uint32_t)ct[4] << 24) | ((uint32_t)ct[5] << 16) |
1505 1606                      ((uint32_t)ct[6] << 8) | (uint32_t)ct[7]);
1506 1607  
1507 1608                  buffer[2] = (((uint32_t)ct[8] << 24) | ((uint32_t)ct[9] << 16) |
1508 1609                      ((uint32_t)ct[10] << 8) | (uint32_t)ct[11]);
1509 1610  
1510 1611                  buffer[3] = (((uint32_t)ct[12] << 24) |
1511 1612                      ((uint32_t)ct[13] << 16) | ((uint32_t)ct[14] << 8) |
1512 1613                      (uint32_t)ct[15]);
     1614 +#endif
1513 1615  
1514      -                aes_decrypt_impl(&ksch->decr_ks, ksch->nr, buffer, buffer);
     1616 +                AES_DECRYPT_IMPL(&ksch->decr_ks.ks32[0], ksch->nr,
     1617 +                    buffer, buffer);
1515 1618  
     1619 +                /* Copy result from buffer to output block */
     1620 +#ifndef AES_BYTE_SWAP
     1621 +                bcopy(&buffer, pt, AES_BLOCK_LEN);
     1622 +        }
     1623 +
     1624 +#else   /* byte swap */
1516 1625                  pt[0] = buffer[0] >> 24;
1517 1626                  pt[1] = buffer[0] >> 16;
1518 1627                  pt[2] = buffer[0] >> 8;
1519 1628                  pt[3] = (uint8_t)buffer[0];
1520 1629                  pt[4] = buffer[1] >> 24;
1521 1630                  pt[5] = buffer[1] >> 16;
1522 1631                  pt[6] = buffer[1] >> 8;
1523 1632                  pt[7] = (uint8_t)buffer[1];
1524 1633                  pt[8] = buffer[2] >> 24;
1525 1634                  pt[9] = buffer[2] >> 16;
1526 1635                  pt[10] = buffer[2] >> 8;
1527 1636                  pt[11] = (uint8_t)buffer[2];
1528 1637                  pt[12] = buffer[3] >> 24;
1529 1638                  pt[13] = buffer[3] >> 16;
1530 1639                  pt[14] = buffer[3] >> 8;
1531 1640                  pt[15] = (uint8_t)buffer[3];
1532      -#ifdef _BIG_ENDIAN
1533      -        }
1534 1641  #endif
1535 1642  
1536 1643  /* EXPORT DELETE END */
1537 1644  }
1538 1645  
     1646 +
1539 1647  /*
1540      - * Allocate key schedule for AES
     1648 + * Allocate key schedule for AES.
     1649 + *
     1650 + * Return the pointer and set size to the number of bytes allocated.
     1651 + * Memory allocated must be freed by the caller when done.
     1652 + *
     1653 + * Parameters:
     1654 + * size         Size of key schedule allocated, in bytes
     1655 + * kmflag       Flag passed to kmem_alloc(9F); ignored in userland.
1541 1656   */
1542 1657  /* ARGSUSED */
1543 1658  void *
1544 1659  aes_alloc_keysched(size_t *size, int kmflag)
1545 1660  {
1546      -
1547 1661  /* EXPORT DELETE START */
1548      -
1549 1662          aes_key_t *keysched;
1550 1663  
1551      -#ifdef  _KERNEL
     1664 +#ifdef  _KERNEL
1552 1665          keysched = (aes_key_t *)kmem_alloc(sizeof (aes_key_t), kmflag);
1553 1666  #else   /* !_KERNEL */
1554 1667          keysched = (aes_key_t *)malloc(sizeof (aes_key_t));
1555 1668  #endif  /* _KERNEL */
1556 1669  
1557 1670          if (keysched != NULL) {
1558 1671                  *size = sizeof (aes_key_t);
1559 1672                  return (keysched);
1560 1673          }
1561      -
1562 1674  /* EXPORT DELETE END */
1563      -
1564 1675          return (NULL);
1565 1676  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX