cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

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