Skip to content

Commit

Permalink
isolate wolfssh signature problems debug
Browse files Browse the repository at this point in the history
  • Loading branch information
gojimmypi committed Feb 14, 2024
1 parent e9b0b22 commit 4a0429e
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 51 deletions.
89 changes: 63 additions & 26 deletions wolfcrypt/src/port/Espressif/esp32_sha.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,15 +228,17 @@ int esp_sha_init(WC_ESP32SHA* ctx, enum wc_HashType hash_type)
{
int ret = 0;

ESP_LOGI(TAG, "\n\nwcInit SHA256 for ctx %p\n\n", ctx);

if (ctx == NULL) {
ret = ESP_FAIL;
}
#if defined(WOLFSSL_STACK_CHECK)
else {
#if defined(WOLFSSL_STACK_CHECK)
ctx->first_word = 0;
ctx->last_word = 0;
}
#endif
}
CTX_STACK_CHECK(ctx);

#if defined(CONFIG_IDF_TARGET_ESP32) || \
Expand Down Expand Up @@ -360,6 +362,11 @@ int esp_sha_init_ctx(WC_ESP32SHA* ctx)

/* we'll keep track of which ctx initialized this */
ctx->initializer = ctx;
// TODO remove:
if ((word32)ctx == 0x3ffd1544) {
ESP_LOGI(TAG, "Breadcrumb 1: 0x3ffd1544");
}

