fix(hal/sha): Fix unaligned memory access in case of non-byte aligned regions

This commit is contained in:
harshal.patil
2025-04-28 14:40:44 +05:30
parent 4ea1facb42
commit 43a0026701
2 changed files with 36 additions and 4 deletions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -380,6 +380,19 @@ static inline uint32_t mmu_ll_entry_id_to_vaddr_base(uint32_t mmu_id, uint32_t e
return vaddr_base + (entry_id << 16);
}
/**
* Check if the external memory vaddr belongs to the DPORT bus region
*
* @param vaddr start of the virtual address
*
* @return True for valid
*/
__attribute__((always_inline))
static inline bool mmu_ll_vaddr_in_dport_bus_region(uint32_t vaddr)
{
return (vaddr >= SOC_DPORT_CACHE_ADDRESS_LOW && vaddr < SOC_DPORT_CACHE_ADDRESS_HIGH);
}
#ifdef __cplusplus
}
#endif

View File

@@ -1,14 +1,16 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <string.h>
#include "soc/hwcrypto_reg.h"
#include "hal/sha_types.h"
#include "soc/dport_reg.h"
#include "hal/mmu_ll.h"
#ifdef __cplusplus
extern "C" {
@@ -135,11 +137,28 @@ static inline bool sha_ll_busy(void)
*/
static inline void sha_ll_fill_text_block(const void *input_text, size_t block_word_len)
{
uint32_t *data_words = (uint32_t *)input_text;
uint32_t input_word;
uint8_t *data_bytes = (uint8_t *)input_text;
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
bool force_word_aligned_access = false;
/* In case of ESP32-S2, the DPORT bus region is word-aligned memory
* and does not support 8-bit accesses.
* Thus, when accessing data from these addresses we need to ensure
* the operations are word-aligned.
*/
if (mmu_ll_vaddr_in_dport_bus_region((uint32_t)input_text)) {
force_word_aligned_access = true;
}
for (size_t i = 0; i < block_word_len; i++) {
REG_WRITE(&reg_addr_buf[i], data_words[i]);
if (force_word_aligned_access) {
memcpy(&input_word, data_bytes + 4 * i, 4);
REG_WRITE(&reg_addr_buf[i], input_word);
} else {
REG_WRITE(&reg_addr_buf[i], *((uint32_t *)data_bytes + i));
}
}
}