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