#ifdef ESP_MONITOR_HW_TASK_LOCK
{
/* Keep track of which freeRTOS task actually locks HW */
Expand All @@ -369,14 +376,15 @@ int esp_sha_init_ctx(WC_ESP32SHA* ctx)
ctx->mode = ESP32_SHA_INIT;
}
else {
ESP_LOGI(TAG, "This esp_sha_init_ctx ctx mode: %d", ctx->mode);
/* things may be more interesting when previously initialized */
if (ctx->initializer == ctx) {
/* We're likely re-using an existing object previously initialized.
** There's of course a non-zero probability that garbage data is
** the same pointer value, but that's highly unlikely; We'd need
** to discard, then re-init to same memory location for a matching
** initializer. */
ESP_LOGV(TAG, "re-using existing WC_ESP32SHA ctx");
ESP_LOGI(TAG, "re-using existing WC_ESP32SHA ctx %p", ctx);

/* we should never have an unexpected mode in a known ctx */
switch (ctx->mode) {
Expand All @@ -391,6 +399,7 @@ int esp_sha_init_ctx(WC_ESP32SHA* ctx)
ESP_LOGW(TAG, "Warning: unable to unlock ctx mutex ");
}
#else
/* Here we assume the locking task also does unlocking. */
esp_sha_hw_unlock(ctx);
#endif
ctx->mode = ESP32_SHA_INIT;
Expand Down Expand Up @@ -424,17 +433,30 @@ int esp_sha_init_ctx(WC_ESP32SHA* ctx)
** May need to unlock HW, below. */
} /* ctx->initializer == ctx */
else {
// TODO remove:
if ((word32)ctx == 0x3ffd1544) {
ESP_LOGI(TAG, "Breadcrumb 2: 0x3ffd1544");
}
if ((ctx->initializer >= (void*)0x3ff00000) &&
(ctx->initializer <= (void*)0x3ffFFFFF)) {
ESP_LOGW(TAG, "ctx initializer overwrite! from %0x to %0x",
(word32)ctx->initializer,
(word32)ctx
);
ESP_LOGI(TAG, "This ctx mode: %d", ctx->mode);
}
else {
ESP_LOGW(TAG, "ctx initializer overwrite! from garbage to %0x",
(word32)ctx
);
}
/* We may end up here with either dirty memory
** or copied SHA ctx.
**
** Any copy function should have already set mode = ESP32_SHA_INIT.
**
** In either case, initialize: */
ctx->initializer = ctx; /* set a new address */
ESP_LOGW(TAG, "ctx initializer overwrite! from %0x to %0x",
(word32)ctx->initializer,
(word32)ctx
);
if (ctx->mode != ESP32_SHA_INIT) {
ESP_LOGW(TAG, "Warning: SHA CTX not in init mode as expected");
ctx->mode = ESP32_SHA_INIT;
Expand Down Expand Up @@ -1089,6 +1111,10 @@ int esp_sha_set_stray(WC_ESP32SHA* ctx)
return ret;
}

int esp_sha_hw_in_use()
{
return InUse;
}
/*
** return HW lock owner, otherwise zero if not locked.
**
Expand All @@ -1100,7 +1126,7 @@ int esp_sha_hw_islocked(WC_ESP32SHA* ctx)
int ret = 0;
CTX_STACK_CHECK(ctx);

#ifdef WOLFSSL_DEBUG_MUTEX
#ifdef WOLFSSL_DEBUG_MUTEX_disabled
taskENTER_CRITICAL(&sha_crit_sect);
{
ret = (int)mutex_ctx_owner;
Expand Down Expand Up @@ -1146,7 +1172,7 @@ int esp_sha_hw_islocked(WC_ESP32SHA* ctx)

/*
* The HW is typically unlocked when the SHA hash wc_Sha[nn]Final() is called.
* However, in the case of TS connections, the in progress hash may at times be
* However, in the case of TLS connections the in-progress hash may at times be
* abandoned. Thus this function should be called at free time. See internal.c
*/
int esp_sha_release_unfinished_lock(WC_ESP32SHA* ctx)
Expand All @@ -1156,9 +1182,10 @@ int esp_sha_release_unfinished_lock(WC_ESP32SHA* ctx)

ret = esp_sha_hw_islocked(ctx); /* get the owner of the current lock */
if (ret == 0) {
/* no lock */
ESP_LOGI(TAG, "No unfinished lock to clean up for ctx %p.", ctx);
}
else {
ESP_LOGI(TAG, "Unfinished lock clean up: %p.", ctx);
if (ret == (int)ctx) {
/* found a match for this object */
if (ret == (int)(ctx->initializer)) {
Expand Down Expand Up @@ -1194,6 +1221,10 @@ int esp_sha_release_unfinished_lock(WC_ESP32SHA* ctx)
}
}
CTX_STACK_CHECK(ctx);
// ctx->mode = ESP32_SHA_SW;
if (ctx->mode != ESP32_SHA_INIT) {
ESP_LOGW(TAG, "esp_sha_release_unfinished_lock mode = %d", ctx->mode);
}
return ret;
}

Expand Down Expand Up @@ -1235,9 +1266,10 @@ int esp_sha_try_hw_lock(WC_ESP32SHA* ctx)
if (!InUse) {
ctx->mode = ESP32_SHA_HW;
InUse = 1;
ESP_LOGW(TAG, "\n\nHW in use\n\n"); ret = 0;
}
else {
ctx->mode = ESP32_SHA_SW;
ctx->mode = ESP32_SHA_SW; ret = 1;
}
}
else {
Expand Down Expand Up @@ -1476,32 +1508,36 @@ int esp_sha_hw_unlock(WC_ESP32SHA* ctx)
ESP_LOGV(TAG, "enter esp_sha_hw_unlock");
#endif

#if defined(CONFIG_IDF_TARGET_ESP32C2) || \
defined(CONFIG_IDF_TARGET_ESP8684) || \
defined(CONFIG_IDF_TARGET_ESP32C3) || \
defined(CONFIG_IDF_TARGET_ESP32C6)
ets_sha_disable(); /* disable also resets active, ongoing hash */
ESP_LOGV(TAG, "ets_sha_disable in esp_sha_hw_unlock()");
#else
/* Disable AES hardware */
// TODO Note: Jim, is there any cost associated with enable/disable hardware here? This seems like
// a power saving feature that could be handled at a different level than per-calculation.
periph_module_disable(PERIPH_SHA_MODULE);
#endif
/* we'll keep track of our lock depth.
* in case of unexpected results, all the periph_module_disable() calls
* and periph_module_disable() need to be unwound.
*
* see ref_counts[periph] in file: periph_ctrl.c */
#ifdef WOLFSSL_ESP32_HW_LOCK_DEBUG
/* TODO ESP_LOG */
printf("2) esp_sha_hw_unlock Lock depth @ %d = %d for WC_ESP32SHA @ %0x\n",
__LINE__, ctx->lockDepth, (unsigned)ctx);
printf("2) esp_sha_hw_unlock Lock depth @ %d = %d for WC_ESP32SHA ctx @ %p\n",
__LINE__, ctx->lockDepth, ctx);
#endif


if (ctx->lockDepth > 0) {
#if defined(CONFIG_IDF_TARGET_ESP32C2) || \
defined(CONFIG_IDF_TARGET_ESP8684) || \
defined(CONFIG_IDF_TARGET_ESP32C3) || \
defined(CONFIG_IDF_TARGET_ESP32C6)
ets_sha_disable(); /* disable also resets active, ongoing hash */
ESP_LOGV(TAG, "ets_sha_disable in esp_sha_hw_unlock()");
#else
/* Disable AES hardware */
// TODO Note: Jim, is there any cost associated with enable/disable hardware here? This seems like
// a power saving feature that could be handled at a different level than per-calculation.
ESP_LOGI(TAG, ">> Disable SHA module ctx %p; for ctx->initializer %p", ctx, ctx->initializer);
periph_module_disable(PERIPH_SHA_MODULE);
#endif
ctx->lockDepth--;
}
else {
ESP_LOGI(TAG, ">> Disable SHA module skipped for %p", ctx->initializer);
ctx->lockDepth = 0;
}

Expand All @@ -1513,7 +1549,8 @@ int esp_sha_hw_unlock(WC_ESP32SHA* ctx)
if (0 == ctx->lockDepth) // should we only unlock if depth is 0?
{
#if defined(SINGLE_THREADED)
InUse = 0;
ESP_LOGW(TAG, "\n\nHW released, not in use\n\n");
InUse = 0;
#else
/* unlock HW engine for next use */
#ifdef WOLFSSL_ESP32_HW_LOCK_DEBUG
Expand Down
64 changes: 61 additions & 3 deletions wolfcrypt/src/random.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ This library contains implementation for the random number generator.
#include <config.h>
#endif

// TODO Remove:
#define TAG "rng"
#include <esp_log.h>


#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#if defined(DEBUG_WOLFSSL)
Expand Down Expand Up @@ -361,8 +366,10 @@ static int Hash_df(DRBG_internal* drbg, byte* out, word32 outSz, byte type,
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
#else
ESP_LOGI(TAG, "Sha256 init");
ret = wc_InitSha256(sha);
#endif
// not this one sha->ctx.mode = ESP32_SHA_SW;
#endif
if (ret != 0)
break;
#endif
Expand All @@ -386,6 +393,8 @@ static int Hash_df(DRBG_internal* drbg, byte* out, word32 outSz, byte type,
if (ret == 0)
ret = wc_Sha256Final(sha, digest);


ESP_LOGI(TAG, "RNG Sha256 final");
#ifndef WOLFSSL_SMALL_STACK_CACHE
wc_Sha256Free(sha);
#endif
Expand Down Expand Up @@ -525,17 +534,42 @@ static int Hash_gen(DRBG_internal* drbg, byte* out, word32 outSz, const byte* V)

XMEMCPY(data, V, DRBG_SEED_LEN);
for (i = 0; i < len; i++) {
ESP_LOGI(TAG, "RNG Sha256 init 2");

#ifndef WOLFSSL_SMALL_STACK_CACHE
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
#else
int this_force_sw = 0;
// if (esp_sha_hw_in_use()) {
// ESP_LOGW(TAG, "\n\nHW In use!");
// this_force_sw = 1;
// }
ret = wc_InitSha256(sha);
if (ret != 0) {
ESP_LOGE(TAG, "wc_InitSha256 failed!");
}
if (this_force_sw) {
sha->ctx.mode = ESP32_SHA_SW; /* Hash_gen probably this one */
force_sw++;
}
#endif
if (ret == 0)
#endif
ret = wc_Sha256Update(sha, data, DRBG_SEED_LEN);
if (ret != 0) {
ESP_LOGE(TAG, "wc_Sha256Update failed!");
}

if (ret == 0)
ret = wc_Sha256Final(sha, digest);

if (ret != 0) {
ESP_LOGE(TAG, "wc_Sha256Final failed!");
}

ESP_LOGI(TAG, "RNG Sha256 final 2");

#ifndef WOLFSSL_SMALL_STACK_CACHE
wc_Sha256Free(sha);
#endif
Expand Down Expand Up @@ -629,15 +663,39 @@ static int Hash_DRBG_Generate(DRBG_internal* drbg, byte* out, word32 outSz)
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)
ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
#else
ESP_LOGI(TAG, "RNG Sha256 init 3");
ret = wc_InitSha256(sha);
if (ret != 0) {
ESP_LOGE(TAG, "wc_InitSha256 failed!");
}
if (force_sw) {
sha->ctx.mode = ESP32_SHA_SW; /* Hash_DRBG_Generate probably this one */
force_sw++;
}

#endif
if (ret == 0)
#endif
ret = wc_Sha256Update(sha, &type, sizeof(type));
if (ret == 0)
if (ret != 0) {
ESP_LOGE(TAG, "wc_Sha256Update failed!");
}

if (ret == 0) {
ret = wc_Sha256Update(sha, drbg->V, sizeof(drbg->V));
if (ret == 0)
}
else {
ESP_LOGE(TAG, "wc_Sha256Update failed!");
}

if (ret == 0) {
ret = wc_Sha256Final(sha, digest);
}
else {
ESP_LOGE(TAG, "wc_Sha256Final failed!");
}

ESP_LOGI(TAG, "RNG Sha256 final 3");

#ifndef WOLFSSL_SMALL_STACK_CACHE
wc_Sha256Free(sha);
Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/src/sha.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
#ifdef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
if (sha->ctx.mode != ESP32_SHA_INIT) {
/* it may be interesting to see old values during debugging */
ESP_LOGV(TAG, "Set ctx mode from prior value: %d", sha->ctx.mode);
ESP_LOGV(TAG, "Set sha ctx mode to ESP32_SHA_INIT from prior value: %d", sha->ctx.mode);
}
/* We know this is a fresh, uninitialized item, so set to INIT */
sha->ctx.mode = ESP32_SHA_INIT;
Expand Down
Loading

0 comments on commit 4a0429e

Please sign in to comment.