wolf SSL / CyaSSL-2.9.4

Dependents:  

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers aes.c Source File

aes.c

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