This is a port of cyaSSL 2.7.0.

Dependents:   CyaSSL_DTLS_Cellular CyaSSL_DTLS_Ethernet

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers aes.c Source File

aes.c

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