mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 03:07:21 +02:00
hwcrypto: SHA acceleration using safe DPORT reads
This commit is contained in:
committed by
Angus Gratton
parent
7be002ec0f
commit
d0c300c52d
@ -159,13 +159,17 @@ static void esp_sha_lock_engine_inner(sha_engine_state *engine)
|
|||||||
_lock_acquire(&state_change_lock);
|
_lock_acquire(&state_change_lock);
|
||||||
|
|
||||||
if (sha_engines_all_idle()) {
|
if (sha_engines_all_idle()) {
|
||||||
/* Enable SHA hardware */
|
DPORT_STALL_OTHER_CPU_START();
|
||||||
DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
|
{
|
||||||
/* also clear reset on secure boot, otherwise SHA is held in reset */
|
/* Enable SHA hardware */
|
||||||
DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
|
_DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
|
||||||
DPORT_PERI_EN_SHA
|
/* also clear reset on secure boot, otherwise SHA is held in reset */
|
||||||
| DPORT_PERI_EN_SECUREBOOT);
|
_DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
|
||||||
ets_sha_enable();
|
DPORT_PERI_EN_SHA
|
||||||
|
| DPORT_PERI_EN_SECUREBOOT);
|
||||||
|
ets_sha_enable();
|
||||||
|
}
|
||||||
|
DPORT_STALL_OTHER_CPU_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
_lock_release(&state_change_lock);
|
_lock_release(&state_change_lock);
|
||||||
@ -187,8 +191,12 @@ void esp_sha_unlock_engine(esp_sha_type sha_type)
|
|||||||
if (sha_engines_all_idle()) {
|
if (sha_engines_all_idle()) {
|
||||||
/* Disable SHA hardware */
|
/* Disable SHA hardware */
|
||||||
/* Don't assert reset on secure boot, otherwise AES is held in reset */
|
/* Don't assert reset on secure boot, otherwise AES is held in reset */
|
||||||
DPORT_REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_SHA);
|
DPORT_STALL_OTHER_CPU_START();
|
||||||
DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
|
{
|
||||||
|
_DPORT_REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_SHA);
|
||||||
|
_DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
|
||||||
|
}
|
||||||
|
DPORT_STALL_OTHER_CPU_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
_lock_release(&state_change_lock);
|
_lock_release(&state_change_lock);
|
||||||
@ -198,10 +206,16 @@ void esp_sha_unlock_engine(esp_sha_type sha_type)
|
|||||||
|
|
||||||
void esp_sha_wait_idle(void)
|
void esp_sha_wait_idle(void)
|
||||||
{
|
{
|
||||||
while(REG_READ(SHA_1_BUSY_REG) == 1) {}
|
DPORT_STALL_OTHER_CPU_START();
|
||||||
while(REG_READ(SHA_256_BUSY_REG) == 1) {}
|
while(1) {
|
||||||
while(REG_READ(SHA_384_BUSY_REG) == 1) {}
|
if(_DPORT_REG_READ(SHA_1_BUSY_REG) == 0
|
||||||
while(REG_READ(SHA_512_BUSY_REG) == 1) {}
|
&& _DPORT_REG_READ(SHA_256_BUSY_REG) == 0
|
||||||
|
&& _DPORT_REG_READ(SHA_384_BUSY_REG) == 0
|
||||||
|
&& _DPORT_REG_READ(SHA_512_BUSY_REG) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DPORT_STALL_OTHER_CPU_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
|
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
|
||||||
@ -211,23 +225,26 @@ void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
|
|||||||
|
|
||||||
esp_sha_lock_memory_block();
|
esp_sha_lock_memory_block();
|
||||||
|
|
||||||
esp_sha_wait_idle();
|
DPORT_STALL_OTHER_CPU_START(); // This block reads from DPORT memory (reg_addr_buf)
|
||||||
|
{
|
||||||
|
esp_sha_wait_idle();
|
||||||
|
|
||||||
REG_WRITE(SHA_LOAD_REG(sha_type), 1);
|
_DPORT_REG_WRITE(SHA_LOAD_REG(sha_type), 1);
|
||||||
while(REG_READ(SHA_BUSY_REG(sha_type)) == 1) { }
|
while(_DPORT_REG_READ(SHA_BUSY_REG(sha_type)) == 1) { }
|
||||||
|
|
||||||
uint32_t *digest_state_words = (uint32_t *)digest_state;
|
uint32_t *digest_state_words = (uint32_t *)digest_state;
|
||||||
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
|
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
|
||||||
if(sha_type == SHA2_384 || sha_type == SHA2_512) {
|
if(sha_type == SHA2_384 || sha_type == SHA2_512) {
|
||||||
/* for these ciphers using 64-bit states, swap each pair of words */
|
/* for these ciphers using 64-bit states, swap each pair of words */
|
||||||
for(int i = 0; i < sha_length(sha_type)/4; i += 2) {
|
for(int i = 0; i < sha_length(sha_type)/4; i += 2) {
|
||||||
digest_state_words[i+1] = reg_addr_buf[i];
|
digest_state_words[i+1] = reg_addr_buf[i];
|
||||||
digest_state_words[i]= reg_addr_buf[i+1];
|
digest_state_words[i]= reg_addr_buf[i+1];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(digest_state_words, reg_addr_buf, sha_length(sha_type));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
memcpy(digest_state_words, reg_addr_buf, sha_length(sha_type));
|
|
||||||
}
|
}
|
||||||
asm volatile ("memw");
|
DPORT_STALL_OTHER_CPU_END();
|
||||||
|
|
||||||
esp_sha_unlock_memory_block();
|
esp_sha_unlock_memory_block();
|
||||||
}
|
}
|
||||||
@ -250,9 +267,9 @@ void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_
|
|||||||
asm volatile ("memw");
|
asm volatile ("memw");
|
||||||
|
|
||||||
if(is_first_block) {
|
if(is_first_block) {
|
||||||
REG_WRITE(SHA_START_REG(sha_type), 1);
|
DPORT_REG_WRITE(SHA_START_REG(sha_type), 1);
|
||||||
} else {
|
} else {
|
||||||
REG_WRITE(SHA_CONTINUE_REG(sha_type), 1);
|
DPORT_REG_WRITE(SHA_CONTINUE_REG(sha_type), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_sha_unlock_memory_block();
|
esp_sha_unlock_memory_block();
|
||||||
@ -275,14 +292,23 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns
|
|||||||
size_t chunk_len = (ilen > block_len) ? block_len : ilen;
|
size_t chunk_len = (ilen > block_len) ? block_len : ilen;
|
||||||
esp_sha_lock_memory_block();
|
esp_sha_lock_memory_block();
|
||||||
esp_sha_wait_idle();
|
esp_sha_wait_idle();
|
||||||
ets_sha_update(&ctx, sha_type, input, chunk_len * 8);
|
DPORT_STALL_OTHER_CPU_START();
|
||||||
|
{
|
||||||
|
// This SHA ROM function reads DPORT regs
|
||||||
|
ets_sha_update(&ctx, sha_type, input, chunk_len * 8);
|
||||||
|
}
|
||||||
|
DPORT_STALL_OTHER_CPU_END();
|
||||||
esp_sha_unlock_memory_block();
|
esp_sha_unlock_memory_block();
|
||||||
input += chunk_len;
|
input += chunk_len;
|
||||||
ilen -= chunk_len;
|
ilen -= chunk_len;
|
||||||
}
|
}
|
||||||
esp_sha_lock_memory_block();
|
esp_sha_lock_memory_block();
|
||||||
esp_sha_wait_idle();
|
esp_sha_wait_idle();
|
||||||
ets_sha_finish(&ctx, sha_type, output);
|
DPORT_STALL_OTHER_CPU_START();
|
||||||
|
{
|
||||||
|
ets_sha_finish(&ctx, sha_type, output);
|
||||||
|
}
|
||||||
|
DPORT_STALL_OTHER_CPU_END();
|
||||||
esp_sha_unlock_memory_block();
|
esp_sha_unlock_memory_block();
|
||||||
|
|
||||||
esp_sha_unlock_engine(sha_type);
|
esp_sha_unlock_engine(sha_type);
|
||||||
|
Reference in New Issue
Block a user