From 388c0bb327ef06a5cda4bb0d33791451a6d6b2bf Mon Sep 17 00:00:00 2001 From: areviu Date: Sun, 3 Dec 2017 11:17:37 +0000 Subject: added SHA in dma mode git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11115 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c | 15 ++- os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c | 5 +- os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c | 161 +++++++++++++++-------- os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c | 18 ++- 4 files changed, 132 insertions(+), 67 deletions(-) (limited to 'os') diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c index da66978fc..bbe51ab20 100644 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c @@ -112,6 +112,7 @@ cryerror_t sama_aes_lld_process_polling(CRYDriver *cryp, aesparams *params, uint32_t i; cryerror_t ret; + osalMutexLock(&cryp->mutex); //AES soft reset AES->AES_CR = AES_CR_SWRST; @@ -125,11 +126,11 @@ cryerror_t sama_aes_lld_process_polling(CRYDriver *cryp, aesparams *params, AES->AES_MR |= (AES_MR_CFBS(cryp->config->cfbs) | AES_MR_CKEY_PASSWD); - osalMutexLock(&cryp->mutex); + sama_aes_lld_write_key(cryp->key0_buffer,( const uint32_t *) params->iv, cryp->key0_size); - osalMutexUnlock(&cryp->mutex); + if (params->encrypt) AES->AES_MR |= AES_MR_CIPHER; @@ -156,6 +157,8 @@ cryerror_t sama_aes_lld_process_polling(CRYDriver *cryp, aesparams *params, } + osalMutexUnlock(&cryp->mutex); + return CRY_NOERROR; } @@ -167,6 +170,8 @@ cryerror_t sama_aes_lld_process_dma(CRYDriver *cryp, aesparams *params, osalDbgAssert(cryp->thread == NULL, "already waiting"); + osalMutexLock(&cryp->mutex); + //set chunk size cryp->dmachunksize = DMA_CHUNK_SIZE_4; @@ -230,12 +235,8 @@ cryerror_t sama_aes_lld_process_dma(CRYDriver *cryp, aesparams *params, AES->AES_MR |= (AES_MR_CFBS(cryp->config->cfbs) | AES_MR_CKEY_PASSWD); - osalMutexLock(&cryp->mutex); - sama_aes_lld_write_key(cryp->key0_buffer,( const uint32_t *) params->iv, cryp->key0_size); - osalMutexUnlock(&cryp->mutex); - if (params->encrypt) AES->AES_MR |= AES_MR_CIPHER; else @@ -258,6 +259,8 @@ cryerror_t sama_aes_lld_process_dma(CRYDriver *cryp, aesparams *params, osalSysUnlock(); + osalMutexUnlock(&cryp->mutex); + return CRY_NOERROR; } diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c index f06ef34ed..12c2df965 100644 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c @@ -133,8 +133,6 @@ static void crypto_lld_serve_read_interrupt(CRYDriver *cryp, uint32_t flags) { #endif /* Stop everything.*/ - - dmaChannelDisable(cryp->dmatx); dmaChannelDisable(cryp->dmarx); /* Portable CRY ISR code defined in the high level driver, note, it is a macro.*/ @@ -161,7 +159,10 @@ static void crypto_lld_serve_write_interrupt(CRYDriver *cryp, uint32_t flags) { (void)flags; #endif + dmaChannelDisable(cryp->dmatx); + if (cryp->rxdmamode == 0xFFFFFFFF) + _cry_isr_code(cryp); } #endif diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c index 9806541fd..673fa6ffd 100644 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c @@ -39,9 +39,9 @@ static uint32_t shadPaddedMessSize(uint8_t mode, uint32_t len); uint8_t shaBlockSize(shadalgo_t algo); static void loadData(const uint8_t* data, int len); static void readData(const uint8_t* data, int len); -static uint32_t processBlock(const uint8_t* data, uint32_t len, uint32_t block_size); -static void updatePollingMode(CRYDriver *cryp,struct sha_data *shadata,const uint8_t* data, uint32_t data_size); -static void updateDMA(CRYDriver *cryp,struct sha_data *shadata,const uint8_t* data, uint32_t data_size); +static uint32_t processBlockPolling(CRYDriver *cryp, uint32_t len, uint32_t block_size); +static uint32_t processBlockDMA(CRYDriver *cryp, uint32_t len, uint32_t block_size); +static void update(CRYDriver *cryp,struct sha_data *shadata,const uint8_t* data, uint32_t data_size); static uint32_t fillPadding(struct sha_data *shadata, uint32_t len, uint8_t* buffer); @@ -90,7 +90,10 @@ int sha_finish(CRYDriver *cryp,struct sha_data *shadata,const uint8_t* buffer,ui &cryp->sha_buffer[shadata->remaining] ); - processBlock(cryp->sha_buffer, shadata->remaining + padding_len, shadata->block_size); + if (cryp->config->transfer_mode == TRANSFER_POLLING) + processBlockPolling(cryp, shadata->remaining + padding_len, shadata->block_size); + else + processBlockDMA(cryp, shadata->remaining + padding_len, shadata->block_size); readData(buffer, buffer_size); @@ -107,12 +110,13 @@ cryerror_t sama_sha_lld_process(CRYDriver *cryp, uint32_t algoregval; struct sha_data shadata; - if (!(cryp->enabledPer & SHA_PER)) { - cryp->enabledPer |= SHA_PER; - pmcEnableSHA(); + cryp->enabledPer |= SHA_PER; + pmcEnableSHA(); } + osalMutexLock(&cryp->mutex); + shadata.processed = 0; shadata.remaining = 0; shadata.output_size = shaOutputSize(params->algo); @@ -120,66 +124,86 @@ cryerror_t sama_sha_lld_process(CRYDriver *cryp, shadata.algo = params->algo; if (shadata.output_size == 0) { - return CRY_ERR_INV_ALGO; + return CRY_ERR_INV_ALGO; } switch (params->algo) { - case CRY_SHA_1: - algoregval = SHA_MR_ALGO_SHA1; - break; - case CRY_SHA_224: - algoregval = SHA_MR_ALGO_SHA224; - break; - case CRY_SHA_256: - algoregval = SHA_MR_ALGO_SHA256; - break; - #ifdef SHA_MR_ALGO_SHA384 - case CRY_SHA_384: - algoregval = SHA_MR_ALGO_SHA384; - break; - #endif - #ifdef SHA_MR_ALGO_SHA512 - case CRY_SHA_512: - algoregval = SHA_MR_ALGO_SHA512; - break; - #endif - default: - return CRY_ERR_INV_ALGO; - } + case CRY_SHA_1: + algoregval = SHA_MR_ALGO_SHA1; + break; + case CRY_SHA_224: + algoregval = SHA_MR_ALGO_SHA224; + break; + case CRY_SHA_256: + algoregval = SHA_MR_ALGO_SHA256; + break; +#ifdef SHA_MR_ALGO_SHA384 + case CRY_SHA_384: + algoregval = SHA_MR_ALGO_SHA384; + break; +#endif +#ifdef SHA_MR_ALGO_SHA512 + case CRY_SHA_512: + algoregval = SHA_MR_ALGO_SHA512; + break; +#endif + default: + return CRY_ERR_INV_ALGO; + } //soft reset SHA->SHA_CR = SHA_CR_SWRST; + if (cryp->config->transfer_mode == TRANSFER_POLLING) { + algoregval |= SHA_MR_SMOD_MANUAL_START; + } else { + algoregval |= SHA_MR_SMOD_IDATAR0_START; + + cryp->dmawith = DMA_DATA_WIDTH_WORD; + cryp->dmachunksize = DMA_CHUNK_SIZE_16; + + cryp->txdmamode = XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_PROT_SEC | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE(cryp->dmachunksize) | + XDMAC_CC_DWIDTH(cryp->dmawith) | + XDMAC_CC_SIF_AHB_IF0 | + XDMAC_CC_DIF_AHB_IF1 | + XDMAC_CC_SAM_INCREMENTED_AM | + XDMAC_CC_DAM_FIXED_AM | + XDMAC_CC_PERID(PERID_SHA_TX); + + cryp->rxdmamode = 0xFFFFFFFF; + + dmaChannelSetMode(cryp->dmatx, cryp->txdmamode); + } //configure - SHA->SHA_MR = algoregval | SHA_MR_SMOD_MANUAL_START | SHA_MR_PROCDLY_LONGEST; + SHA->SHA_MR = algoregval | SHA_MR_PROCDLY_LONGEST; //enable interrupt SHA->SHA_IER = SHA_IER_DATRDY; uint32_t buf_in_size; - const uint8_t *p=in; + const uint8_t *p = in; while (indata_len) { - buf_in_size = min_u32(indata_len, SHA_UPDATE_LEN); + buf_in_size = min_u32(indata_len, SHA_UPDATE_LEN); - //First block - if (!shadata.processed) { - SHA->SHA_CR = SHA_CR_FIRST; - } + //First block + if (!shadata.processed) { + SHA->SHA_CR = SHA_CR_FIRST; + } - if (cryp->config->transfer_mode == TRANSFER_POLLING) - updatePollingMode(cryp,&shadata, in, buf_in_size); - else - updateDMA(cryp,&shadata, in, buf_in_size); + update(cryp, &shadata, in, buf_in_size); - p += buf_in_size; - indata_len -= buf_in_size; + p += buf_in_size; + indata_len -= buf_in_size; } - sha_finish(cryp, &shadata,out, shadata.output_size); - + sha_finish(cryp, &shadata, out, shadata.output_size); + osalMutexUnlock(&cryp->mutex); return CRY_NOERROR; } @@ -258,14 +282,14 @@ static void readData(const uint8_t* data, int len) } -static uint32_t processBlock(const uint8_t* data, uint32_t len, uint32_t block_size) +static uint32_t processBlockPolling(CRYDriver *cryp,uint32_t len, uint32_t block_size) { uint32_t processed = 0; while ((len - processed) >= block_size) { // load data in the sha input registers - loadData(&data[processed], block_size); + loadData(&cryp->sha_buffer[processed], block_size); SHA->SHA_CR = SHA_CR_START; @@ -278,14 +302,34 @@ static uint32_t processBlock(const uint8_t* data, uint32_t len, uint32_t block_s return processed; } -static void updateDMA(CRYDriver *cryp,struct sha_data *shadata,const uint8_t* data, uint32_t data_size) +static uint32_t processBlockDMA(CRYDriver *cryp, uint32_t len, uint32_t block_size) { - (void)shadata; - (void)data; - (void)data_size; - (void)cryp; + uint32_t processed = 0; + + while ((len - processed) >= block_size) { + + // load data in the sha input registers + // Writing channel + dmaChannelSetSource(cryp->dmatx, &cryp->sha_buffer[processed]); + dmaChannelSetDestination(cryp->dmatx, SHA->SHA_IDATAR); + dmaChannelSetTransactionSize(cryp->dmatx, + (block_size / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith))); + + osalSysLock(); + + dmaChannelEnable(cryp->dmatx); + + osalThreadSuspendS(&cryp->thread); + + osalSysUnlock(); + + processed += block_size; + } + + return processed; } -static void updatePollingMode(CRYDriver *cryp,struct sha_data *shadata,const uint8_t* data, uint32_t data_size) + +static void update(CRYDriver *cryp,struct sha_data *shadata,const uint8_t* data, uint32_t data_size) { uint32_t i; uint32_t processed; @@ -301,7 +345,10 @@ static void updatePollingMode(CRYDriver *cryp,struct sha_data *shadata,const uin //if data is complete process the block if (shadata->remaining == shadata->block_size) { - processBlock(cryp->sha_buffer, shadata->remaining, shadata->block_size); + if (cryp->config->transfer_mode == TRANSFER_POLLING ) + processBlockPolling(cryp,shadata->remaining, shadata->block_size); + else + processBlockDMA(cryp, shadata->remaining, shadata->block_size); shadata->processed += shadata->block_size; shadata->remaining = 0; @@ -312,7 +359,11 @@ static void updatePollingMode(CRYDriver *cryp,struct sha_data *shadata,const uin } // Process blocks - processed = processBlock(data, data_size, shadata->block_size); + if (cryp->config->transfer_mode == TRANSFER_POLLING ) + processed = processBlockPolling(cryp, data_size, shadata->block_size); + else + processed = processBlockDMA(cryp, data_size, shadata->block_size); + shadata->processed += processed; //check remaining data and process diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c index a2dcd5cd3..76ff34145 100644 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c @@ -44,6 +44,9 @@ cryerror_t sama_tdes_lld_polling(CRYDriver *cryp, tdes_config_t *params, uint32_t i; uint8_t size = 8; uint32_t *vectors = (uint32_t *) iv; + + osalMutexLock(&cryp->mutex); + //soft reset TDES->TDES_CR = TDES_CR_SWRST; //configure @@ -78,7 +81,7 @@ cryerror_t sama_tdes_lld_polling(CRYDriver *cryp, tdes_config_t *params, } TDES->TDES_MR = mode; - osalMutexLock(&cryp->mutex); + //write keys TDES->TDES_KEY1WR[0] = cryp->key0_buffer[0]; @@ -106,7 +109,7 @@ cryerror_t sama_tdes_lld_polling(CRYDriver *cryp, tdes_config_t *params, if (params->algo == TDES_ALGO_XTEA) { TDES->TDES_XTEA_RNDR = TDES_XTEA_RNDR_XTEA_RNDS(32); } - osalMutexUnlock(&cryp->mutex); + //load 64 bit data size in tdes registers for (i = 0; i < data_len; i += size) { if (size == 8) @@ -129,6 +132,9 @@ cryerror_t sama_tdes_lld_polling(CRYDriver *cryp, tdes_config_t *params, tdes_get_output((uint32_t *) ((out) + i), NULL); } + osalMutexUnlock(&cryp->mutex); + + return CRY_NOERROR; } @@ -139,6 +145,8 @@ cryerror_t sama_tdes_lld_dma(CRYDriver *cryp, tdes_config_t *params, uint32_t mode = 0; uint32_t *vectors = (uint32_t *) iv; + osalMutexLock(&cryp->mutex); + cryp->dmachunksize = DMA_CHUNK_SIZE_1; cryp->dmawith = DMA_DATA_WIDTH_WORD; @@ -214,7 +222,7 @@ cryerror_t sama_tdes_lld_dma(CRYDriver *cryp, tdes_config_t *params, TDES->TDES_MR = mode; - osalMutexLock(&cryp->mutex); + //write keys TDES->TDES_KEY1WR[0] = cryp->key0_buffer[0]; @@ -240,7 +248,7 @@ cryerror_t sama_tdes_lld_dma(CRYDriver *cryp, tdes_config_t *params, TDES->TDES_IVR[1] = vectors[1]; } - osalMutexUnlock(&cryp->mutex); + if (params->algo == TDES_ALGO_XTEA) { TDES->TDES_XTEA_RNDR = TDES_XTEA_RNDR_XTEA_RNDS(32); @@ -257,6 +265,8 @@ cryerror_t sama_tdes_lld_dma(CRYDriver *cryp, tdes_config_t *params, osalThreadSuspendS(&cryp->thread); osalSysUnlock(); + osalMutexUnlock(&cryp->mutex); + return CRY_NOERROR; } -- cgit v1.2.3