added crypto aes and des polling mode

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10983 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
areviu 2017-11-11 20:07:22 +00:00
parent 7c499f0433
commit b487618ca5
11 changed files with 2282 additions and 1 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;i<size;i++)
{
p[i] = keyp[i];
}
}
else
{
return CRY_ERR_INV_KEY_SIZE;
}
return CRY_NOERROR;
}
void samaClearKeyBuffer(void)
{
for (size_t i=0;i<KEY0_BUFFER_SIZE_W;i++)
{
key0_buffer[i] = 0;
}
}
void samaCryptoDriverDisable(CRYDriver *cryp)
{
if ((cryp->enabledPer & 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

View File

@ -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_

View File

@ -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;
}

View File

@ -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_ */

File diff suppressed because it is too large Load Diff

View File

@ -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 */
/** @} */

View File

@ -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/aic.c \
$(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x/sama_matrix.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/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. # Required include directories.
PLATFORMINC := $(CHIBIOS)/os/hal/ports/SAMA/SAMA5D2x 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/SPIv1/driver.mk
include $(CHIBIOS)/os/hal/ports/SAMA/LLD/RTCv1/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/USARTv1/driver.mk
include $(CHIBIOS)/os/hal/ports/SAMA/LLD/Cryptov1/driver.mk

View File

@ -408,8 +408,68 @@
*/ */
#define pmcDisableTC1() pmcDisablePidHigh(ID_TC1_MSK) #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. */ /* External declarations. */
/*===========================================================================*/ /*===========================================================================*/