mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
fix(mbedtls/aes): fix ESP32-S2 Crypto DMA stall on PSRAM output with partial blocks
The ESP32-S2 Crypto DMA in-channel stalls silently when a receive descriptor list transitions from external to internal RAM. The AES driver hits this when a PSRAM-output operation has a trailing partial block, as the internal stream descriptor is linked after the external RAM data descriptors. - esp_aes_process_dma(): process the block-aligned part and the partial block as two separate DMA operations, keeping each descriptor list uniform - crypto_dma_ll_reset(): also reset the in-channel (per the TRM receive reset sequence), otherwise stale state from a preceding external-RAM operation corrupts the next operation's output The GCM DMA path is unaffected; it never operates on PSRAM buffers.
This commit is contained in:
@@ -31,8 +31,8 @@ typedef enum {
|
|||||||
*/
|
*/
|
||||||
static inline void crypto_dma_ll_reset(void)
|
static inline void crypto_dma_ll_reset(void)
|
||||||
{
|
{
|
||||||
SET_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
|
SET_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_IN_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
|
||||||
CLEAR_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
|
CLEAR_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_IN_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -360,6 +360,26 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
|
|||||||
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
|
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOC_AES_CRYPTO_DMA && CONFIG_SPIRAM
|
||||||
|
/* The Crypto DMA in-channel stalls indefinitely (no descriptor error is raised) when a
|
||||||
|
receive descriptor list transitions from a buffer in external RAM to one in internal
|
||||||
|
RAM. Avoid linking the internal stream buffer descriptor after external-RAM data
|
||||||
|
descriptors by processing the block-aligned part and the trailing partial block as
|
||||||
|
two separate DMA operations. */
|
||||||
|
if (block_bytes > 0 && stream_bytes > 0 && esp_ptr_external_ram(output)) {
|
||||||
|
ret = esp_aes_process_dma(ctx, input, output, block_bytes, NULL);
|
||||||
|
if (ret != 0) {
|
||||||
|
mbedtls_platform_zeroize(output, len);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = esp_aes_process_dma(ctx, input + block_bytes, output + block_bytes, stream_bytes, stream_out);
|
||||||
|
if (ret != 0) {
|
||||||
|
mbedtls_platform_zeroize(output, len);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* SOC_AES_CRYPTO_DMA && CONFIG_SPIRAM */
|
||||||
|
|
||||||
if (block_bytes > 0) {
|
if (block_bytes > 0) {
|
||||||
/* Flush cache if input in external ram */
|
/* Flush cache if input in external ram */
|
||||||
#if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE)
|
#if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE)
|
||||||
|
|||||||
Reference in New Issue
Block a user