diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk b/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk new file mode 100644 index 000000000..120be44b7 --- /dev/null +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk @@ -0,0 +1,9 @@ +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 + + + +PLATFORMINC +=$(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1 + + diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c new file mode 100644 index 000000000..563269d42 --- /dev/null +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c @@ -0,0 +1,235 @@ +/* + ChibiOS - Copyright (C) 2006..2016 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 "sama_crypto_lld.h" + + + + + +void sama_aes_lld_write_key(const uint32_t * key, const uint32_t * vectors, + uint32_t len) { + + AES->AES_KEYWR[0] = key[0]; + AES->AES_KEYWR[1] = key[1]; + AES->AES_KEYWR[2] = key[2]; + AES->AES_KEYWR[3] = key[3]; + + if (len >= 24) { + AES->AES_KEYWR[4] = key[4]; + AES->AES_KEYWR[5] = key[5]; + } + + else { + AES->AES_KEYWR[4] = 0; + AES->AES_KEYWR[5] = 0; + AES->AES_KEYWR[6] = 0; + AES->AES_KEYWR[7] = 0; + } + + if (len == 32) { + AES->AES_KEYWR[6] = key[6]; + AES->AES_KEYWR[7] = key[7]; + } + + if (vectors != NULL) { + AES->AES_IVR[0] = vectors[0]; + AES->AES_IVR[1] = vectors[1]; + AES->AES_IVR[2] = vectors[2]; + AES->AES_IVR[3] = vectors[3]; + } + + else { + AES->AES_IVR[0] = 0; + AES->AES_IVR[1] = 0; + AES->AES_IVR[2] = 0; + AES->AES_IVR[3] = 0; + } + +} + +cryerror_t sama_aes_lld_set_key_size(size_t size) { + + uint32_t key_size = AES_MR_KEYSIZE_AES128; + + if (size == 16) + key_size = AES_MR_KEYSIZE_AES128; + else if (size == 24) + key_size = AES_MR_KEYSIZE_AES192; + else if (size == 32) + key_size = AES_MR_KEYSIZE_AES256; + else + return CRY_ERR_INV_KEY_SIZE; + //set key size + AES->AES_MR |= (( AES_MR_KEYSIZE_Msk & (key_size)) | AES_MR_CKEY_PASSWD); + + return CRY_NOERROR; +} + +void sama_aes_lld_set_input(uint32_t* data) { + uint8_t i; + uint8_t size = 4; + + if ((AES->AES_MR & AES_MR_OPMOD_Msk) == AES_MR_OPMOD_CFB) { + if ((AES->AES_MR & AES_MR_CFBS_Msk) == + AES_MR_CFBS_SIZE_128BIT) + size = 4; + else if ((AES->AES_MR & AES_MR_CFBS_Msk) == + AES_MR_CFBS_SIZE_64BIT) + size = 2; + else + size = 1; + } + + for (i = 0; i < size; i++) { + AES->AES_IDATAR[i] = data[i]; + } + +} + +void sama_aes_lld_get_output(uint32_t* data) { + uint8_t i; + + for (i = 0; i < 4; i++) { + data[i] = (AES->AES_ODATAR[i]); + } +} + +cryerror_t sama_aes_lld_process_polling(CRYDriver *cryp, aesparams *params, + const uint8_t *in, uint8_t *out, size_t indata_len) { + uint32_t i; + cryerror_t ret; + +//AES soft reset + AES->AES_CR = AES_CR_SWRST; + +//AES set op mode + AES->AES_MR |= ((AES_MR_OPMOD_Msk & (params->mode)) | 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_CFBS(cryp->config->cfbs) | AES_MR_CKEY_PASSWD); + + sama_aes_lld_write_key(key0_buffer,( const uint32_t *) params->iv, cryp->key0_size); + + if (params->encrypt) + AES->AES_MR |= AES_MR_CIPHER; + else + AES->AES_MR &= ~AES_MR_CIPHER; + + AES->AES_MR |= (((AES_MR_SMOD_Msk & (AES_MR_SMOD_MANUAL_START))) + | AES_MR_CKEY_PASSWD); + +//Enable aes interrupt + AES->AES_IER = AES_IER_DATRDY; + + for (i = 0; i < indata_len; i += params->block_size) { + + sama_aes_lld_set_input((uint32_t *) ((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 *) ((out) + i)); + } + + } + + return CRY_NOERROR; + +} + +cryerror_t sama_aes_lld_process_dma(CRYDriver *cryp, aesparams *params, + const uint8_t *in, uint8_t *out, size_t indata_len) { + + 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 with + 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); + + /* Writing channel */ + dmaChannelSetSource(cryp->dmatx, in); + dmaChannelSetDestination(cryp->dmatx, AES->AES_IDATAR); + dmaChannelSetTransactionSize(cryp->dmatx, ( indata_len / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith))); + + + /* Reading channel */ + dmaChannelSetSource(cryp->dmarx, AES->AES_ODATAR); + dmaChannelSetDestination(cryp->dmarx, out); + dmaChannelSetTransactionSize(cryp->dmarx, ( indata_len / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith))); + + if (params->encrypt) + AES->AES_MR |= AES_MR_CIPHER; + else + AES->AES_MR &= ~AES_MR_CIPHER; + + 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(); + + return CRY_NOERROR; + +} + diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.h new file mode 100644 index 000000000..3df2d28e1 --- /dev/null +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.h @@ -0,0 +1,29 @@ +/* + ChibiOS - Copyright (C) 2006..2016 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_AES_H_ +#define CRYPTOLIB_LLD_SAMA_AES_H_ + +extern void sama_aes_lld_write_key(const uint32_t * key, const uint32_t * vectors,uint32_t len); +extern cryerror_t sama_aes_lld_set_key_size(size_t size); +extern cryerror_t sama_aes_lld_process_polling(CRYDriver *cryp,aesparams *params,const uint8_t *in,uint8_t *out,size_t indata_len); +extern cryerror_t sama_aes_lld_process_dma(CRYDriver *cryp,aesparams *params,const uint8_t *in,uint8_t *out,size_t indata_len); + +extern void sama_aes_lld_set_input(uint32_t* data); +extern void sama_aes_lld_get_output(uint32_t* data); + + + +#endif /* CRYPTOLIB_LLD_SAMA_AES_H_ */ diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c new file mode 100644 index 000000000..8375dab67 --- /dev/null +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c @@ -0,0 +1,193 @@ +/* + ChibiOS - Copyright (C) 2006..2016 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 "sama_crypto_lld.h" + +#define KEY0_BUFFER_SIZE_W HAL_CRY_MAX_KEY_SIZE/4 + +uint32_t key0_buffer[KEY0_BUFFER_SIZE_W]; + +#if defined(SAMA_DMA_REQUIRED) +static void crypto_lld_serve_read_interrupt(CRYDriver *cryp, uint32_t flags); +static void crypto_lld_serve_write_interrupt(CRYDriver *cryp, uint32_t flags); +#endif + +/** + * @brief Wakes up the waiting thread. + * + * @param[in] cryp pointer to the @p CRYDRiver object + * + * @notapi + */ +#define _cry_wakeup_isr(cryp) { \ + osalSysLockFromISR(); \ + osalThreadResumeI(&cryp->thread, MSG_OK); \ + osalSysUnlockFromISR(); \ +} + + +/** + * @brief Common ISR code. + * @details This code handles the portable part of the ISR code: + * - Callback invocation. + * - Waiting thread wakeup, if any. + * - Driver state transitions. + * . + * @note This macro is meant to be used in the low level drivers + * implementation only. + * + * @param[in] spip pointer to the @p SPIDriver object + * + * @notapi + */ +#define _cry_isr_code(cryp) { \ + _cry_wakeup_isr(cryp); \ +} + +void samaCryptoDriverInit(CRYDriver *cryp) { + cryp->enabledPer = 0; + cryp->thread = NULL; +} + +void samaCryptoDriverStart(CRYDriver *cryp) { + + + samaClearKeyBuffer(); + + if (cryp->config->transfer_mode == TRANSFER_DMA) + { +#if defined(SAMA_DMA_REQUIRED) + cryp->dmarx = dmaChannelAllocate(SAMA_CRY_CRYD1_DMA_IRQ_PRIORITY, + (sama_dmaisr_t) crypto_lld_serve_read_interrupt, (void *) cryp); + osalDbgAssert(cryp->dmarx != NULL, "no channel allocated"); + + cryp->dmatx = dmaChannelAllocate(SAMA_CRY_CRYD1_DMA_IRQ_PRIORITY, + (sama_dmaisr_t) crypto_lld_serve_write_interrupt, (void *) cryp); + osalDbgAssert(cryp->dmatx != NULL, "no channel allocated"); +#endif + } + +} + +void samaCryptoDriverStop(CRYDriver *cryp) { + samaCryptoDriverDisable(cryp); +} + + +/** + * write key into internal buffer + */ +cryerror_t samaCryptoDriverWriteTransientKey(const uint8_t *keyp,size_t size) +{ + uint8_t *p = (uint8_t *)key0_buffer; + + if (size <= HAL_CRY_MAX_KEY_SIZE) + { + samaClearKeyBuffer(); + + for (size_t i=0;ienabledPer & AES_PER)) { + cryp->enabledPer &= ~AES_PER; + pmcDisableAES(); + } + if ((cryp->enabledPer & TDES_PER)) { + cryp->enabledPer &= ~TDES_PER; + pmcDisableDES(); + } + if ((cryp->enabledPer & SHA_PER)) { + cryp->enabledPer &= ~SHA_PER; + pmcDisableSHA(); + } + if ((cryp->enabledPer & TRNG_PER)) { + cryp->enabledPer &= ~TRNG_PER; + pmcDisableTRNG(); + } +} + +#if defined(SAMA_DMA_REQUIRED) +/** + * @brief Shared end-of-rx service routine. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void crypto_lld_serve_read_interrupt(CRYDriver *cryp, uint32_t flags) { + + /* DMA errors handling.*/ + #if defined(SAMA_CRY_DMA_ERROR_HOOK) + if ((flags & (XDMAC_CIS_RBEIS | XDMAC_CIS_ROIS)) != 0) { + SAMA_CRY_DMA_ERROR_HOOK(cryp); + } +#else + (void)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.*/ + _cry_isr_code(cryp); +} + +/** + * @brief Shared end-of-tx service routine. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void crypto_lld_serve_write_interrupt(CRYDriver *cryp, uint32_t flags) { + + /* DMA errors handling.*/ + +#if defined(SAMA_CRY_DMA_ERROR_HOOK) + (void)cryp; + if ((flags & (XDMAC_CIS_WBEIS | XDMAC_CIS_ROIS)) != 0) { + SAMA_CRY_DMA_ERROR_HOOK(cryp); + } +#else + (void)cryp; + (void)flags; +#endif + + +} + +#endif diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h new file mode 100644 index 000000000..734fad25b --- /dev/null +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h @@ -0,0 +1,54 @@ +/* + ChibiOS - Copyright (C) 2006..2016 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 SAMA_CRYPTO_LLD_H_ +#define SAMA_CRYPTO_LLD_H_ + +extern void samaCryptoDriverInit(CRYDriver *cryp); +extern void samaCryptoDriverStart(CRYDriver *cryp); +extern void samaCryptoDriverStop(CRYDriver *cryp); +extern cryerror_t samaCryptoDriverWriteTransientKey(const uint8_t *keyp,size_t size); +extern void samaCryptoDriverDisable(CRYDriver *cryp); +extern void samaClearKeyBuffer(void); + +#define AES_PER 0x01 +#define TRNG_PER 0x02 +#define SHA_PER 0x04 +#define TDES_PER 0x08 + +#define DMA_DATA_WIDTH_BYTE 0 +#define DMA_DATA_WIDTH_HALF_WORD 1 +#define DMA_DATA_WIDTH_WORD 2 +#define DMA_DATA_WIDTH_DWORD 3 + +#define DMA_CHUNK_SIZE_1 0 +#define DMA_CHUNK_SIZE_2 1 +#define DMA_CHUNK_SIZE_4 2 +#define DMA_CHUNK_SIZE_8 3 +#define DMA_CHUNK_SIZE_16 4 + +#define DMA_DATA_WIDTH_TO_BYTE(w) (1 << w) + + + +extern uint32_t key0_buffer[HAL_CRY_MAX_KEY_SIZE/4]; + + + +#include "sama_aes_lld.h" +#include "sama_tdes_lld.h" + + +#endif //SAMA_CRYPTO_LLD_H_ diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c new file mode 100644 index 000000000..2e804cf8e --- /dev/null +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c @@ -0,0 +1,250 @@ +/* + ChibiOS - Copyright (C) 2006..2016 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 "sama_crypto_lld.h" +#include "sama_tdes_lld.h" + +enum tdesd_key_mode_t { + TDES_KEY_THREE = 0, TDES_KEY_TWO +}; + +void tdes_set_input(uint32_t* data0, uint32_t* data1) { + TDES->TDES_IDATAR[0] = *data0; + if (data1) + TDES->TDES_IDATAR[1] = *data1; +} + +void tdes_get_output(uint32_t *data0, uint32_t *data1) { + *data0 = TDES->TDES_ODATAR[0]; + if (data1) + *data1 = TDES->TDES_ODATAR[1]; +} + +cryerror_t sama_tdes_lld_polling(CRYDriver *cryp, tdes_config_t *params, + bool encrypt, const uint8_t *data, size_t data_len, uint8_t * out, + const uint8_t *iv) { + + uint32_t mode = 0; + uint32_t i; + uint8_t size = 8; + uint32_t *vectors = (uint32_t *) iv; + //soft reset + TDES->TDES_CR = TDES_CR_SWRST; + //configure + if (encrypt) + mode |= TDES_MR_CIPHER_ENCRYPT; + else + mode |= TDES_MR_CIPHER_DECRYPT; + + if (cryp->key0_size == 16) + mode |= (TDES_KEY_TWO << 4); + else + mode |= (TDES_KEY_THREE << 4); + + mode |= TDES_MR_TDESMOD(params->algo); + + mode |= TDES_MR_SMOD_MANUAL_START; + + mode |= TDES_MR_OPMOD(params->mode); + + if (cryp->config != NULL) { + mode |= TDES_MR_CFBS(cryp->config->cfbs); + + if (params->mode == TDES_MODE_CFB) { + if (cryp->config->cfbs == TDES_CFBS_32) + size = 4; + else if (cryp->config->cfbs == TDES_CFBS_16) + size = 2; + else if (cryp->config->cfbs == TDES_CFBS_8) + size = 1; + } + + } + + TDES->TDES_MR = mode; + + //write keys + /* Write the 64-bit key(s) in the different Key Word Registers, + * depending on whether one, two or three keys are required. */ + + TDES->TDES_KEY1WR[0] = key0_buffer[0]; + TDES->TDES_KEY1WR[1] = key0_buffer[1]; + + if (cryp->key0_size > 8) { + TDES->TDES_KEY2WR[0] = key0_buffer[2]; + TDES->TDES_KEY2WR[1] = key0_buffer[3]; + } else { + TDES->TDES_KEY2WR[0] = 0x0; + TDES->TDES_KEY2WR[1] = 0x0; + } + if (cryp->key0_size > 16) { + TDES->TDES_KEY3WR[0] = key0_buffer[4]; + TDES->TDES_KEY3WR[1] = key0_buffer[5]; + } else { + TDES->TDES_KEY3WR[0] = 0x0; + TDES->TDES_KEY3WR[1] = 0x0; + } + /* The Initialization Vector Registers apply to all modes except ECB. */ + if (params->mode != TDES_MODE_ECB && vectors != NULL) { + TDES->TDES_IVR[0] = vectors[0]; + TDES->TDES_IVR[1] = vectors[1]; + } + if (params->algo == TDES_ALGO_XTEA) { + TDES->TDES_XTEA_RNDR = TDES_XTEA_RNDR_XTEA_RNDS(32); + } + + /* Iterate per 64-bit data block */ + for (i = 0; i < data_len; i += size) { + if (size == 8) + tdes_set_input((uint32_t *) ((data) + i), + (uint32_t *) ((data) + i + 4)); + else + tdes_set_input((uint32_t *) ((data) + i), NULL); + + //Start TDES + TDES->TDES_CR = TDES_CR_START; + + //check status + while ((TDES->TDES_ISR & TDES_ISR_DATRDY) != TDES_ISR_DATRDY) + ; + + if (size == 8) + tdes_get_output((uint32_t *) ((out) + i), + (uint32_t *) ((out) + i + 4)); + else + tdes_get_output((uint32_t *) ((out) + i), NULL); + } + + return CRY_NOERROR; +} + +cryerror_t sama_tdes_lld_dma(CRYDriver *cryp, tdes_config_t *params, + bool encrypt, const uint8_t *data, size_t data_len, uint8_t * out, + const uint8_t *iv) { + + + uint32_t mode = 0; + uint32_t *vectors = (uint32_t *) iv; + + cryp->dmachunksize = DMA_CHUNK_SIZE_1; + cryp->dmawith = 4; + if ((params->mode == TDES_MODE_CFB)) { + if (cryp->config->cfbs == TDES_CFBS_16) + cryp->dmawith = DMA_DATA_WIDTH_HALF_WORD; + if (cryp->config->cfbs == TDES_CFBS_8) + cryp->dmawith = DMA_DATA_WIDTH_BYTE; + } + cryp->rxdmamode = + 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_TDES_RX); + + cryp->txdmamode = + 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_TDES_TX); + + dmaChannelSetMode(cryp->dmarx, cryp->rxdmamode); + dmaChannelSetMode(cryp->dmatx, cryp->txdmamode); + + /* Writing channel */ + dmaChannelSetSource(cryp->dmatx, data); + dmaChannelSetDestination(cryp->dmatx, TDES->TDES_IDATAR); + dmaChannelSetTransactionSize(cryp->dmatx, ( data_len / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith)) ); + + // ( data_len / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith)) + + /* Reading channel */ + dmaChannelSetSource(cryp->dmarx, TDES->TDES_ODATAR); + dmaChannelSetDestination(cryp->dmarx, out); + dmaChannelSetTransactionSize(cryp->dmarx, ( data_len / DMA_DATA_WIDTH_TO_BYTE(cryp->dmawith)) ); + + + //soft reset + TDES->TDES_CR = TDES_CR_SWRST; + //configure + if (encrypt) + mode |= TDES_MR_CIPHER_ENCRYPT; + else + mode |= TDES_MR_CIPHER_DECRYPT; + + if (cryp->key0_size == 16) + mode |= (TDES_KEY_TWO << 4); + else + mode |= (TDES_KEY_THREE << 4); + + mode |= TDES_MR_TDESMOD(params->algo); + + mode |= TDES_MR_SMOD(2); + + mode |= TDES_MR_OPMOD(params->mode); + + TDES->TDES_MR = mode; + + //write keys + /* Write the 64-bit key(s) in the different Key Word Registers, + * depending on whether one, two or three keys are required. */ + + TDES->TDES_KEY1WR[0] = key0_buffer[0]; + TDES->TDES_KEY1WR[1] = key0_buffer[1]; + + if (cryp->key0_size > 8) { + TDES->TDES_KEY2WR[0] = key0_buffer[2]; + TDES->TDES_KEY2WR[1] = key0_buffer[3]; + } else { + TDES->TDES_KEY2WR[0] = 0x0; + TDES->TDES_KEY2WR[1] = 0x0; + } + if (cryp->key0_size > 16) { + TDES->TDES_KEY3WR[0] = key0_buffer[4]; + TDES->TDES_KEY3WR[1] = key0_buffer[5]; + } else { + TDES->TDES_KEY3WR[0] = 0x0; + TDES->TDES_KEY3WR[1] = 0x0; + } + /* The Initialization Vector Registers apply to all modes except ECB. */ + if (params->mode != TDES_MODE_ECB && vectors != NULL) { + TDES->TDES_IVR[0] = vectors[0]; + TDES->TDES_IVR[1] = vectors[1]; + } + if (params->algo == TDES_ALGO_XTEA) { + TDES->TDES_XTEA_RNDR = TDES_XTEA_RNDR_XTEA_RNDS(32); + } + + + osalSysLock(); + + dmaChannelEnable(cryp->dmarx); + dmaChannelEnable(cryp->dmatx); + + + osalThreadSuspendS(&cryp->thread); + osalSysUnlock(); + + + return CRY_NOERROR; +} + diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.h new file mode 100644 index 000000000..bc48f02b1 --- /dev/null +++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.h @@ -0,0 +1,61 @@ +/* + ChibiOS - Copyright (C) 2006..2016 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_TDES_H_ +#define CRYPTOLIB_LLD_TDES_H_ + + + +typedef enum { + TDES_MODE_ECB = 0, + TDES_MODE_CBC, + TDES_MODE_OFB, + TDES_MODE_CFB +}tdes_mode_t; + + + +typedef enum { + TDES_CFBS_64 = 0, + TDES_CFBS_32, + TDES_CFBS_16, + TDES_CFBS_8 +}tdes_cipher_size_t; + +typedef struct { + tdes_algo_t algo; + tdes_mode_t mode; +}tdes_config_t; + + +extern void sama_tdes_lld_init(CRYDriver *cryp); + +extern cryerror_t sama_tdes_lld_polling(CRYDriver *cryp, + tdes_config_t *params, + bool encrypt, + const uint8_t *data, + size_t data_len, + uint8_t *out, + const uint8_t *iv); +extern cryerror_t sama_tdes_lld_dma(CRYDriver *cryp, + tdes_config_t *params, + bool encrypt, + const uint8_t *data, + size_t data_len, + uint8_t *out, + const uint8_t *iv); + + +#endif /* CRYPTOLIB_LLD_TDES_H_ */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c b/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c new file mode 100644 index 000000000..7665f9204 --- /dev/null +++ b/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c @@ -0,0 +1,1089 @@ +/* + ChibiOS - Copyright (C) 2006..2016 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. + */ + +/** + * @file hal_crypto_lld.c + * @brief PLATFORM cryptographic subsystem low level driver source. + * + * @addtogroup CRYPTO + * @{ + */ +#include +#include "hal.h" + +#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__) + +#include "sama_crypto_lld.h" +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + + +/** @brief CRY1 driver identifier.*/ +#if PLATFORM_CRY_USE_CRY1 || defined(__DOXYGEN__) +CRYDriver CRYD1; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level crypto driver initialization. + * + * @notapi + */ +void cry_lld_init(void) { +#if PLATFORM_CRY_USE_CRY1 == TRUE + cryObjectInit(&CRYD1); + samaCryptoDriverInit(&CRYD1); +#endif +} + +/** + * @brief Configures and activates the crypto peripheral. + * + * @param[in] cryp pointer to the @p CRYDriver object + * + * @notapi + */ +void cry_lld_start(CRYDriver *cryp) { + + if (cryp->state == CRY_STOP) { +#if PLATFORM_CRY_USE_CRY1 + if (&CRYD1 == cryp) { + samaCryptoDriverStart(&CRYD1); + } +#endif /* PLATFORM_CRY_USE_CRY1 */ + } +} + +/** + * @brief Deactivates the crypto peripheral. + * + * @param[in] cryp pointer to the @p CRYDriver object + * + * @notapi + */ +void cry_lld_stop(CRYDriver *cryp) { + + if (cryp->state == CRY_READY) { +#if PLATFORM_CRY_USE_CRY1 + if (&CRYD1 == cryp) { + samaCryptoDriverStop(&CRYD1); + } +#endif /* PLATFORM_CRY_USE_CRY1 */ + + } +} + +/** + * @brief Initializes the transient key for a specific algorithm. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] keyp pointer to the key data + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the specified algorithm is unknown or + * unsupported. + * @retval CRY_ERR_INV_KEY_SIZE if the specified key size is invalid. + * + * @notapi + */ +cryerror_t cry_lld_loadkey(CRYDriver *cryp, cryalgorithm_t algorithm, + size_t size, const uint8_t *keyp) { + + (void)(cryp); + (void)(algorithm); + return samaCryptoDriverWriteTransientKey(keyp, size); + +} + +/** + * @brief Encryption of a single block using AES. + * @note The implementation of this function must guarantee that it can + * be called from any context. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] in buffer containing the input plaintext + * @param[out] out buffer for the output cyphertext + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_encrypt_AES(CRYDriver *cryp, crykey_t key_id, + const uint8_t *in, uint8_t *out) { + + cryerror_t ret = CRY_NOERROR; + aesparams params; + + if(key_id != 0 ) + return CRY_ERR_INV_KEY_ID; + + if (!(cryp->enabledPer & AES_PER)) { + cryp->enabledPer |= AES_PER; + pmcEnableAES(); + } + + params.encrypt = 1; + params.block_size = 16; + params.mode = 0; + params.iv = NULL; + + + ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, 16); + + + return ret; +} + +/** + * @brief Decryption of a single block using AES. + * @note The implementation of this function must guarantee that it can + * be called from any context. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] in buffer containing the input cyphertext + * @param[out] out buffer for the output plaintext + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_decrypt_AES(CRYDriver *cryp, crykey_t key_id, + const uint8_t *in, uint8_t *out) { + + cryerror_t ret = CRY_NOERROR; + aesparams params; + + if(key_id != 0 ) + return CRY_ERR_INV_KEY_ID; + + if (!(cryp->enabledPer & AES_PER)) { + cryp->enabledPer |= AES_PER; + pmcEnableAES(); + } + + params.encrypt = 0; + params.block_size = 16; + params.mode = 0; + params.iv = NULL; + + + ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, 16); + + + return ret; +} + +/** + * @brief Encryption operation using AES-ECB. + * @note The function operates on data buffers whose lenght is a multiple + * of an AES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the plaintext buffer, this number must be a + * multiple of the selected key size + * @param[in] in buffer containing the input plaintext + * @param[out] out buffer for the output cyphertext + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_encrypt_AES_ECB(CRYDriver *cryp, crykey_t key_id, + size_t size, const uint8_t *in, uint8_t *out) { + + cryerror_t ret = CRY_NOERROR; + aesparams params; + + if(key_id != 0 ) + return CRY_ERR_INV_KEY_ID; + + if (!(cryp->enabledPer & AES_PER)) { + cryp->enabledPer |= AES_PER; + pmcEnableAES(); + } + + params.encrypt = 1; + params.block_size = 16; + params.mode = AES_MR_OPMOD_ECB; + params.iv = NULL; + + + if (cryp->config->transfer_mode == TRANSFER_POLLING) + ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); + else + ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); + + + return ret; +} + +/** + * @brief Decryption operation using AES-ECB. + * @note The function operates on data buffers whose lenght is a multiple + * of an AES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the plaintext buffer, this number must be a + * multiple of the selected key size + * @param[in] in buffer containing the input plaintext + * @param[out] out buffer for the output cyphertext + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_decrypt_AES_ECB(CRYDriver *cryp, crykey_t key_id, + size_t size, const uint8_t *in, uint8_t *out) { + + cryerror_t ret = CRY_NOERROR; + aesparams params; + if(key_id != 0 ) + return CRY_ERR_INV_KEY_ID; + + if (!(cryp->enabledPer & AES_PER)) { + cryp->enabledPer |= AES_PER; + pmcEnableAES(); + } + + params.encrypt = 0; + params.block_size = 16; + params.mode = AES_MR_OPMOD_ECB; + + + + if (cryp->config->transfer_mode == TRANSFER_POLLING) + ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); + else + ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); + + + + return ret; +} + +/** + * @brief Encryption operation using AES-CBC. + * @note The function operates on data buffers whose lenght is a multiple + * of an AES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the plaintext buffer, this number must be a + * multiple of the selected key size + * @param[in] in buffer containing the input plaintext + * @param[out] out buffer for the output cyphertext + * @param[in] iv 128 bits initial vector + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_encrypt_AES_CBC(CRYDriver *cryp, crykey_t key_id, + size_t size, const uint8_t *in, uint8_t *out, const uint8_t *iv) { + + cryerror_t ret = CRY_NOERROR; + aesparams params; + if(key_id != 0 ) + return CRY_ERR_INV_KEY_ID; + + if (!(cryp->enabledPer & AES_PER)) { + cryp->enabledPer |= AES_PER; + pmcEnableAES() + ; + } + params.encrypt = 1; + params.block_size = 16; + params.mode = AES_MR_OPMOD_CBC; + params.iv = iv; + + if (cryp->config->transfer_mode == TRANSFER_POLLING) + ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); + else + ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); + + + + return ret; +} + +/** + * @brief Decryption operation using AES-CBC. + * @note The function operates on data buffers whose lenght is a multiple + * of an AES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the plaintext buffer, this number must be a + * multiple of the selected key size + * @param[in] in buffer containing the input plaintext + * @param[out] out buffer for the output cyphertext + * @param[in] iv 128 bits initial vector + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_decrypt_AES_CBC(CRYDriver *cryp, crykey_t key_id, + size_t size, const uint8_t *in, uint8_t *out, const uint8_t *iv) { + + cryerror_t ret = CRY_NOERROR; + aesparams params; + if(key_id != 0 ) + return CRY_ERR_INV_KEY_ID; + + if (!(cryp->enabledPer & AES_PER)) { + cryp->enabledPer |= AES_PER; + pmcEnableAES() + ; + } + + params.encrypt = 0; + params.block_size = 16; + params.mode = AES_MR_OPMOD_CBC; + params.iv = iv; + if (cryp->config->transfer_mode == TRANSFER_POLLING) + ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); + else + ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); + + + + return ret; +} + +/** + * @brief Encryption operation using AES-CFB. + * @note The function operates on data buffers whose lenght is a multiple + * of an AES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the plaintext buffer, this number must be a + * multiple of the selected key size + * @param[in] in buffer containing the input plaintext + * @param[out] out buffer for the output cyphertext + * @param[in] iv 128 bits initial vector + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_encrypt_AES_CFB(CRYDriver *cryp, crykey_t key_id, + size_t size, const uint8_t *in, uint8_t *out, const uint8_t *iv) { + + cryerror_t ret = CRY_NOERROR; + aesparams params; + if(key_id != 0 ) + return CRY_ERR_INV_KEY_ID; + + if (!(cryp->enabledPer & AES_PER)) { + cryp->enabledPer |= AES_PER; + pmcEnableAES() + ; + } + params.encrypt = 1; + params.block_size = 16; + switch (cryp->config->cfbs) { + case AES_CFBS_128: + params.block_size = 16; + break; + case AES_CFBS_64: + params.block_size = 8; + break; + case AES_CFBS_32: + params.block_size = 4; + break; + case AES_CFBS_16: + params.block_size = 2; + break; + case AES_CFBS_8: + params.block_size = 1; + break; + } + params.mode = AES_MR_OPMOD_CFB; + params.iv = iv; + + if (cryp->config->transfer_mode == TRANSFER_POLLING) + ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); + else + ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); + + + return ret; +} + +/** + * @brief Decryption operation using AES-CFB. + * @note The function operates on data buffers whose lenght is a multiple + * of an AES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the plaintext buffer, this number must be a + * multiple of the selected key size + * @param[in] in buffer containing the input plaintext + * @param[out] out buffer for the output cyphertext + * @param[in] iv 128 bits initial vector + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_decrypt_AES_CFB(CRYDriver *cryp, crykey_t key_id, + size_t size, const uint8_t *in, uint8_t *out, const uint8_t *iv) { + + cryerror_t ret = CRY_NOERROR; + aesparams params; + if(key_id != 0 ) + return CRY_ERR_INV_KEY_ID; + + if (!(cryp->enabledPer & AES_PER)) { + cryp->enabledPer |= AES_PER; + pmcEnableAES() + ; + } + + params.encrypt = 0; + params.block_size = 16; + switch (cryp->config->cfbs) { + case AES_CFBS_128: + params.block_size = 16; + break; + case AES_CFBS_64: + params.block_size = 8; + break; + case AES_CFBS_32: + params.block_size = 4; + break; + case AES_CFBS_16: + params.block_size = 2; + break; + case AES_CFBS_8: + params.block_size = 1; + break; + } + params.mode = AES_MR_OPMOD_CFB; + params.iv = iv; + + if (cryp->config->transfer_mode == TRANSFER_POLLING) + ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); + else + ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); + + + + return ret; +} + +/** + * @brief Encryption operation using AES-CTR. + * @note The function operates on data buffers whose lenght is a multiple + * of an AES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the plaintext buffer, this number must be a + * multiple of 16 + * @param[in] in buffer containing the input plaintext + * @param[out] out buffer for the output cyphertext + * @param[in] iv 128 bits initial vector + counter, it contains + * a 96 bits IV and a 32 bits counter + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_encrypt_AES_CTR(CRYDriver *cryp, crykey_t key_id, + size_t size, const uint8_t *in, uint8_t *out, const uint8_t *iv) { + + cryerror_t ret = CRY_NOERROR; + aesparams params; + if(key_id != 0 ) + return CRY_ERR_INV_KEY_ID; + + if (!(cryp->enabledPer & AES_PER)) { + cryp->enabledPer |= AES_PER; + pmcEnableAES() + ; + } + + params.encrypt = 1; + params.block_size = 16; + params.mode = AES_MR_OPMOD_CTR; + params.iv = iv; + if (cryp->config->transfer_mode == TRANSFER_POLLING) + ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); + else + ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); + + + + return ret; +} + +/** + * @brief Decryption operation using AES-CTR. + * @note The function operates on data buffers whose lenght is a multiple + * of an AES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the plaintext buffer, this number must be a + * multiple of 16 + * @param[in] in buffer containing the input cyphertext + * @param[out] out buffer for the output plaintext + * @param[in] iv 128 bits initial vector + counter, it contains + * a 96 bits IV and a 32 bits counter + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_decrypt_AES_CTR(CRYDriver *cryp, crykey_t key_id, + size_t size, const uint8_t *in, uint8_t *out, const uint8_t *iv) { + + cryerror_t ret = CRY_NOERROR; + aesparams params; + if (key_id != 0) + return CRY_ERR_INV_KEY_ID; + + if (!(cryp->enabledPer & AES_PER)) { + cryp->enabledPer |= AES_PER; + pmcEnableAES() + ; + } + + params.encrypt = 0; + params.block_size = 16; + params.mode = AES_MR_OPMOD_CTR; + params.iv = iv; + if (cryp->config->transfer_mode == TRANSFER_POLLING) + ret = sama_aes_lld_process_polling(cryp, ¶ms, in, out, size); + else + ret = sama_aes_lld_process_dma(cryp, ¶ms, in, out, size); + + return ret; +} + +/** + * @brief Encryption operation using AES-GCM. + * @note The function operates on data buffers whose lenght is a multiple + * of an AES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the text buffers, this number must be a + * multiple of 16 + * @param[in] in buffer containing the input plaintext + * @param[out] out buffer for the output cyphertext + * @param[in] iv 128 bits initial vector + counter, it contains + * a 96 bits IV and a 32 bits counter + * @param[in] aadsize size of the authentication data, this number must be a + * multiple of 16 + * @param[in] aad buffer containing the authentication data + * @param[in] authtag 128 bits buffer for the generated authentication tag + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_encrypt_AES_GCM(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out, + const uint8_t *iv, + size_t aadsize, + const uint8_t *aad, + uint8_t *authtag) { + + (void)cryp; + (void)key_id; + (void)size; + (void)in; + (void)out; + (void)iv; + (void)aadsize; + (void)aad; + (void)authtag; + + return CRY_ERR_INV_ALGO; +} + +/** + * @brief Decryption operation using AES-GCM. + * @note The function operates on data buffers whose lenght is a multiple + * of an AES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the text buffers, this number must be a + * multiple of 16 + * @param[in] in buffer for the output cyphertext + * @param[out] out buffer containing the input plaintext + * @param[in] iv 128 bits initial vector + counter, it contains + * a 96 bits IV and a 32 bits counter + * @param[in] aadsize size of the authentication data, this number must be a + * multiple of 16 + * @param[in] aad buffer containing the authentication data + * @param[in] authtag 128 bits buffer for the generated authentication tag + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_decrypt_AES_GCM(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out, + const uint8_t *iv, + size_t aadsize, + const uint8_t *aad, + uint8_t *authtag) { + + (void)cryp; + (void)key_id; + (void)size; + (void)in; + (void)out; + (void)iv; + (void)aadsize; + (void)aad; + (void)authtag; + + return CRY_ERR_INV_ALGO; +} + + +/** + * @brief Encryption of a single block using (T)DES. + * @note The implementation of this function must guarantee that it can + * be called from any context. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] in buffer containing the input plaintext + * @param[out] out buffer for the output cyphertext + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_encrypt_DES(CRYDriver *cryp, crykey_t key_id, + const uint8_t *in, uint8_t *out) { + + cryerror_t ret = CRY_NOERROR; + + if(key_id != 0 ) + return CRY_ERR_INV_KEY_ID; + + if ( ( cryp->config->tdes_algo == TDES_ALGO_SINGLE && cryp->key0_size != 8 ) || + ( cryp->config->tdes_algo == TDES_ALGO_TRIPLE && cryp->key0_size != 24 ) ) + return CRY_ERR_INV_KEY_SIZE; + + tdes_config_t params = { cryp->config->tdes_algo, + 0 + }; + + if (!(cryp->enabledPer & TDES_PER)) { + cryp->enabledPer |= TDES_PER; + pmcEnableDES(); + } + + ret = sama_tdes_lld_polling(cryp,¶ms, true, in, + 8, out,NULL); + + return ret; +} + +/** + * @brief Decryption of a single block using (T)DES. + * @note The implementation of this function must guarantee that it can + * be called from any context. + * + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] in buffer containing the input cyphertext + * @param[out] out buffer for the output plaintext + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_decrypt_DES(CRYDriver *cryp, crykey_t key_id, + const uint8_t *in, uint8_t *out) { + + cryerror_t ret = CRY_NOERROR; + tdes_config_t params = { cryp->config->tdes_algo, + 0 + }; + if(key_id != 0 ) + return CRY_ERR_INV_KEY_ID; + if (!(cryp->enabledPer & TDES_PER)) { + cryp->enabledPer |= TDES_PER; + pmcEnableDES(); + } + + ret = sama_tdes_lld_polling(cryp,¶ms, false, in, + 8, out,NULL); + + + return ret; +} + +/** + * @brief Encryption operation using (T)DES-ECB. + * @note The function operates on data buffers whose length is a multiple + * of an DES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the plaintext buffer, this number must be a + * multiple of 8 + * @param[in] in buffer containing the input plaintext + * @param[out] out buffer for the output cyphertext + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_encrypt_DES_ECB(CRYDriver *cryp, crykey_t key_id, + size_t size, const uint8_t *in, uint8_t *out) { + + cryerror_t ret = CRY_NOERROR; + tdes_config_t params = { cryp->config->tdes_algo, TDES_MODE_ECB }; + if (key_id != 0) + return CRY_ERR_INV_KEY_ID; + + if (cryp->key0_size != 16 && cryp->key0_size != 24) { + return CRY_ERR_INV_KEY_SIZE; + } + + if (!(cryp->enabledPer & TDES_PER)) { + cryp->enabledPer |= TDES_PER; + pmcEnableDES() + ; + } + if (cryp->config->transfer_mode == TRANSFER_POLLING) + ret = sama_tdes_lld_polling(cryp, ¶ms, true, in, size, out, NULL); + else + ret = sama_tdes_lld_dma(cryp, ¶ms, true, in, size, out, NULL); + + return ret; +} + +/** + * @brief Decryption operation using (T)DES-ECB. + * @note The function operates on data buffers whose length is a multiple + * of an DES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the plaintext buffer, this number must be a + * multiple of 8 + * @param[in] in buffer containing the input cyphertext + * @param[out] out buffer for the output plaintext + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_decrypt_DES_ECB(CRYDriver *cryp, crykey_t key_id, + size_t size, const uint8_t *in, uint8_t *out) { + + cryerror_t ret = CRY_NOERROR; + tdes_config_t params = { cryp->config->tdes_algo, TDES_MODE_ECB }; + if (key_id != 0) + return CRY_ERR_INV_KEY_ID; + + if (cryp->key0_size != 16 && cryp->key0_size != 24) { + return CRY_ERR_INV_KEY_SIZE; + } + if (!(cryp->enabledPer & TDES_PER)) { + cryp->enabledPer |= TDES_PER; + pmcEnableDES() + ; + } + + if (cryp->config->transfer_mode == TRANSFER_POLLING) + ret = sama_tdes_lld_polling(cryp, ¶ms, false, in, size, out, NULL); + else + ret = sama_tdes_lld_dma(cryp, ¶ms, false, in, size, out, NULL); + + return ret; +} + +/** + * @brief Encryption operation using (T)DES-CBC. + * @note The function operates on data buffers whose length is a multiple + * of an DES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the plaintext buffer, this number must be a + * multiple of 8 + * @param[in] in buffer containing the input plaintext + * @param[out] out buffer for the output cyphertext + * @param[in] iv 64 bits input vector + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_encrypt_DES_CBC(CRYDriver *cryp, crykey_t key_id, + size_t size, const uint8_t *in, uint8_t *out, const uint8_t *iv) { + + + cryerror_t ret = CRY_NOERROR; + tdes_config_t params = { cryp->config->tdes_algo, TDES_MODE_CBC }; + if (key_id != 0) + return CRY_ERR_INV_KEY_ID; + + if (cryp->key0_size != 16 && cryp->key0_size != 24) { + return CRY_ERR_INV_KEY_SIZE; + } + + if (!(cryp->enabledPer & TDES_PER)) { + cryp->enabledPer |= TDES_PER; + pmcEnableDES() + ; + } + + if (cryp->config->transfer_mode == TRANSFER_POLLING) + ret = sama_tdes_lld_polling(cryp, ¶ms, true, in, size, out, iv); + else + ret = sama_tdes_lld_dma(cryp, ¶ms, true, in, size, out, iv); + return ret; +} + +/** + * @brief Decryption operation using (T)DES-CBC. + * @note The function operates on data buffers whose length is a multiple + * of an DES block, this means that padding must be done by the + * caller. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] key_id the key to be used for the operation, zero is the + * transient key, other values are keys stored in an + * unspecified way + * @param[in] size size of the plaintext buffer, this number must be a + * multiple of 8 + * @param[in] in buffer containing the input cyphertext + * @param[out] out buffer for the output plaintext + * @param[in] iv 64 bits input vector + * @return The operation status. + * @retval CRY_NOERROR if the operation succeeded. + * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this + * device instance. + * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation. + * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid + * or refers to an empty key slot. + * + * @notapi + */ +cryerror_t cry_lld_decrypt_DES_CBC(CRYDriver *cryp, crykey_t key_id, + size_t size, const uint8_t *in, uint8_t *out, const uint8_t *iv) { + + cryerror_t ret = CRY_NOERROR; + tdes_config_t params = { cryp->config->tdes_algo, TDES_MODE_CBC }; + if (key_id != 0) + return CRY_ERR_INV_KEY_ID; + + if (cryp->key0_size != 16 && cryp->key0_size != 24) { + return CRY_ERR_INV_KEY_SIZE; + } + + if (!(cryp->enabledPer & TDES_PER)) { + cryp->enabledPer |= TDES_PER; + pmcEnableDES() + ; + } + + if (cryp->config->transfer_mode == TRANSFER_POLLING) + ret = sama_tdes_lld_polling(cryp, ¶ms, false, in, size, out, iv); + else + ret = sama_tdes_lld_dma(cryp, ¶ms, false, in, size, out, iv); + + return ret; +} + + + +#endif /* HAL_USE_CRY == TRUE */ + +/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h b/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h new file mode 100644 index 000000000..135ac600c --- /dev/null +++ b/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h @@ -0,0 +1,299 @@ +/* + ChibiOS - Copyright (C) 2006..2016 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. +*/ + +/** + * @file hal_cry_lld.h + * @brief PLATFORM cryptographic subsystem low level driver header. + * + * @addtogroup CRYPTO + * @{ + */ + +#ifndef HAL_CRYPTO_LLD_H +#define HAL_CRYPTO_LLD_H + +#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Driver capability switches + * @{ + */ +#define CRY_LLD_SUPPORTS_AES TRUE +#define CRY_LLD_SUPPORTS_AES_ECB TRUE +#define CRY_LLD_SUPPORTS_AES_CBC TRUE +#define CRY_LLD_SUPPORTS_AES_CFB TRUE +#define CRY_LLD_SUPPORTS_AES_CTR TRUE +#define CRY_LLD_SUPPORTS_AES_GCM TRUE +#define CRY_LLD_SUPPORTS_DES TRUE +#define CRY_LLD_SUPPORTS_DES_ECB TRUE +#define CRY_LLD_SUPPORTS_DES_CBC TRUE +/** @{ */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name PLATFORM configuration options + * @{ + */ +/** + * @brief CRY1 driver enable switch. + * @details If set to @p TRUE the support for CRY1 is included. + * @note The default is @p FALSE. + */ +#if !defined(PLATFORM_CRY_USE_CRY1) || defined(__DOXYGEN__) +#define PLATFORM_CRY_USE_CRY1 FALSE +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +typedef struct +{ + uint32_t encrypt; + uint32_t block_size; + uint32_t mode; + const uint8_t *iv; +}aesparams; + +typedef enum { + TRANSFER_DMA = 0, + TRANSFER_POLLING, +}crytransfermode_t; + +typedef enum { + AES_CFBS_128 = 0, + AES_CFBS_64, + AES_CFBS_32, + AES_CFBS_16, + AES_CFBS_8 +}aesciphersize_t; + + +/** + * @brief CRY key identifier type. + */ +typedef uint32_t crykey_t; + +/** + * @brief Type of a structure representing an CRY driver. + */ +typedef struct CRYDriver CRYDriver; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ + + +typedef enum { + TDES_ALGO_SINGLE = 0, + TDES_ALGO_TRIPLE, + TDES_ALGO_XTEA +}tdes_algo_t; + +typedef struct { + + crytransfermode_t transfer_mode; + uint32_t cfbs; + tdes_algo_t tdes_algo; + +} CRYConfig; + +#define CRY_DRIVER_EXT_FIELDS thread_reference_t thread; \ + sama_dma_channel_t *dmarx; \ + sama_dma_channel_t *dmatx; \ + uint32_t rxdmamode; \ + uint32_t txdmamode; \ + uint8_t dmawith; \ + uint8_t dmachunksize; \ + uint8_t enabledPer; +/** + * @brief Structure representing an CRY driver. + */ +struct CRYDriver { + /** + * @brief Driver state. + */ + crystate_t state; + /** + * @brief Current configuration data. + */ + const CRYConfig *config; + /** + * @brief Algorithm type of transient key. + */ + cryalgorithm_t key0_type; + /** + * @brief Size of transient key. + */ + size_t key0_size; +#if (HAL_CRY_USE_FALLBACK == TRUE) || defined(__DOXYGEN__) + /** + * @brief Key buffer for the fall-back implementation. + */ + uint8_t key0_buffer[HAL_CRY_MAX_KEY_SIZE]; +#endif +#if defined(CRY_DRIVER_EXT_FIELDS) + CRY_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if (PLATFORM_CRY_USE_CRY1 == TRUE) && !defined(__DOXYGEN__) +extern CRYDriver CRYD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void cry_lld_init(void); + void cry_lld_start(CRYDriver *cryp); + void cry_lld_stop(CRYDriver *cryp); + cryerror_t cry_lld_loadkey(CRYDriver *cryp, + cryalgorithm_t algorithm, + size_t size, + const uint8_t *keyp); + cryerror_t cry_lld_encrypt_AES(CRYDriver *cryp, + crykey_t key_id, + const uint8_t *in, + uint8_t *out); + cryerror_t cry_lld_decrypt_AES(CRYDriver *cryp, + crykey_t key_id, + const uint8_t *in, + uint8_t *out); + cryerror_t cry_lld_encrypt_AES_ECB(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out); + cryerror_t cry_lld_decrypt_AES_ECB(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out); + cryerror_t cry_lld_encrypt_AES_CBC(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out, + const uint8_t *iv); + cryerror_t cry_lld_decrypt_AES_CBC(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out, + const uint8_t *iv); + cryerror_t cry_lld_encrypt_AES_CFB(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out, + const uint8_t *iv); + cryerror_t cry_lld_decrypt_AES_CFB(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out, + const uint8_t *iv); + cryerror_t cry_lld_encrypt_AES_CTR(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out, + const uint8_t *iv); + cryerror_t cry_lld_decrypt_AES_CTR(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out, + const uint8_t *iv); + cryerror_t cry_lld_encrypt_AES_GCM(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out, + const uint8_t *iv, + size_t aadsize, + const uint8_t *aad, + uint8_t *authtag); + cryerror_t cry_lld_decrypt_AES_GCM(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out, + const uint8_t *iv, + size_t aadsize, + const uint8_t *aad, + uint8_t *authtag); + cryerror_t cry_lld_encrypt_DES(CRYDriver *cryp, + crykey_t key_id, + const uint8_t *in, + uint8_t *out); + cryerror_t cry_lld_decrypt_DES(CRYDriver *cryp, + crykey_t key_id, + const uint8_t *in, + uint8_t *out); + cryerror_t cry_lld_encrypt_DES_ECB(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out); + cryerror_t cry_lld_decrypt_DES_ECB(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out); + cryerror_t cry_lld_encrypt_DES_CBC(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out, + const uint8_t *iv); + cryerror_t cry_lld_decrypt_DES_CBC(CRYDriver *cryp, + crykey_t key_id, + size_t size, + const uint8_t *in, + uint8_t *out, + const uint8_t *iv); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_CRY == TRUE */ + +#endif /* HAL_CRYPTO_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/SAMA/SAMA5D2x/platform.mk b/os/hal/ports/SAMA/SAMA5D2x/platform.mk index 59fda14fc..6f826f1cf 100644 --- a/os/hal/ports/SAMA/SAMA5D2x/platform.mk +++ b/os/hal/ports/SAMA/SAMA5D2x/platform.mk @@ -5,7 +5,8 @@ PLATFORMSRC := $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/hal_lld.c \ $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/aic.c \ $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/sama_matrix.c \ $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/sama_cache.c \ - $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/hal_tc_lld.c + $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/hal_tc_lld.c \ + $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.c # Required include directories. PLATFORMINC := $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x @@ -29,3 +30,4 @@ include $(CHIBIOS)/os/hal/ports/SAMA/LLD/PIOv1/driver.mk include $(CHIBIOS)/os/hal/ports/SAMA/LLD/SPIv1/driver.mk include $(CHIBIOS)/os/hal/ports/SAMA/LLD/RTCv1/driver.mk include $(CHIBIOS)/os/hal/ports/SAMA/LLD/USARTv1/driver.mk +include $(CHIBIOS)/os/hal/ports/SAMA/LLD/Cryptov1/driver.mk diff --git a/os/hal/ports/SAMA/SAMA5D2x/sama_pmc.h b/os/hal/ports/SAMA/SAMA5D2x/sama_pmc.h index 8c010a6d8..39354054e 100644 --- a/os/hal/ports/SAMA/SAMA5D2x/sama_pmc.h +++ b/os/hal/ports/SAMA/SAMA5D2x/sama_pmc.h @@ -408,8 +408,68 @@ */ #define pmcDisableTC1() pmcDisablePidHigh(ID_TC1_MSK) + +/** + * @brief Enables the AES peripheral clock. + * + * @api + */ +#define pmcEnableAES() pmcEnablePidLow(ID_AES_MSK) + +/** + * @brief Disables the AES peripheral clock. + * + * @api + */ +#define pmcDisableAES() pmcDisablePidLow(ID_AES_MSK) + +/** + * @brief Enables the TRNG peripheral clock. + * + * @api + */ +#define pmcEnableTRNG() pmcEnablePidHigh(ID_TRNG_MSK) +/** + * @brief Disables the TRNG peripheral clock. + * + * @api + */ +#define pmcDisableTRNG() pmcDisablePidHigh(ID_TRNG_MSK) + +/** + * @brief Enables the DES peripheral clock. + * + * @api + */ +#define pmcEnableDES() pmcEnablePidLow(ID_TDES_MSK) +/** + * @brief Disables the DES peripheral clock. + * + * @api + */ +#define pmcDisableDES() pmcDisablePidLow(ID_TDES_MSK) + +/** + * @brief Enables the SHA peripheral clock. + * + * @api + */ +#define pmcEnableSHA() pmcEnablePidLow(ID_SHA_MSK) +/** + * @brief Disables the SHA peripheral clock. + * + * @api + */ +#define pmcDisableSHA() pmcDisablePidLow(ID_SHA_MSK) + + /** @} */ + + + + + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/