cyassl re-port with cellular comms, PSK test
Dependencies: VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src
aes.c
00001 /* aes.c 00002 * 00003 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #ifndef NO_AES 00027 00028 #include <cyassl/ctaocrypt/aes.h> 00029 #include <cyassl/ctaocrypt/error.h> 00030 #include <cyassl/ctaocrypt/logging.h> 00031 #ifdef NO_INLINE 00032 #include <cyassl/ctaocrypt/misc.h> 00033 #else 00034 #include <ctaocrypt/src/misc.c> 00035 #endif 00036 00037 00038 #ifdef _MSC_VER 00039 /* 4127 warning constant while(1) */ 00040 #pragma warning(disable: 4127) 00041 #endif 00042 00043 00044 #ifdef HAVE_CAVIUM 00045 static int AesCaviumSetKey(Aes* aes, const byte* key, word32 length, 00046 const byte* iv); 00047 static void AesCaviumCbcEncrypt(Aes* aes, byte* out, const byte* in, 00048 word32 length); 00049 static void AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in, 00050 word32 length); 00051 #endif 00052 00053 #ifdef STM32F2_CRYPTO 00054 /* 00055 * STM32F2 hardware AES support through the STM32F2 standard peripheral 00056 * library. Documentation located in STM32F2xx Standard Peripheral Library 00057 * document (See note in README). 00058 */ 00059 #include "stm32f2xx.h" 00060 00061 int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, 00062 int dir) 00063 { 00064 word32 *rk = aes->key; 00065 00066 if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) 00067 return BAD_FUNC_ARG; 00068 00069 aes->rounds = keylen/4 + 6; 00070 XMEMCPY(rk, userKey, keylen); 00071 ByteReverseWords(rk, rk, keylen); 00072 00073 return AesSetIV(aes, iv); 00074 } 00075 00076 void AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) 00077 { 00078 word32 *enc_key, *iv; 00079 CRYP_InitTypeDef AES_CRYP_InitStructure; 00080 CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure; 00081 CRYP_IVInitTypeDef AES_CRYP_IVInitStructure; 00082 00083 enc_key = aes->key; 00084 iv = aes->reg; 00085 00086 /* crypto structure initialization */ 00087 CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure); 00088 CRYP_StructInit(&AES_CRYP_InitStructure); 00089 CRYP_IVStructInit(&AES_CRYP_IVInitStructure); 00090 00091 /* reset registers to their default values */ 00092 CRYP_DeInit(); 00093 00094 /* load key into correct registers */ 00095 switch(aes->rounds) 00096 { 00097 case 10: /* 128-bit key */ 00098 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b; 00099 AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[0]; 00100 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1]; 00101 AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[2]; 00102 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3]; 00103 break; 00104 00105 case 12: /* 192-bit key */ 00106 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b; 00107 AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[0]; 00108 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1]; 00109 AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[2]; 00110 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3]; 00111 AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[4]; 00112 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5]; 00113 break; 00114 00115 case 14: /* 256-bit key */ 00116 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b; 00117 AES_CRYP_KeyInitStructure.CRYP_Key0Left = enc_key[0]; 00118 AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1]; 00119 AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[2]; 00120 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3]; 00121 AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[4]; 00122 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5]; 00123 AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[6]; 00124 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7]; 00125 break; 00126 00127 default: 00128 break; 00129 } 00130 CRYP_KeyInit(&AES_CRYP_KeyInitStructure); 00131 00132 /* set iv */ 00133 ByteReverseWords(iv, iv, AES_BLOCK_SIZE); 00134 AES_CRYP_IVInitStructure.CRYP_IV0Left = iv[0]; 00135 AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1]; 00136 AES_CRYP_IVInitStructure.CRYP_IV1Left = iv[2]; 00137 AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3]; 00138 CRYP_IVInit(&AES_CRYP_IVInitStructure); 00139 00140 /* set direction, mode, and datatype */ 00141 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; 00142 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC; 00143 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; 00144 CRYP_Init(&AES_CRYP_InitStructure); 00145 00146 /* enable crypto processor */ 00147 CRYP_Cmd(ENABLE); 00148 00149 while (sz > 0) 00150 { 00151 /* flush IN/OUT FIFOs */ 00152 CRYP_FIFOFlush(); 00153 00154 CRYP_DataIn(*(uint32_t*)&in[0]); 00155 CRYP_DataIn(*(uint32_t*)&in[4]); 00156 CRYP_DataIn(*(uint32_t*)&in[8]); 00157 CRYP_DataIn(*(uint32_t*)&in[12]); 00158 00159 /* wait until the complete message has been processed */ 00160 while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} 00161 00162 *(uint32_t*)&out[0] = CRYP_DataOut(); 00163 *(uint32_t*)&out[4] = CRYP_DataOut(); 00164 *(uint32_t*)&out[8] = CRYP_DataOut(); 00165 *(uint32_t*)&out[12] = CRYP_DataOut(); 00166 00167 /* store iv for next call */ 00168 XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); 00169 00170 sz -= 16; 00171 in += 16; 00172 out += 16; 00173 } 00174 00175 /* disable crypto processor */ 00176 CRYP_Cmd(DISABLE); 00177 } 00178 00179 void AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) 00180 { 00181 word32 *dec_key, *iv; 00182 CRYP_InitTypeDef AES_CRYP_InitStructure; 00183 CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure; 00184 CRYP_IVInitTypeDef AES_CRYP_IVInitStructure; 00185 00186 dec_key = aes->key; 00187 iv = aes->reg; 00188 00189 /* crypto structure initialization */ 00190 CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure); 00191 CRYP_StructInit(&AES_CRYP_InitStructure); 00192 CRYP_IVStructInit(&AES_CRYP_IVInitStructure); 00193 00194 /* if input and output same will overwrite input iv */ 00195 XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); 00196 00197 /* reset registers to their default values */ 00198 CRYP_DeInit(); 00199 00200 /* load key into correct registers */ 00201 switch(aes->rounds) 00202 { 00203 case 10: /* 128-bit key */ 00204 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b; 00205 AES_CRYP_KeyInitStructure.CRYP_Key2Left = dec_key[0]; 00206 AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[1]; 00207 AES_CRYP_KeyInitStructure.CRYP_Key3Left = dec_key[2]; 00208 AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[3]; 00209 break; 00210 00211 case 12: /* 192-bit key */ 00212 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b; 00213 AES_CRYP_KeyInitStructure.CRYP_Key1Left = dec_key[0]; 00214 AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[1]; 00215 AES_CRYP_KeyInitStructure.CRYP_Key2Left = dec_key[2]; 00216 AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[3]; 00217 AES_CRYP_KeyInitStructure.CRYP_Key3Left = dec_key[4]; 00218 AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[5]; 00219 break; 00220 00221 case 14: /* 256-bit key */ 00222 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b; 00223 AES_CRYP_KeyInitStructure.CRYP_Key0Left = dec_key[0]; 00224 AES_CRYP_KeyInitStructure.CRYP_Key0Right = dec_key[1]; 00225 AES_CRYP_KeyInitStructure.CRYP_Key1Left = dec_key[2]; 00226 AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[3]; 00227 AES_CRYP_KeyInitStructure.CRYP_Key2Left = dec_key[4]; 00228 AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[5]; 00229 AES_CRYP_KeyInitStructure.CRYP_Key3Left = dec_key[6]; 00230 AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[7]; 00231 break; 00232 00233 default: 00234 break; 00235 } 00236 00237 /* set direction, mode, and datatype for key preparation */ 00238 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; 00239 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key; 00240 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b; 00241 CRYP_Init(&AES_CRYP_InitStructure); 00242 CRYP_KeyInit(&AES_CRYP_KeyInitStructure); 00243 00244 /* enable crypto processor */ 00245 CRYP_Cmd(ENABLE); 00246 00247 /* wait until key has been prepared */ 00248 while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} 00249 00250 /* set direction, mode, and datatype for decryption */ 00251 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; 00252 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC; 00253 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; 00254 CRYP_Init(&AES_CRYP_InitStructure); 00255 00256 /* set iv */ 00257 ByteReverseWords(iv, iv, AES_BLOCK_SIZE); 00258 00259 AES_CRYP_IVInitStructure.CRYP_IV0Left = iv[0]; 00260 AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1]; 00261 AES_CRYP_IVInitStructure.CRYP_IV1Left = iv[2]; 00262 AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3]; 00263 CRYP_IVInit(&AES_CRYP_IVInitStructure); 00264 00265 /* enable crypto processor */ 00266 CRYP_Cmd(ENABLE); 00267 00268 while (sz > 0) 00269 { 00270 /* flush IN/OUT FIFOs */ 00271 CRYP_FIFOFlush(); 00272 00273 CRYP_DataIn(*(uint32_t*)&in[0]); 00274 CRYP_DataIn(*(uint32_t*)&in[4]); 00275 CRYP_DataIn(*(uint32_t*)&in[8]); 00276 CRYP_DataIn(*(uint32_t*)&in[12]); 00277 00278 /* wait until the complete message has been processed */ 00279 while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} 00280 00281 *(uint32_t*)&out[0] = CRYP_DataOut(); 00282 *(uint32_t*)&out[4] = CRYP_DataOut(); 00283 *(uint32_t*)&out[8] = CRYP_DataOut(); 00284 *(uint32_t*)&out[12] = CRYP_DataOut(); 00285 00286 /* store iv for next call */ 00287 XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); 00288 00289 sz -= 16; 00290 in += 16; 00291 out += 16; 00292 } 00293 00294 /* disable crypto processor */ 00295 CRYP_Cmd(DISABLE); 00296 } 00297 00298 #ifdef CYASSL_AES_COUNTER 00299 00300 /* AES-CTR calls this for key setup */ 00301 int AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, 00302 const byte* iv, int dir) 00303 { 00304 return AesSetKey(aes, userKey, keylen, iv, dir); 00305 } 00306 00307 void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) 00308 { 00309 word32 *enc_key, *iv; 00310 CRYP_InitTypeDef AES_CRYP_InitStructure; 00311 CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure; 00312 CRYP_IVInitTypeDef AES_CRYP_IVInitStructure; 00313 00314 enc_key = aes->key; 00315 iv = aes->reg; 00316 00317 /* crypto structure initialization */ 00318 CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure); 00319 CRYP_StructInit(&AES_CRYP_InitStructure); 00320 CRYP_IVStructInit(&AES_CRYP_IVInitStructure); 00321 00322 /* reset registers to their default values */ 00323 CRYP_DeInit(); 00324 00325 /* load key into correct registers */ 00326 switch(aes->rounds) 00327 { 00328 case 10: /* 128-bit key */ 00329 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b; 00330 AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[0]; 00331 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1]; 00332 AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[2]; 00333 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3]; 00334 break; 00335 00336 case 12: /* 192-bit key */ 00337 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b; 00338 AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[0]; 00339 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1]; 00340 AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[2]; 00341 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3]; 00342 AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[4]; 00343 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5]; 00344 break; 00345 00346 case 14: /* 256-bit key */ 00347 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b; 00348 AES_CRYP_KeyInitStructure.CRYP_Key0Left = enc_key[0]; 00349 AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1]; 00350 AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[2]; 00351 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3]; 00352 AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[4]; 00353 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5]; 00354 AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[6]; 00355 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7]; 00356 break; 00357 00358 default: 00359 break; 00360 } 00361 CRYP_KeyInit(&AES_CRYP_KeyInitStructure); 00362 00363 /* set iv */ 00364 ByteReverseWords(iv, iv, AES_BLOCK_SIZE); 00365 AES_CRYP_IVInitStructure.CRYP_IV0Left = iv[0]; 00366 AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1]; 00367 AES_CRYP_IVInitStructure.CRYP_IV1Left = iv[2]; 00368 AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3]; 00369 CRYP_IVInit(&AES_CRYP_IVInitStructure); 00370 00371 /* set direction, mode, and datatype */ 00372 AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; 00373 AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR; 00374 AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; 00375 CRYP_Init(&AES_CRYP_InitStructure); 00376 00377 /* enable crypto processor */ 00378 CRYP_Cmd(ENABLE); 00379 00380 while (sz > 0) 00381 { 00382 /* flush IN/OUT FIFOs */ 00383 CRYP_FIFOFlush(); 00384 00385 CRYP_DataIn(*(uint32_t*)&in[0]); 00386 CRYP_DataIn(*(uint32_t*)&in[4]); 00387 CRYP_DataIn(*(uint32_t*)&in[8]); 00388 CRYP_DataIn(*(uint32_t*)&in[12]); 00389 00390 /* wait until the complete message has been processed */ 00391 while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} 00392 00393 *(uint32_t*)&out[0] = CRYP_DataOut(); 00394 *(uint32_t*)&out[4] = CRYP_DataOut(); 00395 *(uint32_t*)&out[8] = CRYP_DataOut(); 00396 *(uint32_t*)&out[12] = CRYP_DataOut(); 00397 00398 /* store iv for next call */ 00399 XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); 00400 00401 sz -= 16; 00402 in += 16; 00403 out += 16; 00404 } 00405 00406 /* disable crypto processor */ 00407 CRYP_Cmd(DISABLE); 00408 } 00409 00410 #endif /* CYASSL_AES_COUNTER */ 00411 00412 #else /* CTaoCrypt software implementation */ 00413 00414 static const word32 rcon[] = { 00415 0x01000000, 0x02000000, 0x04000000, 0x08000000, 00416 0x10000000, 0x20000000, 0x40000000, 0x80000000, 00417 0x1B000000, 0x36000000, 00418 /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ 00419 }; 00420 00421 00422 static const word32 Te[5][256] = { 00423 { 00424 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 00425 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, 00426 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, 00427 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, 00428 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, 00429 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, 00430 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, 00431 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, 00432 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, 00433 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, 00434 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, 00435 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, 00436 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, 00437 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, 00438 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, 00439 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, 00440 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, 00441 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, 00442 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, 00443 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, 00444 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, 00445 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, 00446 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, 00447 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, 00448 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, 00449 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, 00450 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, 00451 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, 00452 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, 00453 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, 00454 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, 00455 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, 00456 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, 00457 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, 00458 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, 00459 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, 00460 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, 00461 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, 00462 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, 00463 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, 00464 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, 00465 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, 00466 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, 00467 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, 00468 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, 00469 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, 00470 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, 00471 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, 00472 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, 00473 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, 00474 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, 00475 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, 00476 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, 00477 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, 00478 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, 00479 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, 00480 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, 00481 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, 00482 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, 00483 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, 00484 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, 00485 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, 00486 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, 00487 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, 00488 }, 00489 { 00490 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, 00491 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, 00492 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, 00493 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, 00494 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, 00495 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, 00496 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, 00497 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, 00498 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, 00499 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, 00500 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, 00501 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, 00502 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, 00503 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, 00504 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, 00505 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, 00506 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, 00507 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, 00508 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, 00509 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, 00510 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, 00511 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, 00512 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, 00513 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, 00514 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, 00515 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, 00516 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, 00517 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, 00518 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, 00519 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, 00520 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, 00521 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, 00522 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, 00523 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, 00524 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, 00525 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, 00526 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, 00527 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, 00528 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, 00529 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, 00530 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, 00531 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, 00532 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, 00533 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, 00534 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, 00535 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, 00536 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, 00537 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, 00538 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, 00539 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, 00540 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, 00541 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, 00542 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, 00543 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, 00544 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, 00545 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, 00546 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, 00547 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, 00548 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, 00549 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, 00550 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, 00551 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, 00552 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, 00553 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, 00554 }, 00555 { 00556 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 00557 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, 00558 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, 00559 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, 00560 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, 00561 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, 00562 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, 00563 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, 00564 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, 00565 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, 00566 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, 00567 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, 00568 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, 00569 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, 00570 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, 00571 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, 00572 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, 00573 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, 00574 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, 00575 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, 00576 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, 00577 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, 00578 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, 00579 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, 00580 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, 00581 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, 00582 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, 00583 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, 00584 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, 00585 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, 00586 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, 00587 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, 00588 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, 00589 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, 00590 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, 00591 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, 00592 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, 00593 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, 00594 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, 00595 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, 00596 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, 00597 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, 00598 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, 00599 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, 00600 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, 00601 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, 00602 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, 00603 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, 00604 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, 00605 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, 00606 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, 00607 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, 00608 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, 00609 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, 00610 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, 00611 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, 00612 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, 00613 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, 00614 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, 00615 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, 00616 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, 00617 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, 00618 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, 00619 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, 00620 }, 00621 { 00622 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, 00623 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, 00624 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, 00625 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, 00626 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, 00627 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, 00628 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, 00629 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, 00630 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, 00631 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, 00632 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, 00633 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, 00634 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, 00635 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, 00636 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, 00637 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, 00638 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, 00639 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, 00640 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, 00641 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, 00642 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, 00643 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, 00644 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, 00645 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, 00646 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, 00647 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, 00648 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, 00649 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, 00650 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, 00651 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, 00652 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, 00653 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, 00654 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, 00655 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, 00656 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, 00657 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, 00658 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, 00659 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, 00660 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, 00661 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, 00662 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, 00663 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, 00664 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, 00665 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, 00666 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, 00667 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, 00668 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, 00669 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, 00670 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, 00671 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, 00672 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, 00673 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, 00674 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, 00675 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, 00676 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, 00677 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, 00678 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, 00679 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, 00680 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, 00681 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, 00682 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, 00683 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, 00684 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, 00685 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, 00686 }, 00687 { 00688 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, 00689 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, 00690 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, 00691 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, 00692 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, 00693 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, 00694 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, 00695 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, 00696 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, 00697 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, 00698 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, 00699 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, 00700 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, 00701 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, 00702 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, 00703 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, 00704 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, 00705 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, 00706 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, 00707 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, 00708 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, 00709 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, 00710 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, 00711 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, 00712 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, 00713 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, 00714 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, 00715 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, 00716 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, 00717 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, 00718 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, 00719 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, 00720 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, 00721 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, 00722 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, 00723 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, 00724 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, 00725 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, 00726 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, 00727 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, 00728 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, 00729 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, 00730 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, 00731 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, 00732 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, 00733 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, 00734 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, 00735 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, 00736 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, 00737 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, 00738 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, 00739 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, 00740 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, 00741 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, 00742 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, 00743 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, 00744 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, 00745 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, 00746 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, 00747 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, 00748 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, 00749 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, 00750 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, 00751 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, 00752 } 00753 }; 00754 00755 00756 static const word32 Td[5][256] = { 00757 { 00758 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 00759 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, 00760 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, 00761 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, 00762 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, 00763 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, 00764 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, 00765 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, 00766 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, 00767 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, 00768 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, 00769 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, 00770 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, 00771 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, 00772 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, 00773 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, 00774 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, 00775 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, 00776 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, 00777 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, 00778 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, 00779 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, 00780 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, 00781 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, 00782 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, 00783 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, 00784 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, 00785 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, 00786 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, 00787 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, 00788 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, 00789 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, 00790 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, 00791 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, 00792 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, 00793 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, 00794 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, 00795 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, 00796 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, 00797 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, 00798 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, 00799 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, 00800 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, 00801 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, 00802 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, 00803 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, 00804 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, 00805 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, 00806 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, 00807 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, 00808 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, 00809 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, 00810 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, 00811 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, 00812 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, 00813 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, 00814 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, 00815 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, 00816 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, 00817 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, 00818 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, 00819 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, 00820 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, 00821 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, 00822 }, 00823 { 00824 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, 00825 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, 00826 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, 00827 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, 00828 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, 00829 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, 00830 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, 00831 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, 00832 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, 00833 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, 00834 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, 00835 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, 00836 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, 00837 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, 00838 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, 00839 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, 00840 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, 00841 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, 00842 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, 00843 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, 00844 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, 00845 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, 00846 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, 00847 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, 00848 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, 00849 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, 00850 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, 00851 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, 00852 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, 00853 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, 00854 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, 00855 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, 00856 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, 00857 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, 00858 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, 00859 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, 00860 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, 00861 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, 00862 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, 00863 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, 00864 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, 00865 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, 00866 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, 00867 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, 00868 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, 00869 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, 00870 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, 00871 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, 00872 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, 00873 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, 00874 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, 00875 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, 00876 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, 00877 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, 00878 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, 00879 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, 00880 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, 00881 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, 00882 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, 00883 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, 00884 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, 00885 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, 00886 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, 00887 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, 00888 }, 00889 { 00890 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, 00891 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, 00892 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, 00893 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, 00894 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, 00895 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, 00896 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, 00897 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, 00898 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, 00899 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, 00900 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, 00901 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, 00902 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, 00903 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, 00904 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, 00905 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, 00906 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, 00907 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, 00908 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, 00909 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, 00910 00911 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, 00912 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, 00913 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, 00914 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, 00915 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, 00916 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, 00917 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, 00918 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, 00919 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, 00920 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, 00921 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, 00922 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, 00923 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, 00924 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, 00925 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, 00926 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, 00927 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, 00928 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, 00929 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, 00930 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, 00931 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, 00932 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, 00933 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, 00934 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, 00935 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, 00936 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, 00937 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, 00938 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, 00939 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, 00940 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, 00941 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, 00942 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, 00943 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, 00944 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, 00945 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, 00946 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, 00947 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, 00948 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, 00949 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, 00950 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, 00951 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, 00952 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, 00953 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, 00954 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, 00955 }, 00956 { 00957 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, 00958 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, 00959 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, 00960 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, 00961 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, 00962 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, 00963 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, 00964 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, 00965 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, 00966 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, 00967 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, 00968 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, 00969 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, 00970 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, 00971 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, 00972 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, 00973 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, 00974 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, 00975 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, 00976 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, 00977 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, 00978 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, 00979 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, 00980 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, 00981 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, 00982 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, 00983 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, 00984 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, 00985 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, 00986 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, 00987 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, 00988 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, 00989 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, 00990 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, 00991 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, 00992 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, 00993 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, 00994 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, 00995 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, 00996 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, 00997 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, 00998 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, 00999 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, 01000 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, 01001 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, 01002 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, 01003 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, 01004 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, 01005 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, 01006 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, 01007 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, 01008 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, 01009 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, 01010 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, 01011 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, 01012 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, 01013 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, 01014 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, 01015 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, 01016 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, 01017 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, 01018 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, 01019 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, 01020 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, 01021 }, 01022 { 01023 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, 01024 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, 01025 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, 01026 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, 01027 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, 01028 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, 01029 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, 01030 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, 01031 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, 01032 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, 01033 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, 01034 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, 01035 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, 01036 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, 01037 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, 01038 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, 01039 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, 01040 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, 01041 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, 01042 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, 01043 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, 01044 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, 01045 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, 01046 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, 01047 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, 01048 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, 01049 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, 01050 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, 01051 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, 01052 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, 01053 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, 01054 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, 01055 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, 01056 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, 01057 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, 01058 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, 01059 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, 01060 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, 01061 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, 01062 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, 01063 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, 01064 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, 01065 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, 01066 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, 01067 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, 01068 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, 01069 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, 01070 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, 01071 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, 01072 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, 01073 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, 01074 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, 01075 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, 01076 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, 01077 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, 01078 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, 01079 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, 01080 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, 01081 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, 01082 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, 01083 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, 01084 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, 01085 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, 01086 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, 01087 } 01088 }; 01089 01090 01091 01092 #define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y)))) 01093 01094 01095 #ifdef CYASSL_AESNI 01096 01097 #ifndef _MSC_VER 01098 01099 #define cpuid(func,ax,bx,cx,dx)\ 01100 __asm__ __volatile__ ("cpuid":\ 01101 "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func)); 01102 01103 #else 01104 01105 #define cpuid(func,ax,bx,cx,dx)\ 01106 __asm mov eax, func \ 01107 __asm cpuid \ 01108 __asm mov ax, eax \ 01109 __asm mov bx, ebx \ 01110 __asm mov cx, ecx \ 01111 __asm mov dx, edx 01112 01113 #endif /* _MSC_VER */ 01114 01115 01116 static int Check_CPU_support_AES(void) 01117 { 01118 unsigned int a,b,c,d; 01119 cpuid(1,a,b,c,d); 01120 01121 if (c & 0x2000000) 01122 return 1; 01123 01124 return 0; 01125 } 01126 01127 static int checkAESNI = 0; 01128 static int haveAESNI = 0; 01129 01130 01131 void AES_CBC_encrypt(const unsigned char* in, unsigned char* out, 01132 unsigned char* ivec, unsigned long length, 01133 const unsigned char* KS, int nr); 01134 01135 01136 void AES_CBC_decrypt(const unsigned char* in, unsigned char* out, 01137 unsigned char* ivec, unsigned long length, 01138 const unsigned char* KS, int nr); 01139 01140 void AES_128_Key_Expansion(const unsigned char* userkey, 01141 unsigned char* key_schedule); 01142 01143 void AES_192_Key_Expansion(const unsigned char* userkey, 01144 unsigned char* key_schedule); 01145 01146 void AES_256_Key_Expansion(const unsigned char* userkey, 01147 unsigned char* key_schedule); 01148 01149 01150 static int AES_set_encrypt_key(const unsigned char *userKey, const int bits, 01151 Aes* aes) 01152 { 01153 if (!userKey || !aes) 01154 return BAD_FUNC_ARG; 01155 01156 if (bits == 128) { 01157 AES_128_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 10; 01158 return 0; 01159 } 01160 else if (bits == 192) { 01161 AES_192_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 12; 01162 return 0; 01163 } 01164 else if (bits == 256) { 01165 AES_256_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 14; 01166 return 0; 01167 } 01168 return BAD_FUNC_ARG; 01169 } 01170 01171 01172 static int AES_set_decrypt_key(const unsigned char* userKey, const int bits, 01173 Aes* aes) 01174 { 01175 int nr; 01176 Aes temp_key; 01177 __m128i *Key_Schedule = (__m128i*)aes->key; 01178 __m128i *Temp_Key_Schedule = (__m128i*)temp_key.key; 01179 01180 if (!userKey || !aes) 01181 return BAD_FUNC_ARG; 01182 01183 if (AES_set_encrypt_key(userKey,bits,&temp_key) == BAD_FUNC_ARG) 01184 return BAD_FUNC_ARG; 01185 01186 nr = temp_key.rounds; 01187 aes->rounds = nr; 01188 01189 Key_Schedule[nr] = Temp_Key_Schedule[0]; 01190 Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]); 01191 Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]); 01192 Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]); 01193 Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]); 01194 Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]); 01195 Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]); 01196 Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]); 01197 Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]); 01198 Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]); 01199 01200 if(nr>10) { 01201 Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]); 01202 Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]); 01203 } 01204 01205 if(nr>12) { 01206 Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]); 01207 Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]); 01208 } 01209 01210 Key_Schedule[0] = Temp_Key_Schedule[nr]; 01211 01212 return 0; 01213 } 01214 01215 01216 01217 #endif /* CYASSL_AESNI */ 01218 01219 01220 static int AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen, 01221 const byte* iv, int dir) 01222 { 01223 word32 temp, *rk = aes->key; 01224 unsigned int i = 0; 01225 01226 #ifdef CYASSL_AESNI 01227 aes->use_aesni = 0; 01228 #endif /* CYASSL_AESNI */ 01229 aes->rounds = keylen/4 + 6; 01230 01231 XMEMCPY(rk, userKey, keylen); 01232 #ifdef LITTLE_ENDIAN_ORDER 01233 ByteReverseWords(rk, rk, keylen); 01234 #endif 01235 01236 switch(keylen) 01237 { 01238 case 16: 01239 while (1) 01240 { 01241 temp = rk[3]; 01242 rk[4] = rk[0] ^ 01243 (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ 01244 (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ 01245 (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ 01246 (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ 01247 rcon[i]; 01248 rk[5] = rk[1] ^ rk[4]; 01249 rk[6] = rk[2] ^ rk[5]; 01250 rk[7] = rk[3] ^ rk[6]; 01251 if (++i == 10) 01252 break; 01253 rk += 4; 01254 } 01255 break; 01256 01257 case 24: 01258 while (1) /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */ 01259 { 01260 temp = rk[ 5]; 01261 rk[ 6] = rk[ 0] ^ 01262 (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ 01263 (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ 01264 (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ 01265 (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ 01266 rcon[i]; 01267 rk[ 7] = rk[ 1] ^ rk[ 6]; 01268 rk[ 8] = rk[ 2] ^ rk[ 7]; 01269 rk[ 9] = rk[ 3] ^ rk[ 8]; 01270 if (++i == 8) 01271 break; 01272 rk[10] = rk[ 4] ^ rk[ 9]; 01273 rk[11] = rk[ 5] ^ rk[10]; 01274 rk += 6; 01275 } 01276 break; 01277 01278 case 32: 01279 while (1) 01280 { 01281 temp = rk[ 7]; 01282 rk[ 8] = rk[ 0] ^ 01283 (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ 01284 (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ 01285 (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ 01286 (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ 01287 rcon[i]; 01288 rk[ 9] = rk[ 1] ^ rk[ 8]; 01289 rk[10] = rk[ 2] ^ rk[ 9]; 01290 rk[11] = rk[ 3] ^ rk[10]; 01291 if (++i == 7) 01292 break; 01293 temp = rk[11]; 01294 rk[12] = rk[ 4] ^ 01295 (Te[4][GETBYTE(temp, 3)] & 0xff000000) ^ 01296 (Te[4][GETBYTE(temp, 2)] & 0x00ff0000) ^ 01297 (Te[4][GETBYTE(temp, 1)] & 0x0000ff00) ^ 01298 (Te[4][GETBYTE(temp, 0)] & 0x000000ff); 01299 rk[13] = rk[ 5] ^ rk[12]; 01300 rk[14] = rk[ 6] ^ rk[13]; 01301 rk[15] = rk[ 7] ^ rk[14]; 01302 01303 rk += 8; 01304 } 01305 break; 01306 01307 default: 01308 return BAD_FUNC_ARG; 01309 } 01310 01311 if (dir == AES_DECRYPTION) 01312 { 01313 unsigned int j; 01314 rk = aes->key; 01315 01316 /* invert the order of the round keys: */ 01317 for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) { 01318 temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; 01319 temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; 01320 temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; 01321 temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; 01322 } 01323 /* apply the inverse MixColumn transform to all round keys but the 01324 first and the last: */ 01325 for (i = 1; i < aes->rounds; i++) { 01326 rk += 4; 01327 rk[0] = 01328 Td[0][Te[4][GETBYTE(rk[0], 3)] & 0xff] ^ 01329 Td[1][Te[4][GETBYTE(rk[0], 2)] & 0xff] ^ 01330 Td[2][Te[4][GETBYTE(rk[0], 1)] & 0xff] ^ 01331 Td[3][Te[4][GETBYTE(rk[0], 0)] & 0xff]; 01332 rk[1] = 01333 Td[0][Te[4][GETBYTE(rk[1], 3)] & 0xff] ^ 01334 Td[1][Te[4][GETBYTE(rk[1], 2)] & 0xff] ^ 01335 Td[2][Te[4][GETBYTE(rk[1], 1)] & 0xff] ^ 01336 Td[3][Te[4][GETBYTE(rk[1], 0)] & 0xff]; 01337 rk[2] = 01338 Td[0][Te[4][GETBYTE(rk[2], 3)] & 0xff] ^ 01339 Td[1][Te[4][GETBYTE(rk[2], 2)] & 0xff] ^ 01340 Td[2][Te[4][GETBYTE(rk[2], 1)] & 0xff] ^ 01341 Td[3][Te[4][GETBYTE(rk[2], 0)] & 0xff]; 01342 rk[3] = 01343 Td[0][Te[4][GETBYTE(rk[3], 3)] & 0xff] ^ 01344 Td[1][Te[4][GETBYTE(rk[3], 2)] & 0xff] ^ 01345 Td[2][Te[4][GETBYTE(rk[3], 1)] & 0xff] ^ 01346 Td[3][Te[4][GETBYTE(rk[3], 0)] & 0xff]; 01347 } 01348 } 01349 01350 return AesSetIV(aes, iv); 01351 } 01352 01353 01354 int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, 01355 int dir) 01356 { 01357 01358 if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) 01359 return BAD_FUNC_ARG; 01360 01361 #ifdef HAVE_CAVIUM 01362 if (aes->magic == CYASSL_AES_CAVIUM_MAGIC) 01363 return AesCaviumSetKey(aes, userKey, keylen, iv); 01364 #endif 01365 01366 #ifdef CYASSL_AESNI 01367 if (checkAESNI == 0) { 01368 haveAESNI = Check_CPU_support_AES(); 01369 checkAESNI = 1; 01370 } 01371 if (haveAESNI) { 01372 aes->use_aesni = 1; 01373 if (iv) 01374 XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); 01375 if (dir == AES_ENCRYPTION) 01376 return AES_set_encrypt_key(userKey, keylen * 8, aes); 01377 else 01378 return AES_set_decrypt_key(userKey, keylen * 8, aes); 01379 } 01380 #endif /* CYASSL_AESNI */ 01381 01382 return AesSetKeyLocal(aes, userKey, keylen, iv, dir); 01383 } 01384 01385 01386 static void AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) 01387 { 01388 word32 s0, s1, s2, s3; 01389 word32 t0, t1, t2, t3; 01390 word32 r = aes->rounds >> 1; 01391 01392 const word32* rk = aes->key; 01393 if (r > 7 || r == 0) { 01394 CYASSL_MSG("AesEncrypt encountered improper key, set it up"); 01395 return; /* stop instead of segfaulting, set up your keys! */ 01396 } 01397 #ifdef CYASSL_AESNI 01398 if (aes->use_aesni) { 01399 CYASSL_MSG("AesEncrypt encountered aesni keysetup, don't use direct"); 01400 return; /* just stop now */ 01401 } 01402 #endif 01403 01404 /* 01405 * map byte array block to cipher state 01406 * and add initial round key: 01407 */ 01408 XMEMCPY(&s0, inBlock, sizeof(s0)); 01409 XMEMCPY(&s1, inBlock + sizeof(s0), sizeof(s1)); 01410 XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2)); 01411 XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3)); 01412 01413 #ifdef LITTLE_ENDIAN_ORDER 01414 s0 = ByteReverseWord32(s0); 01415 s1 = ByteReverseWord32(s1); 01416 s2 = ByteReverseWord32(s2); 01417 s3 = ByteReverseWord32(s3); 01418 #endif 01419 01420 s0 ^= rk[0]; 01421 s1 ^= rk[1]; 01422 s2 ^= rk[2]; 01423 s3 ^= rk[3]; 01424 01425 /* 01426 * Nr - 1 full rounds: 01427 */ 01428 01429 for (;;) { 01430 t0 = 01431 Te[0][GETBYTE(s0, 3)] ^ 01432 Te[1][GETBYTE(s1, 2)] ^ 01433 Te[2][GETBYTE(s2, 1)] ^ 01434 Te[3][GETBYTE(s3, 0)] ^ 01435 rk[4]; 01436 t1 = 01437 Te[0][GETBYTE(s1, 3)] ^ 01438 Te[1][GETBYTE(s2, 2)] ^ 01439 Te[2][GETBYTE(s3, 1)] ^ 01440 Te[3][GETBYTE(s0, 0)] ^ 01441 rk[5]; 01442 t2 = 01443 Te[0][GETBYTE(s2, 3)] ^ 01444 Te[1][GETBYTE(s3, 2)] ^ 01445 Te[2][GETBYTE(s0, 1)] ^ 01446 Te[3][GETBYTE(s1, 0)] ^ 01447 rk[6]; 01448 t3 = 01449 Te[0][GETBYTE(s3, 3)] ^ 01450 Te[1][GETBYTE(s0, 2)] ^ 01451 Te[2][GETBYTE(s1, 1)] ^ 01452 Te[3][GETBYTE(s2, 0)] ^ 01453 rk[7]; 01454 01455 rk += 8; 01456 if (--r == 0) { 01457 break; 01458 } 01459 01460 s0 = 01461 Te[0][GETBYTE(t0, 3)] ^ 01462 Te[1][GETBYTE(t1, 2)] ^ 01463 Te[2][GETBYTE(t2, 1)] ^ 01464 Te[3][GETBYTE(t3, 0)] ^ 01465 rk[0]; 01466 s1 = 01467 Te[0][GETBYTE(t1, 3)] ^ 01468 Te[1][GETBYTE(t2, 2)] ^ 01469 Te[2][GETBYTE(t3, 1)] ^ 01470 Te[3][GETBYTE(t0, 0)] ^ 01471 rk[1]; 01472 s2 = 01473 Te[0][GETBYTE(t2, 3)] ^ 01474 Te[1][GETBYTE(t3, 2)] ^ 01475 Te[2][GETBYTE(t0, 1)] ^ 01476 Te[3][GETBYTE(t1, 0)] ^ 01477 rk[2]; 01478 s3 = 01479 Te[0][GETBYTE(t3, 3)] ^ 01480 Te[1][GETBYTE(t0, 2)] ^ 01481 Te[2][GETBYTE(t1, 1)] ^ 01482 Te[3][GETBYTE(t2, 0)] ^ 01483 rk[3]; 01484 } 01485 01486 /* 01487 * apply last round and 01488 * map cipher state to byte array block: 01489 */ 01490 01491 s0 = 01492 (Te[4][GETBYTE(t0, 3)] & 0xff000000) ^ 01493 (Te[4][GETBYTE(t1, 2)] & 0x00ff0000) ^ 01494 (Te[4][GETBYTE(t2, 1)] & 0x0000ff00) ^ 01495 (Te[4][GETBYTE(t3, 0)] & 0x000000ff) ^ 01496 rk[0]; 01497 s1 = 01498 (Te[4][GETBYTE(t1, 3)] & 0xff000000) ^ 01499 (Te[4][GETBYTE(t2, 2)] & 0x00ff0000) ^ 01500 (Te[4][GETBYTE(t3, 1)] & 0x0000ff00) ^ 01501 (Te[4][GETBYTE(t0, 0)] & 0x000000ff) ^ 01502 rk[1]; 01503 s2 = 01504 (Te[4][GETBYTE(t2, 3)] & 0xff000000) ^ 01505 (Te[4][GETBYTE(t3, 2)] & 0x00ff0000) ^ 01506 (Te[4][GETBYTE(t0, 1)] & 0x0000ff00) ^ 01507 (Te[4][GETBYTE(t1, 0)] & 0x000000ff) ^ 01508 rk[2]; 01509 s3 = 01510 (Te[4][GETBYTE(t3, 3)] & 0xff000000) ^ 01511 (Te[4][GETBYTE(t0, 2)] & 0x00ff0000) ^ 01512 (Te[4][GETBYTE(t1, 1)] & 0x0000ff00) ^ 01513 (Te[4][GETBYTE(t2, 0)] & 0x000000ff) ^ 01514 rk[3]; 01515 01516 /* write out */ 01517 #ifdef LITTLE_ENDIAN_ORDER 01518 s0 = ByteReverseWord32(s0); 01519 s1 = ByteReverseWord32(s1); 01520 s2 = ByteReverseWord32(s2); 01521 s3 = ByteReverseWord32(s3); 01522 #endif 01523 01524 XMEMCPY(outBlock, &s0, sizeof(s0)); 01525 XMEMCPY(outBlock + sizeof(s0), &s1, sizeof(s1)); 01526 XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2)); 01527 XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3)); 01528 } 01529 01530 01531 static void AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) 01532 { 01533 word32 s0, s1, s2, s3; 01534 word32 t0, t1, t2, t3; 01535 word32 r = aes->rounds >> 1; 01536 01537 const word32* rk = aes->key; 01538 if (r > 7 || r == 0) { 01539 CYASSL_MSG("AesDecrypt encountered improper key, set it up"); 01540 return; /* stop instead of segfaulting, set up your keys! */ 01541 } 01542 #ifdef CYASSL_AESNI 01543 if (aes->use_aesni) { 01544 CYASSL_MSG("AesEncrypt encountered aesni keysetup, don't use direct"); 01545 return; /* just stop now */ 01546 } 01547 #endif 01548 01549 /* 01550 * map byte array block to cipher state 01551 * and add initial round key: 01552 */ 01553 XMEMCPY(&s0, inBlock, sizeof(s0)); 01554 XMEMCPY(&s1, inBlock + sizeof(s0), sizeof(s1)); 01555 XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2)); 01556 XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3)); 01557 01558 #ifdef LITTLE_ENDIAN_ORDER 01559 s0 = ByteReverseWord32(s0); 01560 s1 = ByteReverseWord32(s1); 01561 s2 = ByteReverseWord32(s2); 01562 s3 = ByteReverseWord32(s3); 01563 #endif 01564 01565 s0 ^= rk[0]; 01566 s1 ^= rk[1]; 01567 s2 ^= rk[2]; 01568 s3 ^= rk[3]; 01569 01570 /* 01571 * Nr - 1 full rounds: 01572 */ 01573 01574 for (;;) { 01575 t0 = 01576 Td[0][GETBYTE(s0, 3)] ^ 01577 Td[1][GETBYTE(s3, 2)] ^ 01578 Td[2][GETBYTE(s2, 1)] ^ 01579 Td[3][GETBYTE(s1, 0)] ^ 01580 rk[4]; 01581 t1 = 01582 Td[0][GETBYTE(s1, 3)] ^ 01583 Td[1][GETBYTE(s0, 2)] ^ 01584 Td[2][GETBYTE(s3, 1)] ^ 01585 Td[3][GETBYTE(s2, 0)] ^ 01586 rk[5]; 01587 t2 = 01588 Td[0][GETBYTE(s2, 3)] ^ 01589 Td[1][GETBYTE(s1, 2)] ^ 01590 Td[2][GETBYTE(s0, 1)] ^ 01591 Td[3][GETBYTE(s3, 0)] ^ 01592 rk[6]; 01593 t3 = 01594 Td[0][GETBYTE(s3, 3)] ^ 01595 Td[1][GETBYTE(s2, 2)] ^ 01596 Td[2][GETBYTE(s1, 1)] ^ 01597 Td[3][GETBYTE(s0, 0)] ^ 01598 rk[7]; 01599 01600 rk += 8; 01601 if (--r == 0) { 01602 break; 01603 } 01604 01605 s0 = 01606 Td[0][GETBYTE(t0, 3)] ^ 01607 Td[1][GETBYTE(t3, 2)] ^ 01608 Td[2][GETBYTE(t2, 1)] ^ 01609 Td[3][GETBYTE(t1, 0)] ^ 01610 rk[0]; 01611 s1 = 01612 Td[0][GETBYTE(t1, 3)] ^ 01613 Td[1][GETBYTE(t0, 2)] ^ 01614 Td[2][GETBYTE(t3, 1)] ^ 01615 Td[3][GETBYTE(t2, 0)] ^ 01616 rk[1]; 01617 s2 = 01618 Td[0][GETBYTE(t2, 3)] ^ 01619 Td[1][GETBYTE(t1, 2)] ^ 01620 Td[2][GETBYTE(t0, 1)] ^ 01621 Td[3][GETBYTE(t3, 0)] ^ 01622 rk[2]; 01623 s3 = 01624 Td[0][GETBYTE(t3, 3)] ^ 01625 Td[1][GETBYTE(t2, 2)] ^ 01626 Td[2][GETBYTE(t1, 1)] ^ 01627 Td[3][GETBYTE(t0, 0)] ^ 01628 rk[3]; 01629 } 01630 /* 01631 * apply last round and 01632 * map cipher state to byte array block: 01633 */ 01634 s0 = 01635 (Td[4][GETBYTE(t0, 3)] & 0xff000000) ^ 01636 (Td[4][GETBYTE(t3, 2)] & 0x00ff0000) ^ 01637 (Td[4][GETBYTE(t2, 1)] & 0x0000ff00) ^ 01638 (Td[4][GETBYTE(t1, 0)] & 0x000000ff) ^ 01639 rk[0]; 01640 s1 = 01641 (Td[4][GETBYTE(t1, 3)] & 0xff000000) ^ 01642 (Td[4][GETBYTE(t0, 2)] & 0x00ff0000) ^ 01643 (Td[4][GETBYTE(t3, 1)] & 0x0000ff00) ^ 01644 (Td[4][GETBYTE(t2, 0)] & 0x000000ff) ^ 01645 rk[1]; 01646 s2 = 01647 (Td[4][GETBYTE(t2, 3)] & 0xff000000) ^ 01648 (Td[4][GETBYTE(t1, 2)] & 0x00ff0000) ^ 01649 (Td[4][GETBYTE(t0, 1)] & 0x0000ff00) ^ 01650 (Td[4][GETBYTE(t3, 0)] & 0x000000ff) ^ 01651 rk[2]; 01652 s3 = 01653 (Td[4][GETBYTE(t3, 3)] & 0xff000000) ^ 01654 (Td[4][GETBYTE(t2, 2)] & 0x00ff0000) ^ 01655 (Td[4][GETBYTE(t1, 1)] & 0x0000ff00) ^ 01656 (Td[4][GETBYTE(t0, 0)] & 0x000000ff) ^ 01657 rk[3]; 01658 01659 /* write out */ 01660 #ifdef LITTLE_ENDIAN_ORDER 01661 s0 = ByteReverseWord32(s0); 01662 s1 = ByteReverseWord32(s1); 01663 s2 = ByteReverseWord32(s2); 01664 s3 = ByteReverseWord32(s3); 01665 #endif 01666 01667 XMEMCPY(outBlock, &s0, sizeof(s0)); 01668 XMEMCPY(outBlock + sizeof(s0), &s1, sizeof(s1)); 01669 XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2)); 01670 XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3)); 01671 } 01672 01673 01674 void AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) 01675 { 01676 word32 blocks = sz / AES_BLOCK_SIZE; 01677 01678 #ifdef HAVE_CAVIUM 01679 if (aes->magic == CYASSL_AES_CAVIUM_MAGIC) 01680 return AesCaviumCbcEncrypt(aes, out, in, sz); 01681 #endif 01682 01683 #ifdef CYASSL_AESNI 01684 if (haveAESNI) { 01685 #ifdef DEBUG_AESNI 01686 printf("about to aes cbc encrypt\n"); 01687 printf("in = %p\n", in); 01688 printf("out = %p\n", out); 01689 printf("aes->key = %p\n", aes->key); 01690 printf("aes->reg = %p\n", aes->reg); 01691 printf("aes->rounds = %d\n", aes->rounds); 01692 printf("sz = %d\n", sz); 01693 #endif 01694 AES_CBC_encrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key, 01695 aes->rounds); 01696 /* store iv for next call */ 01697 XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); 01698 return; 01699 } 01700 #endif 01701 01702 while (blocks--) { 01703 xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE); 01704 AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg); 01705 XMEMCPY(out, aes->reg, AES_BLOCK_SIZE); 01706 01707 out += AES_BLOCK_SIZE; 01708 in += AES_BLOCK_SIZE; 01709 } 01710 } 01711 01712 01713 void AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) 01714 { 01715 word32 blocks = sz / AES_BLOCK_SIZE; 01716 01717 #ifdef HAVE_CAVIUM 01718 if (aes->magic == CYASSL_AES_CAVIUM_MAGIC) 01719 return AesCaviumCbcDecrypt(aes, out, in, sz); 01720 #endif 01721 01722 #ifdef CYASSL_AESNI 01723 if (haveAESNI) { 01724 #ifdef DEBUG_AESNI 01725 printf("about to aes cbc decrypt\n"); 01726 printf("in = %p\n", in); 01727 printf("out = %p\n", out); 01728 printf("aes->key = %p\n", aes->key); 01729 printf("aes->reg = %p\n", aes->reg); 01730 printf("aes->rounds = %d\n", aes->rounds); 01731 printf("sz = %d\n", sz); 01732 #endif 01733 01734 /* if input and output same will overwrite input iv */ 01735 XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); 01736 AES_CBC_decrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key, 01737 aes->rounds); 01738 /* store iv for next call */ 01739 XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); 01740 return; 01741 } 01742 #endif 01743 01744 while (blocks--) { 01745 XMEMCPY(aes->tmp, in, AES_BLOCK_SIZE); 01746 AesDecrypt(aes, (byte*)aes->tmp, out); 01747 xorbuf(out, (byte*)aes->reg, AES_BLOCK_SIZE); 01748 XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); 01749 01750 out += AES_BLOCK_SIZE; 01751 in += AES_BLOCK_SIZE; 01752 } 01753 } 01754 01755 01756 #ifdef CYASSL_AES_DIRECT 01757 01758 /* Allow direct access to one block encrypt */ 01759 void AesEncryptDirect(Aes* aes, byte* out, const byte* in) 01760 { 01761 return AesEncrypt(aes, in, out); 01762 } 01763 01764 01765 /* Allow direct access to one block decrypt */ 01766 void AesDecryptDirect(Aes* aes, byte* out, const byte* in) 01767 { 01768 return AesDecrypt(aes, in, out); 01769 } 01770 01771 01772 #endif /* CYASSL_AES_DIRECT */ 01773 01774 01775 #if defined(CYASSL_AES_DIRECT) || defined(CYASSL_AES_COUNTER) 01776 01777 /* AES-CTR and AES-DIRECT need to use this for key setup, no aesni yet */ 01778 int AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, 01779 const byte* iv, int dir) 01780 { 01781 return AesSetKeyLocal(aes, userKey, keylen, iv, dir); 01782 } 01783 01784 #endif /* CYASSL_AES_DIRECT || CYASSL_AES_COUNTER */ 01785 01786 01787 #ifdef CYASSL_AES_COUNTER 01788 01789 /* Increment AES counter */ 01790 static INLINE void IncrementAesCounter(byte* inOutCtr) 01791 { 01792 int i; 01793 01794 /* in network byte order so start at end and work back */ 01795 for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { 01796 if (++inOutCtr[i]) /* we're done unless we overflow */ 01797 return; 01798 } 01799 } 01800 01801 01802 void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) 01803 { 01804 word32 blocks = sz / AES_BLOCK_SIZE; 01805 01806 while (blocks--) { 01807 AesEncrypt(aes, (byte*)aes->reg, out); 01808 IncrementAesCounter((byte*)aes->reg); 01809 xorbuf(out, in, AES_BLOCK_SIZE); 01810 01811 out += AES_BLOCK_SIZE; 01812 in += AES_BLOCK_SIZE; 01813 } 01814 } 01815 01816 #endif /* CYASSL_AES_COUNTER */ 01817 01818 01819 #ifdef HAVE_AESGCM 01820 01821 /* 01822 * The IV for AES GCM, stored in struct Aes's member reg, is comprised of 01823 * three parts in order: 01824 * 1. The implicit IV. This is generated from the PRF using the shared 01825 * secrets between endpoints. It is 4 bytes long. 01826 * 2. The explicit IV. This is set by the user of the AES. It needs to be 01827 * unique for each call to encrypt. The explicit IV is shared with the 01828 * other end of the transaction in the clear. 01829 * 3. The counter. Each block of data is encrypted with its own sequence 01830 * number counter. 01831 */ 01832 01833 enum { 01834 CTR_SZ = 4 01835 }; 01836 01837 01838 static INLINE void InitGcmCounter(byte* inOutCtr) 01839 { 01840 inOutCtr[AES_BLOCK_SIZE - 4] = 0; 01841 inOutCtr[AES_BLOCK_SIZE - 3] = 0; 01842 inOutCtr[AES_BLOCK_SIZE - 2] = 0; 01843 inOutCtr[AES_BLOCK_SIZE - 1] = 1; 01844 } 01845 01846 01847 static INLINE void IncrementGcmCounter(byte* inOutCtr) 01848 { 01849 int i; 01850 01851 /* in network byte order so start at end and work back */ 01852 for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) { 01853 if (++inOutCtr[i]) /* we're done unless we overflow */ 01854 return; 01855 } 01856 } 01857 01858 01859 #if defined(GCM_SMALL) || defined(GCM_TABLE) 01860 01861 static INLINE void FlattenSzInBits(byte* buf, word32 sz) 01862 { 01863 /* Multiply the sz by 8 */ 01864 word32 szHi = (sz >> (8*sizeof(sz) - 3)); 01865 sz <<= 3; 01866 01867 /* copy over the words of the sz into the destination buffer */ 01868 buf[0] = (szHi >> 24) & 0xff; 01869 buf[1] = (szHi >> 16) & 0xff; 01870 buf[2] = (szHi >> 8) & 0xff; 01871 buf[3] = szHi & 0xff; 01872 buf[4] = (sz >> 24) & 0xff; 01873 buf[5] = (sz >> 16) & 0xff; 01874 buf[6] = (sz >> 8) & 0xff; 01875 buf[7] = sz & 0xff; 01876 } 01877 01878 01879 static INLINE void RIGHTSHIFTX(byte* x) 01880 { 01881 int i; 01882 int carryOut = 0; 01883 int carryIn = 0; 01884 int borrow = x[15] & 0x01; 01885 01886 for (i = 0; i < AES_BLOCK_SIZE; i++) { 01887 carryOut = x[i] & 0x01; 01888 x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0); 01889 carryIn = carryOut; 01890 } 01891 if (borrow) x[0] ^= 0xE1; 01892 } 01893 01894 #endif /* defined(GCM_SMALL) || defined(GCM_TABLE) */ 01895 01896 01897 #ifdef GCM_TABLE 01898 01899 static void GenerateM0(Aes* aes) 01900 { 01901 int i, j; 01902 byte (*m)[AES_BLOCK_SIZE] = aes->M0; 01903 01904 XMEMCPY(m[128], aes->H, AES_BLOCK_SIZE); 01905 01906 for (i = 64; i > 0; i /= 2) { 01907 XMEMCPY(m[i], m[i*2], AES_BLOCK_SIZE); 01908 RIGHTSHIFTX(m[i]); 01909 } 01910 01911 for (i = 2; i < 256; i *= 2) { 01912 for (j = 1; j < i; j++) { 01913 XMEMCPY(m[i+j], m[i], AES_BLOCK_SIZE); 01914 xorbuf(m[i+j], m[j], AES_BLOCK_SIZE); 01915 } 01916 } 01917 01918 XMEMSET(m[0], 0, AES_BLOCK_SIZE); 01919 } 01920 01921 #endif /* GCM_TABLE */ 01922 01923 01924 void AesGcmSetKey(Aes* aes, const byte* key, word32 len) 01925 { 01926 byte iv[AES_BLOCK_SIZE]; 01927 01928 if (!((len == 16) || (len == 24) || (len == 32))) 01929 return; 01930 01931 XMEMSET(iv, 0, AES_BLOCK_SIZE); 01932 AesSetKeyLocal(aes, key, len, iv, AES_ENCRYPTION); 01933 01934 AesEncrypt(aes, iv, aes->H); 01935 #ifdef GCM_TABLE 01936 GenerateM0(aes); 01937 #endif /* GCM_TABLE */ 01938 } 01939 01940 01941 #if defined(GCM_SMALL) 01942 01943 static void GMULT(byte* X, byte* Y) 01944 { 01945 byte Z[AES_BLOCK_SIZE]; 01946 byte V[AES_BLOCK_SIZE]; 01947 int i, j; 01948 01949 XMEMSET(Z, 0, AES_BLOCK_SIZE); 01950 XMEMCPY(V, X, AES_BLOCK_SIZE); 01951 for (i = 0; i < AES_BLOCK_SIZE; i++) 01952 { 01953 byte y = Y[i]; 01954 for (j = 0; j < 8; j++) 01955 { 01956 if (y & 0x80) { 01957 xorbuf(Z, V, AES_BLOCK_SIZE); 01958 } 01959 01960 RIGHTSHIFTX(V); 01961 y = y << 1; 01962 } 01963 } 01964 XMEMCPY(X, Z, AES_BLOCK_SIZE); 01965 } 01966 01967 01968 static void GHASH(Aes* aes, const byte* a, word32 aSz, 01969 const byte* c, word32 cSz, byte* s, word32 sSz) 01970 { 01971 byte x[AES_BLOCK_SIZE]; 01972 byte scratch[AES_BLOCK_SIZE]; 01973 word32 blocks, partial; 01974 byte* h = aes->H; 01975 01976 XMEMSET(x, 0, AES_BLOCK_SIZE); 01977 01978 /* Hash in A, the Additional Authentication Data */ 01979 if (aSz != 0 && a != NULL) { 01980 blocks = aSz / AES_BLOCK_SIZE; 01981 partial = aSz % AES_BLOCK_SIZE; 01982 while (blocks--) { 01983 xorbuf(x, a, AES_BLOCK_SIZE); 01984 GMULT(x, h); 01985 a += AES_BLOCK_SIZE; 01986 } 01987 if (partial != 0) { 01988 XMEMSET(scratch, 0, AES_BLOCK_SIZE); 01989 XMEMCPY(scratch, a, partial); 01990 xorbuf(x, scratch, AES_BLOCK_SIZE); 01991 GMULT(x, h); 01992 } 01993 } 01994 01995 /* Hash in C, the Ciphertext */ 01996 if (cSz != 0 && c != NULL) { 01997 blocks = cSz / AES_BLOCK_SIZE; 01998 partial = cSz % AES_BLOCK_SIZE; 01999 while (blocks--) { 02000 xorbuf(x, c, AES_BLOCK_SIZE); 02001 GMULT(x, h); 02002 c += AES_BLOCK_SIZE; 02003 } 02004 if (partial != 0) { 02005 XMEMSET(scratch, 0, AES_BLOCK_SIZE); 02006 XMEMCPY(scratch, c, partial); 02007 xorbuf(x, scratch, AES_BLOCK_SIZE); 02008 GMULT(x, h); 02009 } 02010 } 02011 02012 /* Hash in the lengths of A and C in bits */ 02013 FlattenSzInBits(&scratch[0], aSz); 02014 FlattenSzInBits(&scratch[8], cSz); 02015 xorbuf(x, scratch, AES_BLOCK_SIZE); 02016 GMULT(x, h); 02017 02018 /* Copy the result into s. */ 02019 XMEMCPY(s, x, sSz); 02020 } 02021 02022 /* end GCM_SMALL */ 02023 #elif defined(GCM_TABLE) 02024 02025 static const byte R[256][2] = { 02026 {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46}, 02027 {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e}, 02028 {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56}, 02029 {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e}, 02030 {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66}, 02031 {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e}, 02032 {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76}, 02033 {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e}, 02034 {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06}, 02035 {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e}, 02036 {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16}, 02037 {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e}, 02038 {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26}, 02039 {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e}, 02040 {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36}, 02041 {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e}, 02042 {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6}, 02043 {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce}, 02044 {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6}, 02045 {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde}, 02046 {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6}, 02047 {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee}, 02048 {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6}, 02049 {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe}, 02050 {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86}, 02051 {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e}, 02052 {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96}, 02053 {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e}, 02054 {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6}, 02055 {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae}, 02056 {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6}, 02057 {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe}, 02058 {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46}, 02059 {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e}, 02060 {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56}, 02061 {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e}, 02062 {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66}, 02063 {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e}, 02064 {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76}, 02065 {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e}, 02066 {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06}, 02067 {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e}, 02068 {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16}, 02069 {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e}, 02070 {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26}, 02071 {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e}, 02072 {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36}, 02073 {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e}, 02074 {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6}, 02075 {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce}, 02076 {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6}, 02077 {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde}, 02078 {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6}, 02079 {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee}, 02080 {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6}, 02081 {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe}, 02082 {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86}, 02083 {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e}, 02084 {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96}, 02085 {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e}, 02086 {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6}, 02087 {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae}, 02088 {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6}, 02089 {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} }; 02090 02091 02092 static void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE]) 02093 { 02094 int i, j; 02095 byte Z[AES_BLOCK_SIZE]; 02096 byte a; 02097 02098 XMEMSET(Z, 0, sizeof(Z)); 02099 02100 for (i = 15; i > 0; i--) { 02101 xorbuf(Z, m[x[i]], AES_BLOCK_SIZE); 02102 a = Z[15]; 02103 02104 for (j = 15; j > 0; j--) { 02105 Z[j] = Z[j-1]; 02106 } 02107 02108 Z[0] = R[a][0]; 02109 Z[1] ^= R[a][1]; 02110 } 02111 xorbuf(Z, m[x[0]], AES_BLOCK_SIZE); 02112 02113 XMEMCPY(x, Z, AES_BLOCK_SIZE); 02114 } 02115 02116 02117 static void GHASH(Aes* aes, const byte* a, word32 aSz, 02118 const byte* c, word32 cSz, byte* s, word32 sSz) 02119 { 02120 byte x[AES_BLOCK_SIZE]; 02121 byte scratch[AES_BLOCK_SIZE]; 02122 word32 blocks, partial; 02123 02124 XMEMSET(x, 0, AES_BLOCK_SIZE); 02125 02126 /* Hash in A, the Additional Authentication Data */ 02127 if (aSz != 0 && a != NULL) { 02128 blocks = aSz / AES_BLOCK_SIZE; 02129 partial = aSz % AES_BLOCK_SIZE; 02130 while (blocks--) { 02131 xorbuf(x, a, AES_BLOCK_SIZE); 02132 GMULT(x, aes->M0); 02133 a += AES_BLOCK_SIZE; 02134 } 02135 if (partial != 0) { 02136 XMEMSET(scratch, 0, AES_BLOCK_SIZE); 02137 XMEMCPY(scratch, a, partial); 02138 xorbuf(x, scratch, AES_BLOCK_SIZE); 02139 GMULT(x, aes->M0); 02140 } 02141 } 02142 02143 /* Hash in C, the Ciphertext */ 02144 if (cSz != 0 && c != NULL) { 02145 blocks = cSz / AES_BLOCK_SIZE; 02146 partial = cSz % AES_BLOCK_SIZE; 02147 while (blocks--) { 02148 xorbuf(x, c, AES_BLOCK_SIZE); 02149 GMULT(x, aes->M0); 02150 c += AES_BLOCK_SIZE; 02151 } 02152 if (partial != 0) { 02153 XMEMSET(scratch, 0, AES_BLOCK_SIZE); 02154 XMEMCPY(scratch, c, partial); 02155 xorbuf(x, scratch, AES_BLOCK_SIZE); 02156 GMULT(x, aes->M0); 02157 } 02158 } 02159 02160 /* Hash in the lengths of A and C in bits */ 02161 FlattenSzInBits(&scratch[0], aSz); 02162 FlattenSzInBits(&scratch[8], cSz); 02163 xorbuf(x, scratch, AES_BLOCK_SIZE); 02164 GMULT(x, aes->M0); 02165 02166 /* Copy the result into s. */ 02167 XMEMCPY(s, x, sSz); 02168 } 02169 02170 /* end GCM_TABLE */ 02171 #elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) 02172 02173 static void GMULT(word64* X, word64* Y) 02174 { 02175 word64 Z[2] = {0,0}; 02176 word64 V[2] = {X[0], X[1]}; 02177 int i, j; 02178 02179 for (i = 0; i < 2; i++) 02180 { 02181 word64 y = Y[i]; 02182 for (j = 0; j < 64; j++) 02183 { 02184 if (y & 0x8000000000000000) { 02185 Z[0] ^= V[0]; 02186 Z[1] ^= V[1]; 02187 } 02188 02189 if (V[1] & 0x0000000000000001) { 02190 V[1] >>= 1; 02191 V[1] |= ((V[0] & 0x0000000000000001) ? 0x8000000000000000 : 0); 02192 V[0] >>= 1; 02193 V[0] ^= 0xE100000000000000; 02194 } 02195 else { 02196 V[1] >>= 1; 02197 V[1] |= ((V[0] & 0x0000000000000001) ? 0x8000000000000000 : 0); 02198 V[0] >>= 1; 02199 } 02200 y <<= 1; 02201 } 02202 } 02203 X[0] = Z[0]; 02204 X[1] = Z[1]; 02205 } 02206 02207 02208 static void GHASH(Aes* aes, const byte* a, word32 aSz, 02209 const byte* c, word32 cSz, byte* s, word32 sSz) 02210 { 02211 word64 x[2] = {0,0}; 02212 word32 blocks, partial; 02213 word64 bigH[2]; 02214 02215 XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE); 02216 #ifdef LITTLE_ENDIAN_ORDER 02217 ByteReverseWords64(bigH, bigH, AES_BLOCK_SIZE); 02218 #endif 02219 02220 /* Hash in A, the Additional Authentication Data */ 02221 if (aSz != 0 && a != NULL) { 02222 word64 bigA[2]; 02223 blocks = aSz / AES_BLOCK_SIZE; 02224 partial = aSz % AES_BLOCK_SIZE; 02225 while (blocks--) { 02226 XMEMCPY(bigA, a, AES_BLOCK_SIZE); 02227 #ifdef LITTLE_ENDIAN_ORDER 02228 ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE); 02229 #endif 02230 x[0] ^= bigA[0]; 02231 x[1] ^= bigA[1]; 02232 GMULT(x, bigH); 02233 a += AES_BLOCK_SIZE; 02234 } 02235 if (partial != 0) { 02236 XMEMSET(bigA, 0, AES_BLOCK_SIZE); 02237 XMEMCPY(bigA, a, partial); 02238 #ifdef LITTLE_ENDIAN_ORDER 02239 ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE); 02240 #endif 02241 x[0] ^= bigA[0]; 02242 x[1] ^= bigA[1]; 02243 GMULT(x, bigH); 02244 } 02245 } 02246 02247 /* Hash in C, the Ciphertext */ 02248 if (cSz != 0 && c != NULL) { 02249 word64 bigC[2]; 02250 blocks = cSz / AES_BLOCK_SIZE; 02251 partial = cSz % AES_BLOCK_SIZE; 02252 while (blocks--) { 02253 XMEMCPY(bigC, c, AES_BLOCK_SIZE); 02254 #ifdef LITTLE_ENDIAN_ORDER 02255 ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE); 02256 #endif 02257 x[0] ^= bigC[0]; 02258 x[1] ^= bigC[1]; 02259 GMULT(x, bigH); 02260 c += AES_BLOCK_SIZE; 02261 } 02262 if (partial != 0) { 02263 XMEMSET(bigC, 0, AES_BLOCK_SIZE); 02264 XMEMCPY(bigC, c, partial); 02265 #ifdef LITTLE_ENDIAN_ORDER 02266 ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE); 02267 #endif 02268 x[0] ^= bigC[0]; 02269 x[1] ^= bigC[1]; 02270 GMULT(x, bigH); 02271 } 02272 } 02273 02274 /* Hash in the lengths in bits of A and C */ 02275 { 02276 word64 len[2] = {aSz, cSz}; 02277 02278 /* Lengths are in bytes. Convert to bits. */ 02279 len[0] *= 8; 02280 len[1] *= 8; 02281 02282 x[0] ^= len[0]; 02283 x[1] ^= len[1]; 02284 GMULT(x, bigH); 02285 } 02286 #ifdef LITTLE_ENDIAN_ORDER 02287 ByteReverseWords64(x, x, AES_BLOCK_SIZE); 02288 #endif 02289 XMEMCPY(s, x, sSz); 02290 } 02291 02292 /* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */ 02293 #else /* GCM_WORD32 */ 02294 02295 static void GMULT(word32* X, word32* Y) 02296 { 02297 word32 Z[4] = {0,0,0,0}; 02298 word32 V[4] = {X[0], X[1], X[2], X[3]}; 02299 int i, j; 02300 02301 for (i = 0; i < 4; i++) 02302 { 02303 word32 y = Y[i]; 02304 for (j = 0; j < 32; j++) 02305 { 02306 if (y & 0x80000000) { 02307 Z[0] ^= V[0]; 02308 Z[1] ^= V[1]; 02309 Z[2] ^= V[2]; 02310 Z[3] ^= V[3]; 02311 } 02312 02313 if (V[3] & 0x00000001) { 02314 V[3] >>= 1; 02315 V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0); 02316 V[2] >>= 1; 02317 V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0); 02318 V[1] >>= 1; 02319 V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0); 02320 V[0] >>= 1; 02321 V[0] ^= 0xE1000000; 02322 } else { 02323 V[3] >>= 1; 02324 V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0); 02325 V[2] >>= 1; 02326 V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0); 02327 V[1] >>= 1; 02328 V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0); 02329 V[0] >>= 1; 02330 } 02331 y <<= 1; 02332 } 02333 } 02334 X[0] = Z[0]; 02335 X[1] = Z[1]; 02336 X[2] = Z[2]; 02337 X[3] = Z[3]; 02338 } 02339 02340 02341 static void GHASH(Aes* aes, const byte* a, word32 aSz, 02342 const byte* c, word32 cSz, byte* s, word32 sSz) 02343 { 02344 word32 x[4] = {0,0,0,0}; 02345 word32 blocks, partial; 02346 word32 bigH[4]; 02347 02348 XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE); 02349 #ifdef LITTLE_ENDIAN_ORDER 02350 ByteReverseWords(bigH, bigH, AES_BLOCK_SIZE); 02351 #endif 02352 02353 /* Hash in A, the Additional Authentication Data */ 02354 if (aSz != 0 && a != NULL) { 02355 word32 bigA[4]; 02356 blocks = aSz / AES_BLOCK_SIZE; 02357 partial = aSz % AES_BLOCK_SIZE; 02358 while (blocks--) { 02359 XMEMCPY(bigA, a, AES_BLOCK_SIZE); 02360 #ifdef LITTLE_ENDIAN_ORDER 02361 ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE); 02362 #endif 02363 x[0] ^= bigA[0]; 02364 x[1] ^= bigA[1]; 02365 x[2] ^= bigA[2]; 02366 x[3] ^= bigA[3]; 02367 GMULT(x, bigH); 02368 a += AES_BLOCK_SIZE; 02369 } 02370 if (partial != 0) { 02371 XMEMSET(bigA, 0, AES_BLOCK_SIZE); 02372 XMEMCPY(bigA, a, partial); 02373 #ifdef LITTLE_ENDIAN_ORDER 02374 ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE); 02375 #endif 02376 x[0] ^= bigA[0]; 02377 x[1] ^= bigA[1]; 02378 x[2] ^= bigA[2]; 02379 x[3] ^= bigA[3]; 02380 GMULT(x, bigH); 02381 } 02382 } 02383 02384 /* Hash in C, the Ciphertext */ 02385 if (cSz != 0 && c != NULL) { 02386 word32 bigC[4]; 02387 blocks = cSz / AES_BLOCK_SIZE; 02388 partial = cSz % AES_BLOCK_SIZE; 02389 while (blocks--) { 02390 XMEMCPY(bigC, c, AES_BLOCK_SIZE); 02391 #ifdef LITTLE_ENDIAN_ORDER 02392 ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE); 02393 #endif 02394 x[0] ^= bigC[0]; 02395 x[1] ^= bigC[1]; 02396 x[2] ^= bigC[2]; 02397 x[3] ^= bigC[3]; 02398 GMULT(x, bigH); 02399 c += AES_BLOCK_SIZE; 02400 } 02401 if (partial != 0) { 02402 XMEMSET(bigC, 0, AES_BLOCK_SIZE); 02403 XMEMCPY(bigC, c, partial); 02404 #ifdef LITTLE_ENDIAN_ORDER 02405 ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE); 02406 #endif 02407 x[0] ^= bigC[0]; 02408 x[1] ^= bigC[1]; 02409 x[2] ^= bigC[2]; 02410 x[3] ^= bigC[3]; 02411 GMULT(x, bigH); 02412 } 02413 } 02414 02415 /* Hash in the lengths in bits of A and C */ 02416 { 02417 word32 len[4]; 02418 02419 /* Lengths are in bytes. Convert to bits. */ 02420 len[0] = (aSz >> (8*sizeof(aSz) - 3)); 02421 len[1] = aSz << 3; 02422 len[2] = (cSz >> (8*sizeof(cSz) - 3)); 02423 len[3] = cSz << 3; 02424 02425 x[0] ^= len[0]; 02426 x[1] ^= len[1]; 02427 x[2] ^= len[2]; 02428 x[3] ^= len[3]; 02429 GMULT(x, bigH); 02430 } 02431 #ifdef LITTLE_ENDIAN_ORDER 02432 ByteReverseWords(x, x, AES_BLOCK_SIZE); 02433 #endif 02434 XMEMCPY(s, x, sSz); 02435 } 02436 02437 #endif /* end GCM_WORD32 */ 02438 02439 02440 void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, 02441 const byte* iv, word32 ivSz, 02442 byte* authTag, word32 authTagSz, 02443 const byte* authIn, word32 authInSz) 02444 { 02445 word32 blocks = sz / AES_BLOCK_SIZE; 02446 word32 partial = sz % AES_BLOCK_SIZE; 02447 const byte* p = in; 02448 byte* c = out; 02449 byte ctr[AES_BLOCK_SIZE]; 02450 byte scratch[AES_BLOCK_SIZE]; 02451 02452 CYASSL_ENTER("AesGcmEncrypt"); 02453 02454 XMEMSET(ctr, 0, AES_BLOCK_SIZE); 02455 XMEMCPY(ctr, iv, ivSz); 02456 InitGcmCounter(ctr); 02457 02458 while (blocks--) { 02459 IncrementGcmCounter(ctr); 02460 AesEncrypt(aes, ctr, scratch); 02461 xorbuf(scratch, p, AES_BLOCK_SIZE); 02462 XMEMCPY(c, scratch, AES_BLOCK_SIZE); 02463 02464 p += AES_BLOCK_SIZE; 02465 c += AES_BLOCK_SIZE; 02466 } 02467 if (partial != 0) { 02468 IncrementGcmCounter(ctr); 02469 AesEncrypt(aes, ctr, scratch); 02470 xorbuf(scratch, p, partial); 02471 XMEMCPY(c, scratch, partial); 02472 } 02473 GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz); 02474 InitGcmCounter(ctr); 02475 AesEncrypt(aes, ctr, scratch); 02476 xorbuf(authTag, scratch, authTagSz); 02477 } 02478 02479 02480 int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, 02481 const byte* iv, word32 ivSz, 02482 const byte* authTag, word32 authTagSz, 02483 const byte* authIn, word32 authInSz) 02484 { 02485 word32 blocks = sz / AES_BLOCK_SIZE; 02486 word32 partial = sz % AES_BLOCK_SIZE; 02487 const byte* c = in; 02488 byte* p = out; 02489 byte ctr[AES_BLOCK_SIZE]; 02490 byte scratch[AES_BLOCK_SIZE]; 02491 02492 CYASSL_ENTER("AesGcmDecrypt"); 02493 02494 XMEMSET(ctr, 0, AES_BLOCK_SIZE); 02495 XMEMCPY(ctr, iv, ivSz); 02496 InitGcmCounter(ctr); 02497 02498 /* Calculate the authTag again using the received auth data and the 02499 * cipher text. */ 02500 { 02501 byte Tprime[AES_BLOCK_SIZE]; 02502 byte EKY0[AES_BLOCK_SIZE]; 02503 02504 GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime)); 02505 AesEncrypt(aes, ctr, EKY0); 02506 xorbuf(Tprime, EKY0, sizeof(Tprime)); 02507 if (XMEMCMP(authTag, Tprime, authTagSz) != 0) { 02508 return AES_GCM_AUTH_E; 02509 } 02510 } 02511 02512 while (blocks--) { 02513 IncrementGcmCounter(ctr); 02514 AesEncrypt(aes, ctr, scratch); 02515 xorbuf(scratch, c, AES_BLOCK_SIZE); 02516 XMEMCPY(p, scratch, AES_BLOCK_SIZE); 02517 02518 p += AES_BLOCK_SIZE; 02519 c += AES_BLOCK_SIZE; 02520 } 02521 if (partial != 0) { 02522 IncrementGcmCounter(ctr); 02523 AesEncrypt(aes, ctr, scratch); 02524 xorbuf(scratch, c, partial); 02525 XMEMCPY(p, scratch, partial); 02526 } 02527 02528 return 0; 02529 } 02530 02531 #endif /* HAVE_AESGCM */ 02532 02533 #ifdef HAVE_AESCCM 02534 02535 void AesCcmSetKey(Aes* aes, const byte* key, word32 keySz) 02536 { 02537 byte nonce[AES_BLOCK_SIZE]; 02538 02539 if (!((keySz == 16) || (keySz == 24) || (keySz == 32))) 02540 return; 02541 02542 XMEMSET(nonce, 0, sizeof(nonce)); 02543 AesSetKeyLocal(aes, key, keySz, nonce, AES_ENCRYPTION); 02544 } 02545 02546 02547 static void roll_x(Aes* aes, const byte* in, word32 inSz, byte* out) 02548 { 02549 /* process the bulk of the data */ 02550 while (inSz >= AES_BLOCK_SIZE) { 02551 xorbuf(out, in, AES_BLOCK_SIZE); 02552 in += AES_BLOCK_SIZE; 02553 inSz -= AES_BLOCK_SIZE; 02554 02555 AesEncrypt(aes, out, out); 02556 } 02557 02558 /* process remainder of the data */ 02559 if (inSz > 0) { 02560 xorbuf(out, in, inSz); 02561 AesEncrypt(aes, out, out); 02562 } 02563 } 02564 02565 02566 static void roll_auth(Aes* aes, const byte* in, word32 inSz, byte* out) 02567 { 02568 word32 authLenSz; 02569 word32 remainder; 02570 02571 /* encode the length in */ 02572 if (inSz <= 0xFEFF) { 02573 authLenSz = 2; 02574 out[0] ^= ((inSz & 0xFF00) >> 8); 02575 out[1] ^= (inSz & 0x00FF); 02576 } 02577 else if (inSz <= 0xFFFFFFFF) { 02578 authLenSz = 6; 02579 out[0] ^= 0xFF; out[1] ^= 0xFE; 02580 out[2] ^= ((inSz & 0xFF000000) >> 24); 02581 out[3] ^= ((inSz & 0x00FF0000) >> 16); 02582 out[4] ^= ((inSz & 0x0000FF00) >> 8); 02583 out[5] ^= (inSz & 0x000000FF); 02584 } 02585 /* Note, the protocol handles auth data up to 2^64, but we are 02586 * using 32-bit sizes right now, so the bigger data isn't handled 02587 * else if (inSz <= 0xFFFFFFFFFFFFFFFF) {} */ 02588 else 02589 return; 02590 02591 /* start fill out the rest of the first block */ 02592 remainder = AES_BLOCK_SIZE - authLenSz; 02593 if (inSz >= remainder) { 02594 /* plenty of bulk data to fill the remainder of this block */ 02595 xorbuf(out + authLenSz, in, remainder); 02596 inSz -= remainder; 02597 in += remainder; 02598 } 02599 else { 02600 /* not enough bulk data, copy what is available, and pad zero */ 02601 xorbuf(out + authLenSz, in, inSz); 02602 inSz = 0; 02603 } 02604 AesEncrypt(aes, out, out); 02605 02606 if (inSz > 0) 02607 roll_x(aes, in, inSz, out); 02608 } 02609 02610 02611 static INLINE void AesCcmCtrInc(byte* B, word32 lenSz) 02612 { 02613 word32 i; 02614 02615 for (i = 0; i < lenSz; i++) { 02616 if (++B[AES_BLOCK_SIZE - 1 - i] != 0) return; 02617 } 02618 } 02619 02620 02621 void AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, 02622 const byte* nonce, word32 nonceSz, 02623 byte* authTag, word32 authTagSz, 02624 const byte* authIn, word32 authInSz) 02625 { 02626 byte A[AES_BLOCK_SIZE]; 02627 byte B[AES_BLOCK_SIZE]; 02628 word32 i, lenSz; 02629 02630 XMEMCPY(B+1, nonce, nonceSz); 02631 lenSz = AES_BLOCK_SIZE - 1 - nonceSz; 02632 B[0] = (authInSz > 0 ? 64 : 0) 02633 + (8 * ((authTagSz - 2) / 2)) 02634 + (lenSz - 1); 02635 for (i = 0; i < lenSz; i++) 02636 B[AES_BLOCK_SIZE - 1 - i] = (inSz >> (8 * i)) & 0xFF; 02637 02638 AesEncrypt(aes, B, A); 02639 if (authInSz > 0) 02640 roll_auth(aes, authIn, authInSz, A); 02641 if (inSz > 0) 02642 roll_x(aes, in, inSz, A); 02643 XMEMCPY(authTag, A, authTagSz); 02644 02645 B[0] = (lenSz - 1); 02646 for (i = 0; i < lenSz; i++) 02647 B[AES_BLOCK_SIZE - 1 - i] = 0; 02648 AesEncrypt(aes, B, A); 02649 xorbuf(authTag, A, authTagSz); 02650 02651 B[15] = 1; 02652 while (inSz >= AES_BLOCK_SIZE) { 02653 AesEncrypt(aes, B, A); 02654 xorbuf(A, in, AES_BLOCK_SIZE); 02655 XMEMCPY(out, A, AES_BLOCK_SIZE); 02656 02657 AesCcmCtrInc(B, lenSz); 02658 inSz -= AES_BLOCK_SIZE; 02659 in += AES_BLOCK_SIZE; 02660 out += AES_BLOCK_SIZE; 02661 } 02662 if (inSz > 0) { 02663 AesEncrypt(aes, B, A); 02664 xorbuf(A, in, inSz); 02665 XMEMCPY(out, A, inSz); 02666 } 02667 02668 XMEMSET(A, 0, AES_BLOCK_SIZE); 02669 XMEMSET(B, 0, AES_BLOCK_SIZE); 02670 } 02671 02672 02673 int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, 02674 const byte* nonce, word32 nonceSz, 02675 const byte* authTag, word32 authTagSz, 02676 const byte* authIn, word32 authInSz) 02677 { 02678 byte A[AES_BLOCK_SIZE]; 02679 byte B[AES_BLOCK_SIZE]; 02680 byte* o; 02681 word32 i, lenSz, oSz, result = 0; 02682 02683 o = out; 02684 oSz = inSz; 02685 XMEMCPY(B+1, nonce, nonceSz); 02686 lenSz = AES_BLOCK_SIZE - 1 - nonceSz; 02687 02688 B[0] = (lenSz - 1); 02689 for (i = 0; i < lenSz; i++) 02690 B[AES_BLOCK_SIZE - 1 - i] = 0; 02691 B[15] = 1; 02692 02693 while (oSz >= AES_BLOCK_SIZE) { 02694 AesEncrypt(aes, B, A); 02695 xorbuf(A, in, AES_BLOCK_SIZE); 02696 XMEMCPY(o, A, AES_BLOCK_SIZE); 02697 02698 AesCcmCtrInc(B, lenSz); 02699 oSz -= AES_BLOCK_SIZE; 02700 in += AES_BLOCK_SIZE; 02701 o += AES_BLOCK_SIZE; 02702 } 02703 if (inSz > 0) { 02704 AesEncrypt(aes, B, A); 02705 xorbuf(A, in, oSz); 02706 XMEMCPY(o, A, oSz); 02707 } 02708 02709 for (i = 0; i < lenSz; i++) 02710 B[AES_BLOCK_SIZE - 1 - i] = 0; 02711 AesEncrypt(aes, B, A); 02712 02713 o = out; 02714 oSz = inSz; 02715 02716 B[0] = (authInSz > 0 ? 64 : 0) 02717 + (8 * ((authTagSz - 2) / 2)) 02718 + (lenSz - 1); 02719 for (i = 0; i < lenSz; i++) 02720 B[AES_BLOCK_SIZE - 1 - i] = (inSz >> (8 * i)) & 0xFF; 02721 02722 AesEncrypt(aes, B, A); 02723 if (authInSz > 0) 02724 roll_auth(aes, authIn, authInSz, A); 02725 if (inSz > 0) 02726 roll_x(aes, o, oSz, A); 02727 02728 B[0] = (lenSz - 1); 02729 for (i = 0; i < lenSz; i++) 02730 B[AES_BLOCK_SIZE - 1 - i] = 0; 02731 AesEncrypt(aes, B, B); 02732 xorbuf(A, B, authTagSz); 02733 02734 if (XMEMCMP(A, authTag, authTagSz) != 0) { 02735 /* If the authTag check fails, don't keep the decrypted data. 02736 * Unfortunately, you need the decrypted data to calculate the 02737 * check value. */ 02738 XMEMSET(out, 0, inSz); 02739 result = AES_CCM_AUTH_E; 02740 } 02741 02742 XMEMSET(A, 0, AES_BLOCK_SIZE); 02743 XMEMSET(B, 0, AES_BLOCK_SIZE); 02744 o = NULL; 02745 02746 return result; 02747 } 02748 02749 #endif 02750 02751 #endif /* STM32F2_CRYPTO */ 02752 02753 int AesSetIV(Aes* aes, const byte* iv) 02754 { 02755 if (aes == NULL) 02756 return BAD_FUNC_ARG; 02757 02758 if (iv) 02759 XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); 02760 02761 return 0; 02762 } 02763 02764 02765 #ifdef HAVE_CAVIUM 02766 02767 #include <cyassl/ctaocrypt/logging.h> 02768 #include "cavium_common.h" 02769 02770 /* Initiliaze Aes for use with Nitrox device */ 02771 int AesInitCavium(Aes* aes, int devId) 02772 { 02773 if (aes == NULL) 02774 return -1; 02775 02776 if (CspAllocContext(CONTEXT_SSL, &aes->contextHandle, devId) != 0) 02777 return -1; 02778 02779 aes->devId = devId; 02780 aes->magic = CYASSL_AES_CAVIUM_MAGIC; 02781 02782 return 0; 02783 } 02784 02785 02786 /* Free Aes from use with Nitrox device */ 02787 void AesFreeCavium(Aes* aes) 02788 { 02789 if (aes == NULL) 02790 return; 02791 02792 if (aes->magic != CYASSL_AES_CAVIUM_MAGIC) 02793 return; 02794 02795 CspFreeContext(CONTEXT_SSL, aes->contextHandle, aes->devId); 02796 aes->magic = 0; 02797 } 02798 02799 02800 static int AesCaviumSetKey(Aes* aes, const byte* key, word32 length, 02801 const byte* iv) 02802 { 02803 if (aes == NULL) 02804 return -1; 02805 02806 XMEMCPY(aes->key, key, length); /* key still holds key, iv still in reg */ 02807 if (length == 16) 02808 aes->type = AES_128; 02809 else if (length == 24) 02810 aes->type = AES_192; 02811 else if (length == 32) 02812 aes->type = AES_256; 02813 02814 return AesSetIV(aes, iv); 02815 } 02816 02817 02818 static void AesCaviumCbcEncrypt(Aes* aes, byte* out, const byte* in, 02819 word32 length) 02820 { 02821 word offset = 0; 02822 word32 requestId; 02823 02824 while (length > CYASSL_MAX_16BIT) { 02825 word16 slen = (word16)CYASSL_MAX_16BIT; 02826 if (CspEncryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE, 02827 aes->type, slen, (byte*)in + offset, out + offset, 02828 (byte*)aes->reg, (byte*)aes->key, &requestId, 02829 aes->devId) != 0) { 02830 CYASSL_MSG("Bad Cavium Aes Encrypt"); 02831 } 02832 length -= CYASSL_MAX_16BIT; 02833 offset += CYASSL_MAX_16BIT; 02834 XMEMCPY(aes->reg, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE); 02835 } 02836 if (length) { 02837 word16 slen = (word16)length; 02838 if (CspEncryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE, 02839 aes->type, slen, (byte*)in + offset, out + offset, 02840 (byte*)aes->reg, (byte*)aes->key, &requestId, 02841 aes->devId) != 0) { 02842 CYASSL_MSG("Bad Cavium Aes Encrypt"); 02843 } 02844 XMEMCPY(aes->reg, out + offset+length - AES_BLOCK_SIZE, AES_BLOCK_SIZE); 02845 } 02846 } 02847 02848 static void AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in, 02849 word32 length) 02850 { 02851 word32 requestId; 02852 word offset = 0; 02853 02854 while (length > CYASSL_MAX_16BIT) { 02855 word16 slen = (word16)CYASSL_MAX_16BIT; 02856 XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE); 02857 if (CspDecryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE, 02858 aes->type, slen, (byte*)in + offset, out + offset, 02859 (byte*)aes->reg, (byte*)aes->key, &requestId, 02860 aes->devId) != 0) { 02861 CYASSL_MSG("Bad Cavium Aes Decrypt"); 02862 } 02863 length -= CYASSL_MAX_16BIT; 02864 offset += CYASSL_MAX_16BIT; 02865 XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); 02866 } 02867 if (length) { 02868 word16 slen = (word16)length; 02869 XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE); 02870 if (CspDecryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE, 02871 aes->type, slen, (byte*)in + offset, out + offset, 02872 (byte*)aes->reg, (byte*)aes->key, &requestId, 02873 aes->devId) != 0) { 02874 CYASSL_MSG("Bad Cavium Aes Decrypt"); 02875 } 02876 XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); 02877 } 02878 } 02879 02880 #endif /* HAVE_CAVIUM */ 02881 02882 #endif /* NO_AES */ 02883
Generated on Thu Jul 14 2022 00:25:23 by 1.7.2