Skip to content

Commit 67386b9

Browse files
committed
[NUC472/M487] Fix DMA input/output buffers are overlapped in AES alter.
1 parent 4023078 commit 67386b9

File tree

8 files changed

+90
-0
lines changed

8 files changed

+90
-0
lines changed

features/mbedtls/targets/TARGET_NUVOTON/TARGET_M480/aes/aes_alt.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
160160
AES_Open(0, ctx->encDec, ctx->opMode, ctx->keySize, AES_IN_OUT_SWAP);
161161
AES_SetInitVect(0, ctx->iv);
162162
AES_SetKey(0, ctx->keys, ctx->keySize);
163+
163164
/* AES DMA buffer requirements same as above */
164165
if (! crypto_dma_buff_compat(input, dataSize, 16)) {
165166
memcpy(au8InputData, input, dataSize);
@@ -174,6 +175,14 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
174175
pOut = output;
175176
}
176177

178+
/* Even though AES H/W has limited support for overlapped DMA input/output buffers,
179+
* we still seek to one backup buffer to make them non-overlapped for simplicity. */
180+
if (crypto_dma_buffs_overlap(pIn, dataSize, pOut, dataSize)) {
181+
memcpy(au8InputData, input, dataSize);
182+
pIn = au8InputData;
183+
}
184+
MBED_ASSERT(! crypto_dma_buffs_overlap(pIn, dataSize, pOut, dataSize));
185+
177186
AES_SetDMATransfer(0, (uint32_t)pIn, (uint32_t)pOut, dataSize);
178187

179188
crypto_aes_prestart();

features/mbedtls/targets/TARGET_NUVOTON/TARGET_M480/des/des_alt.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
407407

408408
memcpy(dmabuf_in, in_pos, data_len);
409409

410+
/* We always use DMA backup buffers, which are guaranteed to be non-overlapped. */
410411
TDES_SetDMATransfer(0, (uint32_t) dmabuf_in, (uint32_t) dmabuf_out, data_len);
411412

412413
crypto_des_prestart();

features/mbedtls/targets/TARGET_NUVOTON/TARGET_NUC472/aes/aes_alt.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
160160
AES_Open(0, ctx->encDec, ctx->opMode, ctx->keySize, AES_IN_OUT_SWAP);
161161
AES_SetInitVect(0, ctx->iv);
162162
AES_SetKey(0, ctx->keys, ctx->keySize);
163+
163164
/* AES DMA buffer requirements same as above */
164165
if (! crypto_dma_buff_compat(input, dataSize, 16)) {
165166
memcpy(au8InputData, input, dataSize);
@@ -174,6 +175,14 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
174175
pOut = output;
175176
}
176177

178+
/* Even though AES H/W has limited support for overlapped DMA input/output buffers,
179+
* we still seek to one backup buffer to make them non-overlapped for simplicity. */
180+
if (crypto_dma_buffs_overlap(pIn, dataSize, pOut, dataSize)) {
181+
memcpy(au8InputData, input, dataSize);
182+
pIn = au8InputData;
183+
}
184+
MBED_ASSERT(! crypto_dma_buffs_overlap(pIn, dataSize, pOut, dataSize));
185+
177186
AES_SetDMATransfer(0, (uint32_t)pIn, (uint32_t)pOut, dataSize);
178187

179188
crypto_aes_prestart();

features/mbedtls/targets/TARGET_NUVOTON/TARGET_NUC472/des/des_alt.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ static int mbedtls_des_docrypt(uint16_t keyopt, uint8_t key[3][MBEDTLS_DES_KEY_S
407407

408408
memcpy(dmabuf_in, in_pos, data_len);
409409

410+
/* We always use DMA backup buffers, which are guaranteed to be non-overlapped. */
410411
TDES_SetDMATransfer(0, (uint32_t) dmabuf_in, (uint32_t) dmabuf_out, data_len);
411412

412413
crypto_des_prestart();

targets/TARGET_NUVOTON/TARGET_M480/crypto/crypto-misc.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,38 @@ bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_alig
171171
(((buff_ >> 28) == 0x2) && (buff_size <= (0x30000000 - buff_)))); /* 0x20000000-0x2FFFFFFF */
172172
}
173173

