Skip to content

Commit

Permalink
aes: fix DMA descriptor calculation for the alignment case
Browse files Browse the repository at this point in the history
The number of the DMA descriptors allocated for certain length (e.g.,
8176) were not sufficient (off by 1 error). This used to result in the
dynamic memory corruption as the region was modified beyond the
allocated range.

This change fixes the DMA descriptor calculation part and allocates
sufficient DMA descriptors based on the data length alignment considerations.

Test has also been added to cover the specific scenario in the CI.

Closes #11310
  • Loading branch information
mahavirj committed Jun 7, 2023
1 parent 4bc7626 commit 69bcbe9
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 3 deletions.
4 changes: 2 additions & 2 deletions components/mbedtls/port/aes/dma/esp_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,8 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
return esp_aes_process_dma_ext_ram(ctx, input, output, len, stream_out, input_needs_realloc, output_needs_realloc);
}

/* Set up dma descriptors for input and output */
lldesc_num = lldesc_get_required_num(block_bytes);
/* Set up dma descriptors for input and output considering the 16 byte alignment requirement for EDMA */
lldesc_num = lldesc_get_required_num_constrained(block_bytes, LLDESC_MAX_NUM_PER_DESC_16B_ALIGNED);

/* Allocate both in and out descriptors to save a malloc/free per function call */
block_desc = heap_caps_calloc(lldesc_num * 2, sizeof(lldesc_t), MALLOC_CAP_DMA);
Expand Down
52 changes: 51 additions & 1 deletion components/mbedtls/test_apps/main/test_aes.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
Expand All @@ -21,6 +21,7 @@
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_memory_utils.h"
#include "soc/lldesc.h"


static const uint8_t key_256[] = {
Expand Down Expand Up @@ -115,6 +116,55 @@ TEST_CASE("mbedtls CBC AES-256 test", "[aes]")
free(decryptedtext);
}

TEST_CASE("mbedtls CBC AES-256 DMA buffer align test", "[aes]")
{
#define ALIGN_DOWN(val, align) ((val) & ~((align) - 1))
// Size is taken considering the maximum DMA buffer size
const unsigned SZ = ALIGN_DOWN((2*LLDESC_MAX_NUM_PER_DESC), 16);
mbedtls_aes_context ctx;
uint8_t nonce[16];

const uint8_t expected_cipher_end[] = {
0x9e, 0xcb, 0x1d, 0x24, 0x01, 0xc8, 0x3f, 0xba,
0xde, 0x76, 0xea, 0x9c, 0xf3, 0x64, 0x23, 0x19,
0x8c, 0x67, 0xd4, 0x1a, 0xd1, 0xe0, 0xbf, 0xc3,
0xd2, 0xb8, 0x40, 0x95, 0x89, 0x41, 0x09, 0xdb,
};

memcpy(nonce, iv, 16);

// allocate internal memory
uint8_t *chipertext = heap_caps_malloc(SZ, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
uint8_t *plaintext = heap_caps_malloc(SZ, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
uint8_t *decryptedtext = heap_caps_malloc(SZ, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);

TEST_ASSERT_NOT_NULL(chipertext);
TEST_ASSERT_NOT_NULL(plaintext);
TEST_ASSERT_NOT_NULL(decryptedtext);

mbedtls_aes_init(&ctx);
mbedtls_aes_setkey_enc(&ctx, key_256, 256);

memset(plaintext, 0x3A, SZ);
memset(decryptedtext, 0x0, SZ);

// Encrypt
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, SZ, nonce, plaintext, chipertext);
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, chipertext + SZ - 32, 32);

// Decrypt
memcpy(nonce, iv, 16);
mbedtls_aes_setkey_dec(&ctx, key_256, 256);
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, SZ, nonce, chipertext, decryptedtext);

TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);

mbedtls_aes_free(&ctx);
free(plaintext);
free(chipertext);
free(decryptedtext);
}

TEST_CASE("mbedtls CTR AES-256 test", "[aes]")
{
const unsigned SZ = 1000;
Expand Down

0 comments on commit 69bcbe9

Please sign in to comment.