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