174+
/* Overlap cases
175+
*
176+
* 1. in_buff in front of out_buff:
177+
*
178+
* in in_end
179+
* | |
180+
* ||||||||||||||||
181+
* ||||||||||||||||
182+
* | |
183+
* out out_end
184+
*
185+
* 2. out_buff in front of in_buff:
186+
*
187+
* in in_end
188+
* | |
189+
* ||||||||||||||||
190+
* ||||||||||||||||
191+
* | |
192+
* out out_end
193+
*/
194+
bool crypto_dma_buffs_overlap(const void *in_buff, size_t in_buff_size, const void *out_buff, size_t out_buff_size)
195+
{
196+
uint32_t in = (uint32_t) in_buff;
197+
uint32_t in_end = in + in_buff_size;
198+
uint32_t out = (uint32_t) out_buff;
199+
uint32_t out_end = out + out_buff_size;
200+
201+
bool overlap = (in <= out && out < in_end) || (out <= in && in < out_end);
202+
203+
return overlap;
204+
}
205+
174206
static bool crypto_submodule_acquire(uint16_t *submodule_avail)
175207
{
176208
uint16_t expectedCurrentValue = 1;

targets/TARGET_NUVOTON/TARGET_M480/crypto/crypto-misc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ bool crypto_des_wait(void);
7676
*/
7777
bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to);
7878

79+
/* Check if input/output buffers are overlapped */
80+
bool crypto_dma_buffs_overlap(const void *in_buff, size_t in_buff_size, const void *out_buff, size_t out_buff_size);
81+
7982
#ifdef __cplusplus
8083
}
8184
#endif

targets/TARGET_NUVOTON/TARGET_NUC472/crypto/crypto-misc.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,38 @@ bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_alig
171171
(((buff_ >> 28) == 0x2) && (buff_size <= (0x30000000 - buff_)))); /* 0x20000000-0x2FFFFFFF */
172172
}
173173

174+
/* Overlap cases
175+
*
176+
* 1. in_buff in front of out_buff:
177+
*
178+
* in in_end
179+
* | |
180+
* ||||||||||||||||
181+
* ||||||||||||||||
182+
* | |
183+
* out out_end
184+
*
185+
* 2. out_buff in front of in_buff:
186+
*
187+
* in in_end
188+
* | |
189+
* ||||||||||||||||
190+
* ||||||||||||||||
191+
* | |
192+
* out out_end
193+
*/
194+
bool crypto_dma_buffs_overlap(const void *in_buff, size_t in_buff_size, const void *out_buff, size_t out_buff_size)
195+
{
196+
uint32_t in = (uint32_t) in_buff;
197+
uint32_t in_end = in + in_buff_size;
198+
uint32_t out = (uint32_t) out_buff;
199+
uint32_t out_end = out + out_buff_size;
200+
201+
bool overlap = (in <= out && out < in_end) || (out <= in && in < out_end);
202+
203+
return overlap;
204+
}
205+
174206
static bool crypto_submodule_acquire(uint16_t *submodule_avail)
175207
{
176208
uint16_t expectedCurrentValue = 1;

targets/TARGET_NUVOTON/TARGET_NUC472/crypto/crypto-misc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ bool crypto_des_wait(void);
7676
*/
7777
bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to);
7878

79+
/* Check if input/output buffers are overlapped */
80+
bool crypto_dma_buffs_overlap(const void *in_buff, size_t in_buff_size, const void *out_buff, size_t out_buff_size);
81+
7982
#ifdef __cplusplus
8083
}
8184
#endif

0 commit comments

Comments
 (0)