aes.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                              AAA   EEEEE  SSSSS                             %
00007 %                             A   A  E      SS                                %
00008 %                             AAAAA  EEE     SSS                              %
00009 %                             A   A  E         SS                             %
00010 %                             A   A  EEEEE  SSSSS                             %
00011 %                                                                             %
00012 %                                                                             %
00013 %         Wizard's Toolkit Advanced Encryption Standard Cipher Methods        %
00014 %                                                                             %
00015 %                               Software Design                               %
00016 %                                 John Cristy                                 %
00017 %                                 March 2003                                  %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.wizards-toolkit.org/script/license.php                        %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
00041 */
00042 #include "wizard/studio.h"
00043 #include "wizard/aes.h"
00044 #include "wizard/exception.h"
00045 #include "wizard/exception-private.h"
00046 #include "wizard/memory_.h"
00047 
00048 /*
00049   Typedef declarations.
00050 */
00051 struct _AESInfo
00052 {
00053   StringInfo
00054     *key;
00055 
00056   unsigned int
00057     blocksize,
00058     *encipher_key,
00059     *decipher_key;
00060 
00061   ssize_t
00062     rounds;
00063 
00064   time_t
00065     timestamp;
00066 
00067   size_t
00068     signature;
00069 };
00070 
00071 /*
00072   Define declarations.
00073 */
00074 #define AESBlocksize 16
00075 
00076 /*
00077   Global declarations.
00078 */
00079 static unsigned char
00080   InverseLog[256] =
00081   {
00082       1,   3,   5,  15,  17,  51,  85, 255,  26,  46, 114, 150, 161, 248,
00083      19,  53,  95, 225,  56,  72, 216, 115, 149, 164, 247,   2,   6,  10,
00084      30,  34, 102, 170, 229,  52,  92, 228,  55,  89, 235,  38, 106, 190,
00085     217, 112, 144, 171, 230,  49,  83, 245,   4,  12,  20,  60,  68, 204,
00086      79, 209, 104, 184, 211, 110, 178, 205,  76, 212, 103, 169, 224,  59,
00087      77, 215,  98, 166, 241,   8,  24,  40, 120, 136, 131, 158, 185, 208,
00088     107, 189, 220, 127, 129, 152, 179, 206,  73, 219, 118, 154, 181, 196,
00089      87, 249,  16,  48,  80, 240,  11,  29,  39, 105, 187, 214,  97, 163,
00090     254,  25,  43, 125, 135, 146, 173, 236,  47, 113, 147, 174, 233,  32,
00091      96, 160, 251,  22,  58,  78, 210, 109, 183, 194,  93, 231,  50,  86,
00092     250,  21,  63,  65, 195,  94, 226,  61,  71, 201,  64, 192,  91, 237,
00093      44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172, 239,  42, 126,
00094     130, 157, 188, 223, 122, 142, 137, 128, 155, 182, 193,  88, 232,  35,
00095     101, 175, 234,  37, 111, 177, 200,  67, 197,  84, 252,  31,  33,  99,
00096     165, 244,   7,   9,  27,  45, 119, 153, 176, 203,  70, 202,  69, 207,
00097      74, 222, 121, 139, 134, 145, 168, 227,  62,  66, 198,  81, 243,  14,
00098      18,  54,  90, 238,  41, 123, 141, 140, 143, 138, 133, 148, 167, 242,
00099      13,  23,  57,  75, 221, 124, 132, 151, 162, 253,  28,  36, 108, 180,
00100     199,  82, 246,   1
00101   },
00102   Log[256] =
00103   {
00104       0,   0,  25,   1,  50,   2,  26, 198,  75, 199,  27, 104,  51, 238,
00105     223,   3, 100,   4, 224,  14,  52, 141, 129, 239,  76, 113,   8, 200,
00106     248, 105,  28, 193, 125, 194,  29, 181, 249, 185,  39, 106,  77, 228,
00107     166, 114, 154, 201,   9, 120, 101,  47, 138,   5,  33,  15, 225,  36,
00108      18, 240, 130,  69,  53, 147, 218, 142, 150, 143, 219, 189,  54, 208,
00109     206, 148,  19,  92, 210, 241,  64,  70, 131,  56, 102, 221, 253,  48,
00110     191,   6, 139,  98, 179,  37, 226, 152,  34, 136, 145,  16, 126, 110,
00111      72, 195, 163, 182,  30,  66,  58, 107,  40,  84, 250, 133,  61, 186,
00112      43, 121,  10,  21, 155, 159,  94, 202,  78, 212, 172, 229, 243, 115,
00113     167,  87, 175,  88, 168,  80, 244, 234, 214, 116,  79, 174, 233, 213,
00114     231, 230, 173, 232,  44, 215, 117, 122, 235,  22,  11, 245,  89, 203,
00115      95, 176, 156, 169,  81, 160, 127,  12, 246, 111,  23, 196,  73, 236,
00116     216,  67,  31,  45, 164, 118, 123, 183, 204, 187,  62,  90, 251,  96,
00117     177, 134,  59,  82, 161, 108, 170,  85,  41, 157, 151, 178, 135, 144,
00118      97, 190, 220, 252, 188, 149, 207, 205,  55,  63,  91, 209,  83,  57,
00119     132, 60,   65, 162, 109,  71,  20,  42, 158,  93,  86, 242, 211, 171,
00120      68,  17, 146, 217,  35,  32,  46, 137, 180, 124, 184,  38, 119, 153,
00121     227, 165, 103,  74, 237, 222, 197,  49, 254,  24,  13,  99, 140, 128,
00122     192, 247, 112,   7,
00123   },
00124   SBox[256] =
00125   {
00126      99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215,
00127     171, 118, 202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175,
00128     156, 164, 114, 192, 183, 253, 147,  38,  54,  63, 247, 204,  52, 165,
00129     229, 241, 113, 216,  49,  21,   4, 199,  35, 195,  24, 150,   5, 154,
00130       7,  18, 128, 226, 235,  39, 178, 117,   9, 131,  44,  26,  27, 110,
00131      90, 160,  82,  59, 214, 179,  41, 227,  47, 132,  83, 209,   0, 237,
00132      32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207, 208, 239,
00133     170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168,
00134      81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255,
00135     243, 210, 205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61,
00136     100,  93,  25, 115,  96, 129,  79, 220,  34,  42, 144, 136,  70, 238,
00137     184,  20, 222,  94,  11, 219, 224,  50,  58,  10,  73,   6,  36,  92,
00138     194, 211, 172,  98, 145, 149, 228, 121, 231, 200,  55, 109, 141, 213,
00139      78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 186, 120,  37,  46,
00140      28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 112,  62,
00141     181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158,
00142     225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,
00143      40, 223, 140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15,
00144     176,  84, 187, 22
00145   };
00146 
00147 /*
00148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00149 %                                                                             %
00150 %                                                                             %
00151 %                                                                             %
00152 %   A c q u i r e A E S I n f o                                               %
00153 %                                                                             %
00154 %                                                                             %
00155 %                                                                             %
00156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00157 %
00158 %  AcquireAESInfo() allocate the AESInfo structure.
00159 %
00160 %  The format of the AcquireAESInfo method is:
00161 %
00162 %      AESInfo *AcquireAESInfo(void)
00163 %
00164 */
00165 WizardExport AESInfo *AcquireAESInfo(void)
00166 {
00167   AESInfo
00168     *aes_info;
00169 
00170   aes_info=(AESInfo *) AcquireAlignedMemory(1,sizeof(*aes_info));
00171   if (aes_info == (AESInfo *) NULL)
00172     ThrowWizardFatalError(CipherDomain,MemoryError);
00173   (void) ResetWizardMemory(aes_info,0,sizeof(*aes_info));
00174   aes_info->blocksize=AESBlocksize;
00175   aes_info->key=AcquireStringInfo(32);
00176   aes_info->encipher_key=(unsigned int *) AcquireQuantumMemory(60UL,
00177     sizeof(*aes_info->encipher_key));
00178   aes_info->decipher_key=(unsigned int *) AcquireQuantumMemory(60UL,
00179     sizeof(*aes_info->decipher_key));
00180   if ((aes_info->key == (StringInfo *) NULL) ||
00181       (aes_info->encipher_key == (unsigned int *) NULL) ||
00182       (aes_info->decipher_key == (unsigned int *) NULL))
00183     ThrowWizardFatalError(CipherDomain,MemoryError);
00184   aes_info->timestamp=time((time_t *) NULL);
00185   aes_info->signature=WizardSignature;
00186   return(aes_info);
00187 }
00188 
00189 /*
00190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00191 %                                                                             %
00192 %                                                                             %
00193 %                                                                             %
00194 %   D e c i p h e r A E S B l o c k                                           %
00195 %                                                                             %
00196 %                                                                             %
00197 %                                                                             %
00198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00199 %
00200 %  DecipherAESBlock() deciphers a single block of ciphertext to produce a block
00201 %  of plaintext.
00202 %
00203 %  The format of the DecipherAESBlock method is:
00204 %
00205 %     void DecipherAES(AESInfo *aes_info,const unsigned char *ciphertext,
00206 %       unsigned char *plaintext)
00207 %
00208 %  A description of each parameter follows:
00209 %
00210 %    o aes_info: The cipher context.
00211 %
00212 %    o ciphertext: The cipher text.
00213 %
00214 %    o plainttext: The plaint text.
00215 %
00216 */
00217 
00218 static inline void AddRoundKey(const unsigned int *ciphertext,
00219   const unsigned int *key,unsigned int *plaintext)
00220 {
00221   register ssize_t
00222     i;
00223 
00224   /*
00225     Xor corresponding text input and round key input bytes.
00226   */
00227   for (i=0; i < 4; i++)
00228     plaintext[i]=key[i] ^ ciphertext[i];
00229 }
00230 
00231 static inline unsigned char ByteMultiply(const unsigned char alpha,
00232   const unsigned char beta)
00233 {
00234   /*
00235     Byte multiply two elements of GF(2^m) (mix columns and inverse mix columns).
00236   */
00237   if ((alpha == 0) || (beta == 0))
00238     return(0);
00239   return(InverseLog[(Log[alpha]+Log[beta]) % 0xff]);
00240 }
00241 
00242 static inline unsigned int ByteSubTransform(unsigned int x,
00243   unsigned char *s_box)
00244 {
00245   unsigned int
00246     key;
00247 
00248   /*
00249     Non-linear layer resists differential and linear cryptoanalysis attacks.
00250   */
00251   key=(s_box[x & 0xff]) | (s_box[(x >> 8) & 0xff] << 8) |
00252     (s_box[(x >> 16) & 0xff] << 16) | (s_box[(x >> 24) & 0xff] << 24);
00253   return(key);
00254 }
00255 
00256 static void FinalizeRoundKey(const unsigned int *ciphertext,
00257   const unsigned int *key,unsigned char *plaintext)
00258 {
00259   register unsigned char
00260     *p;
00261 
00262   register unsigned int
00263     i,
00264     j;
00265 
00266   unsigned int
00267     value;
00268 
00269   /*
00270     The round key is XORed with the result of the mix-column transformation.
00271   */
00272   p=plaintext;
00273   for (i=0; i < 4; i++)
00274   {
00275     value=ciphertext[i] ^ key[i];
00276     for (j=0; j < 4; j++)
00277       *p++=(value >> (8*j)) & 0xff;
00278   }
00279   /*
00280     Reset registers.
00281   */
00282   value=0;
00283 }
00284 
00285 static void InitializeRoundKey(const unsigned char *ciphertext,
00286   const unsigned int *key,unsigned int *plaintext)
00287 {
00288   register const unsigned char
00289     *p;
00290 
00291   register unsigned int
00292     i,
00293     j;
00294 
00295   unsigned int
00296     value;
00297 
00298   p=ciphertext;
00299   for (i=0; i < 4; i++)
00300   {
00301     value=0;
00302     for (j=0; j < 4; j++)
00303       value|=(*p++ << (8*j));
00304     plaintext[i]=key[i] ^ value;
00305   }
00306   /*
00307     Reset registers.
00308   */
00309   value=0;
00310 }
00311 
00312 static inline unsigned int RotateLeft(const unsigned int x)
00313 {
00314   return(((x << 8) | ((x >> 24) & 0xff)));
00315 }
00316 
00317 WizardExport void DecipherAESBlock(AESInfo *aes_info,
00318   const unsigned char *ciphertext,unsigned char *plaintext)
00319 {
00320   static int
00321     map[4][4] =
00322     {
00323       { 0, 1, 2, 3 },
00324       { 3, 0, 1, 2 },
00325       { 2, 3, 0, 1 },
00326       { 1, 2, 3, 0 }
00327     };
00328 
00329   static unsigned char
00330     InverseSBox[256] =
00331     {
00332        82,   9, 106, 213,  48,  54, 165,  56, 191,  64, 163, 158, 129, 243,
00333       215, 251, 124, 227,  57, 130, 155,  47, 255, 135,  52, 142,  67,  68,
00334       196, 222, 233, 203,  84, 123, 148,  50, 166, 194,  35,  61, 238,  76,
00335       149,  11,  66, 250, 195,  78,   8,  46, 161, 102,  40, 217,  36, 178,
00336       118,  91, 162,  73, 109, 139, 209,  37, 114, 248, 246, 100, 134, 104,
00337       152,  22, 212, 164,  92, 204,  93, 101, 182, 146, 108, 112,  72,  80,
00338       253, 237, 185, 218,  94,  21,  70,  87, 167, 141, 157, 132, 144, 216,
00339       171,   0, 140, 188, 211,  10, 247, 228,  88,   5, 184, 179,  69,   6,
00340       208,  44,  30, 143, 202,  63,  15,   2, 193, 175, 189,   3,   1,  19,
00341       138, 107,  58, 145,  17,  65,  79, 103, 220, 234, 151, 242, 207, 206,
00342       240, 180, 230, 115, 150, 172, 116,  34, 231, 173,  53, 133, 226, 249,
00343        55, 232,  28, 117, 223, 110,  71, 241,  26, 113,  29,  41, 197, 137,
00344       111, 183,  98,  14, 170,  24, 190,  27, 252,  86,  62,  75, 198, 210,
00345       121,  32, 154, 219, 192, 254, 120, 205,  90, 244,  31, 221, 168,  51,
00346       136,   7, 199,  49, 177,  18,  16,  89,  39, 128, 236,  95,  96,  81,
00347       127, 169,  25, 181,  74,  13,  45, 229, 122, 159, 147, 201, 156, 239,
00348       160, 224,  59,  77, 174,  42, 245, 176, 200, 235, 187,  60, 131,  83,
00349       153,  97,  23,  43,   4, 126, 186, 119, 214,  38, 225, 105,  20,  99,
00350        85,  33,  12, 125,
00351     };
00352 
00353   static unsigned int
00354     I[] =
00355     {
00356       0x50a7f451U, 0x5365417eU, 0xc3a4171aU, 0x965e273aU, 0xcb6bab3bU,
00357       0xf1459d1fU, 0xab58faacU, 0x9303e34bU, 0x55fa3020U, 0xf66d76adU,
00358       0x9176cc88U, 0x254c02f5U, 0xfcd7e54fU, 0xd7cb2ac5U, 0x80443526U,
00359       0x8fa362b5U, 0x495ab1deU, 0x671bba25U, 0x980eea45U, 0xe1c0fe5dU,
00360       0x02752fc3U, 0x12f04c81U, 0xa397468dU, 0xc6f9d36bU, 0xe75f8f03U,
00361       0x959c9215U, 0xeb7a6dbfU, 0xda595295U, 0x2d83bed4U, 0xd3217458U,
00362       0x2969e049U, 0x44c8c98eU, 0x6a89c275U, 0x78798ef4U, 0x6b3e5899U,
00363       0xdd71b927U, 0xb64fe1beU, 0x17ad88f0U, 0x66ac20c9U, 0xb43ace7dU,
00364       0x184adf63U, 0x82311ae5U, 0x60335197U, 0x457f5362U, 0xe07764b1U,
00365       0x84ae6bbbU, 0x1ca081feU, 0x942b08f9U, 0x58684870U, 0x19fd458fU,
00366       0x876cde94U, 0xb7f87b52U, 0x23d373abU, 0xe2024b72U, 0x578f1fe3U,
00367       0x2aab5566U, 0x0728ebb2U, 0x03c2b52fU, 0x9a7bc586U, 0xa50837d3U,
00368       0xf2872830U, 0xb2a5bf23U, 0xba6a0302U, 0x5c8216edU, 0x2b1ccf8aU,
00369       0x92b479a7U, 0xf0f207f3U, 0xa1e2694eU, 0xcdf4da65U, 0xd5be0506U,
00370       0x1f6234d1U, 0x8afea6c4U, 0x9d532e34U, 0xa055f3a2U, 0x32e18a05U,
00371       0x75ebf6a4U, 0x39ec830bU, 0xaaef6040U, 0x069f715eU, 0x51106ebdU,
00372       0xf98a213eU, 0x3d06dd96U, 0xae053eddU, 0x46bde64dU, 0xb58d5491U,
00373       0x055dc471U, 0x6fd40604U, 0xff155060U, 0x24fb9819U, 0x97e9bdd6U,
00374       0xcc434089U, 0x779ed967U, 0xbd42e8b0U, 0x888b8907U, 0x385b19e7U,
00375       0xdbeec879U, 0x470a7ca1U, 0xe90f427cU, 0xc91e84f8U, 0x00000000U,
00376       0x83868009U, 0x48ed2b32U, 0xac70111eU, 0x4e725a6cU, 0xfbff0efdU,
00377       0x5638850fU, 0x1ed5ae3dU, 0x27392d36U, 0x64d90f0aU, 0x21a65c68U,
00378       0xd1545b9bU, 0x3a2e3624U, 0xb1670a0cU, 0x0fe75793U, 0xd296eeb4U,
00379       0x9e919b1bU, 0x4fc5c080U, 0xa220dc61U, 0x694b775aU, 0x161a121cU,
00380       0x0aba93e2U, 0xe52aa0c0U, 0x43e0223cU, 0x1d171b12U, 0x0b0d090eU,
00381       0xadc78bf2U, 0xb9a8b62dU, 0xc8a91e14U, 0x8519f157U, 0x4c0775afU,
00382       0xbbdd99eeU, 0xfd607fa3U, 0x9f2601f7U, 0xbcf5725cU, 0xc53b6644U,
00383       0x347efb5bU, 0x7629438bU, 0xdcc623cbU, 0x68fcedb6U, 0x63f1e4b8U,
00384       0xcadc31d7U, 0x10856342U, 0x40229713U, 0x2011c684U, 0x7d244a85U,
00385       0xf83dbbd2U, 0x1132f9aeU, 0x6da129c7U, 0x4b2f9e1dU, 0xf330b2dcU,
00386       0xec52860dU, 0xd0e3c177U, 0x6c16b32bU, 0x99b970a9U, 0xfa489411U,
00387       0x2264e947U, 0xc48cfca8U, 0x1a3ff0a0U, 0xd82c7d56U, 0xef903322U,
00388       0xc74e4987U, 0xc1d138d9U, 0xfea2ca8cU, 0x360bd498U, 0xcf81f5a6U,
00389       0x28de7aa5U, 0x268eb7daU, 0xa4bfad3fU, 0xe49d3a2cU, 0x0d927850U,
00390       0x9bcc5f6aU, 0x62467e54U, 0xc2138df6U, 0xe8b8d890U, 0x5ef7392eU,
00391       0xf5afc382U, 0xbe805d9fU, 0x7c93d069U, 0xa92dd56fU, 0xb31225cfU,
00392       0x3b99acc8U, 0xa77d1810U, 0x6e639ce8U, 0x7bbb3bdbU, 0x097826cdU,
00393       0xf418596eU, 0x01b79aecU, 0xa89a4f83U, 0x656e95e6U, 0x7ee6ffaaU,
00394       0x08cfbc21U, 0xe6e815efU, 0xd99be7baU, 0xce366f4aU, 0xd4099feaU,
00395       0xd67cb029U, 0xafb2a431U, 0x31233f2aU, 0x3094a5c6U, 0xc066a235U,
00396       0x37bc4e74U, 0xa6ca82fcU, 0xb0d090e0U, 0x15d8a733U, 0x4a9804f1U,
00397       0xf7daec41U, 0x0e50cd7fU, 0x2ff69117U, 0x8dd64d76U, 0x4db0ef43U,
00398       0x544daaccU, 0xdf0496e4U, 0xe3b5d19eU, 0x1b886a4cU, 0xb81f2cc1U,
00399       0x7f516546U, 0x04ea5e9dU, 0x5d358c01U, 0x737487faU, 0x2e410bfbU,
00400       0x5a1d67b3U, 0x52d2db92U, 0x335610e9U, 0x1347d66dU, 0x8c61d79aU,
00401       0x7a0ca137U, 0x8e14f859U, 0x893c13ebU, 0xee27a9ceU, 0x35c961b7U,
00402       0xede51ce1U, 0x3cb1477aU, 0x59dfd29cU, 0x3f73f255U, 0x79ce1418U,
00403       0xbf37c773U, 0xeacdf753U, 0x5baafd5fU, 0x146f3ddfU, 0x86db4478U,
00404       0x81f3afcaU, 0x3ec468b9U, 0x2c342438U, 0x5f40a3c2U, 0x72c31d16U,
00405       0x0c25e2bcU, 0x8b493c28U, 0x41950dffU, 0x7101a839U, 0xdeb30c08U,
00406       0x9ce4b4d8U, 0x90c15664U, 0x6184cb7bU, 0x70b632d5U, 0x745c6c48U,
00407       0x4257b8d0U
00408     };
00409 
00410   register ssize_t
00411     i,
00412     j;
00413 
00414   unsigned int
00415     alpha,
00416     key[4],
00417     text[4];
00418 
00419   /*
00420     Decipher one block.
00421   */
00422   (void) memset(text,0,sizeof(text));
00423   InitializeRoundKey(ciphertext,aes_info->decipher_key+4*aes_info->rounds,text);
00424   for (i=aes_info->rounds-1; i > 0;  i--)
00425   {
00426     /*
00427       This linear mixing step undiffuses the bits over multiple rounds.
00428     */
00429     for (j=0; j < 4; j++)
00430       key[j]=I[text[j] & 0xff] ^
00431         RotateLeft(I[(text[map[1][j]] >> 8) & 0xff] ^
00432         RotateLeft(I[(text[map[2][j]] >> 16) & 0xff] ^
00433         RotateLeft(I[(text[map[3][j]] >> 24) & 0xff])));
00434     AddRoundKey(key,aes_info->decipher_key+4*i,text);
00435   }
00436   for (i=0; i < 4; i++)
00437   {
00438     alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) |
00439       ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000);
00440     key[i]=ByteSubTransform(alpha,InverseSBox);
00441   }
00442   FinalizeRoundKey(key,aes_info->decipher_key,plaintext);
00443   /*
00444     Reset registers.
00445   */
00446   alpha=0;
00447   (void) ResetWizardMemory(key,0,sizeof(key));
00448   (void) ResetWizardMemory(text,0,sizeof(text));
00449 }
00450 
00451 /*
00452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00453 %                                                                             %
00454 %                                                                             %
00455 %                                                                             %
00456 %   D e s t r o y A E S I n f o                                               %
00457 %                                                                             %
00458 %                                                                             %
00459 %                                                                             %
00460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00461 %
00462 %  DestroyAESInfo() zeros memory associated with the AESInfo structure.
00463 %
00464 %  The format of the DestroyAESInfo method is:
00465 %
00466 %      AESInfo *DestroyAESInfo(AESInfo *aes_info)
00467 %
00468 %  A description of each parameter follows:
00469 %
00470 %    o aes_info: The cipher context.
00471 %
00472 */
00473 WizardExport AESInfo *DestroyAESInfo(AESInfo *aes_info)
00474 {
00475   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00476   WizardAssert(CipherDomain,aes_info != (AESInfo *) NULL);
00477   WizardAssert(CipherDomain,aes_info->signature == WizardSignature);
00478   if (aes_info->decipher_key != (unsigned int *) NULL)
00479     aes_info->decipher_key=(unsigned int *)
00480       RelinquishWizardMemory(aes_info->decipher_key);
00481   if (aes_info->encipher_key != (unsigned int *) NULL)
00482     aes_info->encipher_key=(unsigned int *)
00483       RelinquishWizardMemory(aes_info->encipher_key);
00484   if (aes_info->key != (StringInfo *) NULL)
00485     aes_info->key=DestroyStringInfo(aes_info->key);
00486   aes_info->signature=(~WizardSignature);
00487   aes_info=(AESInfo *) RelinquishWizardMemory(aes_info);
00488   return(aes_info);
00489 }
00490 
00491 /*
00492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00493 %                                                                             %
00494 %                                                                             %
00495 %                                                                             %
00496 %   E n c i p h e r A E S B l o c k                                           %
00497 %                                                                             %
00498 %                                                                             %
00499 %                                                                             %
00500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00501 %
00502 %  EncipherAESBlock() enciphers a single block of plaintext to produce a block
00503 %  of ciphertext.
00504 %
00505 %  The format of the EncipherAESBlock method is:
00506 %
00507 %      void EncipherAES(AESInfo *aes_info,const unsigned char *plaintext,
00508 %        unsigned char *ciphertext)
00509 %
00510 %  A description of each parameter follows:
00511 %
00512 %    o aes_info: The cipher context.
00513 %
00514 %    o plaintext: The plain text.
00515 %
00516 %    o ciphertext: The cipher text.
00517 %
00518 */
00519 WizardExport void EncipherAESBlock(AESInfo *aes_info,
00520   const unsigned char *plaintext,unsigned char *ciphertext)
00521 {
00522   register ssize_t
00523     i,
00524     j;
00525 
00526   static int
00527     map[4][4] =
00528     {
00529       { 0, 1, 2, 3 },
00530       { 1, 2, 3, 0 },
00531       { 2, 3, 0, 1 },
00532       { 3, 0, 1, 2 }
00533     };
00534 
00535   static unsigned int
00536     D[] =
00537     {
00538       0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, 0x0df2f2ffU,
00539       0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, 0x50303060U, 0x03010102U,
00540       0xa96767ceU, 0x7d2b2b56U, 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU,
00541       0x9a7676ecU, 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU,
00542       0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, 0xecadad41U,
00543       0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, 0xbf9c9c23U, 0xf7a4a453U,
00544       0x967272e4U, 0x5bc0c09bU, 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU,
00545       0x6a26264cU, 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U,
00546       0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, 0x937171e2U,
00547       0x73d8d8abU, 0x53313162U, 0x3f15152aU, 0x0c040408U, 0x52c7c795U,
00548       0x65232346U, 0x5ec3c39dU, 0x28181830U, 0xa1969637U, 0x0f05050aU,
00549       0xb59a9a2fU, 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU,
00550       0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, 0x1b090912U,
00551       0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, 0x2d1b1b36U, 0xb26e6edcU,
00552       0xee5a5ab4U, 0xfba0a05bU, 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U,
00553       0xceb3b37dU, 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U,
00554       0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, 0x60202040U,
00555       0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, 0xbe6a6ad4U, 0x46cbcb8dU,
00556       0xd9bebe67U, 0x4b393972U, 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U,
00557       0x4acfcf85U, 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU,
00558       0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, 0xcf45458aU,
00559       0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, 0xf05050a0U, 0x443c3c78U,
00560       0xba9f9f25U, 0xe3a8a84bU, 0xf35151a2U, 0xfea3a35dU, 0xc0404080U,
00561       0x8a8f8f05U, 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U,
00562       0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, 0x30101020U,
00563       0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, 0x4ccdcd81U, 0x140c0c18U,
00564       0x35131326U, 0x2fececc3U, 0xe15f5fbeU, 0xa2979735U, 0xcc444488U,
00565       0x3917172eU, 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU,
00566       0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, 0xa06060c0U,
00567       0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, 0x66222244U, 0x7e2a2a54U,
00568       0xab90903bU, 0x8388880bU, 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU,
00569       0x3c141428U, 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU,
00570       0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, 0xdb494992U,
00571       0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, 0x5dc2c29fU, 0x6ed3d3bdU,
00572       0xefacac43U, 0xa66262c4U, 0xa8919139U, 0xa4959531U, 0x37e4e4d3U,
00573       0x8b7979f2U, 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU,
00574       0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, 0xb46c6cd8U,
00575       0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, 0xaf6565caU, 0x8e7a7af4U,
00576       0xe9aeae47U, 0x18080810U, 0xd5baba6fU, 0x887878f0U, 0x6f25254aU,
00577       0x722e2e5cU, 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U,
00578       0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, 0xdd4b4b96U,
00579       0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, 0x907070e0U, 0x423e3e7cU,
00580       0xc4b5b571U, 0xaa6666ccU, 0xd8484890U, 0x05030306U, 0x01f6f6f7U,
00581       0x120e0e1cU, 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U,
00582       0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, 0x38e1e1d9U,
00583       0x13f8f8ebU, 0xb398982bU, 0x33111122U, 0xbb6969d2U, 0x70d9d9a9U,
00584       0x898e8e07U, 0xa7949433U, 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U,
00585       0x20e9e9c9U, 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U,
00586       0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, 0xdabfbf65U,
00587       0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, 0xc3414182U, 0xb0999929U,
00588       0x772d2d5aU, 0x110f0f1eU, 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU,
00589       0x3a16162cU
00590     };
00591 
00592   unsigned int
00593     alpha,
00594     key[4],
00595     text[4];
00596 
00597   /*
00598     Encipher one block.
00599   */
00600   (void) memset(text,0,sizeof(text));
00601   InitializeRoundKey(plaintext,aes_info->encipher_key,text);
00602   for (i=1; i < aes_info->rounds; i++)
00603   {
00604     /*
00605       Linear mixing step: cause diffusion of the bits over multiple rounds.
00606     */
00607     for (j=0; j < 4; j++)
00608       key[j]=D[text[j] & 0xff] ^
00609         RotateLeft(D[(text[map[1][j]] >> 8) & 0xff] ^
00610         RotateLeft(D[(text[map[2][j]] >> 16) & 0xff] ^
00611         RotateLeft(D[(text[map[3][j]] >> 24) & 0xff])));
00612     AddRoundKey(key,aes_info->encipher_key+4*i,text);
00613   }
00614   for (i=0; i < 4; i++)
00615   {
00616     alpha=(text[i] & 0x000000ff) | ((text[map[1][i]]) & 0x0000ff00) |
00617       ((text[map[2][i]]) & 0x00ff0000) | ((text[map[3][i]]) & 0xff000000);
00618     key[i]=ByteSubTransform(alpha,SBox);
00619   }
00620   FinalizeRoundKey(key,aes_info->encipher_key+4*aes_info->rounds,ciphertext);
00621   /*
00622     Reset registers.
00623   */
00624   alpha=0;
00625   (void) ResetWizardMemory(key,0,sizeof(key));
00626   (void) ResetWizardMemory(text,0,sizeof(text));
00627 }
00628 
00629 /*
00630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00631 %                                                                             %
00632 %                                                                             %
00633 %                                                                             %
00634 %   G e t A E S B l o c k s i z e                                             %
00635 %                                                                             %
00636 %                                                                             %
00637 %                                                                             %
00638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00639 %
00640 %  GetAESBlocksize() returns the AES blocksize.
00641 %
00642 %  The format of the GetAESBlocksize method is:
00643 %
00644 %      unsigned int *GetAESBlocksize(const AESInfo *aes_info)
00645 %
00646 %  A description of each parameter follows:
00647 %
00648 %    o aes_info: The aes info.
00649 %
00650 */
00651 WizardExport unsigned int GetAESBlocksize(const AESInfo *aes_info)
00652 {
00653   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00654   WizardAssert(CipherDomain,aes_info != (AESInfo *) NULL);
00655   WizardAssert(CipherDomain,aes_info->signature == WizardSignature);
00656   return(aes_info->blocksize);
00657 }
00658 
00659 /*
00660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00661 %                                                                             %
00662 %                                                                             %
00663 %                                                                             %
00664 %   S e t A E S K e y                                                         %
00665 %                                                                             %
00666 %                                                                             %
00667 %                                                                             %
00668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00669 %
00670 %  SetAESKey() sets the key for the AES cipher.  The key length is specified
00671 %  in bits.  Valid values are 128, 192, or 256 requiring a key buffer length
00672 %  in bytes of 16, 24, and 32 respectively.
00673 %
00674 %  The format of the SetAESKey method is:
00675 %
00676 %      SetAESKey(AESInfo *aes_info,const StringInfo *key)
00677 %
00678 %  A description of each parameter follows:
00679 %
00680 %    o aes_info: The cipher context.
00681 %
00682 %    o key: The key.
00683 %
00684 */
00685 
00686 static inline void InverseAddRoundKey(const unsigned int *alpha,
00687   unsigned int *beta)
00688 {
00689   register unsigned int
00690     i,
00691     j;
00692 
00693   for (i=0; i < 4; i++)
00694   {
00695     beta[i]=0;
00696     for (j=0; j < 4; j++)
00697       beta[i]|=(ByteMultiply(0xe,(alpha[i] >> (8*j)) & 0xff) ^
00698         ByteMultiply(0xb,(alpha[i] >> (8*((j+1) % 4))) & 0xff) ^
00699         ByteMultiply(0xd,(alpha[i] >> (8*((j+2) % 4))) & 0xff) ^
00700         ByteMultiply(0x9,(alpha[i] >> (8*((j+3) % 4))) & 0xff)) << (8*j);
00701   }
00702 }
00703 
00704 static inline unsigned int XTime(unsigned char alpha)
00705 {
00706   unsigned char
00707     beta;
00708 
00709   beta=(unsigned char) ((alpha & 0x80) != 0 ? 0x1b : 0);
00710   alpha<<=1;
00711   alpha^=beta;
00712   return(alpha);
00713 }
00714 
00715 static inline unsigned int RotateRight(const unsigned int x)
00716 {
00717   return((x >> 8) | ((x & 0xff) << 24));
00718 }
00719 
00720 WizardExport void SetAESKey(AESInfo *aes_info,const StringInfo *key)
00721 {
00722   ssize_t
00723     bytes,
00724     n;
00725 
00726   register ssize_t
00727     i;
00728 
00729   unsigned char
00730     *datum;
00731 
00732   unsigned int
00733     alpha,
00734     beta;
00735 
00736   /*
00737     Determine the number of rounds based on the number of bits in key.
00738   */
00739   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00740   WizardAssert(CipherDomain,aes_info != (AESInfo *) NULL);
00741   WizardAssert(CipherDomain,aes_info->signature == WizardSignature);
00742   WizardAssert(CipherDomain,key != (StringInfo *) NULL);
00743   n=4;
00744   aes_info->rounds=10;
00745   if ((8*GetStringInfoLength(key)) >= 256)
00746     {
00747       n=8;
00748       aes_info->rounds=14;
00749     }
00750   else
00751     if ((8*GetStringInfoLength(key)) >= 192)
00752       {
00753         n=6;
00754         aes_info->rounds=12;
00755       }
00756   /*
00757     Generate crypt key.
00758   */
00759   datum=GetStringInfoDatum(aes_info->key);
00760   (void) ResetWizardMemory(datum,0,GetStringInfoLength(aes_info->key));
00761   (void) CopyWizardMemory(datum,GetStringInfoDatum(key),
00762     Min(GetStringInfoLength(key),GetStringInfoLength(aes_info->key)));
00763   for (i=0; i < n; i++)
00764     aes_info->encipher_key[i]=datum[4*i] | (datum[4*i+1] << 8) |
00765       (datum[4*i+2] << 16) | (datum[4*i+3] << 24);
00766   beta=1;
00767   bytes=(AESBlocksize/4)*(aes_info->rounds+1);
00768   for (i=n; i < bytes; i++)
00769   {
00770     alpha=aes_info->encipher_key[i-1];
00771     if ((i % n) == 0)
00772       {
00773         alpha=ByteSubTransform(RotateRight(alpha),SBox) ^ beta;
00774         beta=XTime((unsigned char) (beta & 0xff));
00775       }
00776     else
00777       if ((n > 6) && ((i % n) == 4))
00778         alpha=ByteSubTransform(alpha,SBox);
00779     aes_info->encipher_key[i]=aes_info->encipher_key[i-n] ^ alpha;
00780   }
00781   /*
00782     Generate deciphering key (in reverse order).
00783   */
00784   for (i=0; i < 4; i++)
00785   {
00786     aes_info->decipher_key[i]=aes_info->encipher_key[i];
00787     aes_info->decipher_key[bytes-4+i]=aes_info->encipher_key[bytes-4+i];
00788   }
00789   for (i=4; i < (bytes-4); i+=4)
00790     InverseAddRoundKey(aes_info->encipher_key+i,aes_info->decipher_key+i);
00791   /*
00792     Reset registers.
00793   */
00794   datum=GetStringInfoDatum(aes_info->key);
00795   (void) ResetWizardMemory(datum,0,GetStringInfoLength(aes_info->key));
00796   alpha=0;
00797   beta=0;
00798 }
Generated by  doxygen 1.6.2-20100208