MultiTech / CyaSSL

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

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