Skip to content

Commit

Permalink
fix(aes): correct the linking of the DMA descriptors
Browse files Browse the repository at this point in the history
For certain data lengths, the last input descriptor was not getting appended
correctly and hence the EOF flag in the DMA descriptor link list was
set at incorrect location. This was resulting in the peripheral being
stalled expecting more data and eventually the code used to timeout
waiting for the AES completion interrupt.

Required configs for this issue:

CONFIG_MBEDTLS_HARDWARE_AES
CONFIG_SOC_AES_SUPPORT_DMA

This observation is similar to the issue reported in:
#10647

To recreate this issue, start the AES-GCM DMA operation with data length
12280 bytes and this should stall the operation forever.

In this fix, we are tracing the entire descriptor list and then appending the
extra bytes descriptor at correct position (as the last node).
  • Loading branch information
mahavirj committed Sep 6, 2023
1 parent 29be69d commit aba35cd
Showing 1 changed file with 7 additions and 10 deletions.
17 changes: 7 additions & 10 deletions components/mbedtls/port/aes/dma/esp_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,10 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
//Limit max inlink descriptor length to be 16 byte aligned, require for EDMA
lldesc_setup_link_constrained(block_out_desc, output, block_bytes, LLDESC_MAX_NUM_PER_DESC_16B_ALIGNED, 0);

/* Setup in/out start descriptors */
lldesc_append(&in_desc_head, block_in_desc);
lldesc_append(&out_desc_head, block_out_desc);

out_desc_tail = &block_out_desc[lldesc_num - 1];
}

Expand All @@ -412,20 +416,13 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
lldesc_setup_link(&s_stream_in_desc, s_stream_in, AES_BLOCK_BYTES, 0);
lldesc_setup_link(&s_stream_out_desc, s_stream_out, AES_BLOCK_BYTES, 0);

if (block_bytes > 0) {
/* Link with block descriptors*/
block_in_desc[lldesc_num - 1].empty = (uint32_t)&s_stream_in_desc;
block_out_desc[lldesc_num - 1].empty = (uint32_t)&s_stream_out_desc;
}
/* Link with block descriptors */
lldesc_append(&in_desc_head, &s_stream_in_desc);
lldesc_append(&out_desc_head, &s_stream_out_desc);

out_desc_tail = &s_stream_out_desc;
}

// block buffers are sent to DMA first, unless there aren't any
in_desc_head = (block_bytes > 0) ? block_in_desc : &s_stream_in_desc;
out_desc_head = (block_bytes > 0) ? block_out_desc : &s_stream_out_desc;


#if defined (CONFIG_MBEDTLS_AES_USE_INTERRUPT)
/* Only use interrupt for long AES operations */
if (len > AES_DMA_INTR_TRIG_LEN) {
Expand Down

0 comments on commit aba35cd

Please sign in to comment.