diff --git a/ctaocrypt/src/aes.c b/ctaocrypt/src/aes.c index 083bc807b..f5fa52b53 100644 --- a/ctaocrypt/src/aes.c +++ b/ctaocrypt/src/aes.c @@ -51,841 +51,59 @@ #endif +#if defined(STM32F2_CRYPTO) + /* STM32F2 hardware AES support for CBC, CTR modes through the STM32F2 + * Standard Peripheral Library. Documentation located in STM32F2xx + * Standard Peripheral Library document (See note in README). + * NOTE: no support for AES-GCM/CCM/Direct */ + #include "stm32f2xx.h" + #include "stm32f2xx_cryp.h" +#elif defined(HAVE_COLDFIRE_SEC) + /* Freescale Coldfire SEC support for CBC mode. + * NOTE: no support for AES-CTR/GCM/CCM/Direct */ + #include + #include "sec.h" + #include "mcf5475_sec.h" + #include "mcf5475_siu.h" +#elif defined(FREESCALE_MMCAU) + /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes + * through the CAU/mmCAU library. Documentation located in + * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User + * Guide (See note in README). + * NOTE: no support for AES-CTR */ + #include "cau_api.h" +#elif defined(CYASSL_PIC32MZ_CRYPT) + /* NOTE: no support for AES-CCM/Direct */ + #define DEBUG_CYASSL + #include "cyassl/ctaocrypt/port/pic32/pic32mz-crypt.h" +#elif defined(HAVE_CAVIUM) + #include + #include "cavium_common.h" + + /* still leave SW crypto available */ + #define NEED_AES_TABLES -#ifdef HAVE_CAVIUM static int AesCaviumSetKey(Aes* aes, const byte* key, word32 length, const byte* iv); static int AesCaviumCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 length); static int AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 length); -#endif +#else + /* using CTaoCrypt software AES implementation */ + #define NEED_AES_TABLES +#endif /* STM32F2_CRYPTO */ -#if defined(CYASSL_PIC32MZ_CRYPT) -#include "cyassl/ctaocrypt/port/pic32/pic32mz-crypt.h" -#define DEBUG_CYASSL - - /* core hardware crypt engine driver */ - static void AesCrypt(Aes *aes, byte* out, const byte* in, word32 sz, - int dir, int algo, int cryptoalgo) - { - securityAssociation *sa_p ; - bufferDescriptor *bd_p ; - - volatile securityAssociation sa __attribute__((aligned (8))); - volatile bufferDescriptor bd __attribute__((aligned (8))); - volatile int k ; - - /* get uncached address */ - sa_p = KVA0_TO_KVA1(&sa) ; - bd_p = KVA0_TO_KVA1(&bd) ; - - /* Sync cache and physical memory */ - if(PIC32MZ_IF_RAM(in)) { - XMEMCPY((void *)KVA0_TO_KVA1(in), (void *)in, sz); - } - XMEMSET((void *)KVA0_TO_KVA1(out), 0, sz); - /* Set up the Security Association */ - XMEMSET((byte *)KVA0_TO_KVA1(&sa), 0, sizeof(sa)); - sa_p->SA_CTRL.ALGO = algo ; /* AES */ - sa_p->SA_CTRL.LNC = 1; - sa_p->SA_CTRL.LOADIV = 1; - sa_p->SA_CTRL.FB = 1; - sa_p->SA_CTRL.ENCTYPE = dir ; /* Encryption/Decryption */ - sa_p->SA_CTRL.CRYPTOALGO = cryptoalgo; - - if(cryptoalgo == PIC32_CRYPTOALGO_AES_GCM){ - switch(aes->keylen) { - case 32: - sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_256 ; - break ; - case 24: - sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_192 ; - break ; - case 16: - sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_128 ; - break ; - } - } else - sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_128 ; - - ByteReverseWords( - (word32 *)KVA0_TO_KVA1(sa.SA_ENCKEY + 8 - aes->keylen/sizeof(word32)), - (word32 *)aes->key_ce, aes->keylen); - ByteReverseWords( - (word32*)KVA0_TO_KVA1(sa.SA_ENCIV), (word32 *)aes->iv_ce, 16); - - XMEMSET((byte *)KVA0_TO_KVA1(&bd), 0, sizeof(bd)); - /* Set up the Buffer Descriptor */ - bd_p->BD_CTRL.BUFLEN = sz; - if(cryptoalgo == PIC32_CRYPTOALGO_AES_GCM) { - if(sz % 0x10) - bd_p->BD_CTRL.BUFLEN = (sz/0x10 + 1) * 0x10 ; - } - bd_p->BD_CTRL.LIFM = 1; - bd_p->BD_CTRL.SA_FETCH_EN = 1; - bd_p->BD_CTRL.LAST_BD = 1; - bd_p->BD_CTRL.DESC_EN = 1; - - bd_p->SA_ADDR = (unsigned int)KVA_TO_PA(&sa) ; - bd_p->SRCADDR = (unsigned int)KVA_TO_PA(in) ; - bd_p->DSTADDR = (unsigned int)KVA_TO_PA(out); - bd_p->MSGLEN = sz ; - - CECON = 1 << 6; - while (CECON); - - /* Run the engine */ - CEBDPADDR = (unsigned int)KVA_TO_PA(&bd) ; - CEINTEN = 0x07; - CECON = 0x27; - - WAIT_ENGINE ; - - if((cryptoalgo == PIC32_CRYPTOALGO_CBC) || - (cryptoalgo == PIC32_CRYPTOALGO_TCBC)|| - (cryptoalgo == PIC32_CRYPTOALGO_RCBC)) { - /* set iv for the next call */ - if(dir == PIC32_ENCRYPTION) { - XMEMCPY((void *)aes->iv_ce, - (void*)KVA0_TO_KVA1(out + sz - AES_BLOCK_SIZE), - AES_BLOCK_SIZE) ; - } else { - ByteReverseWords((word32*)aes->iv_ce, - (word32 *)KVA0_TO_KVA1(in + sz - AES_BLOCK_SIZE), - AES_BLOCK_SIZE); - } - } - XMEMCPY((byte *)out, (byte *)KVA0_TO_KVA1(out), sz) ; - ByteReverseWords((word32*)out, (word32 *)out, sz); - } - - int AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) - { - AesCrypt(aes, out, in, sz, PIC32_ENCRYPTION, PIC32_ALGO_AES, - PIC32_CRYPTOALGO_RCBC ); - return 0 ; - } - - int AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) - { - AesCrypt(aes, out, in, sz, PIC32_DECRYPTION, PIC32_ALGO_AES, - PIC32_CRYPTOALGO_RCBC); - return 0 ; - } - - #if defined(CYASSL_AES_COUNTER) - void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) - { - int i ; - char out_block[AES_BLOCK_SIZE] ; - int odd ; - int even ; - char *tmp ; /* (char *)aes->tmp, for short */ - - tmp = (char *)aes->tmp ; - if(aes->left) { - if((aes->left + sz) >= AES_BLOCK_SIZE){ - odd = AES_BLOCK_SIZE - aes->left ; - } else { - odd = sz ; - } - XMEMCPY(tmp+aes->left, in, odd) ; - if((odd+aes->left) == AES_BLOCK_SIZE){ - AesCrypt(aes, out_block, tmp, AES_BLOCK_SIZE, - PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR); - XMEMCPY(out, out_block+aes->left, odd) ; - aes->left = 0 ; - XMEMSET(tmp, 0x0, AES_BLOCK_SIZE) ; - /* Increment IV */ - for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { - if (++((byte *)aes->iv_ce)[i]) - break ; - } - } - in += odd ; - out+= odd ; - sz -= odd ; - } - odd = sz % AES_BLOCK_SIZE ; /* if there is tail flagment */ - if(sz / AES_BLOCK_SIZE) { - even = (sz/AES_BLOCK_SIZE)*AES_BLOCK_SIZE ; - AesCrypt(aes, out, in, even, PIC32_ENCRYPTION, PIC32_ALGO_AES, - PIC32_CRYPTOALGO_RCTR); - out += even ; - in += even ; - do { /* Increment IV */ - for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { - if (++((byte *)aes->iv_ce)[i]) - break ; - } - even -= AES_BLOCK_SIZE ; - } while((int)even > 0) ; - } - if(odd) { - XMEMSET(tmp+aes->left, 0x0, AES_BLOCK_SIZE - aes->left) ; - XMEMCPY(tmp+aes->left, in, odd) ; - AesCrypt(aes, out_block, tmp, AES_BLOCK_SIZE, - PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR); - XMEMCPY(out, out_block+aes->left,odd) ; - aes->left += odd ; - } - } - #endif /* CYASSL_AES_COUNTER */ - - #ifdef HAVE_AESGCM - #define HAVE_AES_ENGINE - /* Hardware AESGCM borows most of the software AESGCM, GMAC */ - #endif - -#endif /* CYASSL_PIC32MZ_CRYPT */ - -#ifdef STM32F2_CRYPTO - /* - * STM32F2 hardware AES support through the STM32F2 standard peripheral - * library. Documentation located in STM32F2xx Standard Peripheral Library - * document (See note in README). - */ - #include "stm32f2xx.h" - #include "stm32f2xx_cryp.h" - - int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, - int dir) - { - word32 *rk = aes->key; - - if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) - return BAD_FUNC_ARG; - - aes->rounds = keylen/4 + 6; - XMEMCPY(rk, userKey, keylen); - ByteReverseWords(rk, rk, keylen); - - return AesSetIV(aes, iv); - } - - int AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) - { - word32 *enc_key, *iv; - CRYP_InitTypeDef AES_CRYP_InitStructure; - CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure; - CRYP_IVInitTypeDef AES_CRYP_IVInitStructure; - - enc_key = aes->key; - iv = aes->reg; - - /* crypto structure initialization */ - CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure); - CRYP_StructInit(&AES_CRYP_InitStructure); - CRYP_IVStructInit(&AES_CRYP_IVInitStructure); - - /* reset registers to their default values */ - CRYP_DeInit(); - - /* load key into correct registers */ - switch(aes->rounds) - { - case 10: /* 128-bit key */ - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[0]; - AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1]; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[2]; - AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3]; - break; - - case 12: /* 192-bit key */ - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b; - AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[0]; - AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1]; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[2]; - AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3]; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[4]; - AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5]; - break; - - case 14: /* 256-bit key */ - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b; - AES_CRYP_KeyInitStructure.CRYP_Key0Left = enc_key[0]; - AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1]; - AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[2]; - AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3]; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[4]; - AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5]; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[6]; - AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7]; - break; - - default: - break; - } - CRYP_KeyInit(&AES_CRYP_KeyInitStructure); - - /* set iv */ - ByteReverseWords(iv, iv, AES_BLOCK_SIZE); - AES_CRYP_IVInitStructure.CRYP_IV0Left = iv[0]; - AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1]; - AES_CRYP_IVInitStructure.CRYP_IV1Left = iv[2]; - AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3]; - CRYP_IVInit(&AES_CRYP_IVInitStructure); - - /* set direction, mode, and datatype */ - AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; - AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC; - AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; - CRYP_Init(&AES_CRYP_InitStructure); - - /* enable crypto processor */ - CRYP_Cmd(ENABLE); - - while (sz > 0) - { - /* flush IN/OUT FIFOs */ - CRYP_FIFOFlush(); - - CRYP_DataIn(*(uint32_t*)&in[0]); - CRYP_DataIn(*(uint32_t*)&in[4]); - CRYP_DataIn(*(uint32_t*)&in[8]); - CRYP_DataIn(*(uint32_t*)&in[12]); - - /* wait until the complete message has been processed */ - while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} - - *(uint32_t*)&out[0] = CRYP_DataOut(); - *(uint32_t*)&out[4] = CRYP_DataOut(); - *(uint32_t*)&out[8] = CRYP_DataOut(); - *(uint32_t*)&out[12] = CRYP_DataOut(); - - /* store iv for next call */ - XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); - - sz -= 16; - in += 16; - out += 16; - } - - /* disable crypto processor */ - CRYP_Cmd(DISABLE); - - return 0; - } - - int AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) - { - word32 *dec_key, *iv; - CRYP_InitTypeDef AES_CRYP_InitStructure; - CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure; - CRYP_IVInitTypeDef AES_CRYP_IVInitStructure; - - dec_key = aes->key; - iv = aes->reg; - - /* crypto structure initialization */ - CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure); - CRYP_StructInit(&AES_CRYP_InitStructure); - CRYP_IVStructInit(&AES_CRYP_IVInitStructure); - - /* if input and output same will overwrite input iv */ - XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); - - /* reset registers to their default values */ - CRYP_DeInit(); - - /* load key into correct registers */ - switch(aes->rounds) - { - case 10: /* 128-bit key */ - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = dec_key[0]; - AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[1]; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = dec_key[2]; - AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[3]; - break; - - case 12: /* 192-bit key */ - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b; - AES_CRYP_KeyInitStructure.CRYP_Key1Left = dec_key[0]; - AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[1]; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = dec_key[2]; - AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[3]; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = dec_key[4]; - AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[5]; - break; - - case 14: /* 256-bit key */ - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b; - AES_CRYP_KeyInitStructure.CRYP_Key0Left = dec_key[0]; - AES_CRYP_KeyInitStructure.CRYP_Key0Right = dec_key[1]; - AES_CRYP_KeyInitStructure.CRYP_Key1Left = dec_key[2]; - AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[3]; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = dec_key[4]; - AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[5]; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = dec_key[6]; - AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[7]; - break; - - default: - break; - } - - /* set direction, mode, and datatype for key preparation */ - AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; - AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key; - AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b; - CRYP_Init(&AES_CRYP_InitStructure); - CRYP_KeyInit(&AES_CRYP_KeyInitStructure); - - /* enable crypto processor */ - CRYP_Cmd(ENABLE); - - /* wait until key has been prepared */ - while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} - - /* set direction, mode, and datatype for decryption */ - AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; - AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC; - AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; - CRYP_Init(&AES_CRYP_InitStructure); - - /* set iv */ - ByteReverseWords(iv, iv, AES_BLOCK_SIZE); - - AES_CRYP_IVInitStructure.CRYP_IV0Left = iv[0]; - AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1]; - AES_CRYP_IVInitStructure.CRYP_IV1Left = iv[2]; - AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3]; - CRYP_IVInit(&AES_CRYP_IVInitStructure); - - /* enable crypto processor */ - CRYP_Cmd(ENABLE); - - while (sz > 0) - { - /* flush IN/OUT FIFOs */ - CRYP_FIFOFlush(); - - CRYP_DataIn(*(uint32_t*)&in[0]); - CRYP_DataIn(*(uint32_t*)&in[4]); - CRYP_DataIn(*(uint32_t*)&in[8]); - CRYP_DataIn(*(uint32_t*)&in[12]); - - /* wait until the complete message has been processed */ - while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} - - *(uint32_t*)&out[0] = CRYP_DataOut(); - *(uint32_t*)&out[4] = CRYP_DataOut(); - *(uint32_t*)&out[8] = CRYP_DataOut(); - *(uint32_t*)&out[12] = CRYP_DataOut(); - - /* store iv for next call */ - XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); - - sz -= 16; - in += 16; - out += 16; - } - - /* disable crypto processor */ - CRYP_Cmd(DISABLE); - - return 0; - } - - #ifdef CYASSL_AES_COUNTER - - /* AES-CTR calls this for key setup */ - int AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, - const byte* iv, int dir) - { - return AesSetKey(aes, userKey, keylen, iv, dir); - } - - void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) - { - word32 *enc_key, *iv; - CRYP_InitTypeDef AES_CRYP_InitStructure; - CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure; - CRYP_IVInitTypeDef AES_CRYP_IVInitStructure; - - enc_key = aes->key; - iv = aes->reg; - - /* crypto structure initialization */ - CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure); - CRYP_StructInit(&AES_CRYP_InitStructure); - CRYP_IVStructInit(&AES_CRYP_IVInitStructure); - - /* reset registers to their default values */ - CRYP_DeInit(); - - /* load key into correct registers */ - switch(aes->rounds) - { - case 10: /* 128-bit key */ - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[0]; - AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1]; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[2]; - AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3]; - break; - - case 12: /* 192-bit key */ - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b; - AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[0]; - AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1]; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[2]; - AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3]; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[4]; - AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5]; - break; - - case 14: /* 256-bit key */ - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b; - AES_CRYP_KeyInitStructure.CRYP_Key0Left = enc_key[0]; - AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1]; - AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[2]; - AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3]; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[4]; - AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5]; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[6]; - AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7]; - break; - - default: - break; - } - CRYP_KeyInit(&AES_CRYP_KeyInitStructure); - - /* set iv */ - ByteReverseWords(iv, iv, AES_BLOCK_SIZE); - AES_CRYP_IVInitStructure.CRYP_IV0Left = iv[0]; - AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1]; - AES_CRYP_IVInitStructure.CRYP_IV1Left = iv[2]; - AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3]; - CRYP_IVInit(&AES_CRYP_IVInitStructure); - - /* set direction, mode, and datatype */ - AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; - AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR; - AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; - CRYP_Init(&AES_CRYP_InitStructure); - - /* enable crypto processor */ - CRYP_Cmd(ENABLE); - - while (sz > 0) - { - /* flush IN/OUT FIFOs */ - CRYP_FIFOFlush(); - - CRYP_DataIn(*(uint32_t*)&in[0]); - CRYP_DataIn(*(uint32_t*)&in[4]); - CRYP_DataIn(*(uint32_t*)&in[8]); - CRYP_DataIn(*(uint32_t*)&in[12]); - - /* wait until the complete message has been processed */ - while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} - - *(uint32_t*)&out[0] = CRYP_DataOut(); - *(uint32_t*)&out[4] = CRYP_DataOut(); - *(uint32_t*)&out[8] = CRYP_DataOut(); - *(uint32_t*)&out[12] = CRYP_DataOut(); - - /* store iv for next call */ - XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); - - sz -= 16; - in += 16; - out += 16; - } - - /* disable crypto processor */ - CRYP_Cmd(DISABLE); - } - - #endif /* CYASSL_AES_COUNTER */ - -#elif defined(HAVE_COLDFIRE_SEC) - - #include - - #include "sec.h" - #include "mcf5475_sec.h" - #include "mcf5475_siu.h" - - #if defined (HAVE_THREADX) - #include "memory_pools.h" - extern TX_BYTE_POOL mp_ncached; /* Non Cached memory pool */ - #endif - - #define AES_BUFFER_SIZE (AES_BLOCK_SIZE * 64) - static unsigned char *AESBuffIn = NULL; - static unsigned char *AESBuffOut = NULL; - static byte *secReg; - static byte *secKey; - static volatile SECdescriptorType *secDesc; - - static CyaSSL_Mutex Mutex_AesSEC; - - #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010 - #define SEC_DESC_AES_CBC_DECRYPT 0x60200010 - - extern volatile unsigned char __MBAR[]; - - static int AesCbcCrypt(Aes* aes, byte* po, const byte* pi, word32 sz, - word32 descHeader) - { - #ifdef DEBUG_CYASSL - int i; int stat1, stat2; int ret; - #endif - - int size; - volatile int v; - - if ((pi == NULL) || (po == NULL)) - return BAD_FUNC_ARG; /*wrong pointer*/ - - LockMutex(&Mutex_AesSEC); - - /* Set descriptor for SEC */ - secDesc->length1 = 0x0; - secDesc->pointer1 = NULL; - - secDesc->length2 = AES_BLOCK_SIZE; - secDesc->pointer2 = (byte *)secReg; /* Initial Vector */ - - switch(aes->rounds) { - case 10: secDesc->length3 = 16 ; break ; - case 12: secDesc->length3 = 24 ; break ; - case 14: secDesc->length3 = 32 ; break ; - } - XMEMCPY(secKey, aes->key, secDesc->length3); - - secDesc->pointer3 = (byte *)secKey; - secDesc->pointer4 = AESBuffIn; - secDesc->pointer5 = AESBuffOut; - secDesc->length6 = 0x0; - secDesc->pointer6 = NULL; - secDesc->length7 = 0x0; - secDesc->pointer7 = NULL; - secDesc->nextDescriptorPtr = NULL; - - while (sz) { - secDesc->header = descHeader; - XMEMCPY(secReg, aes->reg, AES_BLOCK_SIZE); - if ((sz % AES_BUFFER_SIZE) == sz) { - size = sz; - sz = 0; - } else { - size = AES_BUFFER_SIZE; - sz -= AES_BUFFER_SIZE; - } - secDesc->length4 = size; - secDesc->length5 = size; - - XMEMCPY(AESBuffIn, pi, size); - if(descHeader == SEC_DESC_AES_CBC_DECRYPT) { - XMEMCPY((void*)aes->tmp, (void*)&(pi[size-AES_BLOCK_SIZE]), - AES_BLOCK_SIZE); - } - - /* Point SEC to the location of the descriptor */ - MCF_SEC_FR0 = (uint32)secDesc; - /* Initialize SEC and wait for encryption to complete */ - MCF_SEC_CCCR0 = 0x0000001a; - /* poll SISR to determine when channel is complete */ - v=0; - - while ((secDesc->header>> 24) != 0xff) v++; - - #ifdef DEBUG_CYASSL - ret = MCF_SEC_SISRH; - stat1 = MCF_SEC_AESSR; - stat2 = MCF_SEC_AESISR; - if (ret & 0xe0000000) { - db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, " - "AESISR=%08x\n", i, ret, stat1, stat2); - } - #endif - - XMEMCPY(po, AESBuffOut, size); - - if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) { - XMEMCPY((void*)aes->reg, (void*)&(po[size-AES_BLOCK_SIZE]), - AES_BLOCK_SIZE); - } else { - XMEMCPY((void*)aes->reg, (void*)aes->tmp, AES_BLOCK_SIZE); - } - - pi += size; - po += size; - } - - UnLockMutex(&Mutex_AesSEC); - return 0; - } - - int AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz) - { - return (AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT)); - } - - int AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz) - { - return (AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT)); - } - - int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, - int dir) - { - if (AESBuffIn == NULL) { - #if defined (HAVE_THREADX) - int s1, s2, s3, s4, s5 ; - s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc, - sizeof(SECdescriptorType), TX_NO_WAIT); - s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn, - AES_BUFFER_SIZE, TX_NO_WAIT); - s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut, - AES_BUFFER_SIZE, TX_NO_WAIT); - s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey, - AES_BLOCK_SIZE*2, TX_NO_WAIT); - s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg, - AES_BLOCK_SIZE, TX_NO_WAIT); - - if(s1 || s2 || s3 || s4 || s5) - return BAD_FUNC_ARG; - #else - #warning "Allocate non-Cache buffers" - #endif - - InitMutex(&Mutex_AesSEC); - } - - if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) - return BAD_FUNC_ARG; - - if (aes == NULL) - return BAD_FUNC_ARG; - - aes->rounds = keylen/4 + 6; - XMEMCPY(aes->key, userKey, keylen); - - if (iv) - XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); - - return 0; - } - -#elif defined FREESCALE_MMCAU - /* - * Freescale mmCAU hardware AES support through the CAU/mmCAU library. - * Documentation located in ColdFire/ColdFire+ CAU and Kinetis mmCAU - * Software Library User Guide (See note in README). - */ - #include "cau_api.h" - - int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, - int dir) - { - byte *rk = (byte*)aes->key; - - if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) - return BAD_FUNC_ARG; - - if (rk == NULL) - return BAD_FUNC_ARG; - - aes->rounds = keylen/4 + 6; - cau_aes_set_key(userKey, keylen*8, rk); - - return AesSetIV(aes, iv); - } - - int AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) - { - int i; - int offset = 0; - int len = sz; - - byte *iv, *enc_key; - byte temp_block[AES_BLOCK_SIZE]; - - iv = (byte*)aes->reg; - enc_key = (byte*)aes->key; - - if ((word)out % CYASSL_MMCAU_ALIGNMENT) { - CYASSL_MSG("Bad cau_aes_encrypt alignment"); - return BAD_ALIGN_E; - } - - while (len > 0) - { - XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE); - - /* XOR block with IV for CBC */ - for (i = 0; i < AES_BLOCK_SIZE; i++) - temp_block[i] ^= iv[i]; - - cau_aes_encrypt(temp_block, enc_key, aes->rounds, out + offset); - - len -= AES_BLOCK_SIZE; - offset += AES_BLOCK_SIZE; - - /* store IV for next block */ - XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE); - } - - return 0; - } - - int AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) - { - int i; - int offset = 0; - int len = sz; - - byte* iv, *dec_key; - byte temp_block[AES_BLOCK_SIZE]; - - iv = (byte*)aes->reg; - dec_key = (byte*)aes->key; - - if ((word)out % CYASSL_MMCAU_ALIGNMENT) { - CYASSL_MSG("Bad cau_aes_decrypt alignment"); - return BAD_ALIGN_E; - } - - while (len > 0) - { - XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE); - - cau_aes_decrypt(in + offset, dec_key, aes->rounds, out + offset); - - /* XOR block with IV for CBC */ - for (i = 0; i < AES_BLOCK_SIZE; i++) - (out + offset)[i] ^= iv[i]; - - /* store IV for next block */ - XMEMCPY(iv, temp_block, AES_BLOCK_SIZE); - - len -= AES_BLOCK_SIZE; - offset += AES_BLOCK_SIZE; - } - - return 0; - } - - -#else /* CTaoCrypt software implementation */ +#ifdef NEED_AES_TABLES static const word32 rcon[] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ }; - static const word32 Te[5][256] = { { 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, @@ -1219,7 +437,6 @@ static const word32 Te[5][256] = { } }; - static const word32 Td[5][256] = { { 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, @@ -1554,10 +771,8 @@ static const word32 Td[5][256] = { } }; - #define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y)))) - #ifdef CYASSL_AESNI /* Each platform needs to query info type 1 from cpuid to see if aesni is @@ -1581,7 +796,7 @@ static const word32 Td[5][256] = { #endif /* _MSC_VER */ - + static int Check_CPU_support_AES(void) { unsigned int reg[4]; /* put a,b,c,d into 0,1,2,3 */ @@ -1619,25 +834,25 @@ void AES_ECB_decrypt(const unsigned char* in, unsigned char* out, unsigned long length, const unsigned char* KS, int nr) XASM_LINK("AES_ECB_decrypt"); -void AES_128_Key_Expansion(const unsigned char* userkey, +void AES_128_Key_Expansion(const unsigned char* userkey, unsigned char* key_schedule) XASM_LINK("AES_128_Key_Expansion"); -void AES_192_Key_Expansion(const unsigned char* userkey, +void AES_192_Key_Expansion(const unsigned char* userkey, unsigned char* key_schedule) XASM_LINK("AES_192_Key_Expansion"); -void AES_256_Key_Expansion(const unsigned char* userkey, +void AES_256_Key_Expansion(const unsigned char* userkey, unsigned char* key_schedule) XASM_LINK("AES_256_Key_Expansion"); static int AES_set_encrypt_key(const unsigned char *userKey, const int bits, Aes* aes) -{ +{ if (!userKey || !aes) return BAD_FUNC_ARG; - + if (bits == 128) { AES_128_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 10; return 0; @@ -1661,7 +876,7 @@ static int AES_set_decrypt_key(const unsigned char* userKey, const int bits, Aes temp_key; __m128i *Key_Schedule = (__m128i*)aes->key; __m128i *Temp_Key_Schedule = (__m128i*)temp_key.key; - + if (!userKey || !aes) return BAD_FUNC_ARG; @@ -1681,7 +896,7 @@ static int AES_set_decrypt_key(const unsigned char* userKey, const int bits, Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]); Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]); Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]); - + if(nr>10) { Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]); Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]); @@ -1693,7 +908,7 @@ static int AES_set_decrypt_key(const unsigned char* userKey, const int bits, } Key_Schedule[0] = Temp_Key_Schedule[nr]; - + return 0; } @@ -1702,189 +917,6 @@ static int AES_set_decrypt_key(const unsigned char* userKey, const int bits, #endif /* CYASSL_AESNI */ -static int AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen, - const byte* iv, int dir) -{ - word32 temp, *rk = aes->key; - unsigned int i = 0; - - #ifdef CYASSL_AESNI - aes->use_aesni = 0; - #endif /* CYASSL_AESNI */ - #ifdef CYASSL_AES_COUNTER - aes->left = 0; - #endif /* CYASSL_AES_COUNTER */ - - aes->rounds = keylen/4 + 6; - - XMEMCPY(rk, userKey, keylen); - #ifdef LITTLE_ENDIAN_ORDER - ByteReverseWords(rk, rk, keylen); - #endif - -#ifdef CYASSL_PIC32MZ_CRYPT - { - word32 *akey1 = aes->key_ce; - word32 *areg = aes->iv_ce ; - aes->keylen = keylen ; - XMEMCPY(akey1, userKey, keylen); - if (iv) - XMEMCPY(areg, iv, AES_BLOCK_SIZE); - else - XMEMSET(areg, 0, AES_BLOCK_SIZE); - } -#endif - - switch(keylen) - { - case 16: - while (1) - { - temp = rk[3]; - rk[4] = rk[0] ^ - (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ - (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ - (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ - (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ - rcon[i]; - rk[5] = rk[1] ^ rk[4]; - rk[6] = rk[2] ^ rk[5]; - rk[7] = rk[3] ^ rk[6]; - if (++i == 10) - break; - rk += 4; - } - break; - - case 24: - while (1) /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */ - { - temp = rk[ 5]; - rk[ 6] = rk[ 0] ^ - (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ - (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ - (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ - (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ - rcon[i]; - rk[ 7] = rk[ 1] ^ rk[ 6]; - rk[ 8] = rk[ 2] ^ rk[ 7]; - rk[ 9] = rk[ 3] ^ rk[ 8]; - if (++i == 8) - break; - rk[10] = rk[ 4] ^ rk[ 9]; - rk[11] = rk[ 5] ^ rk[10]; - rk += 6; - } - break; - - case 32: - while (1) - { - temp = rk[ 7]; - rk[ 8] = rk[ 0] ^ - (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ - (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ - (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ - (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ - rcon[i]; - rk[ 9] = rk[ 1] ^ rk[ 8]; - rk[10] = rk[ 2] ^ rk[ 9]; - rk[11] = rk[ 3] ^ rk[10]; - if (++i == 7) - break; - temp = rk[11]; - rk[12] = rk[ 4] ^ - (Te[4][GETBYTE(temp, 3)] & 0xff000000) ^ - (Te[4][GETBYTE(temp, 2)] & 0x00ff0000) ^ - (Te[4][GETBYTE(temp, 1)] & 0x0000ff00) ^ - (Te[4][GETBYTE(temp, 0)] & 0x000000ff); - rk[13] = rk[ 5] ^ rk[12]; - rk[14] = rk[ 6] ^ rk[13]; - rk[15] = rk[ 7] ^ rk[14]; - - rk += 8; - } - break; - - default: - return BAD_FUNC_ARG; - } - - if (dir == AES_DECRYPTION) - { - unsigned int j; - rk = aes->key; - - /* invert the order of the round keys: */ - for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) { - temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; - temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; - temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; - temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; - } - /* apply the inverse MixColumn transform to all round keys but the - first and the last: */ - for (i = 1; i < aes->rounds; i++) { - rk += 4; - rk[0] = - Td[0][Te[4][GETBYTE(rk[0], 3)] & 0xff] ^ - Td[1][Te[4][GETBYTE(rk[0], 2)] & 0xff] ^ - Td[2][Te[4][GETBYTE(rk[0], 1)] & 0xff] ^ - Td[3][Te[4][GETBYTE(rk[0], 0)] & 0xff]; - rk[1] = - Td[0][Te[4][GETBYTE(rk[1], 3)] & 0xff] ^ - Td[1][Te[4][GETBYTE(rk[1], 2)] & 0xff] ^ - Td[2][Te[4][GETBYTE(rk[1], 1)] & 0xff] ^ - Td[3][Te[4][GETBYTE(rk[1], 0)] & 0xff]; - rk[2] = - Td[0][Te[4][GETBYTE(rk[2], 3)] & 0xff] ^ - Td[1][Te[4][GETBYTE(rk[2], 2)] & 0xff] ^ - Td[2][Te[4][GETBYTE(rk[2], 1)] & 0xff] ^ - Td[3][Te[4][GETBYTE(rk[2], 0)] & 0xff]; - rk[3] = - Td[0][Te[4][GETBYTE(rk[3], 3)] & 0xff] ^ - Td[1][Te[4][GETBYTE(rk[3], 2)] & 0xff] ^ - Td[2][Te[4][GETBYTE(rk[3], 1)] & 0xff] ^ - Td[3][Te[4][GETBYTE(rk[3], 0)] & 0xff]; - } - } - - return AesSetIV(aes, iv); -} - - -int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, - int dir) -{ - - if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) - return BAD_FUNC_ARG; - -#ifdef HAVE_CAVIUM - if (aes->magic == CYASSL_AES_CAVIUM_MAGIC) - return AesCaviumSetKey(aes, userKey, keylen, iv); -#endif - -#ifdef CYASSL_AESNI - if (checkAESNI == 0) { - haveAESNI = Check_CPU_support_AES(); - checkAESNI = 1; - } - if (haveAESNI) { - aes->use_aesni = 1; - if (iv) - XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); - if (dir == AES_ENCRYPTION) - return AES_set_encrypt_key(userKey, keylen * 8, aes); - else - return AES_set_decrypt_key(userKey, keylen * 8, aes); - } -#endif /* CYASSL_AESNI */ - - return AesSetKeyLocal(aes, userKey, keylen, iv, dir); -} - - static void AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) { word32 s0, s1, s2, s3; @@ -1958,7 +990,7 @@ static void AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) s1 ^= rk[1]; s2 ^= rk[2]; s3 ^= rk[3]; - + /* * Nr - 1 full rounds: */ @@ -1993,7 +1025,7 @@ static void AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) if (--r == 0) { break; } - + s0 = Te[0][GETBYTE(t0, 3)] ^ Te[1][GETBYTE(t1, 2)] ^ @@ -2064,7 +1096,6 @@ static void AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3)); } - static void AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) { word32 s0, s1, s2, s3; @@ -2120,7 +1151,7 @@ static void AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) s1 ^= rk[1]; s2 ^= rk[2]; s3 ^= rk[3]; - + /* * Nr - 1 full rounds: */ @@ -2224,203 +1255,1227 @@ static void AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3)); } -#ifndef HAVE_AES_ENGINE -int AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) -{ - word32 blocks = sz / AES_BLOCK_SIZE; +#endif /* NEED_AES_TABLES */ -#ifdef HAVE_CAVIUM - if (aes->magic == CYASSL_AES_CAVIUM_MAGIC) - return AesCaviumCbcEncrypt(aes, out, in, sz); -#endif -#ifdef CYASSL_AESNI - if (haveAESNI) { - #ifdef DEBUG_AESNI - printf("about to aes cbc encrypt\n"); - printf("in = %p\n", in); - printf("out = %p\n", out); - printf("aes->key = %p\n", aes->key); - printf("aes->reg = %p\n", aes->reg); - printf("aes->rounds = %d\n", aes->rounds); - printf("sz = %d\n", sz); - #endif +/* AesSetKey */ +#ifdef STM32F2_CRYPTO + int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, + int dir) + { + word32 *rk = aes->key; - /* check alignment, decrypt doesn't need alignment */ - if ((word)in % 16) { - #ifndef NO_CYASSL_ALLOC_ALIGN - byte* tmp = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_TMP_BUFFER); - CYASSL_MSG("AES-CBC encrypt with bad alignment"); - if (tmp == NULL) return MEMORY_E; + if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) + return BAD_FUNC_ARG; - XMEMCPY(tmp, in, sz); - AES_CBC_encrypt(tmp, tmp, (byte*)aes->reg, sz, (byte*)aes->key, - aes->rounds); - /* store iv for next call */ - XMEMCPY(aes->reg, tmp + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + aes->rounds = keylen/4 + 6; + XMEMCPY(rk, userKey, keylen); + ByteReverseWords(rk, rk, keylen); - XMEMCPY(out, tmp, sz); - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return 0; - #else - return BAD_ALIGN_E; - #endif + return AesSetIV(aes, iv); + } + + int AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, + const byte* iv, int dir) + { + return AesSetKey(aes, userKey, keylen, iv, dir); + } + +#elif defined(HAVE_COLDFIRE_SEC) + #if defined (HAVE_THREADX) + #include "memory_pools.h" + extern TX_BYTE_POOL mp_ncached; /* Non Cached memory pool */ + #endif + + #define AES_BUFFER_SIZE (AES_BLOCK_SIZE * 64) + static unsigned char *AESBuffIn = NULL; + static unsigned char *AESBuffOut = NULL; + static byte *secReg; + static byte *secKey; + static volatile SECdescriptorType *secDesc; + + static CyaSSL_Mutex Mutex_AesSEC; + + #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010 + #define SEC_DESC_AES_CBC_DECRYPT 0x60200010 + + extern volatile unsigned char __MBAR[]; + + int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, + int dir) + { + if (AESBuffIn == NULL) { + #if defined (HAVE_THREADX) + int s1, s2, s3, s4, s5 ; + s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc, + sizeof(SECdescriptorType), TX_NO_WAIT); + s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn, + AES_BUFFER_SIZE, TX_NO_WAIT); + s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut, + AES_BUFFER_SIZE, TX_NO_WAIT); + s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey, + AES_BLOCK_SIZE*2, TX_NO_WAIT); + s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg, + AES_BLOCK_SIZE, TX_NO_WAIT); + + if(s1 || s2 || s3 || s4 || s5) + return BAD_FUNC_ARG; + #else + #warning "Allocate non-Cache buffers" + #endif + + InitMutex(&Mutex_AesSEC); } - AES_CBC_encrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key, - aes->rounds); - /* store iv for next call */ - XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) + return BAD_FUNC_ARG; + + if (aes == NULL) + return BAD_FUNC_ARG; + + aes->rounds = keylen/4 + 6; + XMEMCPY(aes->key, userKey, keylen); + + if (iv) + XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); return 0; } -#endif +#elif defined(FREESCALE_MMCAU) + int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, + int dir) + { + byte *rk = (byte*)aes->key; - while (blocks--) { - xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE); - AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg); - XMEMCPY(out, aes->reg, AES_BLOCK_SIZE); + if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) + return BAD_FUNC_ARG; - out += AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; + if (rk == NULL) + return BAD_FUNC_ARG; + + aes->rounds = keylen/4 + 6; + cau_aes_set_key(userKey, keylen*8, rk); + + return AesSetIV(aes, iv); } - return 0; -} + int AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, + const byte* iv, int dir) + { + return AesSetKey(aes, userKey, keylen, iv, dir); + } +#else + static int AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen, + const byte* iv, int dir) + { + word32 temp, *rk = aes->key; + unsigned int i = 0; + #ifdef CYASSL_AESNI + aes->use_aesni = 0; + #endif /* CYASSL_AESNI */ + #ifdef CYASSL_AES_COUNTER + aes->left = 0; + #endif /* CYASSL_AES_COUNTER */ -int AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) -{ - word32 blocks = sz / AES_BLOCK_SIZE; + aes->rounds = keylen/4 + 6; -#ifdef HAVE_CAVIUM - if (aes->magic == CYASSL_AES_CAVIUM_MAGIC) - return AesCaviumCbcDecrypt(aes, out, in, sz); -#endif - -#ifdef CYASSL_AESNI - if (haveAESNI) { - #ifdef DEBUG_AESNI - printf("about to aes cbc decrypt\n"); - printf("in = %p\n", in); - printf("out = %p\n", out); - printf("aes->key = %p\n", aes->key); - printf("aes->reg = %p\n", aes->reg); - printf("aes->rounds = %d\n", aes->rounds); - printf("sz = %d\n", sz); + XMEMCPY(rk, userKey, keylen); + #ifdef LITTLE_ENDIAN_ORDER + ByteReverseWords(rk, rk, keylen); #endif - /* if input and output same will overwrite input iv */ - XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); - AES_CBC_decrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key, - aes->rounds); - /* store iv for next call */ - XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); - return 0; - } -#endif + #ifdef CYASSL_PIC32MZ_CRYPT + { + word32 *akey1 = aes->key_ce; + word32 *areg = aes->iv_ce ; + aes->keylen = keylen ; + XMEMCPY(akey1, userKey, keylen); + if (iv) + XMEMCPY(areg, iv, AES_BLOCK_SIZE); + else + XMEMSET(areg, 0, AES_BLOCK_SIZE); + } + #endif - while (blocks--) { - XMEMCPY(aes->tmp, in, AES_BLOCK_SIZE); - AesDecrypt(aes, (byte*)aes->tmp, out); - xorbuf(out, (byte*)aes->reg, AES_BLOCK_SIZE); - XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); + switch(keylen) + { + case 16: + while (1) + { + temp = rk[3]; + rk[4] = rk[0] ^ + (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ + (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ + (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ + (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) + break; + rk += 4; + } + break; - out += AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; + case 24: + /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */ + while (1) + { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ + (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ + (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ + (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ + (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) + break; + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + break; + + case 32: + while (1) + { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ + (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^ + (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^ + (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^ + (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) + break; + temp = rk[11]; + rk[12] = rk[ 4] ^ + (Te[4][GETBYTE(temp, 3)] & 0xff000000) ^ + (Te[4][GETBYTE(temp, 2)] & 0x00ff0000) ^ + (Te[4][GETBYTE(temp, 1)] & 0x0000ff00) ^ + (Te[4][GETBYTE(temp, 0)] & 0x000000ff); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + + rk += 8; + } + break; + + default: + return BAD_FUNC_ARG; + } + + if (dir == AES_DECRYPTION) + { + unsigned int j; + rk = aes->key; + + /* invert the order of the round keys: */ + for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the + first and the last: */ + for (i = 1; i < aes->rounds; i++) { + rk += 4; + rk[0] = + Td[0][Te[4][GETBYTE(rk[0], 3)] & 0xff] ^ + Td[1][Te[4][GETBYTE(rk[0], 2)] & 0xff] ^ + Td[2][Te[4][GETBYTE(rk[0], 1)] & 0xff] ^ + Td[3][Te[4][GETBYTE(rk[0], 0)] & 0xff]; + rk[1] = + Td[0][Te[4][GETBYTE(rk[1], 3)] & 0xff] ^ + Td[1][Te[4][GETBYTE(rk[1], 2)] & 0xff] ^ + Td[2][Te[4][GETBYTE(rk[1], 1)] & 0xff] ^ + Td[3][Te[4][GETBYTE(rk[1], 0)] & 0xff]; + rk[2] = + Td[0][Te[4][GETBYTE(rk[2], 3)] & 0xff] ^ + Td[1][Te[4][GETBYTE(rk[2], 2)] & 0xff] ^ + Td[2][Te[4][GETBYTE(rk[2], 1)] & 0xff] ^ + Td[3][Te[4][GETBYTE(rk[2], 0)] & 0xff]; + rk[3] = + Td[0][Te[4][GETBYTE(rk[3], 3)] & 0xff] ^ + Td[1][Te[4][GETBYTE(rk[3], 2)] & 0xff] ^ + Td[2][Te[4][GETBYTE(rk[3], 1)] & 0xff] ^ + Td[3][Te[4][GETBYTE(rk[3], 0)] & 0xff]; + } + } + + return AesSetIV(aes, iv); } + int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, + int dir) + { + + if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) + return BAD_FUNC_ARG; + + #ifdef HAVE_CAVIUM + if (aes->magic == CYASSL_AES_CAVIUM_MAGIC) + return AesCaviumSetKey(aes, userKey, keylen, iv); + #endif + + #ifdef CYASSL_AESNI + if (checkAESNI == 0) { + haveAESNI = Check_CPU_support_AES(); + checkAESNI = 1; + } + if (haveAESNI) { + aes->use_aesni = 1; + if (iv) + XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); + if (dir == AES_ENCRYPTION) + return AES_set_encrypt_key(userKey, keylen * 8, aes); + else + return AES_set_decrypt_key(userKey, keylen * 8, aes); + } + #endif /* CYASSL_AESNI */ + + return AesSetKeyLocal(aes, userKey, keylen, iv, dir); + } + + #if defined(CYASSL_AES_DIRECT) || defined(CYASSL_AES_COUNTER) + + /* AES-CTR and AES-DIRECT need to use this for key setup, no aesni yet */ + int AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, + const byte* iv, int dir) + { + return AesSetKeyLocal(aes, userKey, keylen, iv, dir); + } + + #endif /* CYASSL_AES_DIRECT || CYASSL_AES_COUNTER */ +#endif /* STM32F2_CRYPTO, AesSetKey block */ + + +/* AesSetIV is shared between software and hardware */ +int AesSetIV(Aes* aes, const byte* iv) +{ + if (aes == NULL) + return BAD_FUNC_ARG; + + if (iv) + XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); + else + XMEMSET(aes->reg, 0, AES_BLOCK_SIZE); + return 0; } -#endif - -#ifdef CYASSL_AES_DIRECT - -/* Allow direct access to one block encrypt */ -void AesEncryptDirect(Aes* aes, byte* out, const byte* in) -{ - return AesEncrypt(aes, in, out); -} -/* Allow direct access to one block decrypt */ -void AesDecryptDirect(Aes* aes, byte* out, const byte* in) -{ - return AesDecrypt(aes, in, out); -} +/* AES-DIRECT */ +#if defined(CYASSL_AES_DIRECT) + #if defined(FREESCALE_MMCAU) + /* Allow direct access to one block encrypt */ + void AesEncryptDirect(Aes* aes, byte* out, const byte* in) + { + byte* key; + key = (byte*)aes->key; + return cau_aes_encrypt(in, key, aes->rounds, out); + } + + /* Allow direct access to one block decrypt */ + void AesDecryptDirect(Aes* aes, byte* out, const byte* in) + { + byte* key; + key = (byte*)aes->key; + + return cau_aes_decrypt(in, key, aes->rounds, out); + } + + #elif defined(STM32F2_CRYPTO) + #error "STM32F2 crypto doesn't yet support AES direct" + + #elif defined(HAVE_COLDFIRE_SEC) + #error "Coldfire SEC doesn't yet support AES direct" + + #elif defined(CYASSL_PIC32MZ_CRYPT) + #error "PIC32MZ doesn't yet support AES direct" + + #else + /* Allow direct access to one block encrypt */ + void AesEncryptDirect(Aes* aes, byte* out, const byte* in) + { + return AesEncrypt(aes, in, out); + } + + /* Allow direct access to one block decrypt */ + void AesDecryptDirect(Aes* aes, byte* out, const byte* in) + { + return AesDecrypt(aes, in, out); + } + + #endif /* FREESCALE_MMCAU, AES direct block */ #endif /* CYASSL_AES_DIRECT */ -#if defined(CYASSL_AES_DIRECT) || defined(CYASSL_AES_COUNTER) +/* AES-CBC */ +#ifdef STM32F2_CRYPTO + int AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + word32 *enc_key, *iv; + CRYP_InitTypeDef AES_CRYP_InitStructure; + CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure; + CRYP_IVInitTypeDef AES_CRYP_IVInitStructure; -/* AES-CTR and AES-DIRECT need to use this for key setup, no aesni yet */ -int AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, - const byte* iv, int dir) -{ - return AesSetKeyLocal(aes, userKey, keylen, iv, dir); -} + enc_key = aes->key; + iv = aes->reg; -#endif /* CYASSL_AES_DIRECT || CYASSL_AES_COUNTER */ + /* crypto structure initialization */ + CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure); + CRYP_StructInit(&AES_CRYP_InitStructure); + CRYP_IVStructInit(&AES_CRYP_IVInitStructure); + /* reset registers to their default values */ + CRYP_DeInit(); -#if defined(CYASSL_AES_COUNTER) && !defined(HAVE_AES_ENGINE) + /* load key into correct registers */ + switch(aes->rounds) + { + case 10: /* 128-bit key */ + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[0]; + AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1]; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[2]; + AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3]; + break; -/* Increment AES counter */ -static INLINE void IncrementAesCounter(byte* inOutCtr) -{ - int i; + case 12: /* 192-bit key */ + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b; + AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[0]; + AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1]; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[2]; + AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3]; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[4]; + AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5]; + break; - /* in network byte order so start at end and work back */ - for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { - if (++inOutCtr[i]) /* we're done unless we overflow */ - return; - } -} - + case 14: /* 256-bit key */ + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b; + AES_CRYP_KeyInitStructure.CRYP_Key0Left = enc_key[0]; + AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1]; + AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[2]; + AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3]; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[4]; + AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5]; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[6]; + AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7]; + break; -void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) -{ - byte* tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left; - - /* consume any unused bytes left in aes->tmp */ - while (aes->left && sz) { - *(out++) = *(in++) ^ *(tmp++); - aes->left--; - sz--; - } - - /* do as many block size ops as possible */ - while (sz >= AES_BLOCK_SIZE) { - AesEncrypt(aes, (byte*)aes->reg, out); - IncrementAesCounter((byte*)aes->reg); - xorbuf(out, in, AES_BLOCK_SIZE); - - out += AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - sz -= AES_BLOCK_SIZE; - aes->left = 0; - } - - /* handle non block size remaining and sotre unused byte count in left */ - if (sz) { - AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp); - IncrementAesCounter((byte*)aes->reg); - - aes->left = AES_BLOCK_SIZE; - tmp = (byte*)aes->tmp; - - while (sz--) { - *(out++) = *(in++) ^ *(tmp++); - aes->left--; + default: + break; } + CRYP_KeyInit(&AES_CRYP_KeyInitStructure); + + /* set iv */ + ByteReverseWords(iv, iv, AES_BLOCK_SIZE); + AES_CRYP_IVInitStructure.CRYP_IV0Left = iv[0]; + AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1]; + AES_CRYP_IVInitStructure.CRYP_IV1Left = iv[2]; + AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3]; + CRYP_IVInit(&AES_CRYP_IVInitStructure); + + /* set direction, mode, and datatype */ + AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; + AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC; + AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; + CRYP_Init(&AES_CRYP_InitStructure); + + /* enable crypto processor */ + CRYP_Cmd(ENABLE); + + while (sz > 0) + { + /* flush IN/OUT FIFOs */ + CRYP_FIFOFlush(); + + CRYP_DataIn(*(uint32_t*)&in[0]); + CRYP_DataIn(*(uint32_t*)&in[4]); + CRYP_DataIn(*(uint32_t*)&in[8]); + CRYP_DataIn(*(uint32_t*)&in[12]); + + /* wait until the complete message has been processed */ + while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} + + *(uint32_t*)&out[0] = CRYP_DataOut(); + *(uint32_t*)&out[4] = CRYP_DataOut(); + *(uint32_t*)&out[8] = CRYP_DataOut(); + *(uint32_t*)&out[12] = CRYP_DataOut(); + + /* store iv for next call */ + XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + + sz -= 16; + in += 16; + out += 16; + } + + /* disable crypto processor */ + CRYP_Cmd(DISABLE); + + return 0; } -} + + int AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + word32 *dec_key, *iv; + CRYP_InitTypeDef AES_CRYP_InitStructure; + CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure; + CRYP_IVInitTypeDef AES_CRYP_IVInitStructure; + + dec_key = aes->key; + iv = aes->reg; + + /* crypto structure initialization */ + CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure); + CRYP_StructInit(&AES_CRYP_InitStructure); + CRYP_IVStructInit(&AES_CRYP_IVInitStructure); + + /* if input and output same will overwrite input iv */ + XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + + /* reset registers to their default values */ + CRYP_DeInit(); + + /* load key into correct registers */ + switch(aes->rounds) + { + case 10: /* 128-bit key */ + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = dec_key[0]; + AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[1]; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = dec_key[2]; + AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[3]; + break; + + case 12: /* 192-bit key */ + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b; + AES_CRYP_KeyInitStructure.CRYP_Key1Left = dec_key[0]; + AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[1]; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = dec_key[2]; + AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[3]; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = dec_key[4]; + AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[5]; + break; + + case 14: /* 256-bit key */ + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b; + AES_CRYP_KeyInitStructure.CRYP_Key0Left = dec_key[0]; + AES_CRYP_KeyInitStructure.CRYP_Key0Right = dec_key[1]; + AES_CRYP_KeyInitStructure.CRYP_Key1Left = dec_key[2]; + AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[3]; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = dec_key[4]; + AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[5]; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = dec_key[6]; + AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[7]; + break; + + default: + break; + } + + /* set direction, mode, and datatype for key preparation */ + AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; + AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key; + AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b; + CRYP_Init(&AES_CRYP_InitStructure); + CRYP_KeyInit(&AES_CRYP_KeyInitStructure); + + /* enable crypto processor */ + CRYP_Cmd(ENABLE); + + /* wait until key has been prepared */ + while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} + + /* set direction, mode, and datatype for decryption */ + AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; + AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC; + AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; + CRYP_Init(&AES_CRYP_InitStructure); + + /* set iv */ + ByteReverseWords(iv, iv, AES_BLOCK_SIZE); + + AES_CRYP_IVInitStructure.CRYP_IV0Left = iv[0]; + AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1]; + AES_CRYP_IVInitStructure.CRYP_IV1Left = iv[2]; + AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3]; + CRYP_IVInit(&AES_CRYP_IVInitStructure); + + /* enable crypto processor */ + CRYP_Cmd(ENABLE); + + while (sz > 0) + { + /* flush IN/OUT FIFOs */ + CRYP_FIFOFlush(); + + CRYP_DataIn(*(uint32_t*)&in[0]); + CRYP_DataIn(*(uint32_t*)&in[4]); + CRYP_DataIn(*(uint32_t*)&in[8]); + CRYP_DataIn(*(uint32_t*)&in[12]); + + /* wait until the complete message has been processed */ + while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} + + *(uint32_t*)&out[0] = CRYP_DataOut(); + *(uint32_t*)&out[4] = CRYP_DataOut(); + *(uint32_t*)&out[8] = CRYP_DataOut(); + *(uint32_t*)&out[12] = CRYP_DataOut(); + + /* store iv for next call */ + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); + + sz -= 16; + in += 16; + out += 16; + } + + /* disable crypto processor */ + CRYP_Cmd(DISABLE); + + return 0; + } + +#elif defined(HAVE_COLDFIRE_SEC) + static int AesCbcCrypt(Aes* aes, byte* po, const byte* pi, word32 sz, + word32 descHeader) + { + #ifdef DEBUG_CYASSL + int i; int stat1, stat2; int ret; + #endif + + int size; + volatile int v; + + if ((pi == NULL) || (po == NULL)) + return BAD_FUNC_ARG; /*wrong pointer*/ + + LockMutex(&Mutex_AesSEC); + + /* Set descriptor for SEC */ + secDesc->length1 = 0x0; + secDesc->pointer1 = NULL; + + secDesc->length2 = AES_BLOCK_SIZE; + secDesc->pointer2 = (byte *)secReg; /* Initial Vector */ + + switch(aes->rounds) { + case 10: secDesc->length3 = 16 ; break ; + case 12: secDesc->length3 = 24 ; break ; + case 14: secDesc->length3 = 32 ; break ; + } + XMEMCPY(secKey, aes->key, secDesc->length3); + + secDesc->pointer3 = (byte *)secKey; + secDesc->pointer4 = AESBuffIn; + secDesc->pointer5 = AESBuffOut; + secDesc->length6 = 0x0; + secDesc->pointer6 = NULL; + secDesc->length7 = 0x0; + secDesc->pointer7 = NULL; + secDesc->nextDescriptorPtr = NULL; + + while (sz) { + secDesc->header = descHeader; + XMEMCPY(secReg, aes->reg, AES_BLOCK_SIZE); + if ((sz % AES_BUFFER_SIZE) == sz) { + size = sz; + sz = 0; + } else { + size = AES_BUFFER_SIZE; + sz -= AES_BUFFER_SIZE; + } + secDesc->length4 = size; + secDesc->length5 = size; + + XMEMCPY(AESBuffIn, pi, size); + if(descHeader == SEC_DESC_AES_CBC_DECRYPT) { + XMEMCPY((void*)aes->tmp, (void*)&(pi[size-AES_BLOCK_SIZE]), + AES_BLOCK_SIZE); + } + + /* Point SEC to the location of the descriptor */ + MCF_SEC_FR0 = (uint32)secDesc; + /* Initialize SEC and wait for encryption to complete */ + MCF_SEC_CCCR0 = 0x0000001a; + /* poll SISR to determine when channel is complete */ + v=0; + + while ((secDesc->header>> 24) != 0xff) v++; + + #ifdef DEBUG_CYASSL + ret = MCF_SEC_SISRH; + stat1 = MCF_SEC_AESSR; + stat2 = MCF_SEC_AESISR; + if (ret & 0xe0000000) { + db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, " + "AESISR=%08x\n", i, ret, stat1, stat2); + } + #endif + + XMEMCPY(po, AESBuffOut, size); + + if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) { + XMEMCPY((void*)aes->reg, (void*)&(po[size-AES_BLOCK_SIZE]), + AES_BLOCK_SIZE); + } else { + XMEMCPY((void*)aes->reg, (void*)aes->tmp, AES_BLOCK_SIZE); + } + + pi += size; + po += size; + } + + UnLockMutex(&Mutex_AesSEC); + return 0; + } + + int AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz) + { + return (AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT)); + } + + int AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz) + { + return (AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT)); + } + +#elif defined(FREESCALE_MMCAU) + int AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + int i; + int offset = 0; + int len = sz; + + byte *iv, *enc_key; + byte temp_block[AES_BLOCK_SIZE]; + + iv = (byte*)aes->reg; + enc_key = (byte*)aes->key; + + if ((word)out % CYASSL_MMCAU_ALIGNMENT) { + CYASSL_MSG("Bad cau_aes_encrypt alignment"); + return BAD_ALIGN_E; + } + + while (len > 0) + { + XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE); + + /* XOR block with IV for CBC */ + for (i = 0; i < AES_BLOCK_SIZE; i++) + temp_block[i] ^= iv[i]; + + cau_aes_encrypt(temp_block, enc_key, aes->rounds, out + offset); + + len -= AES_BLOCK_SIZE; + offset += AES_BLOCK_SIZE; + + /* store IV for next block */ + XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + } + + return 0; + } + + int AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + int i; + int offset = 0; + int len = sz; + + byte* iv, *dec_key; + byte temp_block[AES_BLOCK_SIZE]; + + iv = (byte*)aes->reg; + dec_key = (byte*)aes->key; + + if ((word)out % CYASSL_MMCAU_ALIGNMENT) { + CYASSL_MSG("Bad cau_aes_decrypt alignment"); + return BAD_ALIGN_E; + } + + while (len > 0) + { + XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE); + + cau_aes_decrypt(in + offset, dec_key, aes->rounds, out + offset); + + /* XOR block with IV for CBC */ + for (i = 0; i < AES_BLOCK_SIZE; i++) + (out + offset)[i] ^= iv[i]; + + /* store IV for next block */ + XMEMCPY(iv, temp_block, AES_BLOCK_SIZE); + + len -= AES_BLOCK_SIZE; + offset += AES_BLOCK_SIZE; + } + + return 0; + } + +#elif defined(CYASSL_PIC32MZ_CRYPT) + /* core hardware crypt engine driver */ + static void AesCrypt(Aes *aes, byte* out, const byte* in, word32 sz, + int dir, int algo, int cryptoalgo) + { + securityAssociation *sa_p ; + bufferDescriptor *bd_p ; + + volatile securityAssociation sa __attribute__((aligned (8))); + volatile bufferDescriptor bd __attribute__((aligned (8))); + volatile int k ; + + /* get uncached address */ + sa_p = KVA0_TO_KVA1(&sa) ; + bd_p = KVA0_TO_KVA1(&bd) ; + + /* Sync cache and physical memory */ + if(PIC32MZ_IF_RAM(in)) { + XMEMCPY((void *)KVA0_TO_KVA1(in), (void *)in, sz); + } + XMEMSET((void *)KVA0_TO_KVA1(out), 0, sz); + /* Set up the Security Association */ + XMEMSET((byte *)KVA0_TO_KVA1(&sa), 0, sizeof(sa)); + sa_p->SA_CTRL.ALGO = algo ; /* AES */ + sa_p->SA_CTRL.LNC = 1; + sa_p->SA_CTRL.LOADIV = 1; + sa_p->SA_CTRL.FB = 1; + sa_p->SA_CTRL.ENCTYPE = dir ; /* Encryption/Decryption */ + sa_p->SA_CTRL.CRYPTOALGO = cryptoalgo; + + if(cryptoalgo == PIC32_CRYPTOALGO_AES_GCM){ + switch(aes->keylen) { + case 32: + sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_256 ; + break ; + case 24: + sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_192 ; + break ; + case 16: + sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_128 ; + break ; + } + } else + sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_128 ; + + ByteReverseWords( + (word32 *)KVA0_TO_KVA1(sa.SA_ENCKEY + 8 - aes->keylen/sizeof(word32)), + (word32 *)aes->key_ce, aes->keylen); + ByteReverseWords( + (word32*)KVA0_TO_KVA1(sa.SA_ENCIV), (word32 *)aes->iv_ce, 16); + + XMEMSET((byte *)KVA0_TO_KVA1(&bd), 0, sizeof(bd)); + /* Set up the Buffer Descriptor */ + bd_p->BD_CTRL.BUFLEN = sz; + if(cryptoalgo == PIC32_CRYPTOALGO_AES_GCM) { + if(sz % 0x10) + bd_p->BD_CTRL.BUFLEN = (sz/0x10 + 1) * 0x10 ; + } + bd_p->BD_CTRL.LIFM = 1; + bd_p->BD_CTRL.SA_FETCH_EN = 1; + bd_p->BD_CTRL.LAST_BD = 1; + bd_p->BD_CTRL.DESC_EN = 1; + + bd_p->SA_ADDR = (unsigned int)KVA_TO_PA(&sa) ; + bd_p->SRCADDR = (unsigned int)KVA_TO_PA(in) ; + bd_p->DSTADDR = (unsigned int)KVA_TO_PA(out); + bd_p->MSGLEN = sz ; + + CECON = 1 << 6; + while (CECON); + + /* Run the engine */ + CEBDPADDR = (unsigned int)KVA_TO_PA(&bd) ; + CEINTEN = 0x07; + CECON = 0x27; + + WAIT_ENGINE ; + + if((cryptoalgo == PIC32_CRYPTOALGO_CBC) || + (cryptoalgo == PIC32_CRYPTOALGO_TCBC)|| + (cryptoalgo == PIC32_CRYPTOALGO_RCBC)) { + /* set iv for the next call */ + if(dir == PIC32_ENCRYPTION) { + XMEMCPY((void *)aes->iv_ce, + (void*)KVA0_TO_KVA1(out + sz - AES_BLOCK_SIZE), + AES_BLOCK_SIZE) ; + } else { + ByteReverseWords((word32*)aes->iv_ce, + (word32 *)KVA0_TO_KVA1(in + sz - AES_BLOCK_SIZE), + AES_BLOCK_SIZE); + } + } + XMEMCPY((byte *)out, (byte *)KVA0_TO_KVA1(out), sz) ; + ByteReverseWords((word32*)out, (word32 *)out, sz); + } + + int AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + AesCrypt(aes, out, in, sz, PIC32_ENCRYPTION, PIC32_ALGO_AES, + PIC32_CRYPTOALGO_RCBC ); + return 0 ; + } + + int AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + AesCrypt(aes, out, in, sz, PIC32_DECRYPTION, PIC32_ALGO_AES, + PIC32_CRYPTOALGO_RCBC); + return 0 ; + } + +#else + int AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + word32 blocks = sz / AES_BLOCK_SIZE; + + #ifdef HAVE_CAVIUM + if (aes->magic == CYASSL_AES_CAVIUM_MAGIC) + return AesCaviumCbcEncrypt(aes, out, in, sz); + #endif + + #ifdef CYASSL_AESNI + if (haveAESNI) { + #ifdef DEBUG_AESNI + printf("about to aes cbc encrypt\n"); + printf("in = %p\n", in); + printf("out = %p\n", out); + printf("aes->key = %p\n", aes->key); + printf("aes->reg = %p\n", aes->reg); + printf("aes->rounds = %d\n", aes->rounds); + printf("sz = %d\n", sz); + #endif + + /* check alignment, decrypt doesn't need alignment */ + if ((word)in % 16) { + #ifndef NO_CYASSL_ALLOC_ALIGN + byte* tmp = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + CYASSL_MSG("AES-CBC encrypt with bad alignment"); + if (tmp == NULL) return MEMORY_E; + + XMEMCPY(tmp, in, sz); + AES_CBC_encrypt(tmp, tmp, (byte*)aes->reg, sz, (byte*)aes->key, + aes->rounds); + /* store iv for next call */ + XMEMCPY(aes->reg, tmp + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + + XMEMCPY(out, tmp, sz); + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return 0; + #else + return BAD_ALIGN_E; + #endif + } + + AES_CBC_encrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key, + aes->rounds); + /* store iv for next call */ + XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + + return 0; + } + #endif + + while (blocks--) { + xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE); + AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg); + XMEMCPY(out, aes->reg, AES_BLOCK_SIZE); + + out += AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + } + + return 0; + } + + int AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + word32 blocks = sz / AES_BLOCK_SIZE; + + #ifdef HAVE_CAVIUM + if (aes->magic == CYASSL_AES_CAVIUM_MAGIC) + return AesCaviumCbcDecrypt(aes, out, in, sz); + #endif + + #ifdef CYASSL_AESNI + if (haveAESNI) { + #ifdef DEBUG_AESNI + printf("about to aes cbc decrypt\n"); + printf("in = %p\n", in); + printf("out = %p\n", out); + printf("aes->key = %p\n", aes->key); + printf("aes->reg = %p\n", aes->reg); + printf("aes->rounds = %d\n", aes->rounds); + printf("sz = %d\n", sz); + #endif + + /* if input and output same will overwrite input iv */ + XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + AES_CBC_decrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key, + aes->rounds); + /* store iv for next call */ + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); + return 0; + } + #endif + + while (blocks--) { + XMEMCPY(aes->tmp, in, AES_BLOCK_SIZE); + AesDecrypt(aes, (byte*)aes->tmp, out); + xorbuf(out, (byte*)aes->reg, AES_BLOCK_SIZE); + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); + + out += AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + } + + return 0; + } + +#endif /* STM32F2_CRYPTO, AES-CBC block */ + +/* AES-CTR */ +#ifdef CYASSL_AES_COUNTER + + #ifdef STM32F2_CRYPTO + void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + word32 *enc_key, *iv; + CRYP_InitTypeDef AES_CRYP_InitStructure; + CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure; + CRYP_IVInitTypeDef AES_CRYP_IVInitStructure; + + enc_key = aes->key; + iv = aes->reg; + + /* crypto structure initialization */ + CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure); + CRYP_StructInit(&AES_CRYP_InitStructure); + CRYP_IVStructInit(&AES_CRYP_IVInitStructure); + + /* reset registers to their default values */ + CRYP_DeInit(); + + /* load key into correct registers */ + switch(aes->rounds) + { + case 10: /* 128-bit key */ + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[0]; + AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1]; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[2]; + AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3]; + break; + + case 12: /* 192-bit key */ + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b; + AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[0]; + AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1]; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[2]; + AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3]; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[4]; + AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5]; + break; + + case 14: /* 256-bit key */ + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b; + AES_CRYP_KeyInitStructure.CRYP_Key0Left = enc_key[0]; + AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1]; + AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[2]; + AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3]; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[4]; + AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5]; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[6]; + AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7]; + break; + + default: + break; + } + CRYP_KeyInit(&AES_CRYP_KeyInitStructure); + + /* set iv */ + ByteReverseWords(iv, iv, AES_BLOCK_SIZE); + AES_CRYP_IVInitStructure.CRYP_IV0Left = iv[0]; + AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1]; + AES_CRYP_IVInitStructure.CRYP_IV1Left = iv[2]; + AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3]; + CRYP_IVInit(&AES_CRYP_IVInitStructure); + + /* set direction, mode, and datatype */ + AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; + AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR; + AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; + CRYP_Init(&AES_CRYP_InitStructure); + + /* enable crypto processor */ + CRYP_Cmd(ENABLE); + + while (sz > 0) + { + /* flush IN/OUT FIFOs */ + CRYP_FIFOFlush(); + + CRYP_DataIn(*(uint32_t*)&in[0]); + CRYP_DataIn(*(uint32_t*)&in[4]); + CRYP_DataIn(*(uint32_t*)&in[8]); + CRYP_DataIn(*(uint32_t*)&in[12]); + + /* wait until the complete message has been processed */ + while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} + + *(uint32_t*)&out[0] = CRYP_DataOut(); + *(uint32_t*)&out[4] = CRYP_DataOut(); + *(uint32_t*)&out[8] = CRYP_DataOut(); + *(uint32_t*)&out[12] = CRYP_DataOut(); + + /* store iv for next call */ + XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + + sz -= 16; + in += 16; + out += 16; + } + + /* disable crypto processor */ + CRYP_Cmd(DISABLE); + } + + #elif defined(CYASSL_PIC32MZ_CRYPT) + void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + int i ; + char out_block[AES_BLOCK_SIZE] ; + int odd ; + int even ; + char *tmp ; /* (char *)aes->tmp, for short */ + + tmp = (char *)aes->tmp ; + if(aes->left) { + if((aes->left + sz) >= AES_BLOCK_SIZE){ + odd = AES_BLOCK_SIZE - aes->left ; + } else { + odd = sz ; + } + XMEMCPY(tmp+aes->left, in, odd) ; + if((odd+aes->left) == AES_BLOCK_SIZE){ + AesCrypt(aes, out_block, tmp, AES_BLOCK_SIZE, + PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR); + XMEMCPY(out, out_block+aes->left, odd) ; + aes->left = 0 ; + XMEMSET(tmp, 0x0, AES_BLOCK_SIZE) ; + /* Increment IV */ + for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { + if (++((byte *)aes->iv_ce)[i]) + break ; + } + } + in += odd ; + out+= odd ; + sz -= odd ; + } + odd = sz % AES_BLOCK_SIZE ; /* if there is tail flagment */ + if(sz / AES_BLOCK_SIZE) { + even = (sz/AES_BLOCK_SIZE)*AES_BLOCK_SIZE ; + AesCrypt(aes, out, in, even, PIC32_ENCRYPTION, PIC32_ALGO_AES, + PIC32_CRYPTOALGO_RCTR); + out += even ; + in += even ; + do { /* Increment IV */ + for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { + if (++((byte *)aes->iv_ce)[i]) + break ; + } + even -= AES_BLOCK_SIZE ; + } while((int)even > 0) ; + } + if(odd) { + XMEMSET(tmp+aes->left, 0x0, AES_BLOCK_SIZE - aes->left) ; + XMEMCPY(tmp+aes->left, in, odd) ; + AesCrypt(aes, out_block, tmp, AES_BLOCK_SIZE, + PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR); + XMEMCPY(out, out_block+aes->left,odd) ; + aes->left += odd ; + } + } + + #elif defined(HAVE_COLDFIRE_SEC) + #error "Coldfire SEC doesn't currently support AES-CTR mode" + + #elif defined(FREESCALE_MMCAU) + #error "Freescale mmCAU doesn't currently support AES-CTR mode" + + #else + /* Increment AES counter */ + static INLINE void IncrementAesCounter(byte* inOutCtr) + { + int i; + + /* in network byte order so start at end and work back */ + for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { + if (++inOutCtr[i]) /* we're done unless we overflow */ + return; + } + } + + void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + byte* tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left; + + /* consume any unused bytes left in aes->tmp */ + while (aes->left && sz) { + *(out++) = *(in++) ^ *(tmp++); + aes->left--; + sz--; + } + + /* do as many block size ops as possible */ + while (sz >= AES_BLOCK_SIZE) { + AesEncrypt(aes, (byte*)aes->reg, out); + IncrementAesCounter((byte*)aes->reg); + xorbuf(out, in, AES_BLOCK_SIZE); + + out += AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + sz -= AES_BLOCK_SIZE; + aes->left = 0; + } + + /* handle non block size remaining and sotre unused byte count in left */ + if (sz) { + AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp); + IncrementAesCounter((byte*)aes->reg); + + aes->left = AES_BLOCK_SIZE; + tmp = (byte*)aes->tmp; + + while (sz--) { + *(out++) = *(in++) ^ *(tmp++); + aes->left--; + } + } + } + + #endif /* STM32F2_CRYPTO, AES-CTR block */ #endif /* CYASSL_AES_COUNTER */ - #ifdef HAVE_AESGCM /* @@ -2435,6 +2490,14 @@ void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) * number counter. */ +#ifdef STM32F2_CRYPTO + #error "STM32F2 crypto doesn't currently support AES-GCM mode" + +#elif defined(HAVE_COLDFIRE_SEC) + #error "Coldfire SEC doesn't currently support AES-GCM mode" + +#endif + enum { CTR_SZ = 4 }; @@ -2530,13 +2593,21 @@ void AesGcmSetKey(Aes* aes, const byte* key, word32 len) { byte iv[AES_BLOCK_SIZE]; + #ifdef FREESCALE_MMCAU + byte* rk = (byte*)aes->key; + #endif + if (!((len == 16) || (len == 24) || (len == 32))) return; XMEMSET(iv, 0, AES_BLOCK_SIZE); AesSetKey(aes, key, len, iv, AES_ENCRYPTION); - AesEncrypt(aes, iv, aes->H); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(iv, rk, aes->rounds, aes->H); + #else + AesEncrypt(aes, iv, aes->H); + #endif #ifdef GCM_TABLE GenerateM0(aes); #endif /* GCM_TABLE */ @@ -3059,6 +3130,10 @@ void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, byte *ctr ; byte scratch[AES_BLOCK_SIZE]; +#ifdef FREESCALE_MMCAU + byte* key = (byte*)aes->key; +#endif + CYASSL_ENTER("AesGcmEncrypt"); #ifdef CYASSL_PIC32MZ_CRYPT @@ -3079,7 +3154,11 @@ void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, while (blocks--) { IncrementGcmCounter(ctr); #ifndef CYASSL_PIC32MZ_CRYPT - AesEncrypt(aes, ctr, scratch); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(ctr, key, aes->rounds, scratch); + #else + AesEncrypt(aes, ctr, scratch); + #endif xorbuf(scratch, p, AES_BLOCK_SIZE); XMEMCPY(c, scratch, AES_BLOCK_SIZE); #endif @@ -3089,7 +3168,11 @@ void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, if (partial != 0) { IncrementGcmCounter(ctr); - AesEncrypt(aes, ctr, scratch); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(ctr, key, aes->rounds, scratch); + #else + AesEncrypt(aes, ctr, scratch); + #endif xorbuf(scratch, p, partial); XMEMCPY(c, scratch, partial); @@ -3097,7 +3180,11 @@ void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz); InitGcmCounter(ctr); - AesEncrypt(aes, ctr, scratch); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(ctr, key, aes->rounds, scratch); + #else + AesEncrypt(aes, ctr, scratch); + #endif xorbuf(authTag, scratch, authTagSz); } @@ -3116,6 +3203,10 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, byte *ctr ; byte scratch[AES_BLOCK_SIZE]; +#ifdef FREESCALE_MMCAU + byte* key = (byte*)aes->key; +#endif + CYASSL_ENTER("AesGcmDecrypt"); #ifdef CYASSL_PIC32MZ_CRYPT @@ -3135,7 +3226,11 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, byte EKY0[AES_BLOCK_SIZE]; GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime)); - AesEncrypt(aes, ctr, EKY0); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(ctr, key, aes->rounds, EKY0); + #else + AesEncrypt(aes, ctr, EKY0); + #endif xorbuf(Tprime, EKY0, sizeof(Tprime)); if (XMEMCMP(authTag, Tprime, authTagSz) != 0) { @@ -3152,7 +3247,11 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, while (blocks--) { IncrementGcmCounter(ctr); #ifndef CYASSL_PIC32MZ_CRYPT - AesEncrypt(aes, ctr, scratch); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(ctr, key, aes->rounds, scratch); + #else + AesEncrypt(aes, ctr, scratch); + #endif xorbuf(scratch, c, AES_BLOCK_SIZE); XMEMCPY(p, scratch, AES_BLOCK_SIZE); #endif @@ -3161,7 +3260,11 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, } if (partial != 0) { IncrementGcmCounter(ctr); - AesEncrypt(aes, ctr, scratch); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(ctr, key, aes->rounds, scratch); + #else + AesEncrypt(aes, ctr, scratch); + #endif xorbuf(scratch, c, partial); XMEMCPY(p, scratch, partial); } @@ -3186,8 +3289,20 @@ CYASSL_API void GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz, #endif /* HAVE_AESGCM */ + #ifdef HAVE_AESCCM +#ifdef STM32F2_CRYPTO + #error "STM32F2 crypto doesn't currently support AES-CCM mode" + +#elif defined(HAVE_COLDFIRE_SEC) + #error "Coldfire SEC doesn't currently support AES-CCM mode" + +#elif defined(CYASSL_PIC32MZ_CRYPT) + #error "PIC32MZ doesn't currently support AES-CCM mode" + +#endif + void AesCcmSetKey(Aes* aes, const byte* key, word32 keySz) { byte nonce[AES_BLOCK_SIZE]; @@ -3202,19 +3317,31 @@ void AesCcmSetKey(Aes* aes, const byte* key, word32 keySz) static void roll_x(Aes* aes, const byte* in, word32 inSz, byte* out) { + #ifdef FREESCALE_MMCAU + byte* key = (byte*)aes->key; + #endif + /* process the bulk of the data */ while (inSz >= AES_BLOCK_SIZE) { xorbuf(out, in, AES_BLOCK_SIZE); in += AES_BLOCK_SIZE; inSz -= AES_BLOCK_SIZE; - AesEncrypt(aes, out, out); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(out, key, aes->rounds, out); + #else + AesEncrypt(aes, out, out); + #endif } /* process remainder of the data */ if (inSz > 0) { xorbuf(out, in, inSz); - AesEncrypt(aes, out, out); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(out, key, aes->rounds, out); + #else + AesEncrypt(aes, out, out); + #endif } } @@ -3224,6 +3351,10 @@ static void roll_auth(Aes* aes, const byte* in, word32 inSz, byte* out) word32 authLenSz; word32 remainder; + #ifdef FREESCALE_MMCAU + byte* key = (byte*)aes->key; + #endif + /* encode the length in */ if (inSz <= 0xFEFF) { authLenSz = 2; @@ -3257,7 +3388,11 @@ static void roll_auth(Aes* aes, const byte* in, word32 inSz, byte* out) xorbuf(out + authLenSz, in, inSz); inSz = 0; } - AesEncrypt(aes, out, out); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(out, key, aes->rounds, out); + #else + AesEncrypt(aes, out, out); + #endif if (inSz > 0) roll_x(aes, in, inSz, out); @@ -3284,6 +3419,10 @@ void AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, byte lenSz; word32 i; + #ifdef FREESCALE_MMCAU + byte* key = (byte*)aes->key; + #endif + XMEMCPY(B+1, nonce, nonceSz); lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz; B[0] = (authInSz > 0 ? 64 : 0) @@ -3292,7 +3431,11 @@ void AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, for (i = 0; i < lenSz; i++) B[AES_BLOCK_SIZE - 1 - i] = (inSz >> (8 * i)) & 0xFF; - AesEncrypt(aes, B, A); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(B, key, aes->rounds, A); + #else + AesEncrypt(aes, B, A); + #endif if (authInSz > 0) roll_auth(aes, authIn, authInSz, A); if (inSz > 0) @@ -3302,12 +3445,20 @@ void AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, B[0] = lenSz - 1; for (i = 0; i < lenSz; i++) B[AES_BLOCK_SIZE - 1 - i] = 0; - AesEncrypt(aes, B, A); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(B, key, aes->rounds, A); + #else + AesEncrypt(aes, B, A); + #endif xorbuf(authTag, A, authTagSz); B[15] = 1; while (inSz >= AES_BLOCK_SIZE) { - AesEncrypt(aes, B, A); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(B, key, aes->rounds, A); + #else + AesEncrypt(aes, B, A); + #endif xorbuf(A, in, AES_BLOCK_SIZE); XMEMCPY(out, A, AES_BLOCK_SIZE); @@ -3317,7 +3468,11 @@ void AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, out += AES_BLOCK_SIZE; } if (inSz > 0) { - AesEncrypt(aes, B, A); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(B, key, aes->rounds, A); + #else + AesEncrypt(aes, B, A); + #endif xorbuf(A, in, inSz); XMEMCPY(out, A, inSz); } @@ -3339,6 +3494,10 @@ int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, word32 i, oSz; int result = 0; + #ifdef FREESCALE_MMCAU + byte* key = (byte*)aes->key; + #endif + o = out; oSz = inSz; XMEMCPY(B+1, nonce, nonceSz); @@ -3350,7 +3509,11 @@ int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, B[15] = 1; while (oSz >= AES_BLOCK_SIZE) { - AesEncrypt(aes, B, A); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(B, key, aes->rounds, A); + #else + AesEncrypt(aes, B, A); + #endif xorbuf(A, in, AES_BLOCK_SIZE); XMEMCPY(o, A, AES_BLOCK_SIZE); @@ -3360,14 +3523,22 @@ int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, o += AES_BLOCK_SIZE; } if (inSz > 0) { - AesEncrypt(aes, B, A); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(B, key, aes->rounds, A); + #else + AesEncrypt(aes, B, A); + #endif xorbuf(A, in, oSz); XMEMCPY(o, A, oSz); } for (i = 0; i < lenSz; i++) B[AES_BLOCK_SIZE - 1 - i] = 0; - AesEncrypt(aes, B, A); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(B, key, aes->rounds, A); + #else + AesEncrypt(aes, B, A); + #endif o = out; oSz = inSz; @@ -3378,7 +3549,11 @@ int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, for (i = 0; i < lenSz; i++) B[AES_BLOCK_SIZE - 1 - i] = (inSz >> (8 * i)) & 0xFF; - AesEncrypt(aes, B, A); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(B, key, aes->rounds, A); + #else + AesEncrypt(aes, B, A); + #endif if (authInSz > 0) roll_auth(aes, authIn, authInSz, A); if (inSz > 0) @@ -3387,7 +3562,11 @@ int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, B[0] = lenSz - 1; for (i = 0; i < lenSz; i++) B[AES_BLOCK_SIZE - 1 - i] = 0; - AesEncrypt(aes, B, B); + #ifdef FREESCALE_MMCAU + cau_aes_encrypt(B, key, aes->rounds, B); + #else + AesEncrypt(aes, B, B); + #endif xorbuf(A, B, authTagSz); if (XMEMCMP(A, authTag, authTagSz) != 0) { @@ -3405,22 +3584,7 @@ int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, return result; } -#endif - -#endif /* STM32F2_CRYPTO */ - -int AesSetIV(Aes* aes, const byte* iv) -{ - if (aes == NULL) - return BAD_FUNC_ARG; - - if (iv) - XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); - else - XMEMSET(aes->reg, 0, AES_BLOCK_SIZE); - - return 0; -} +#endif /* HAVE_AESCCM */ #ifdef HAVE_CAVIUM @@ -3548,4 +3712,3 @@ static int AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in, #endif /* NO_AES */ -