mirror of https://github.com/ARMmbed/mbed-os.git
[NUC472/M487] Fix DMA input/output buffers are overlapped in AES alter.
parent
4023078e14
commit
67386b9ebd
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue