From c44880635c6c6f8b7b026c79ae5ec1e49e38541c Mon Sep 17 00:00:00 2001 From: areviu Date: Sun, 25 Mar 2018 09:16:57 +0000 Subject: added gcm for sama crypto git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11851 110e8d01-0319-4d1e-a829-52ad28d1bb01 --- os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk | 3 +- os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h | 1 + os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c | 215 +++++++++++++++++++++++ os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h | 25 +++ 4 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c create mode 100644 os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h (limited to 'os/hal/ports/SAMA/LLD/CRYPTOv1') diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk b/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk index 9673bb649..24fcc73b3 100644 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk @@ -1,7 +1,8 @@ PLATFORMSRC +=$(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c \ $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c \ $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c \ - $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c + $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c \ + $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h index 029a209ac..b90535392 100644 --- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h @@ -62,6 +62,7 @@ extern void samaCryptoDriverDisable(CRYDriver *cryp); #include "sama_aes_lld.h" #include "sama_tdes_lld.h" #include "sama_sha_lld.h" +#include "sama_gcm_lld.h" #endif /* HAL_USE_CRY */ diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c new file mode 100644 index 000000000..2496c03d3 --- /dev/null +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.c @@ -0,0 +1,215 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ +#include "hal.h" +#include +#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__) + +#include "sama_crypto_lld.h" + +static void incr32(uint8_t* j0) +{ + + uint32_t counter = j0[15] | j0[14] << 0x8 | j0[13] << 0x10 | j0[12] << 0x18; + + counter++; + + j0[12] = (counter>>24) & 0xFF; + j0[13] = (counter>>16) & 0xFF; + j0[14] = (counter>>8) & 0xFF; + j0[15] = counter & 0xFF; +} + +static cryerror_t sama_gcm_lld_process_dma(CRYDriver *cryp,cgmcontext * cxt) +{ +#if defined(SAMA_DMA_REQUIRED) + + osalDbgAssert(cryp->thread == NULL, "already waiting"); + + + //set chunk size + cryp->dmachunksize = DMA_CHUNK_SIZE_4; + + if ((cryp->config->cfbs != AES_CFBS_128)) + cryp->dmachunksize = DMA_CHUNK_SIZE_1; + + //set dma width + cryp->dmawith = DMA_DATA_WIDTH_WORD; + + if (cryp->config->cfbs == AES_CFBS_16) + cryp->dmawith = DMA_DATA_WIDTH_HALF_WORD; + if (cryp->config->cfbs == AES_CFBS_8) + cryp->dmawith = DMA_DATA_WIDTH_BYTE; + + cryp->rxdmamode = XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_PROT_SEC | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_CSIZE(cryp->dmachunksize) | + XDMAC_CC_DWIDTH(cryp->dmawith) | + XDMAC_CC_SIF_AHB_IF1 | + XDMAC_CC_DIF_AHB_IF0 | + XDMAC_CC_SAM_FIXED_AM | + XDMAC_CC_DAM_INCREMENTED_AM | + XDMAC_CC_PERID(PERID_AES_RX); + + 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_AES_TX); + + dmaChannelSetMode(cryp->dmarx, cryp->rxdmamode); + dmaChannelSetMode(cryp->dmatx, cryp->txdmamode); + + // Writing channel + dmaChannelSetSource(cryp->dmatx, cxt->in); + dmaChannelSetDestination(cryp->dmatx, AES->AES_IDATAR); + dmaChannelSetTransactionSize(cryp->dmatx, ( cxt->c_size / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith))); + + + // Reading channel + dmaChannelSetSource(cryp->dmarx, AES->AES_ODATAR); + dmaChannelSetDestination(cryp->dmarx, cxt->out); + dmaChannelSetTransactionSize(cryp->dmarx, ( cxt->c_size / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith))); + + AES->AES_MR |= (((AES_MR_SMOD_Msk & (AES_MR_SMOD_IDATAR0_START))) + | AES_MR_CKEY_PASSWD); + + //Enable aes interrupt + AES->AES_IER = AES_IER_DATRDY; + + osalSysLock(); + + dmaChannelEnable(cryp->dmarx); + dmaChannelEnable(cryp->dmatx); + + osalThreadSuspendS(&cryp->thread); + + osalSysUnlock(); + + +#endif //#if defined(SAMA_DMA_REQUIRED) + return CRY_NOERROR; + +} + +cryerror_t sama_gcm_lld_process(CRYDriver *cryp,cgmcontext * cxt) +{ + cryerror_t ret; + uint32_t *ref32; + uint8_t i; + uint8_t J0[16] = { 0x00 }; + + + osalMutexLock(&cryp->mutex); + + + //AES soft reset + AES->AES_CR = AES_CR_SWRST; + + //AES set op mode + AES->AES_MR =((AES_MR_OPMOD_Msk & (AES_MR_OPMOD_GCM)) | AES_MR_GTAGEN | AES_MR_CKEY_PASSWD); + + + //AES set key size + ret = sama_aes_lld_set_key_size(cryp->key0_size); + + + if (ret == CRY_NOERROR) { + + AES->AES_MR |= ( ((AES_MR_SMOD_Msk & (AES_MR_SMOD_MANUAL_START))) | AES_MR_CKEY_PASSWD); + + sama_aes_lld_write_key(cryp->key0_buffer,NULL, cryp->key0_size); + + AES->AES_CR = AES_CR_START; + + while ((AES->AES_ISR & AES_ISR_DATRDY) != AES_ISR_DATRDY); + + //J0 + + memcpy(J0, cxt->params.iv, 16); // copy the IV to the first 12 bytes of J0 + + incr32(J0); + + // Write incr32(J0) into IV. + + ref32 = (uint32_t*)J0; + AES->AES_IVR[0] = ref32[0]; + AES->AES_IVR[1] = ref32[1]; + AES->AES_IVR[2] = ref32[2]; + AES->AES_IVR[3] = ref32[3]; + + + AES->AES_AADLENR = cxt->aadsize; + AES->AES_CLENR = cxt->c_size; + + if (cxt->params.encrypt) + AES->AES_MR |= AES_MR_CIPHER; + else + AES->AES_MR &= ~AES_MR_CIPHER; + + AES->AES_MR |= AES_MR_GTAGEN| AES_MR_CKEY_PASSWD; + + + for (i = 0; i < cxt->aadsize; i += cxt->params.block_size) { + + sama_aes_lld_set_input((uint32_t *) ((cxt->aad) + i)); + + AES->AES_CR = AES_CR_START; + + while ((AES->AES_ISR & AES_ISR_DATRDY) != AES_ISR_DATRDY); + + } + + if (cryp->config->transfer_mode == TRANSFER_POLLING) { + for (i = 0; i < cxt->c_size; i += cxt->params.block_size) { + + sama_aes_lld_set_input((uint32_t *) ((cxt->in) + i)); + + AES->AES_CR = AES_CR_START; + + while ((AES->AES_ISR & AES_ISR_DATRDY) != AES_ISR_DATRDY); + + sama_aes_lld_get_output((uint32_t *) ((cxt->out) + i)); + } + } + else + { + sama_gcm_lld_process_dma(cryp,cxt); + } + + while ((AES->AES_ISR & AES_ISR_TAGRDY) != AES_ISR_TAGRDY); + + ref32 = (uint32_t*)cxt->authtag; + + for (i = 0; i < 4; i++) { + ref32[i] =AES->AES_TAGR[i]; + } + + + } + osalMutexUnlock(&cryp->mutex); + + return ret; + +} + + +#endif diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h new file mode 100644 index 000000000..1ce7c3c19 --- /dev/null +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_gcm_lld.h @@ -0,0 +1,25 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +#ifndef CRYPTOLIB_LLD_SAMA_GCM_H_ +#define CRYPTOLIB_LLD_SAMA_GCM_H_ + + + +cryerror_t sama_gcm_lld_process(CRYDriver *cryp,cgmcontext * cxt); + + + +#endif /* CRYPTOLIB_LLD_SAMA_GCM_H_ */ -- cgit v1.2.3