From 735c0c325b532b5798099e806a2a0a44050a835f Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Wed, 26 Jul 2023 15:31:12 +0530 Subject: [PATCH 1/2] fix(sha): DMA mode iteration calculation issue for certain data lengths SHA hardware DMA mode calculation had off-by-one error for specific input lengths. This was causing last chunk of the input data not being fed to the hardware accelerator and hence resulting in an incorrect final result. Closes: https://github.com/espressif/esp-idf/issues/11915 --- components/mbedtls/port/sha/dma/sha.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/components/mbedtls/port/sha/dma/sha.c b/components/mbedtls/port/sha/dma/sha.c index 58198fc9b5..f0638ed3cf 100644 --- a/components/mbedtls/port/sha/dma/sha.c +++ b/components/mbedtls/port/sha/dma/sha.c @@ -175,7 +175,6 @@ int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen, { int ret = 0; unsigned char *dma_cap_buf = NULL; - int dma_op_num = ( ilen / (SOC_SHA_DMA_MAX_BUFFER_SIZE + 1) ) + 1; if (buf_len > block_length(sha_type)) { ESP_LOGE(TAG, "SHA DMA buf_len cannot exceed max size for a single block"); @@ -209,6 +208,16 @@ int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen, buf = dma_cap_buf; } + uint32_t dma_op_num; + + if (ilen > 0) { + /* Number of DMA operations based on maximum chunk size in single operation */ + dma_op_num = (ilen + SOC_SHA_DMA_MAX_BUFFER_SIZE - 1) / SOC_SHA_DMA_MAX_BUFFER_SIZE; + } else { + /* For zero input length, we must allow at-least 1 DMA operation to see + * if there is any pending data that is yet to be copied out */ + dma_op_num = 1; + } /* The max amount of blocks in a single hardware operation is 2^6 - 1 = 63 Thus we only do a single DMA input list + dma buf list, From 224a308fd5b1793c3030c59706bfc1758cfa5170 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Wed, 26 Jul 2023 15:40:03 +0530 Subject: [PATCH 2/2] ci(test): add SHA DMA mode test for large data in PSRAM Covers a test scenario described in following issue: https://github.com/espressif/esp-idf/issues/11915 --- .../mbedtls/test_apps/main/test_mbedtls_sha.c | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/components/mbedtls/test_apps/main/test_mbedtls_sha.c b/components/mbedtls/test_apps/main/test_mbedtls_sha.c index 48aa1f208c..6eebf9c4c6 100644 --- a/components/mbedtls/test_apps/main/test_mbedtls_sha.c +++ b/components/mbedtls/test_apps/main/test_mbedtls_sha.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -527,6 +527,40 @@ TEST_CASE("mbedtls SHA256 PSRAM DMA", "[mbedtls]") TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str); } + +#if SOC_SHA_SUPPORT_DMA +TEST_CASE("mbedtls SHA256 PSRAM DMA large buffer", "[hw_crypto]") +{ + mbedtls_sha256_context sha256_ctx; + unsigned char sha256[32]; + + const size_t SZ = 257984; // specific size to cover issue in https://github.com/espressif/esp-idf/issues/11915 + void *buffer = heap_caps_malloc(SZ, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); + TEST_ASSERT_NOT_NULL(buffer); + memset(buffer, 0x55, SZ); + + mbedtls_sha256_init(&sha256_ctx); + int r = mbedtls_sha256_starts(&sha256_ctx, false); + TEST_ASSERT_EQUAL(0, r); + r = mbedtls_sha256_update(&sha256_ctx, buffer, SZ); + TEST_ASSERT_EQUAL(0, r); + r = mbedtls_sha256_finish(&sha256_ctx, sha256); + TEST_ASSERT_EQUAL(0, r); + mbedtls_sha256_free(&sha256_ctx); + free(buffer); + + /* Check the result. Reference value can be calculated using: + * dd if=/dev/zero bs=257984 count=1 | tr '\000' '\125' | sha256sum + */ + const char *expected_hash = "f2330c9f81ff1c8f0515247faa82be8b6f9685601de6f5dae79172766f136c33"; + + char hash_str[sizeof(sha256) * 2 + 1]; + utils_bin2hex(hash_str, sizeof(hash_str), sha256, sizeof(sha256)); + + TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str); +} +#endif // SOC_SHA_SUPPORT_DMA + #endif //CONFIG_SPIRAM_USE_MALLOC #if CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK