hwcrypto: SHA acceleration using safe DPORT reads

This commit is contained in:
Angus Gratton
2017-08-16 12:15:37 +10:00
committed by Angus Gratton
parent 7be002ec0f
commit d0c300c52d

View File

@@ -159,14 +159,18 @@ 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()) {
DPORT_STALL_OTHER_CPU_START();
{
/* Enable SHA hardware */ /* Enable SHA hardware */
DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA); _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 */ /* also clear reset on secure boot, otherwise SHA is held in reset */
DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG, _DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
DPORT_PERI_EN_SHA DPORT_PERI_EN_SHA
| DPORT_PERI_EN_SECUREBOOT); | DPORT_PERI_EN_SECUREBOOT);
ets_sha_enable(); 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,10 +225,12 @@ void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
esp_sha_lock_memory_block(); esp_sha_lock_memory_block();
DPORT_STALL_OTHER_CPU_START(); // This block reads from DPORT memory (reg_addr_buf)
{
esp_sha_wait_idle(); 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);
@@ -227,7 +243,8 @@ void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
} else { } else {
memcpy(digest_state_words, reg_addr_buf, sha_length(sha_type)); 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();
DPORT_STALL_OTHER_CPU_START();
{
// This SHA ROM function reads DPORT regs
ets_sha_update(&ctx, sha_type, input, chunk_len * 8); 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();
DPORT_STALL_OTHER_CPU_START();
{
ets_sha_finish(&ctx, sha_type, output); 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);