diff --git a/ctaocrypt/src/aes.c b/ctaocrypt/src/aes.c index 8f5e357d7..02a15690a 100644 --- a/ctaocrypt/src/aes.c +++ b/ctaocrypt/src/aes.c @@ -55,6 +55,184 @@ word32 length); #endif +#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 ); + } + + int AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + AesCrypt(aes, out, in, sz, PIC32_DECRYPTION, PIC32_ALGO_AES, + PIC32_CRYPTOALGO_RCBC); + } + + #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 @@ -62,8 +240,8 @@ * document (See note in README). */ #include "stm32f2xx.h" - #include "stm32f2xx_cryp.h" - + #include "stm32f2xx_cryp.h" + int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir) { @@ -439,13 +617,11 @@ extern volatile unsigned char __MBAR[]; int AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz) { - //printf("AesCbcEncrypt(%x, %x, %x, %d)\n", aes, po, pi, sz) ; return(AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT)) ; } int AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz) { - //printf("AesCbcDecrypt(%x, %x, %x, %d)\n", aes, po, pi, sz) ; return(AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT)) ; } @@ -553,6 +729,96 @@ int AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, 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; + + 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; + + 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 */ static const word32 rcon[] = { @@ -1232,7 +1498,6 @@ static const word32 Td[5][256] = { }; - #define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y)))) @@ -1386,6 +1651,10 @@ static int AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen, #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); @@ -1393,6 +1662,19 @@ static int AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen, 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: @@ -1882,7 +2164,7 @@ 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; @@ -1989,7 +2271,7 @@ int AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) return 0; } - +#endif #ifdef CYASSL_AES_DIRECT @@ -2022,7 +2304,7 @@ int AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, #endif /* CYASSL_AES_DIRECT || CYASSL_AES_COUNTER */ -#ifdef CYASSL_AES_COUNTER +#if defined(CYASSL_AES_COUNTER) && !defined(HAVE_AES_ENGINE) /* Increment AES counter */ static INLINE void IncrementAesCounter(byte* inOutCtr) @@ -2039,15 +2321,39 @@ static INLINE void IncrementAesCounter(byte* inOutCtr) void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) { - word32 blocks = sz / AES_BLOCK_SIZE; + byte* tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left; - while (blocks--) { + /* 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; + 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--; + } } } @@ -2688,34 +2994,51 @@ void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, word32 partial = sz % AES_BLOCK_SIZE; const byte* p = in; byte* c = out; - byte ctr[AES_BLOCK_SIZE]; + byte counter[AES_BLOCK_SIZE]; + byte *ctr ; byte scratch[AES_BLOCK_SIZE]; CYASSL_ENTER("AesGcmEncrypt"); +#ifdef CYASSL_PIC32MZ_CRYPT + ctr = (char *)aes->iv_ce ; +#else + ctr = counter ; +#endif + XMEMSET(ctr, 0, AES_BLOCK_SIZE); XMEMCPY(ctr, iv, ivSz); InitGcmCounter(ctr); +#ifdef CYASSL_PIC32MZ_CRYPT + if(blocks) + AesCrypt(aes, out, in, blocks*AES_BLOCK_SIZE, + PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM ); +#endif while (blocks--) { IncrementGcmCounter(ctr); + #ifndef CYASSL_PIC32MZ_CRYPT AesEncrypt(aes, ctr, scratch); xorbuf(scratch, p, AES_BLOCK_SIZE); XMEMCPY(c, scratch, AES_BLOCK_SIZE); - + #endif p += AES_BLOCK_SIZE; c += AES_BLOCK_SIZE; } + if (partial != 0) { IncrementGcmCounter(ctr); AesEncrypt(aes, ctr, scratch); xorbuf(scratch, p, partial); XMEMCPY(c, scratch, partial); + } + GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz); InitGcmCounter(ctr); AesEncrypt(aes, ctr, scratch); xorbuf(authTag, scratch, authTagSz); + } @@ -2728,11 +3051,18 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, word32 partial = sz % AES_BLOCK_SIZE; const byte* c = in; byte* p = out; - byte ctr[AES_BLOCK_SIZE]; + byte counter[AES_BLOCK_SIZE]; + byte *ctr ; byte scratch[AES_BLOCK_SIZE]; CYASSL_ENTER("AesGcmDecrypt"); +#ifdef CYASSL_PIC32MZ_CRYPT + ctr = (char *)aes->iv_ce ; +#else + ctr = counter ; +#endif + XMEMSET(ctr, 0, AES_BLOCK_SIZE); XMEMCPY(ctr, iv, ivSz); InitGcmCounter(ctr); @@ -2746,17 +3076,25 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime)); AesEncrypt(aes, ctr, EKY0); xorbuf(Tprime, EKY0, sizeof(Tprime)); + if (XMEMCMP(authTag, Tprime, authTagSz) != 0) { return AES_GCM_AUTH_E; } } + +#ifdef CYASSL_PIC32MZ_CRYPT + if(blocks) + AesCrypt(aes, out, in, blocks*AES_BLOCK_SIZE, + PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM ); +#endif while (blocks--) { IncrementGcmCounter(ctr); + #ifndef CYASSL_PIC32MZ_CRYPT AesEncrypt(aes, ctr, scratch); xorbuf(scratch, c, AES_BLOCK_SIZE); XMEMCPY(p, scratch, AES_BLOCK_SIZE); - + #endif p += AES_BLOCK_SIZE; c += AES_BLOCK_SIZE; } @@ -2766,11 +3104,11 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, xorbuf(scratch, c, partial); XMEMCPY(p, scratch, partial); } - return 0; } + CYASSL_API void GmacSetKey(Gmac* gmac, const byte* key, word32 len) { AesGcmSetKey(&gmac->aes, key, len); diff --git a/ctaocrypt/src/des3.c b/ctaocrypt/src/des3.c index 4a501c93d..ab2c8a76c 100644 --- a/ctaocrypt/src/des3.c +++ b/ctaocrypt/src/des3.c @@ -263,6 +263,469 @@ Des3Crypt(des, out, in, sz, DES_DECRYPTION); } + +#elif defined(HAVE_COLDFIRE_SEC) + +#include "sec.h" +#include "mcf548x_sec.h" + +#include "memory_pools.h" +extern TX_BYTE_POOL mp_ncached; /* Non Cached memory pool */ +#define DES_BUFFER_SIZE (DES_BLOCK_SIZE * 16) +static unsigned char *DesBuffer = NULL ; + +#define SEC_DESC_DES_CBC_ENCRYPT 0x20500010 +#define SEC_DESC_DES_CBC_DECRYPT 0x20400010 +#define SEC_DESC_DES3_CBC_ENCRYPT 0x20700010 +#define SEC_DESC_DES3_CBC_DECRYPT 0x20600010 + +extern volatile unsigned char __MBAR[]; + +static void Des_Cbc(Des* des, byte* out, const byte* in, word32 sz, word32 desc) +{ + static volatile SECdescriptorType descriptor = { NULL } ; + int ret ; int stat1,stat2 ; + int i ; int size ; + volatile int v ; + + while(sz) { + if((sz%DES_BUFFER_SIZE) == sz) { + size = sz ; + sz = 0 ; + } else { + size = DES_BUFFER_SIZE ; + sz -= DES_BUFFER_SIZE ; + } + + descriptor.header = desc ; + /* + escriptor.length1 = 0x0; + descriptor.pointer1 = NULL; + */ + descriptor.length2 = des->ivlen ; + descriptor.pointer2 = (byte *)des->iv ; + descriptor.length3 = des->keylen ; + descriptor.pointer3 = (byte *)des->key; + descriptor.length4 = size; + descriptor.pointer4 = (byte *)in ; + descriptor.length5 = size; + descriptor.pointer5 = DesBuffer ; + /* + descriptor.length6 = 0; + descriptor.pointer6 = NULL; + descriptor.length7 = 0x0; + descriptor.pointer7 = NULL; + descriptor.nextDescriptorPtr = NULL ; + */ + + /* Initialize SEC and wait for encryption to complete */ + MCF_SEC_CCCR0 = 0x0000001A; //enable channel done notification + + /* Point SEC to the location of the descriptor */ + MCF_SEC_FR0 = (uint32)&descriptor; + + /* poll SISR to determine when channel is complete */ + while (!(MCF_SEC_SISRL) && !(MCF_SEC_SISRH)) + ; + + for(v=0; v<500; v++) ; + + ret = MCF_SEC_SISRH; + stat1 = MCF_SEC_DSR ; + stat2 = MCF_SEC_DISR ; + if(ret & 0xe0000000) + db_printf("Des_Cbc(%x):ISRH=%08x, DSR=%08x, DISR=%08x\n", desc, ret, stat1, stat2) ; + + XMEMCPY(out, DesBuffer, size) ; + + if((desc==SEC_DESC_DES3_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_ENCRYPT)) { + XMEMCPY((void*)des->iv, (void*)&(out[size-DES_IVLEN]), DES_IVLEN) ; + } else { + XMEMCPY((void*)des->iv, (void*)&(in[size-DES_IVLEN]), DES_IVLEN) ; + } + + in += size ; + out += size ; + + } +} + + +void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) +{ + Des_Cbc(des, out, in, sz, SEC_DESC_DES_CBC_ENCRYPT) ; +} + +void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) +{ + Des_Cbc(des, out, in, sz, SEC_DESC_DES_CBC_DECRYPT) ; +} + +void Des3_CbcEncrypt(Des3* des3, byte* out, const byte* in, word32 sz) +{ + Des_Cbc((Des *)des3, out, in, sz, SEC_DESC_DES3_CBC_ENCRYPT) ; +} + +void Des3_CbcDecrypt(Des3* des3, byte* out, const byte* in, word32 sz) +{ + Des_Cbc((Des *)des3, out, in, sz, SEC_DESC_DES3_CBC_DECRYPT) ; +} + + +void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir) +{ + int i ; int status ; + + if(DesBuffer == NULL) { + status = tx_byte_allocate(&mp_ncached,(void *)&DesBuffer,DES_BUFFER_SIZE,TX_NO_WAIT); + } + + XMEMCPY(des->key, key, DES_KEYLEN); + des->keylen = DES_KEYLEN ; + des->ivlen = 0 ; + if (iv) { + XMEMCPY(des->iv, iv, DES_IVLEN); + des->ivlen = DES_IVLEN ; + } else { + for(i=0; iiv[i] = 0x0 ; + } + +} + +void Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) +{ + int i ; int status ; + + if(DesBuffer == NULL) { + status = tx_byte_allocate(&mp_ncached,(void *)&DesBuffer,DES_BUFFER_SIZE,TX_NO_WAIT); + } + + XMEMCPY(des3->key, key, DES3_KEYLEN); + des3->keylen = DES3_KEYLEN ; + des3->ivlen = 0 ; + if (iv) { + XMEMCPY(des3->iv, iv, DES3_IVLEN); + des3->ivlen = DES3_IVLEN ; + } else { + for(i=0; iiv[i] = 0x0 ; + } +} + +#elif defined FREESCALE_MMCAU + /* + * Freescale mmCAU hardware DES/3DES 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" + + const unsigned char parityLookup[128] = + { + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 + }; + + void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir) + { + int i = 0; + byte* dkey = (byte*)des->key; + + XMEMCPY(dkey, key, 8); + + Des_SetIV(des, iv); + + /* fix key parity, if needed */ + for (i = 0; i < 8; i++) { + dkey[i] = ((dkey[i] & 0xFE) | parityLookup[dkey[i] >> 1]); + } + } + + void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir) + { + int i = 0; + byte* dkey1 = (byte*)des->key[0]; + byte* dkey2 = (byte*)des->key[1]; + byte* dkey3 = (byte*)des->key[2]; + + XMEMCPY(dkey1, key, 8); /* set key 1 */ + XMEMCPY(dkey2, key + 8, 8); /* set key 2 */ + XMEMCPY(dkey3, key + 16, 8); /* set key 3 */ + + Des3_SetIV(des, iv); + + /* fix key parity if needed */ + for (i = 0; i < 8; i++) + dkey1[i] = ((dkey1[i] & 0xFE) | parityLookup[dkey1[i] >> 1]); + + for (i = 0; i < 8; i++) + dkey2[i] = ((dkey2[i] & 0xFE) | parityLookup[dkey2[i] >> 1]); + + for (i = 0; i < 8; i++) + dkey3[i] = ((dkey3[i] & 0xFE) | parityLookup[dkey3[i] >> 1]); + } + + void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) + { + int i; + int offset = 0; + int len = sz; + byte *iv; + byte temp_block[DES_BLOCK_SIZE]; + + iv = (byte*)des->reg; + + while (len > 0) + { + XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE); + + /* XOR block with IV for CBC */ + for (i = 0; i < DES_BLOCK_SIZE; i++) + temp_block[i] ^= iv[i]; + + cau_des_encrypt(temp_block, (byte*)des->key, out + offset); + + len -= DES_BLOCK_SIZE; + offset += DES_BLOCK_SIZE; + + /* store IV for next block */ + XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE); + } + + return; + } + + void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) + { + int i; + int offset = 0; + int len = sz; + byte* iv; + byte temp_block[DES_BLOCK_SIZE]; + + iv = (byte*)des->reg; + + while (len > 0) + { + XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE); + + cau_des_decrypt(in + offset, (byte*)des->key, out + offset); + + /* XOR block with IV for CBC */ + for (i = 0; i < DES_BLOCK_SIZE; i++) + (out + offset)[i] ^= iv[i]; + + /* store IV for next block */ + XMEMCPY(iv, temp_block, DES_BLOCK_SIZE); + + len -= DES_BLOCK_SIZE; + offset += DES_BLOCK_SIZE; + } + + return; + } + + void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz) + { + int i; + int offset = 0; + int len = sz; + + byte *iv; + byte temp_block[DES_BLOCK_SIZE]; + + iv = (byte*)des->reg; + + while (len > 0) + { + XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE); + + /* XOR block with IV for CBC */ + for (i = 0; i < DES_BLOCK_SIZE; i++) + temp_block[i] ^= iv[i]; + + cau_des_encrypt(temp_block , (byte*)des->key[0], out + offset); + cau_des_decrypt(out + offset, (byte*)des->key[1], out + offset); + cau_des_encrypt(out + offset, (byte*)des->key[2], out + offset); + + len -= DES_BLOCK_SIZE; + offset += DES_BLOCK_SIZE; + + /* store IV for next block */ + XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE); + } + + return; + } + + void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz) + { + int i; + int offset = 0; + int len = sz; + + byte* iv; + byte temp_block[DES_BLOCK_SIZE]; + + iv = (byte*)des->reg; + + while (len > 0) + { + XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE); + + cau_des_decrypt(in + offset , (byte*)des->key[2], out + offset); + cau_des_encrypt(out + offset, (byte*)des->key[1], out + offset); + cau_des_decrypt(out + offset, (byte*)des->key[0], out + offset); + + /* XOR block with IV for CBC */ + for (i = 0; i < DES_BLOCK_SIZE; i++) + (out + offset)[i] ^= iv[i]; + + /* store IV for next block */ + XMEMCPY(iv, temp_block, DES_BLOCK_SIZE); + + len -= DES_BLOCK_SIZE; + offset += DES_BLOCK_SIZE; + } + + return; + } + + +#elif defined(CYASSL_PIC32MZ_CRYPT) + + #include "../../cyassl/ctaocrypt/port/pic32/pic32mz-crypt.h" + +void Des_SetIV(Des* des, const byte* iv); +void Des3_SetIV(Des3* des, const byte* iv); + + void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir) + { + word32 *dkey = des->key ; + word32 *dreg = des->reg ; + + XMEMCPY((byte *)dkey, (byte *)key, 8); + ByteReverseWords(dkey, dkey, 8); + XMEMCPY((byte *)dreg, (byte *)iv, 8); + ByteReverseWords(dreg, dreg, 8); + } + + void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir) + { + word32 *dkey1 = des->key[0]; + word32 *dreg = des->reg ; + + XMEMCPY(dkey1, key, 24); + ByteReverseWords(dkey1, dkey1, 24); + XMEMCPY(dreg, iv, 8); + ByteReverseWords(dreg, dreg, 8) ; + + } + + void DesCrypt(word32 *key, word32 *iv, byte* out, const byte* in, word32 sz, + int dir, int algo, int cryptoalgo) + { + securityAssociation *sa_p ; + bufferDescriptor *bd_p ; + const byte *in_p, *in_l ; + byte *out_p, *out_l ; + volatile securityAssociation sa __attribute__((aligned (8))); + volatile bufferDescriptor bd __attribute__((aligned (8))); + volatile int k ; + + /* get uncached address */ + + in_l = in; + out_l = out ; + sa_p = KVA0_TO_KVA1(&sa) ; + bd_p = KVA0_TO_KVA1(&bd) ; + in_p = KVA0_TO_KVA1(in_l) ; + out_p= KVA0_TO_KVA1(out_l); + + if(PIC32MZ_IF_RAM(in_p)) + XMEMCPY((void *)in_p, (void *)in, sz); + XMEMSET((void *)out_p, 0, sz); + + /* Set up the Security Association */ + XMEMSET((byte *)KVA0_TO_KVA1(&sa), 0, sizeof(sa)); + sa_p->SA_CTRL.ALGO = algo ; + 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; + sa_p->SA_CTRL.KEYSIZE = 1 ; /* KEY is 192 bits */ + XMEMCPY((byte *)KVA0_TO_KVA1(&sa.SA_ENCKEY[algo==PIC32_ALGO_TDES ? 2 : 6]), + (byte *)key, algo==PIC32_ALGO_TDES ? 24 : 8); + XMEMCPY((byte *)KVA0_TO_KVA1(&sa.SA_ENCIV[2]), (byte *)iv, 8); + + XMEMSET((byte *)KVA0_TO_KVA1(&bd), 0, sizeof(bd)); + /* Set up the Buffer Descriptor */ + bd_p->BD_CTRL.BUFLEN = sz; + 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) ; // (unsigned int)sa_p ; + bd_p->SRCADDR = (unsigned int)KVA_TO_PA(in) ; // (unsigned int)in_p ; + bd_p->DSTADDR = (unsigned int)KVA_TO_PA(out); // (unsigned int)out_p ; + bd_p->NXTPTR = (unsigned int)KVA_TO_PA(&bd); + bd_p->MSGLEN = sz ; + + /* Fire in the hole! */ + CECON = 1 << 6; + while (CECON); + + /* Run the engine */ + CEBDPADDR = (unsigned int)KVA_TO_PA(&bd) ; // (unsigned int)bd_p ; + 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 *)iv, (void*)&(out_p[sz-DES_IVLEN]), DES_IVLEN) ; + } else { + ByteReverseWords((word32*)iv, (word32 *)&(in_p[sz-DES_IVLEN]), DES_IVLEN); + } + + } + + ByteReverseWords((word32*)out, (word32 *)KVA0_TO_KVA1(out), sz); + } + + void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) + { + DesCrypt(des->key, des->reg, out, in, sz, + PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC ); + } + + void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) + { + DesCrypt(des->key, des->reg, out, in, sz, + PIC32_DECRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC); + } + + void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz) + { + DesCrypt(des->key[0], des->reg, out, in, sz, + PIC32_ENCRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC); + } + + void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz) + { + DesCrypt(des->key[0], des->reg, out, in, sz, + PIC32_DECRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC); + } + #else /* CTaoCrypt software implementation */ /* permuted choice table (key) */ diff --git a/ctaocrypt/src/hmac.c b/ctaocrypt/src/hmac.c index 003eb6317..25c867997 100644 --- a/ctaocrypt/src/hmac.c +++ b/ctaocrypt/src/hmac.c @@ -27,6 +27,22 @@ #ifndef NO_HMAC +#ifdef CYASSL_PIC32MZ_HASH + +#define InitMd5 InitMd5_sw +#define Md5Update Md5Update_sw +#define Md5Final Md5Final_sw + +#define InitSha InitSha_sw +#define ShaUpdate ShaUpdate_sw +#define ShaFinal ShaFinal_sw + +#define InitSha256 InitSha256_sw +#define Sha256Update Sha256Update_sw +#define Sha256Final Sha256Final_sw + +#endif + #include #include @@ -86,7 +102,6 @@ static int InitHmac(Hmac* hmac, int type) default: return BAD_FUNC_ARG; - break; } return 0; diff --git a/ctaocrypt/src/port/pic32/pic32mz-hash.c b/ctaocrypt/src/port/pic32/pic32mz-hash.c new file mode 100644 index 000000000..fe2c1f3e4 --- /dev/null +++ b/ctaocrypt/src/port/pic32/pic32mz-hash.c @@ -0,0 +1,243 @@ +/* pic32mz-hash.c + * + * Copyright (C) 2006-2013 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifdef CYASSL_PIC32MZ_HASH + +#include +#include +#include +#include + +#include + +#if !defined(NO_MD5) && !defined(NO_SHA) && !defined(NO_SHA256) + +static void reset_engine(pic32mz_desc *desc_l, int algo) +{ + pic32mz_desc *desc ; + desc = KVA0_TO_KVA1(desc_l) ; + + CECON = 1 << 6; + while (CECON); + + /* Make sure everything is clear first before we make settings. */ + XMEMSET((void *)KVA0_TO_KVA1(&desc->sa), 0, sizeof(desc->sa)); + XMEMSET((void *)KVA0_TO_KVA1(&desc->bd[0]), 0, sizeof(desc->bd[0])); + XMEMSET((void *)KVA0_TO_KVA1(&desc->bd[1]), 0, sizeof(desc->bd[1])); + + /* Set up the security association */ + desc->sa.SA_CTRL.ALGO = algo ; + desc->sa.SA_CTRL.LNC = 1; + desc->sa.SA_CTRL.FB = 1; + desc->sa.SA_CTRL.ENCTYPE = 1; + desc->sa.SA_CTRL.LOADIV = 1; + + /* Set up the buffer descriptor */ + desc->err = 0 ; + desc->bd[0].BD_CTRL.LAST_BD = 1; + desc->bd[0].BD_CTRL.LIFM = 1; + desc->bd[0].SA_ADDR = KVA_TO_PA(&desc->sa); + desc->bd[1].BD_CTRL.LAST_BD = 1; + desc->bd[1].BD_CTRL.LIFM = 1; + desc->bd[1].SA_ADDR = KVA_TO_PA(&desc->sa); + desc_l->bdCount = 0 ; + CEBDPADDR = KVA_TO_PA(&(desc->bd[0])); + + CECON = 0x27; +} + +#define PIC32MZ_IF_RAM(addr) (KVA_TO_PA(addr) < 0x80000) + +static void update_engine(pic32mz_desc *desc_l, const char *input, word32 len, + word32 *hash) +{ + pic32mz_desc *desc ; + int i ; + int total ; + desc = KVA0_TO_KVA1(desc_l) ; + + i = desc_l->bdCount ; + if(i >= PIC32MZ_MAX_BD) { + desc_l->err = 1 ; + return ; + } + + if(PIC32MZ_IF_RAM(input)) + XMEMCPY(KVA0_TO_KVA1(input), input, len) ; /* Sync phys with cache */ + desc->bd[i].SRCADDR = KVA_TO_PA(input); + /* Finally, turn on the buffer descriptor */ + if (len % 4) + desc->bd[i].BD_CTRL.BUFLEN = (len + 4) - (len % 4); + else desc->bd[i].BD_CTRL.BUFLEN = len ; + + if(i == 0) { + desc->bd[i].MSGLEN = len ; + desc->bd[i].BD_CTRL.SA_FETCH_EN = 1; + } else { + desc->bd[i-1].NXTPTR = KVA_TO_PA(&(desc->bd[i])) ; + desc->bd[i].BD_CTRL.DESC_EN = 1; + desc->bd[i-1].BD_CTRL.LAST_BD = 0 ; + desc->bd[i-1].BD_CTRL.LIFM = 0 ; + total = desc->bd[i-1].MSGLEN + len ; + desc->bd[i].MSGLEN = total ; + desc->bd[i-1].MSGLEN = total ; + } + desc->bd[i].UPDPTR = KVA_TO_PA(hash); + desc_l->bdCount ++ ; + + #ifdef DEBUG_CYASSL + printf("Input[bd=%d, len=%d]:%x->\"%s\"\n", desc_l->bdCount, len, input, input) ; + print_mem(input, len+4) ; + #endif +} + +static void start_engine(pic32mz_desc *desc) { + bufferDescriptor *hash_bd[2] ; + hash_bd[0] = (bufferDescriptor *)KVA0_TO_KVA1(&(desc->bd[0])) ; + hash_bd[0]->BD_CTRL.DESC_EN = 1; +} + +void wait_engine(pic32mz_desc *desc, char *hash, int hash_sz) { + unsigned int i; + unsigned int *intptr; +#undef DEBUG_CYASSL + #ifdef DEBUG_CYASSL + printf("desc(%x)[bd:%d * 2, sz:%d]\n", desc, sizeof(desc->bd[0]), + sizeof(desc->sa) ); + print_mem(KVA0_TO_KVA1(&(desc->bd[0])), sizeof(desc->bd[0])) ; + print_mem(KVA0_TO_KVA1(&(desc->bd[1])), sizeof(desc->bd[0])) ; + #endif + + WAIT_ENGINE ; + + XMEMCPY(hash, KVA0_TO_KVA1(hash), hash_sz) ; + + #ifdef DEBUG_CYASSL + print_mem(KVA0_TO_KVA1(hash), hash_sz) ; + print_mem( hash , hash_sz) ; + #endif + for (i = 0, intptr = (unsigned int *)hash; i < hash_sz/sizeof(unsigned int); + i++, intptr++) + { + *intptr = ntohl(*intptr); + } +} + +static int fillBuff(char *buff, int *bufflen, const char *data, int len, int blocksz) +{ + int room, copysz ; + + room = blocksz - *bufflen ; + copysz = (len <= room) ? len : room ; + XMEMCPY(buff, data, copysz) ; + *bufflen += copysz ; + return (*bufflen == blocksz) ? 1 : 0 ; +} + +#endif + +#ifndef NO_MD5 +void InitMd5(Md5* md5) +{ + CYASSL_ENTER("InitMd5\n") ; + XMEMSET((void *)md5, 0xcc, sizeof(Md5)) ; + XMEMSET((void *)KVA0_TO_KVA1(md5), 0xcc, sizeof(Md5)) ; + reset_engine(&(md5->desc), PIC32_ALGO_MD5) ; + +} + +void Md5Update(Md5* md5, const byte* data, word32 len) +{ + CYASSL_ENTER("Md5Update\n") ; + update_engine(&(md5->desc), data, len, md5->digest) ; +} + +void Md5Final(Md5* md5, byte* hash) +{ + CYASSL_ENTER("Md5Final\n") ; + start_engine(&(md5->desc)) ; + wait_engine(&(md5->desc), (char *)md5->digest, MD5_HASH_SIZE) ; + XMEMCPY(hash, md5->digest, MD5_HASH_SIZE) ; + InitMd5(md5); /* reset state */ +} +#endif + +#ifndef NO_SHA +void InitSha(Sha* sha) +{ + CYASSL_ENTER("InitSha\n") ; + XMEMSET((void *)sha, 0xcc, sizeof(Sha)) ; + XMEMSET((void *)KVA0_TO_KVA1(sha), 0xcc, sizeof(Sha)) ; + reset_engine(&(sha->desc), PIC32_ALGO_SHA1) ; +} + +void ShaUpdate(Sha* sha, const byte* data, word32 len) +{ + CYASSL_ENTER("ShaUpdate\n") ; + update_engine(&(sha->desc), data, len, sha->digest) ; +} + +void ShaFinal(Sha* sha, byte* hash) +{ + CYASSL_ENTER("ShaFinal\n") ; + start_engine(&(sha->desc)) ; + wait_engine(&(sha->desc), (char *)sha->digest, SHA1_HASH_SIZE) ; + XMEMCPY(hash, sha->digest, SHA1_HASH_SIZE) ; + + InitSha(sha); /* reset state */ +} +#endif /* NO_SHA */ + +#ifndef NO_SHA256 +void InitSha256(Sha256* sha256) +{ + CYASSL_ENTER("InitSha256\n") ; + XMEMSET((void *)sha256, 0xcc, sizeof(Sha256)) ; + XMEMSET((void *)KVA0_TO_KVA1(sha256), 0xcc, sizeof(Sha256)) ; + reset_engine(&(sha256->desc), PIC32_ALGO_SHA256) ; +} + +void Sha256Update(Sha256* sha256, const byte* data, word32 len) +{ + CYASSL_ENTER("Sha256Update\n") ; + update_engine(&(sha256->desc), data, len, sha256->digest) ; +} + +void Sha256Final(Sha256* sha256, byte* hash) +{ + CYASSL_ENTER("Sha256Final\n") ; + start_engine(&(sha256->desc)) ; + wait_engine(&(sha256->desc), (char *)sha256->digest, SHA256_HASH_SIZE) ; + XMEMCPY(hash, sha256->digest, SHA256_HASH_SIZE) ; + InitSha256(sha256); /* reset state */ +} +#endif /* NO_SHA256 */ + +#endif + + + diff --git a/ctaocrypt/src/sha.c b/ctaocrypt/src/sha.c index 20d2261f5..88d76d8e4 100644 --- a/ctaocrypt/src/sha.c +++ b/ctaocrypt/src/sha.c @@ -26,7 +26,13 @@ #include -#ifndef NO_SHA +#if !defined(NO_SHA) + +#ifdef CYASSL_PIC32MZ_HASH +#define InitSha InitSha_sw +#define ShaUpdate ShaUpdate_sw +#define ShaFinal ShaFinal_sw +#endif #include #ifdef NO_INLINE @@ -35,6 +41,13 @@ #include #endif +#ifdef FREESCALE_MMCAU + #include "cau_api.h" + #define XTRANSFORM(S,B) cau_sha1_hash_n((B), 1, ((S))->digest) +#else + #define XTRANSFORM(S,B) Transform((S)) +#endif + #ifdef STM32F2_HASH /* @@ -164,17 +177,23 @@ void InitSha(Sha* sha) { - sha->digest[0] = 0x67452301L; - sha->digest[1] = 0xEFCDAB89L; - sha->digest[2] = 0x98BADCFEL; - sha->digest[3] = 0x10325476L; - sha->digest[4] = 0xC3D2E1F0L; + #ifdef FREESCALE_MMCAU + cau_sha1_initialize_output(sha->digest); + #else + sha->digest[0] = 0x67452301L; + sha->digest[1] = 0xEFCDAB89L; + sha->digest[2] = 0x98BADCFEL; + sha->digest[3] = 0x10325476L; + sha->digest[4] = 0xC3D2E1F0L; + #endif sha->buffLen = 0; sha->loLen = 0; sha->hiLen = 0; } +#ifndef FREESCALE_MMCAU + #define blk0(i) (W[i] = sha->buffer[i]) #define blk1(i) (W[i&15] = \ rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1)) @@ -272,6 +291,8 @@ static void Transform(Sha* sha) sha->digest[4] += e; } +#endif /* FREESCALE_MMCAU */ + static INLINE void AddLength(Sha* sha, word32 len) { @@ -295,10 +316,10 @@ void ShaUpdate(Sha* sha, const byte* data, word32 len) len -= add; if (sha->buffLen == SHA_BLOCK_SIZE) { - #ifdef LITTLE_ENDIAN_ORDER + #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) ByteReverseBytes(local, local, SHA_BLOCK_SIZE); #endif - Transform(sha); + XTRANSFORM(sha, local); AddLength(sha, SHA_BLOCK_SIZE); sha->buffLen = 0; } @@ -310,7 +331,7 @@ void ShaFinal(Sha* sha, byte* hash) { byte* local = (byte*)sha->buffer; - AddLength(sha, sha->buffLen); /* before adding pads */ + AddLength(sha, sha->buffLen); /* before adding pads */ local[sha->buffLen++] = 0x80; /* add 1 */ @@ -319,10 +340,10 @@ void ShaFinal(Sha* sha, byte* hash) XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen); sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen; - #ifdef LITTLE_ENDIAN_ORDER + #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) ByteReverseBytes(local, local, SHA_BLOCK_SIZE); #endif - Transform(sha); + XTRANSFORM(sha, local); sha->buffLen = 0; } XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen); @@ -333,14 +354,20 @@ void ShaFinal(Sha* sha, byte* hash) sha->loLen = sha->loLen << 3; /* store lengths */ - #ifdef LITTLE_ENDIAN_ORDER + #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) ByteReverseBytes(local, local, SHA_BLOCK_SIZE); #endif /* ! length ordering dependent on digest endian type ! */ XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32)); XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32)); - Transform(sha); + #ifdef FREESCALE_MMCAU + /* Kinetis requires only these bytes reversed */ + ByteReverseBytes(&local[SHA_PAD_SIZE], &local[SHA_PAD_SIZE], + 2 * sizeof(word32)); + #endif + + XTRANSFORM(sha, local); #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE); #endif diff --git a/ctaocrypt/src/sha256.c b/ctaocrypt/src/sha256.c index baa379059..b551ff484 100644 --- a/ctaocrypt/src/sha256.c +++ b/ctaocrypt/src/sha256.c @@ -28,7 +28,13 @@ #include -#ifndef NO_SHA256 +#if !defined(NO_SHA256) + +#ifdef CYASSL_PIC32MZ_HASH +#define InitSha256 InitSha256_sw +#define Sha256Update Sha256Update_sw +#define Sha256Final Sha256Final_sw +#endif #include #ifdef NO_INLINE @@ -37,6 +43,13 @@ #include #endif +#ifdef FREESCALE_MMCAU + #include "cau_api.h" + #define XTRANSFORM(S,B) cau_sha256_hash_n((B), 1, ((S))->digest) +#else + #define XTRANSFORM(S,B) Transform((S)) +#endif + #ifndef min @@ -50,20 +63,26 @@ void InitSha256(Sha256* sha256) { - sha256->digest[0] = 0x6A09E667L; - sha256->digest[1] = 0xBB67AE85L; - sha256->digest[2] = 0x3C6EF372L; - sha256->digest[3] = 0xA54FF53AL; - sha256->digest[4] = 0x510E527FL; - sha256->digest[5] = 0x9B05688CL; - sha256->digest[6] = 0x1F83D9ABL; - sha256->digest[7] = 0x5BE0CD19L; + #ifdef FREESCALE_MMCAU + cau_sha256_initialize_output(sha256->digest); + #else + sha256->digest[0] = 0x6A09E667L; + sha256->digest[1] = 0xBB67AE85L; + sha256->digest[2] = 0x3C6EF372L; + sha256->digest[3] = 0xA54FF53AL; + sha256->digest[4] = 0x510E527FL; + sha256->digest[5] = 0x9B05688CL; + sha256->digest[6] = 0x1F83D9ABL; + sha256->digest[7] = 0x5BE0CD19L; + #endif sha256->buffLen = 0; sha256->loLen = 0; sha256->hiLen = 0; } +#ifndef FREESCALE_MMCAU + static const word32 K[64] = { 0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL, 0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L, @@ -128,6 +147,8 @@ static void Transform(Sha256* sha256) } } +#endif /* FREESCALE_MMCAU */ + static INLINE void AddLength(Sha256* sha256, word32 len) { @@ -151,10 +172,10 @@ void Sha256Update(Sha256* sha256, const byte* data, word32 len) len -= add; if (sha256->buffLen == SHA256_BLOCK_SIZE) { - #ifdef LITTLE_ENDIAN_ORDER + #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) ByteReverseBytes(local, local, SHA256_BLOCK_SIZE); #endif - Transform(sha256); + XTRANSFORM(sha256, local); AddLength(sha256, SHA256_BLOCK_SIZE); sha256->buffLen = 0; } @@ -168,17 +189,17 @@ void Sha256Final(Sha256* sha256, byte* hash) AddLength(sha256, sha256->buffLen); /* before adding pads */ - local[sha256->buffLen++] = 0x80; /* add 1 */ + local[sha256->buffLen++] = 0x80; /* add 1 */ /* pad with zeros */ if (sha256->buffLen > SHA256_PAD_SIZE) { XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen); sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen; - #ifdef LITTLE_ENDIAN_ORDER + #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) ByteReverseBytes(local, local, SHA256_BLOCK_SIZE); #endif - Transform(sha256); + XTRANSFORM(sha256, local); sha256->buffLen = 0; } XMEMSET(&local[sha256->buffLen], 0, SHA256_PAD_SIZE - sha256->buffLen); @@ -189,7 +210,7 @@ void Sha256Final(Sha256* sha256, byte* hash) sha256->loLen = sha256->loLen << 3; /* store lengths */ - #ifdef LITTLE_ENDIAN_ORDER + #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) ByteReverseBytes(local, local, SHA256_BLOCK_SIZE); #endif /* ! length ordering dependent on digest endian type ! */ @@ -197,7 +218,13 @@ void Sha256Final(Sha256* sha256, byte* hash) XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen, sizeof(word32)); - Transform(sha256); + #ifdef FREESCALE_MMCAU + /* Kinetis requires only these bytes reversed */ + ByteReverseBytes(&local[SHA256_PAD_SIZE], &local[SHA256_PAD_SIZE], + 2 * sizeof(word32)); + #endif + + XTRANSFORM(sha256, local); #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE); #endif diff --git a/cyassl/ctaocrypt/port/pic32/pic32mz-crypt.h b/cyassl/ctaocrypt/port/pic32/pic32mz-crypt.h new file mode 100644 index 000000000..e52b7d584 --- /dev/null +++ b/cyassl/ctaocrypt/port/pic32/pic32mz-crypt.h @@ -0,0 +1,88 @@ +/* pic32mz-crypt.h + * + * Copyright (C) 2006-2013 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef PIC32MZ_CRYPT_H +#define PIC32MZ_CRYPT_H + +#ifdef CYASSL_PIC32MZ_CRYPT + +#define MICROCHIP_PIC32 +#include +#include +#include +#include "../../../../mplabx/crypto.h" + + +#define PIC32_ENCRYPTION 0b1 +#define PIC32_DECRYPTION 0b0 + +#define PIC32_ALGO_HMAC1 0b01000000 +#define PIC32_ALGO_SHA256 0b00100000 +#define PIC32_ALGO_SHA1 0b00010000 +#define PIC32_ALGO_MD5 0b00001000 +#define PIC32_ALGO_AES 0b00000100 +#define PIC32_ALGO_TDES 0b00000010 +#define PIC32_ALGO_DES 0b00000001 + +#define PIC32_CRYPTOALGO_AES_GCM 0b1110 +#define PIC32_CRYPTOALGO_RCTR 0b1101 +#define PIC32_CRYPTOALGO_RCBC 0b1001 +#define PIC32_CRYPTOALGO_REBC 0b1000 +#define PIC32_CRYPTOALGO_TCBC 0b0101 +#define PIC32_CRYPTOALGO_CBC 0b0001 + +#define PIC32_AES_KEYSIZE_256 0b10 +#define PIC32_AES_KEYSIZE_192 0b01 +#define PIC32_AES_KEYSIZE_128 0b00 + +#define PIC32_AES_BLOCK_SIZE 16 +#define MD5_HASH_SIZE 16 +#define SHA1_HASH_SIZE 20 +#define SHA256_HASH_SIZE 32 +#define PIC32_HASH_SIZE 32 + +#define PIC32MZ_MAX_BD 2 +typedef struct { /* Crypt Engine descripter */ + int bdCount ; + int err ; + volatile bufferDescriptor + bd[PIC32MZ_MAX_BD] __attribute__((aligned (8), coherent)); + securityAssociation + sa __attribute__((aligned (8), coherent)); +} pic32mz_desc ; + +#define PIC32MZ_IF_RAM(addr) (KVA_TO_PA(addr) < 0x80000) + +#define WAIT_ENGINE \ + { volatile int v ; while (CESTATbits.ACTIVE) ; for(v=0; v<100; v++) ; } + +#ifdef DEBUG_CYASSL +static void print_mem(const unsigned char *p, int size) { + for(; size>0; size--, p++) { + if(size%4 == 0)printf(" ") ; + printf("%02x", (int)*p) ; + } + puts("") ; +} +#endif + +#endif +#endif /* PIC32MZ_CRYPT_H */