Use HAL instead of ROM for SHA HW acceleration (#23902)
This commit is contained in:
parent
86e48395c8
commit
c12b5d5863
754
lib/lib_ssl/bearssl-esp8266/src/hash/_sha_hal_idf5x.c
Normal file
754
lib/lib_ssl/bearssl-esp8266/src/hash/_sha_hal_idf5x.c
Normal file
@ -0,0 +1,754 @@
|
||||
/*
|
||||
* _sha_hal_idf5x.c — BearSSL drop‑in with ESP32 HAL SHA acceleration
|
||||
*
|
||||
* This file provides hardware-accelerated implementations of BearSSL-compatible
|
||||
* hash functions (SHA-1, SHA-224, SHA-256, SHA-384, SHA-512) using the ESP-IDF 5.x
|
||||
* SHA HAL. It replaces the software digest core with direct access to the ESP32's
|
||||
* SHA engine, preserving BearSSL's context structure and API semantics.
|
||||
*
|
||||
* Each hash context uses a minimal layout:
|
||||
* - val[] holds the midstate as a raw little-endian byte image.
|
||||
* - buf[] holds the partial block (64 or 128 bytes).
|
||||
* - count tracks the total input length in bytes.
|
||||
*
|
||||
* Endianness is preserved across state() and set_state() calls, allowing seamless
|
||||
* serialization and restoration of midstate snapshots. All conversions for hardware
|
||||
* interaction are localized to update() and out().
|
||||
*
|
||||
* This module is designed for drop-in replacement with no changes to BearSSL clients.
|
||||
* It supports multihash, midstate injection, and digest resumption.
|
||||
*
|
||||
* Author: Christian Baars
|
||||
*/
|
||||
|
||||
#include "t_inner.h"
|
||||
|
||||
#if defined(USE_SHA_ROM)
|
||||
#if defined(ESP_PLATFORM) && !defined(ESP8266)
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#if __has_include("soc/sha_caps.h")
|
||||
# include "soc/sha_caps.h"
|
||||
#elif __has_include("soc/soc_caps.h")
|
||||
# include "soc/soc_caps.h"
|
||||
#else
|
||||
# error "No SHA capability header found"
|
||||
#endif
|
||||
#if SOC_SHA_SUPPORT_RESUME
|
||||
|
||||
#if __has_include("hal/sha_ll.h")
|
||||
# include "hal/sha_ll.h"
|
||||
# define HAVE_SHA_LL 1
|
||||
#else
|
||||
# define HAVE_SHA_LL 0
|
||||
#endif
|
||||
|
||||
|
||||
#define HAVE_HAL_SHA1 (SOC_SHA_SUPPORT_SHA1)
|
||||
#define HAVE_HAL_SHA224 (SOC_SHA_SUPPORT_SHA224)
|
||||
#define HAVE_HAL_SHA256 (SOC_SHA_SUPPORT_SHA256)
|
||||
#define HAVE_HAL_SHA384 (SOC_SHA_SUPPORT_SHA384)
|
||||
#define HAVE_HAL_SHA512 (SOC_SHA_SUPPORT_SHA512)
|
||||
|
||||
static portMUX_TYPE s_sha_mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
#define SHA_ENTER() {portENTER_CRITICAL(&s_sha_mux); int __DECLARE_RCC_ATOMIC_ENV; sha_ll_enable_bus_clock(true); sha_ll_reset_register();}
|
||||
#define SHA_EXIT() {portEXIT_CRITICAL(&s_sha_mux); int __DECLARE_RCC_ATOMIC_ENV; sha_ll_enable_bus_clock(false);}
|
||||
#define SHA_WAIT() {while (sha_ll_busy()) { } }
|
||||
|
||||
/* ================================================================
|
||||
* SHA-1 (HAL path, no save/restore) - needs char buf[112];
|
||||
* ================================================================ */
|
||||
#if HAVE_HAL_SHA1
|
||||
|
||||
static void __attribute__((noinline))
|
||||
sha_hal_process_block(void *state_buf, const void *blk,
|
||||
esp_sha_type type, size_t digest_words,
|
||||
size_t block_words, bool first)
|
||||
{
|
||||
SHA_ENTER();
|
||||
if (!first) {
|
||||
sha_ll_write_digest(type, state_buf, digest_words);
|
||||
}
|
||||
sha_ll_fill_text_block(blk, block_words);
|
||||
if (first) {
|
||||
sha_ll_start_block(type);
|
||||
} else {
|
||||
sha_ll_continue_block(type);
|
||||
}
|
||||
SHA_WAIT();
|
||||
sha_ll_read_digest(type, state_buf, digest_words);
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
static const uint8_t S1_IV_BYTES[20] PROGMEM = {
|
||||
0x67,0x45,0x23,0x01, 0xEF,0xCD,0xAB,0x89,
|
||||
0x98,0xBA,0xDC,0xFE, 0x10,0x32,0x54,0x76,
|
||||
0xC3,0xD2,0xE1,0xF0
|
||||
};
|
||||
|
||||
void br_sha1_init(br_sha1_context *cc)
|
||||
{
|
||||
cc->vtable = &br_sha1_vtable;
|
||||
cc->count = 0;
|
||||
memset(cc->buf, 0, sizeof cc->buf);
|
||||
/* Store IV bytes exactly as given (LE words) into cc->val */
|
||||
memcpy(cc->val, S1_IV_BYTES, sizeof S1_IV_BYTES);
|
||||
}
|
||||
|
||||
void br_sha1_update(br_sha1_context *cc, const void *data, size_t len)
|
||||
{
|
||||
const uint8_t *src = data;
|
||||
size_t used = (size_t)(cc->count & 63U);
|
||||
|
||||
if (!len) return;
|
||||
cc->count += len;
|
||||
|
||||
if (used) {
|
||||
size_t take = 64 - used;
|
||||
if (take > len) take = len;
|
||||
memcpy(cc->buf + used, src, take);
|
||||
src += take;
|
||||
len -= take;
|
||||
used += take;
|
||||
if (used == 64) {
|
||||
sha_hal_process_block(cc->val, cc->buf, SHA1, 5, 16, cc->count == 64);
|
||||
used = 0;
|
||||
}
|
||||
}
|
||||
while (len >= 64) {
|
||||
sha_hal_process_block(cc->val, src, SHA1, 5, 16,
|
||||
(cc->count - len == 0) && !used);
|
||||
src += 64;
|
||||
len -= 64;
|
||||
}
|
||||
if (len) {
|
||||
memcpy(cc->buf, src, len);
|
||||
}
|
||||
}
|
||||
|
||||
void br_sha1_out(const br_sha1_context *cc, void *out)
|
||||
{
|
||||
br_sha1_context ctx = *cc;
|
||||
size_t used = (size_t)(ctx.count & 63U);
|
||||
uint64_t bit_len = (uint64_t)ctx.count << 3;
|
||||
|
||||
ctx.buf[used++] = 0x80;
|
||||
if (used > 56) {
|
||||
memset(ctx.buf + used, 0, 64 - used);
|
||||
sha_hal_process_block(ctx.val, ctx.buf, SHA1, 5, 16, ctx.count <= 64);
|
||||
used = 0;
|
||||
}
|
||||
memset(ctx.buf + used, 0, 56 - used);
|
||||
br_enc64be(ctx.buf + 56, bit_len);
|
||||
sha_hal_process_block(ctx.val, ctx.buf, SHA1, 5, 16, ctx.count <= 64);
|
||||
memcpy(out, ctx.val, 20);
|
||||
}
|
||||
|
||||
uint64_t br_sha1_state(const br_sha1_context *cc, void *dst)
|
||||
{
|
||||
/* Export raw 20-byte LE midstate image exactly as stored */
|
||||
memcpy(dst, cc->val, 20);
|
||||
return cc->count;
|
||||
}
|
||||
|
||||
void br_sha1_set_state(br_sha1_context *cc, const void *src, uint64_t count)
|
||||
{
|
||||
if (!(cc->vtable == &br_sha1_vtable)) {
|
||||
cc->vtable = &br_sha1_vtable;
|
||||
}
|
||||
/* Import raw 20-byte LE midstate image exactly as provided */
|
||||
memcpy(cc->val, src, 20);
|
||||
cc->count = count;
|
||||
memset(cc->buf, 0, sizeof cc->buf);
|
||||
}
|
||||
|
||||
const br_hash_class br_sha1_vtable PROGMEM = {
|
||||
sizeof(br_sha1_context),
|
||||
BR_HASHDESC_ID(br_sha1_ID)
|
||||
| BR_HASHDESC_OUT(20)
|
||||
| BR_HASHDESC_LBLEN(6)
|
||||
| BR_HASHDESC_MD_PADDING
|
||||
| BR_HASHDESC_MD_PADDING_BE
|
||||
| BR_HASHDESC_STATE(32),
|
||||
(void (*)(const br_hash_class **)) &br_sha1_init,
|
||||
(void (*)(const br_hash_class **, const void *, size_t)) &br_sha1_update,
|
||||
(void (*)(const br_hash_class *const *, void *)) &br_sha1_out,
|
||||
(uint64_t (*)(const br_hash_class *const *, void *)) &br_sha1_state,
|
||||
(void (*)(const br_hash_class **, const void *, uint64_t)) &br_sha1_set_state
|
||||
};
|
||||
|
||||
#endif /* HAVE_HAL_SHA1 */
|
||||
|
||||
/* ================================================================
|
||||
* SHA-224 (HAL path, no save/restore)
|
||||
* ================================================================ */
|
||||
#if HAVE_HAL_SHA224
|
||||
|
||||
/* SHA-224 IV as 32-bit words (FIPS 180-4) */
|
||||
static const uint32_t S224_IV_WORDS[8] = {
|
||||
0xc1059ed8U, 0x367cd507U, 0x3070dd17U, 0xf70e5939U,
|
||||
0xffc00b31U, 0x68581511U, 0x64f98fa7U, 0xbefa4fa4U
|
||||
};
|
||||
|
||||
void br_sha224_init(br_sha224_context *cc) {
|
||||
cc->vtable = &br_sha224_vtable;
|
||||
cc->count = 0;
|
||||
memset(cc->buf, 0, sizeof cc->buf);
|
||||
/* Internal state is LE; encode IV directly in LE form into cc->val */
|
||||
br_range_enc32le(cc->val, S224_IV_WORDS, 8);
|
||||
}
|
||||
|
||||
/* Reuse SHA-256 out, then truncate to 28 bytes */
|
||||
void br_sha224_out(const br_sha224_context *cc, void *out) {
|
||||
uint8_t full[32];
|
||||
br_sha256_out((const br_sha256_context *)cc, full);
|
||||
memcpy(out, full, 28);
|
||||
}
|
||||
|
||||
const br_hash_class br_sha224_vtable PROGMEM = {
|
||||
sizeof(br_sha224_context),
|
||||
BR_HASHDESC_ID(br_sha224_ID)
|
||||
| BR_HASHDESC_OUT(28)
|
||||
| BR_HASHDESC_LBLEN(6)
|
||||
| BR_HASHDESC_MD_PADDING
|
||||
| BR_HASHDESC_MD_PADDING_BE
|
||||
| BR_HASHDESC_STATE(32),
|
||||
(void (*)(const br_hash_class **)) &br_sha224_init,
|
||||
(void (*)(const br_hash_class **, const void *, size_t)) &br_sha224_update,
|
||||
(void (*)(const br_hash_class *const *, void *)) &br_sha224_out,
|
||||
(uint64_t (*)(const br_hash_class *const *, void *)) &br_sha224_state,
|
||||
(void (*)(const br_hash_class **, const void *, uint64_t)) &br_sha224_set_state
|
||||
};
|
||||
|
||||
#endif /* HAVE_HAL_SHA224 */
|
||||
|
||||
/* ================================================================
|
||||
* SHA-256 (HAL path, save/restore)
|
||||
* ================================================================ */
|
||||
#if HAVE_HAL_SHA256 && defined(SOC_SHA_SUPPORT_RESUME)
|
||||
|
||||
/* Fixed SHA-256 IV in big-endian bytes (spec-defined) */
|
||||
static const uint8_t S256_IV_BYTES[32] PROGMEM = {
|
||||
0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae, 0x85,
|
||||
0x3c, 0x6e, 0xf3, 0x72, 0xa5, 0x4f, 0xf5, 0x3a,
|
||||
0x51, 0x0e, 0x52, 0x7f, 0x9b, 0x05, 0x68, 0x8c,
|
||||
0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19
|
||||
};
|
||||
|
||||
/* Maintain the partial block in cc->buf[] (64 bytes) */
|
||||
static inline void s256_update_partial(br_sha256_context *cc,
|
||||
const uint8_t *data_ptr,
|
||||
size_t data_len,
|
||||
size_t prev_partial_len)
|
||||
{
|
||||
size_t new_partial_len = (prev_partial_len + data_len) & 63U;
|
||||
|
||||
if (new_partial_len == 0) {
|
||||
/* Exact block boundary: clear partial buffer */
|
||||
memset(cc->buf, 0, sizeof cc->buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data_len >= new_partial_len) {
|
||||
/* Tail entirely from current input */
|
||||
memcpy(cc->buf, data_ptr + (data_len - new_partial_len), new_partial_len);
|
||||
} else {
|
||||
/* Need some bytes from previous partial tail */
|
||||
size_t need_prev = new_partial_len - data_len;
|
||||
if (need_prev && need_prev <= prev_partial_len) {
|
||||
memmove(cc->buf, cc->buf + (prev_partial_len - need_prev), need_prev);
|
||||
} else if (need_prev) {
|
||||
memset(cc->buf, 0, need_prev);
|
||||
}
|
||||
memcpy(cc->buf + need_prev, data_ptr, data_len);
|
||||
}
|
||||
|
||||
if (new_partial_len < sizeof cc->buf) {
|
||||
memset(cc->buf + new_partial_len, 0, sizeof cc->buf - new_partial_len);
|
||||
}
|
||||
}
|
||||
|
||||
void br_sha256_init(br_sha256_context *cc)
|
||||
{
|
||||
cc->vtable = &br_sha256_vtable;
|
||||
cc->count = 0;
|
||||
memset(cc->buf, 0, sizeof cc->buf);
|
||||
/* Keep midstate bytes exactly as IV (BE byte image), as in the original */
|
||||
memcpy(cc->val, S256_IV_BYTES, 32);
|
||||
}
|
||||
|
||||
void br_sha224_update(br_sha224_context *cc, const void *data, size_t len)
|
||||
{
|
||||
if (!len) return;
|
||||
|
||||
/* Embedded mode selection by vtable pointer (no desc, no tags) */
|
||||
const int mode = (cc->vtable == &br_sha256_vtable) ? SHA2_256 : SHA2_224;
|
||||
|
||||
const uint8_t *data_ptr = (const uint8_t *)data;
|
||||
const uint8_t *orig_ptr = data_ptr;
|
||||
size_t orig_len = len;
|
||||
|
||||
size_t prev_partial_len = (size_t)(cc->count & 63U);
|
||||
bool starting_from_iv = (cc->count == 0) && (prev_partial_len == 0);
|
||||
size_t stitch_take = 0;
|
||||
if (prev_partial_len && len >= (64 - prev_partial_len))
|
||||
stitch_take = 64 - prev_partial_len;
|
||||
|
||||
if (stitch_take || len >= 64) {
|
||||
size_t block_count_in_run = 0;
|
||||
|
||||
SHA_ENTER();
|
||||
|
||||
/* Complete the partial block (stitch) if needed */
|
||||
if (stitch_take) {
|
||||
uint32_t midstate_words[8];
|
||||
/* Original semantics: decode state from LE words before seeding HW */
|
||||
br_range_dec32le(midstate_words, 8, cc->val);
|
||||
sha_ll_load(mode);
|
||||
sha_ll_write_digest(mode, midstate_words, 8);
|
||||
|
||||
uint8_t first_block[64];
|
||||
memcpy(first_block, cc->buf, prev_partial_len);
|
||||
memcpy(first_block + prev_partial_len, data_ptr, stitch_take);
|
||||
|
||||
sha_ll_fill_text_block(first_block, 16);
|
||||
sha_ll_continue_block(mode);
|
||||
SHA_WAIT();
|
||||
|
||||
data_ptr += stitch_take;
|
||||
len -= stitch_take;
|
||||
block_count_in_run = 1;
|
||||
}
|
||||
|
||||
/* Process full 64-byte blocks */
|
||||
if (len >= 64) {
|
||||
if (starting_from_iv && stitch_take == 0) {
|
||||
/* Start from IV directly */
|
||||
sha_ll_fill_text_block(data_ptr, 16);
|
||||
sha_ll_start_block(mode);
|
||||
SHA_WAIT();
|
||||
data_ptr += 64;
|
||||
len -= 64;
|
||||
block_count_in_run = 1;
|
||||
} else if (block_count_in_run == 0) {
|
||||
/* Seed from current midstate once before the run */
|
||||
uint32_t midstate_words2[8];
|
||||
br_range_dec32le(midstate_words2, 8, cc->val);
|
||||
sha_ll_load(mode);
|
||||
sha_ll_write_digest(mode, midstate_words2, 8);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ARCH_RISCV) /* RISC-V: enforce 8-block (512B) window with checkpointing */
|
||||
while (len >= 64) {
|
||||
sha_ll_fill_text_block(data_ptr, 16);
|
||||
sha_ll_continue_block(mode);
|
||||
SHA_WAIT();
|
||||
|
||||
data_ptr += 64;
|
||||
len -= 64;
|
||||
block_count_in_run++;
|
||||
|
||||
if (block_count_in_run == 8 && len >= 64) {
|
||||
uint32_t midstate_words3[8];
|
||||
sha_ll_load(mode);
|
||||
sha_ll_read_digest(mode, midstate_words3, 8);
|
||||
sha_ll_load(mode);
|
||||
sha_ll_write_digest(mode, midstate_words3, 8);
|
||||
block_count_in_run = 0;
|
||||
}
|
||||
}
|
||||
#else /* Xtensa: simple per-block processing, no extra checkpointing */
|
||||
while (len >= 64) {
|
||||
sha_ll_fill_text_block(data_ptr, 16);
|
||||
sha_ll_continue_block(mode);
|
||||
SHA_WAIT();
|
||||
data_ptr += 64;
|
||||
len -= 64;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Commit midstate back; keep the same on-wire format as before: LE words in cc->val */
|
||||
{
|
||||
uint32_t tmp_words[8];
|
||||
sha_ll_load(mode);
|
||||
SHA_WAIT();
|
||||
sha_ll_read_digest(mode, tmp_words, 8);
|
||||
br_range_enc32le(cc->val, tmp_words, 8);
|
||||
}
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
/* Bookkeeping and partial buffer maintenance */
|
||||
cc->count += orig_len;
|
||||
s256_update_partial((br_sha256_context *)cc, orig_ptr, orig_len, prev_partial_len);
|
||||
}
|
||||
|
||||
void br_sha256_out(const br_sha256_context *cc, void *out)
|
||||
{
|
||||
uint8_t saved_partial[sizeof cc->buf];
|
||||
uint64_t saved_count = cc->count;
|
||||
uint8_t saved_state[32];
|
||||
|
||||
memcpy(saved_partial, cc->buf, sizeof cc->buf);
|
||||
memcpy(saved_state, cc->val, 32);
|
||||
|
||||
uint8_t partial_len = (uint8_t)(saved_count & 63U);
|
||||
const int mode = (cc->vtable == &br_sha256_vtable) ? SHA2_256 : SHA2_224;
|
||||
|
||||
bool midstate_is_iv = (memcmp(saved_state, S256_IV_BYTES, 32) == 0);
|
||||
bool no_full_blocks_done = (saved_count < 64);
|
||||
bool must_start_from_iv = midstate_is_iv && no_full_blocks_done;
|
||||
|
||||
SHA_ENTER();
|
||||
|
||||
if (!must_start_from_iv) {
|
||||
uint32_t midstate_words[8];
|
||||
/* Original semantics: state stored as LE words in cc->val */
|
||||
br_range_dec32le(midstate_words, 8, saved_state);
|
||||
sha_ll_load(mode);
|
||||
sha_ll_write_digest(mode, midstate_words, 8);
|
||||
}
|
||||
|
||||
uint8_t final_blocks[128];
|
||||
memcpy(final_blocks, saved_partial, partial_len);
|
||||
final_blocks[partial_len] = 0x80;
|
||||
|
||||
size_t zero_len = (partial_len < 56) ? (56 - partial_len - 1)
|
||||
: (120 - partial_len - 1);
|
||||
if (zero_len) {
|
||||
memset(final_blocks + partial_len + 1, 0, zero_len);
|
||||
}
|
||||
|
||||
uint64_t bit_length = saved_count * 8;
|
||||
size_t len_pos = partial_len + 1 + zero_len;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
final_blocks[len_pos + i] = (uint8_t)(bit_length >> (56 - 8 * i));
|
||||
}
|
||||
size_t total_final_len = len_pos + 8;
|
||||
|
||||
if (total_final_len == 64) {
|
||||
sha_ll_fill_text_block(final_blocks, 16);
|
||||
if (must_start_from_iv)
|
||||
sha_ll_start_block(mode);
|
||||
else
|
||||
sha_ll_continue_block(mode);
|
||||
SHA_WAIT();
|
||||
} else {
|
||||
sha_ll_fill_text_block(final_blocks, 16);
|
||||
if (must_start_from_iv)
|
||||
sha_ll_start_block(mode);
|
||||
else
|
||||
sha_ll_continue_block(mode);
|
||||
SHA_WAIT();
|
||||
sha_ll_fill_text_block(final_blocks + 64, 16);
|
||||
sha_ll_continue_block(mode);
|
||||
SHA_WAIT();
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t tmp_words[8];
|
||||
sha_ll_load(mode);
|
||||
sha_ll_read_digest(mode, tmp_words, 8);
|
||||
SHA_EXIT();
|
||||
/* Final digest serialization remains LE as in your original */
|
||||
br_range_enc32le(out, tmp_words, 8);
|
||||
}
|
||||
|
||||
/* Non-destructive out(): restore snapshot */
|
||||
memcpy(((br_sha256_context *)cc)->buf, saved_partial, sizeof cc->buf);
|
||||
((br_sha256_context *)cc)->count = saved_count;
|
||||
/* cc->val was never modified in out() */
|
||||
}
|
||||
|
||||
uint64_t br_sha224_state(const br_sha256_context *cc, void *dst)
|
||||
{
|
||||
/* Export midstate bytes exactly as stored (LE words image), unchanged */
|
||||
memcpy(dst, cc->val, 32);
|
||||
return cc->count;
|
||||
}
|
||||
|
||||
void br_sha224_set_state(br_sha256_context *cc, const void *src, uint64_t count)
|
||||
{
|
||||
if( !(cc->vtable == &br_sha256_vtable) && !(cc->vtable == &br_sha224_vtable)){
|
||||
cc->vtable = &br_sha256_vtable; /* safety for multihash fresh gen context */
|
||||
}
|
||||
/* Reset partial, set count, and import state bytes exactly as provided */
|
||||
memset(cc->buf, 0, sizeof cc->buf);
|
||||
memcpy(cc->val, src, 32);
|
||||
cc->count = count;
|
||||
}
|
||||
|
||||
const br_hash_class br_sha256_vtable PROGMEM = {
|
||||
sizeof(br_sha256_context),
|
||||
BR_HASHDESC_ID(br_sha256_ID)
|
||||
| BR_HASHDESC_OUT(32)
|
||||
| BR_HASHDESC_STATE(32)
|
||||
| BR_HASHDESC_LBLEN(6)
|
||||
| BR_HASHDESC_MD_PADDING
|
||||
| BR_HASHDESC_MD_PADDING_BE,
|
||||
(void (*)(const br_hash_class **))&br_sha256_init,
|
||||
(void (*)(const br_hash_class **,
|
||||
const void *, size_t))&br_sha256_update,
|
||||
(void (*)(const br_hash_class *const *, void *))&br_sha256_out,
|
||||
(uint64_t (*)(const br_hash_class *const *, void *))&br_sha256_state,
|
||||
(void (*)(const br_hash_class **, const void *, uint64_t))
|
||||
&br_sha256_set_state
|
||||
};
|
||||
|
||||
#endif /* HAVE_HAL_SHA256 && SOC_SHA_SUPPORT_RESUME */
|
||||
|
||||
/* ================================================================
|
||||
* SHA-384 (HAL path, no save/restore)
|
||||
* ================================================================ */
|
||||
#if HAVE_HAL_SHA384
|
||||
|
||||
static const uint64_t S384_IV_WORDS[8] = {
|
||||
0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL,
|
||||
0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL,
|
||||
0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
|
||||
0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
|
||||
};
|
||||
|
||||
void br_sha384_init(br_sha384_context *cc) {
|
||||
cc->vtable = &br_sha384_vtable;
|
||||
cc->count = 0;
|
||||
memset(cc->buf, 0, sizeof cc->buf);
|
||||
/* Internal state is LE; encode IV directly in LE form into cc->val */
|
||||
br_range_enc64le(cc->val, S384_IV_WORDS, 8);
|
||||
}
|
||||
|
||||
void br_sha384_update(br_sha384_context *cc, const void *data, size_t len) {
|
||||
if (!len) return;
|
||||
const uint8_t *src = (const uint8_t *)data;
|
||||
size_t used = (size_t)(cc->count & 127U);
|
||||
uint64_t prior_count = cc->count;
|
||||
cc->count += len;
|
||||
|
||||
if (used) {
|
||||
size_t take = 128 - used;
|
||||
if (take > len) take = len;
|
||||
memcpy(cc->buf + used, src, take);
|
||||
src += take;
|
||||
len -= take;
|
||||
used += take;
|
||||
if (used == 128) {
|
||||
uint64_t st_be[8];
|
||||
br_range_dec64le(st_be, 8, cc->val);
|
||||
br_range_enc64be(st_be, st_be, 8);
|
||||
SHA_ENTER();
|
||||
sha_ll_load(SHA2_512);
|
||||
sha_ll_write_digest(SHA2_512, st_be, 16);
|
||||
sha_ll_fill_text_block(cc->buf, 32);
|
||||
sha_ll_continue_block(SHA2_512);
|
||||
SHA_WAIT();
|
||||
sha_ll_read_digest(SHA2_512, st_be, 16);
|
||||
SHA_EXIT();
|
||||
br_range_dec64be(st_be, 8, st_be);
|
||||
br_range_enc64le(cc->val, st_be, 8);
|
||||
prior_count += 128;
|
||||
used = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (len >= 128) {
|
||||
uint64_t st_be[8];
|
||||
br_range_dec64le(st_be, 8, cc->val);
|
||||
br_range_enc64be(st_be, st_be, 8);
|
||||
bool first = (prior_count == 0);
|
||||
SHA_ENTER();
|
||||
sha_ll_load(SHA2_512);
|
||||
sha_ll_write_digest(SHA2_512, st_be, 16);
|
||||
while (len >= 128) {
|
||||
sha_ll_fill_text_block(src, 32);
|
||||
if (first) {
|
||||
sha_ll_start_block(SHA2_512);
|
||||
first = false;
|
||||
} else {
|
||||
sha_ll_continue_block(SHA2_512);
|
||||
}
|
||||
SHA_WAIT();
|
||||
src += 128;
|
||||
len -= 128;
|
||||
}
|
||||
sha_ll_read_digest(SHA2_512, st_be, 16);
|
||||
SHA_EXIT();
|
||||
br_range_dec64be(st_be, 8, st_be);
|
||||
br_range_enc64le(cc->val, st_be, 8);
|
||||
}
|
||||
|
||||
if (len) memcpy(cc->buf, src, len);
|
||||
}
|
||||
|
||||
void br_sha384_out(const br_sha384_context *cc, void *out) {
|
||||
br_sha384_context ctx = *cc;
|
||||
size_t used = (size_t)(ctx.count & 127U);
|
||||
uint64_t bit_hi = (uint64_t)(ctx.count >> 61);
|
||||
uint64_t bit_lo = (uint64_t)(ctx.count << 3);
|
||||
|
||||
ctx.buf[used++] = 0x80;
|
||||
if (used > 112) {
|
||||
memset(ctx.buf + used, 0, 128 - used);
|
||||
uint64_t st_be[8];
|
||||
br_range_dec64le(st_be, 8, ctx.val);
|
||||
br_range_enc64be(st_be, st_be, 8);
|
||||
SHA_ENTER();
|
||||
sha_ll_load(SHA2_512);
|
||||
sha_ll_write_digest(SHA2_512, st_be, 16);
|
||||
sha_ll_fill_text_block(ctx.buf, 32);
|
||||
sha_ll_continue_block(SHA2_512);
|
||||
SHA_WAIT();
|
||||
sha_ll_read_digest(SHA2_512, st_be, 16);
|
||||
SHA_EXIT();
|
||||
br_range_dec64be(st_be, 8, st_be);
|
||||
br_range_enc64le(ctx.val, st_be, 8);
|
||||
used = 0;
|
||||
}
|
||||
|
||||
memset(ctx.buf + used, 0, 112 - used);
|
||||
br_enc64be(ctx.buf + 112, bit_hi);
|
||||
br_enc64be(ctx.buf + 120, bit_lo);
|
||||
|
||||
uint64_t st_be2[8];
|
||||
br_range_dec64le(st_be2, 8, ctx.val);
|
||||
br_range_enc64be(st_be2, st_be2, 8);
|
||||
SHA_ENTER();
|
||||
sha_ll_load(SHA2_512);
|
||||
sha_ll_write_digest(SHA2_512, st_be2, 16);
|
||||
sha_ll_fill_text_block(ctx.buf, 32);
|
||||
sha_ll_continue_block(SHA2_512);
|
||||
SHA_WAIT();
|
||||
sha_ll_read_digest(SHA2_512, st_be2, 16);
|
||||
SHA_EXIT();
|
||||
|
||||
br_range_dec64be(st_be2, 8, st_be2);
|
||||
br_range_enc64be(out, st_be2, 6);
|
||||
}
|
||||
|
||||
uint64_t br_sha384_state(const br_sha384_context *cc, void *dst) {
|
||||
/* Export raw 64-byte LE midstate image exactly as stored */
|
||||
memcpy(dst, cc->val, 64);
|
||||
return cc->count;
|
||||
}
|
||||
|
||||
void br_sha384_set_state(br_sha384_context *cc, const void *src, uint64_t count) {
|
||||
if (!(cc->vtable == &br_sha384_vtable)) {
|
||||
cc->vtable = &br_sha384_vtable;
|
||||
}
|
||||
/* Import raw 64-byte LE midstate image exactly as provided */
|
||||
memcpy(cc->val, src, 64);
|
||||
cc->count = count;
|
||||
memset(cc->buf, 0, sizeof cc->buf);
|
||||
}
|
||||
|
||||
const br_hash_class br_sha384_vtable PROGMEM = {
|
||||
sizeof(br_sha384_context),
|
||||
BR_HASHDESC_ID(br_sha384_ID)
|
||||
| BR_HASHDESC_OUT(48)
|
||||
| BR_HASHDESC_STATE(64)
|
||||
| BR_HASHDESC_LBLEN(7)
|
||||
| BR_HASHDESC_MD_PADDING
|
||||
| BR_HASHDESC_MD_PADDING_BE
|
||||
| BR_HASHDESC_MD_PADDING_128,
|
||||
(void (*)(const br_hash_class **)) &br_sha384_init,
|
||||
(void (*)(const br_hash_class **, const void *, size_t)) &br_sha384_update,
|
||||
(void (*)(const br_hash_class *const *, void *)) &br_sha384_out,
|
||||
(uint64_t (*)(const br_hash_class *const *, void *)) &br_sha384_state,
|
||||
(void (*)(const br_hash_class **, const void *, uint64_t)) &br_sha384_set_state
|
||||
};
|
||||
|
||||
#endif /* HAVE_HAL_SHA384 */
|
||||
|
||||
/* ================================================================
|
||||
* SHA-512 (HAL path, no save/restore)
|
||||
* Uses SHA-384 update/state/set_state
|
||||
* ================================================================ */
|
||||
#if HAVE_HAL_SHA512
|
||||
|
||||
static const uint64_t S512_IV_WORDS[8] = {
|
||||
0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
|
||||
0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
|
||||
0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
|
||||
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
|
||||
};
|
||||
|
||||
void br_sha512_init(br_sha512_context *cc) {
|
||||
cc->vtable = &br_sha512_vtable;
|
||||
cc->count = 0;
|
||||
memset(cc->buf, 0, sizeof cc->buf);
|
||||
/* Internal state is LE; encode IV directly in LE form into cc->val */
|
||||
br_range_enc64le(cc->val, S512_IV_WORDS, 8);
|
||||
}
|
||||
|
||||
void br_sha512_out(const br_sha512_context *cc, void *out) {
|
||||
br_sha512_context ctx = *cc;
|
||||
size_t used = (size_t)(ctx.count & 127U);
|
||||
uint64_t bit_hi = (uint64_t)(ctx.count >> 61);
|
||||
uint64_t bit_lo = (uint64_t)(ctx.count << 3);
|
||||
|
||||
ctx.buf[used++] = 0x80;
|
||||
if (used > 112) {
|
||||
memset(ctx.buf + used, 0, 128 - used);
|
||||
uint64_t st_be[8];
|
||||
br_range_dec64le(st_be, 8, ctx.val);
|
||||
br_range_enc64be(st_be, st_be, 8);
|
||||
SHA_ENTER();
|
||||
sha_ll_load(SHA2_512);
|
||||
sha_ll_write_digest(SHA2_512, st_be, 16);
|
||||
sha_ll_fill_text_block(ctx.buf, 32);
|
||||
sha_ll_continue_block(SHA2_512);
|
||||
SHA_WAIT();
|
||||
sha_ll_read_digest(SHA2_512, st_be, 16);
|
||||
SHA_EXIT();
|
||||
br_range_dec64be(st_be, 8, st_be);
|
||||
br_range_enc64le(ctx.val, st_be, 8);
|
||||
used = 0;
|
||||
}
|
||||
|
||||
memset(ctx.buf + used, 0, 112 - used);
|
||||
br_enc64be(ctx.buf + 112, bit_hi);
|
||||
br_enc64be(ctx.buf + 120, bit_lo);
|
||||
|
||||
uint64_t st_be2[8];
|
||||
br_range_dec64le(st_be2, 8, ctx.val);
|
||||
br_range_enc64be(st_be2, st_be2, 8);
|
||||
SHA_ENTER();
|
||||
sha_ll_load(SHA2_512);
|
||||
sha_ll_write_digest(SHA2_512, st_be2, 16);
|
||||
sha_ll_fill_text_block(ctx.buf, 32);
|
||||
sha_ll_continue_block(SHA2_512);
|
||||
SHA_WAIT();
|
||||
sha_ll_read_digest(SHA2_512, st_be2, 16);
|
||||
SHA_EXIT();
|
||||
|
||||
/* Output digest in big‑endian bytes as BearSSL expects */
|
||||
br_range_dec64be(st_be2, 8, st_be2);
|
||||
br_range_enc64be(out, st_be2, 8);
|
||||
}
|
||||
|
||||
const br_hash_class br_sha512_vtable PROGMEM = {
|
||||
sizeof(br_sha512_context),
|
||||
BR_HASHDESC_ID(br_sha512_ID)
|
||||
| BR_HASHDESC_OUT(64)
|
||||
| BR_HASHDESC_STATE(64)
|
||||
| BR_HASHDESC_LBLEN(7)
|
||||
| BR_HASHDESC_MD_PADDING
|
||||
| BR_HASHDESC_MD_PADDING_BE
|
||||
| BR_HASHDESC_MD_PADDING_128,
|
||||
(void (*)(const br_hash_class **)) &br_sha512_init,
|
||||
(void (*)(const br_hash_class **, const void *, size_t)) &br_sha384_update, /* reuse SHA-384 update */
|
||||
(void (*)(const br_hash_class *const *, void *)) &br_sha512_out,
|
||||
(uint64_t (*)(const br_hash_class *const *, void *)) &br_sha512_state,
|
||||
(void (*)(const br_hash_class **, const void *, uint64_t)) &br_sha512_set_state
|
||||
};
|
||||
|
||||
#endif /* HAVE_HAL_SHA512 */
|
||||
|
||||
#else
|
||||
/* ===== ESP8266 - leave it unchanged ===== */
|
||||
#endif // SOC_SHA_SUPPORT_RESUME
|
||||
#endif // defined(ESP_PLATFORM) && !defined(ESP8266)
|
||||
#endif //USE_SHA_ROM
|
||||
@ -1,393 +0,0 @@
|
||||
/* _sha_rom_idf5x.c — BearSSL drop‑in with ESP32 ROM SHA acceleration
|
||||
*
|
||||
* ⚠ TEST‑ONLY IMPLEMENTATION — SERIALIZED VIA GLOBAL SPINLOCK ⚠
|
||||
*
|
||||
* Overview:
|
||||
* ---------
|
||||
* - Provides BearSSL hash functions backed by the ESP32 ROM SHA engine.
|
||||
* - Uses a single global ROM SHA_CTX instance.
|
||||
* - Access is serialized with a global portMUX spinlock.
|
||||
*
|
||||
* Concurrency Warning:
|
||||
* --------------------
|
||||
* - This locking only prevents simultaneous entry into the ROM SHA engine.
|
||||
* - It does NOT make multiple concurrent hash contexts safe.
|
||||
* - Interleaving operations from different contexts will corrupt state.
|
||||
* - Only one hash context may be active at any given time.
|
||||
*
|
||||
* Platform Notes:
|
||||
* ---------------
|
||||
* - ESP32 (ESP_PLATFORM): Uses ROM SHA acceleration as described above.
|
||||
* - ESP8266 / other targets: This translation unit compiles to nothing;
|
||||
* stock BearSSL symbols are provided instead.
|
||||
*
|
||||
* SHA‑256 Limitation on ESP32:
|
||||
* ----------------------------
|
||||
* - The ESP32 ROM SHA‑256 implementation shares internal state with the
|
||||
* hardware engine; without pause/resume support, state cannot be saved
|
||||
* and restored safely.
|
||||
* - In this “single global context” model, running SHA‑256 concurrently
|
||||
* or interleaving with other operations will corrupt the ROM state.
|
||||
* - Therefore, SHA‑256 acceleration is only enabled when
|
||||
* SOC_SHA_SUPPORT_RESUME is available; otherwise it is unsafe here.
|
||||
* - When unsupported, SHA‑256 silently falls back to BearSSL’s software
|
||||
* implementation at build time (callers see no behavioral change).
|
||||
*
|
||||
* Supported ROM Algorithms (if present in ROM):
|
||||
* ----------------------------------------------
|
||||
* • SHA‑1
|
||||
* • SHA‑224
|
||||
* • SHA‑256 (see limitation and fallback above)
|
||||
* • SHA‑384
|
||||
* • SHA‑512
|
||||
*/
|
||||
|
||||
#include "t_inner.h"
|
||||
|
||||
#if defined(USE_SHA_ROM)
|
||||
#if defined(ESP_PLATFORM) && !defined(ESP8266)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#if __has_include("soc/sha_caps.h")
|
||||
# include "soc/sha_caps.h"
|
||||
#elif __has_include("soc/soc_caps.h")
|
||||
# include "soc/soc_caps.h"
|
||||
#else
|
||||
# error "No SHA capability header found"
|
||||
#endif
|
||||
|
||||
#if __has_include("esp_rom_sha.h")
|
||||
# include "esp_rom_sha.h"
|
||||
#elif __has_include("rom/sha.h")
|
||||
# include "rom/sha.h"
|
||||
#else
|
||||
# error "No ROM SHA header found"
|
||||
#endif
|
||||
|
||||
#define HAVE_ROM_SHA1 (SOC_SHA_SUPPORT_SHA1)
|
||||
#define HAVE_ROM_SHA224 (SOC_SHA_SUPPORT_SHA224)
|
||||
#define HAVE_ROM_SHA256 (SOC_SHA_SUPPORT_SHA256)
|
||||
#define HAVE_ROM_SHA384 (SOC_SHA_SUPPORT_SHA384)
|
||||
#define HAVE_ROM_SHA512 (SOC_SHA_SUPPORT_SHA512)
|
||||
|
||||
#if defined(SOC_SHA_SUPPORT_RESUME)
|
||||
/* Newer chips: mode passed to init, update has no mode */
|
||||
#define ROM_SHA_ENABLE() ets_sha_enable()
|
||||
#define ROM_SHA_DISABLE() ets_sha_disable()
|
||||
#define ROM_SHA_INIT_MODE(ctx, mode) ets_sha_init((ctx), (mode))
|
||||
#define ROM_SHA_UPDATE_MODE(ctx, mode, d, l, last) \
|
||||
ets_sha_update((ctx), (const unsigned char*)(d), (uint32_t)(l), (last))
|
||||
#define ROM_SHA_FINISH_MODE(ctx, mode, out) ets_sha_finish((ctx), (unsigned char*)(out))
|
||||
#define ROM_SHA_FINALIZE_MODE(ctx, mode, out) \
|
||||
do { ROM_SHA_UPDATE_MODE((ctx), mode, NULL, 0, true); ROM_SHA_FINISH_MODE((ctx), mode, (out)); } while (0)
|
||||
|
||||
#else
|
||||
/* Old ESP32: mode passed to update/finish, init takes only ctx */
|
||||
#define ROM_SHA_ENABLE() ets_sha_enable()
|
||||
#define ROM_SHA_DISABLE() ets_sha_disable()
|
||||
#define ROM_SHA_INIT_MODE(ctx, mode) ets_sha_init((ctx))
|
||||
#define ROM_SHA_UPDATE_MODE(ctx, mode, d, l, last) \
|
||||
ets_sha_update((ctx), (mode), (const uint8_t*)(d), (size_t)((l) * 8))
|
||||
#define ROM_SHA_FINISH_MODE(ctx, mode, out) ets_sha_finish((ctx), (mode), (uint8_t*)(out))
|
||||
#define ROM_SHA_FINALIZE_MODE(ctx, mode, out) \
|
||||
do { ROM_SHA_UPDATE_MODE((ctx), mode, NULL, 0, true); ROM_SHA_FINISH_MODE((ctx), mode, (out)); } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
/* One global ROM context; accesses serialized across cores/tasks. */
|
||||
static SHA_CTX rom_ctx;
|
||||
static portMUX_TYPE s_sha_mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
#define SHA_ENTER() portENTER_CRITICAL(&s_sha_mux)
|
||||
#define SHA_EXIT() portEXIT_CRITICAL(&s_sha_mux)
|
||||
|
||||
/* ================================================================
|
||||
* SHA-1 (ROM path, no save/restore)
|
||||
* ================================================================ */
|
||||
#if HAVE_ROM_SHA1
|
||||
void br_sha1_init(br_sha1_context *cc) {
|
||||
SHA_ENTER();
|
||||
cc->vtable = &br_sha1_vtable;
|
||||
cc->count = 0;
|
||||
ROM_SHA_ENABLE();
|
||||
ROM_SHA_INIT_MODE(&rom_ctx, SHA1);
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
void br_sha1_update(br_sha1_context *cc, const void *data, size_t len) {
|
||||
if (!len) return;
|
||||
SHA_ENTER();
|
||||
ROM_SHA_UPDATE_MODE(&rom_ctx, SHA1, data, len, false);
|
||||
cc->count += len;
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
void br_sha1_out(const br_sha1_context *cc, void *out) {
|
||||
(void)cc;
|
||||
SHA_ENTER();
|
||||
ROM_SHA_FINALIZE_MODE(&rom_ctx, SHA1, out);
|
||||
ROM_SHA_INIT_MODE(&rom_ctx, SHA1);
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
const br_hash_class br_sha1_vtable PROGMEM = {
|
||||
sizeof(br_sha1_context),
|
||||
BR_HASHDESC_ID(br_sha1_ID)
|
||||
| BR_HASHDESC_OUT(20)
|
||||
| BR_HASHDESC_LBLEN(6)
|
||||
| BR_HASHDESC_MD_PADDING
|
||||
| BR_HASHDESC_MD_PADDING_BE,
|
||||
(void (*)(const br_hash_class **)) &br_sha1_init,
|
||||
(void (*)(const br_hash_class **, const void *, size_t)) &br_sha1_update,
|
||||
(void (*)(const br_hash_class *const *, void *)) &br_sha1_out,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
/* ================================================================
|
||||
* SHA-224 (ROM path, no save/restore)
|
||||
* ================================================================ */
|
||||
/* ================================================================
|
||||
* SHA-224 (ROM path, no save/restore)
|
||||
* ================================================================ */
|
||||
#if HAVE_ROM_SHA224
|
||||
void br_sha224_init(br_sha224_context *cc) {
|
||||
SHA_ENTER();
|
||||
cc->vtable = &br_sha224_vtable;
|
||||
cc->count = 0;
|
||||
ROM_SHA_ENABLE();
|
||||
ROM_SHA_INIT_MODE(&rom_ctx, SHA2_224);
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
void br_sha224_update(br_sha224_context *cc, const void *data, size_t len) {
|
||||
if (!len) return;
|
||||
SHA_ENTER();
|
||||
ROM_SHA_UPDATE_MODE(&rom_ctx, SHA2_224, data, len, false);
|
||||
cc->count += len;
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
void br_sha224_out(const br_sha224_context *cc, void *out) {
|
||||
(void)cc;
|
||||
uint8_t tmp[32];
|
||||
SHA_ENTER();
|
||||
ROM_SHA_FINALIZE_MODE(&rom_ctx, SHA2_224, tmp);
|
||||
memcpy(out, tmp, 28);
|
||||
ROM_SHA_INIT_MODE(&rom_ctx, SHA2_224);
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
const br_hash_class br_sha224_vtable PROGMEM = {
|
||||
sizeof(br_sha224_context),
|
||||
BR_HASHDESC_ID(br_sha224_ID)
|
||||
| BR_HASHDESC_OUT(28)
|
||||
| BR_HASHDESC_LBLEN(6)
|
||||
| BR_HASHDESC_MD_PADDING
|
||||
| BR_HASHDESC_MD_PADDING_BE,
|
||||
(void (*)(const br_hash_class **)) &br_sha224_init,
|
||||
(void (*)(const br_hash_class **, const void *, size_t)) &br_sha224_update,
|
||||
(void (*)(const br_hash_class *const *, void *)) &br_sha224_out,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
#endif /* HAVE_ROM_SHA224 */
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* SHA-256 with ROM acceleration + per-blob replay save/restore
|
||||
* ================================================================ */
|
||||
#if HAVE_ROM_SHA256 && defined(SOC_SHA_SUPPORT_RESUME)
|
||||
#undef br_sha256_init
|
||||
#undef br_sha256_update
|
||||
#undef br_sha256_out
|
||||
#undef br_sha256_state
|
||||
#undef br_sha256_set_state
|
||||
|
||||
#define S256_CAP 64
|
||||
|
||||
/* Capture buffer for current context */
|
||||
static struct {
|
||||
uint8_t buf[S256_CAP];
|
||||
uint8_t len;
|
||||
} s256_capture;
|
||||
|
||||
void br_sha256_init(br_sha256_context *cc)
|
||||
{
|
||||
SHA_ENTER();
|
||||
cc->vtable = &br_sha256_vtable;
|
||||
cc->count = 0;
|
||||
s256_capture.len = 0;
|
||||
ROM_SHA_ENABLE();
|
||||
ROM_SHA_INIT_MODE(&rom_ctx, SHA2_256);
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
void br_sha256_update(br_sha256_context *cc, const void *data, size_t len)
|
||||
{
|
||||
if (!len) return;
|
||||
const uint8_t *dp = (const uint8_t *)data;
|
||||
|
||||
SHA_ENTER();
|
||||
ROM_SHA_UPDATE_MODE(&rom_ctx, SHA2_256, dp, len, false);
|
||||
cc->count += len;
|
||||
|
||||
if (s256_capture.len < S256_CAP) {
|
||||
size_t want = S256_CAP - s256_capture.len;
|
||||
size_t take = (len < want) ? len : want;
|
||||
memcpy(s256_capture.buf + s256_capture.len, dp, take);
|
||||
s256_capture.len += (uint8_t)take;
|
||||
}
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
void br_sha256_out(const br_sha256_context *cc, void *out)
|
||||
{
|
||||
(void)cc;
|
||||
SHA_ENTER();
|
||||
ROM_SHA_FINALIZE_MODE(&rom_ctx, SHA2_256, out);
|
||||
ROM_SHA_INIT_MODE(&rom_ctx, SHA2_256);
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
uint64_t br_sha256_state(const br_sha256_context *cc, void *dst)
|
||||
{
|
||||
/* Store exactly the captured bytes in the blob */
|
||||
memset(dst, 0, S256_CAP);
|
||||
memcpy(dst, s256_capture.buf, s256_capture.len);
|
||||
return cc->count;
|
||||
}
|
||||
|
||||
void br_sha256_set_state(br_sha256_context *cc, const void *src, uint64_t count)
|
||||
{
|
||||
const uint8_t *sp = (const uint8_t *)src;
|
||||
|
||||
SHA_ENTER();
|
||||
ROM_SHA_INIT_MODE(&rom_ctx, SHA2_256);
|
||||
|
||||
if (count <= S256_CAP) {
|
||||
ROM_SHA_UPDATE_MODE(&rom_ctx, SHA2_256, sp, (size_t)count, false);
|
||||
cc->count = count;
|
||||
} else {
|
||||
cc->count = 0;
|
||||
s256_capture.len = 0;
|
||||
}
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
const br_hash_class br_sha256_vtable PROGMEM = {
|
||||
sizeof(br_sha256_context),
|
||||
BR_HASHDESC_ID(br_sha256_ID)
|
||||
| BR_HASHDESC_OUT(32)
|
||||
| BR_HASHDESC_STATE(S256_CAP) /* store full ipad/opad block */
|
||||
| BR_HASHDESC_LBLEN(6)
|
||||
| BR_HASHDESC_MD_PADDING
|
||||
| BR_HASHDESC_MD_PADDING_BE,
|
||||
(void (*)(const br_hash_class **)) &br_sha256_init,
|
||||
(void (*)(const br_hash_class **, const void *, size_t)) &br_sha256_update,
|
||||
(void (*)(const br_hash_class *const *, void *)) &br_sha256_out,
|
||||
(uint64_t (*)(const br_hash_class *const *, void *)) &br_sha256_state,
|
||||
(void (*)(const br_hash_class **, const void *, uint64_t)) &br_sha256_set_state
|
||||
};
|
||||
#endif /* HAVE_ROM_SHA256 */
|
||||
|
||||
/* ================================================================
|
||||
* SHA-384 (ROM path, no save/restore)
|
||||
* ================================================================ */
|
||||
#if HAVE_ROM_SHA384
|
||||
void br_sha384_init(br_sha384_context *cc) {
|
||||
SHA_ENTER();
|
||||
cc->vtable = &br_sha384_vtable;
|
||||
cc->count = 0;
|
||||
ROM_SHA_ENABLE();
|
||||
ROM_SHA_INIT_MODE(&rom_ctx, SHA2_384);
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
void br_sha384_update(br_sha384_context *cc, const void *data, size_t len) {
|
||||
if (!len) return;
|
||||
SHA_ENTER();
|
||||
ROM_SHA_UPDATE_MODE(&rom_ctx, SHA2_384, data, len, false);
|
||||
cc->count += len;
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
void br_sha384_out(const br_sha384_context *cc, void *out) {
|
||||
(void)cc;
|
||||
uint8_t tmp[64];
|
||||
SHA_ENTER();
|
||||
ROM_SHA_FINALIZE_MODE(&rom_ctx, SHA2_384, tmp);
|
||||
memcpy(out, tmp, 48);
|
||||
ROM_SHA_INIT_MODE(&rom_ctx, SHA2_384);
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
const br_hash_class br_sha384_vtable PROGMEM = {
|
||||
sizeof(br_sha384_context),
|
||||
BR_HASHDESC_ID(br_sha384_ID)
|
||||
| BR_HASHDESC_OUT(48)
|
||||
| BR_HASHDESC_LBLEN(7)
|
||||
| BR_HASHDESC_MD_PADDING
|
||||
| BR_HASHDESC_MD_PADDING_BE,
|
||||
(void (*)(const br_hash_class **)) &br_sha384_init,
|
||||
(void (*)(const br_hash_class **, const void *, size_t)) &br_sha384_update,
|
||||
(void (*)(const br_hash_class *const *, void *)) &br_sha384_out,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
/* ================================================================
|
||||
* SHA-512 (ROM path, no save/restore)
|
||||
* ================================================================ */
|
||||
#if HAVE_ROM_SHA512
|
||||
#undef br_sha512_update
|
||||
void br_sha512_init(br_sha512_context *cc) {
|
||||
SHA_ENTER();
|
||||
cc->vtable = &br_sha512_vtable;
|
||||
cc->count = 0;
|
||||
ROM_SHA_ENABLE();
|
||||
ROM_SHA_INIT_MODE(&rom_ctx, SHA2_512);
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
void br_sha512_update(br_sha512_context *cc, const void *data, size_t len) {
|
||||
if (!len) return;
|
||||
SHA_ENTER();
|
||||
ROM_SHA_UPDATE_MODE(&rom_ctx, SHA2_512, data, len, false);
|
||||
cc->count += len;
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
void br_sha512_out(const br_sha512_context *cc, void *out) {
|
||||
(void)cc;
|
||||
SHA_ENTER();
|
||||
ROM_SHA_FINALIZE_MODE(&rom_ctx, SHA2_512, out);
|
||||
ROM_SHA_INIT_MODE(&rom_ctx, SHA2_512);
|
||||
SHA_EXIT();
|
||||
}
|
||||
|
||||
const br_hash_class br_sha512_vtable PROGMEM = {
|
||||
sizeof(br_sha512_context),
|
||||
BR_HASHDESC_ID(br_sha512_ID)
|
||||
| BR_HASHDESC_OUT(64)
|
||||
| BR_HASHDESC_LBLEN(7)
|
||||
| BR_HASHDESC_MD_PADDING
|
||||
| BR_HASHDESC_MD_PADDING_BE,
|
||||
(void (*)(const br_hash_class **)) &br_sha512_init,
|
||||
(void (*)(const br_hash_class **, const void *, size_t)) &br_sha512_update,
|
||||
(void (*)(const br_hash_class *const *, void *)) &br_sha512_out,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* ===== ESP8266 - leave it unchanged ===== */
|
||||
#endif
|
||||
#endif //USE_SHA_ROM
|
||||
Loading…
Reference in New Issue
Block a user