[NUC472/M487] Fix DMA input/output buffers are overlapped in AES alter.

pull/4925/head
ccli8 2017-12-25 10:54:56 +08:00
parent 4023078e14
commit 67386b9ebd
8 changed files with 90 additions and 0 deletions

View File

@ -160,6 +160,7 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
AES_Open(0, ctx->encDec, ctx->opMode, ctx->keySize, AES_IN_OUT_SWAP);
AES_SetInitVect(0, ctx->iv);
AES_SetKey(0, ctx->keys, ctx->keySize);
/* AES DMA buffer requirements same as above */
if (! crypto_dma_buff_compat(input, dataSize, 16)) {
memcpy(au8InputData, input, dataSize);
@ -174,6 +175,14 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
pOut = output;
}
/* Even though AES H/W has limited support for overlapped DMA input/output buffers,
* we still seek to one backup buffer to make them non-overlapped for simplicity. */
if (crypto_dma_buffs_overlap(pIn, dataSize, pOut, dataSize)) {
memcpy(au8InputData, input, dataSize);
pIn = au8InputData;
}
MBED_ASSERT(! crypto_dma_buffs_overlap(pIn, dataSize, pOut, dataSize));
AES_SetDMATransfer(0, (uint32_t)pIn, (uint32_t)pOut, dataSize);
crypto_aes_prestart();

View File

@ -407,6 +407,7 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
memcpy(dmabuf_in, in_pos, data_len);
/* We always use DMA backup buffers, which are guaranteed to be non-overlapped. */
TDES_SetDMATransfer(0, (uint32_t) dmabuf_in, (uint32_t) dmabuf_out, data_len);
crypto_des_prestart();

View File

@ -160,6 +160,7 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
AES_Open(0, ctx->encDec, ctx->opMode, ctx->keySize, AES_IN_OUT_SWAP);
AES_SetInitVect(0, ctx->iv);
AES_SetKey(0, ctx->keys, ctx->keySize);
/* AES DMA buffer requirements same as above */
if (! crypto_dma_buff_compat(input, dataSize, 16)) {
memcpy(au8InputData, input, dataSize);
@ -174,6 +175,14 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
pOut = output;
}
/* Even though AES H/W has limited support for overlapped DMA input/output buffers,
* we still seek to one backup buffer to make them non-overlapped for simplicity. */
if (crypto_dma_buffs_overlap(pIn, dataSize, pOut, dataSize)) {
memcpy(au8InputData, input, dataSize);
pIn = au8InputData;
}
MBED_ASSERT(! crypto_dma_buffs_overlap(pIn, dataSize, pOut, dataSize));
AES_SetDMATransfer(0, (uint32_t)pIn, (uint32_t)pOut, dataSize);
crypto_aes_prestart();

View File

@ -407,6 +407,7 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
memcpy(dmabuf_in, in_pos, data_len);
/* We always use DMA backup buffers, which are guaranteed to be non-overlapped. */
TDES_SetDMATransfer(0, (uint32_t) dmabuf_in, (uint32_t) dmabuf_out, data_len);
crypto_des_prestart();

View File

@ -171,6 +171,38 @@ bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_alig
(((buff_ >> 28) == 0x2) && (buff_size <= (0x30000000 - buff_)))); /* 0x20000000-0x2FFFFFFF */
}
/* Overlap cases
*
* 1. in_buff in front of out_buff:
*
* in in_end
* | |
* ||||||||||||||||
* ||||||||||||||||
* | |
* out out_end
*
* 2. out_buff in front of in_buff:
*
* in in_end
* | |
* ||||||||||||||||
* ||||||||||||||||
* | |
* out out_end
*/
bool crypto_dma_buffs_overlap(const void *in_buff, size_t in_buff_size, const void *out_buff, size_t out_buff_size)
{
uint32_t in = (uint32_t) in_buff;
uint32_t in_end = in + in_buff_size;
uint32_t out = (uint32_t) out_buff;
uint32_t out_end = out + out_buff_size;
bool overlap = (in <= out && out < in_end) || (out <= in && in < out_end);
return overlap;
}
static bool crypto_submodule_acquire(uint16_t *submodule_avail)
{
uint16_t expectedCurrentValue = 1;

View File

@ -76,6 +76,9 @@ bool crypto_des_wait(void);
*/
bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to);
/* Check if input/output buffers are overlapped */
bool crypto_dma_buffs_overlap(const void *in_buff, size_t in_buff_size, const void *out_buff, size_t out_buff_size);
#ifdef __cplusplus
}
#endif

View File

@ -171,6 +171,38 @@ bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_alig
(((buff_ >> 28) == 0x2) && (buff_size <= (0x30000000 - buff_)))); /* 0x20000000-0x2FFFFFFF */
}
/* Overlap cases
*
* 1. in_buff in front of out_buff:
*
* in in_end
* | |
* ||||||||||||||||
* ||||||||||||||||
* | |
* out out_end
*
* 2. out_buff in front of in_buff:
*
* in in_end
* | |
* ||||||||||||||||
* ||||||||||||||||
* | |
* out out_end
*/
bool crypto_dma_buffs_overlap(const void *in_buff, size_t in_buff_size, const void *out_buff, size_t out_buff_size)
{
uint32_t in = (uint32_t) in_buff;
uint32_t in_end = in + in_buff_size;
uint32_t out = (uint32_t) out_buff;
uint32_t out_end = out + out_buff_size;
bool overlap = (in <= out && out < in_end) || (out <= in && in < out_end);
return overlap;
}
static bool crypto_submodule_acquire(uint16_t *submodule_avail)
{
uint16_t expectedCurrentValue = 1;

View File

@ -76,6 +76,9 @@ bool crypto_des_wait(void);
*/
bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to);
/* Check if input/output buffers are overlapped */
bool crypto_dma_buffs_overlap(const void *in_buff, size_t in_buff_size, const void *out_buff, size_t out_buff_size);
#ifdef __cplusplus
}
#endif