|
WizardsToolkit
1.0.7
|
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-2011 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 *) AcquireWizardMemory(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 }