Various Espressif HW crypto, SHA2, AES, MP updates.#6287
Various Espressif HW crypto, SHA2, AES, MP updates.#6287dgarske merged 8 commits intowolfSSL:masterfrom
Conversation
dgarske
left a comment
There was a problem hiding this comment.
Wow a ton of great work here. Please do a couple cleanups and then it should be ready to merge.
wolfcrypt/benchmark/benchmark.c
Outdated
| #include <xtensa/hal.h> /* reminder Espressif RISC-V not yet implemented */ | ||
| #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) | ||
| #include "driver/gptimer.h" | ||
| gptimer_handle_t esp_gptimer = NULL; |
There was a problem hiding this comment.
Please add static. These don't need to be available outside benchmark.
wolfcrypt/benchmark/benchmark.c
Outdated
|
|
||
| /* the currently observed clock counter value */ | ||
| #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) | ||
| word64 thisVal = 0;; |
There was a problem hiding this comment.
Might consider uint64_t to match gptimer_get_raw_count. Does it need ;;? Just one ; please.
There was a problem hiding this comment.
Ah yes, good catch.
|
|
||
| #if CONFIG_IDF_TARGET_ESP32S3 | ||
| if (mode_ == 1 || mode_ == 5 || mode_ == 7) { | ||
| ESP_LOGE(TAG, " unsupported mode"); |
There was a problem hiding this comment.
ah yes, I neglected to format the code copied from #5950
I've cleaned up this, and others too.
|
|
||
| ESP_LOGV(TAG, "enter esp_aes_bk"); | ||
| #if CONFIG_IDF_TARGET_ESP32S3 | ||
| /* See esp32 - s3 technical reference manual �19.4.3 Operation process |
There was a problem hiding this comment.
Copy paste has unicode here before 19.4.3. Please correct.
There was a problem hiding this comment.
unicode char removed
| DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0); // 0 => no interrupt; 1 => interrupt on completion. | ||
|
|
||
| /* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */ | ||
| uint32_t uOperandBits = max(max(Xs, Ys), Ms); |
There was a problem hiding this comment.
Same variable declarations at top.
There was a problem hiding this comment.
done. also renamed to simply OperandBits
| if (src->ctx.mode == ESP32_SHA_HW) { | ||
| /* Get a copy of the HW digest, but don't process it. */ | ||
| ESP_LOGI(TAG, "esp_sha384_ctx_copy esp_sha512_digest_process"); | ||
| ret = esp_sha512_digest_process(dst, 0); |
There was a problem hiding this comment.
Should below occur even if esp_sha512_digest_process returns a failure?
There was a problem hiding this comment.
esp_sha512_digest_process is currently hard-coded to return success, and remains so in this PR.
So, no: code should abort. This should be checked & I will revisit in the next update.
There was a problem hiding this comment.
@dgarske on this topic, which flow model to you prefer:
- mid-function
return <code> goto out
There are plenty of examples of each. I'm generally not a big fan of goto, but in the this case of exit, it makes sense.
if (something) {
goto out;
}
else {
return err;
}
...more code....
out:
return ret;
There was a problem hiding this comment.
Neither. The ideal is one exit and no goto's. Like this:
int rc;
rc = do_func()
if (rc == 0)
rc = do_func2()
if (rc == 0)
rc = do_func3()
return rc;
There was a problem hiding this comment.
ok, might as well completely resolve this topic: What about in the case of bad parameters?
What are your thoughts on return BAD_FUNC_ARG early on? Good practice for this extra exit, eh?
int coolthing(int* param)
{
int rc;
if (param == NULL) {
return BAD_FUNC_ARG;
}
rc = do_func()
if (rc == 0)
rc = do_func2()
if (rc == 0)
rc = do_func3()
return rc;
}
Or would you prefer to wrap the entire function in if (all good params) { } ?
| /* wait until the engine is available */ | ||
| wc_esp_wait_until_idle(); | ||
| #if CONFIG_IDF_TARGET_ESP32S3 | ||
| uint32_t *pMessageSource = (uint32_t *)data; |
There was a problem hiding this comment.
Variables declared at top please.
| wc_esp_wait_until_idle(); | ||
|
|
||
| /* read hash result into buffer & flip endiness */ | ||
| uint32_t* pHashDestination = (uint32_t*)hash; |
Thank you! I cannot take all of the credit, as @PaulMartinsen contributed some excellent ESP32-S3 Xtensa support in #5950. As I was not yet ready to create a PR to wolfssl, I manually merged most of his changes from that PR into my branch so that we could move forward on his project. This PR does not fully support ESP32-C3 yet. While making the changes here, I was reminded that although there are some changes for the RISC-V chipsets (ESP32-C3 and ESP32-C6), not all of the essential updates are here for optimal user experience. There are other interdependent changes in my ED25519_SHA2_fix branch, specifically the new CMakeLists.txt. PR for that coming soon.
I've completed some cleanups & will push updates soon after more testing. |
|
I've applied the code review suggestions, but build is still failing: and and I've looked over my update & cannot seem to find anything related to OpenSSL and |
|
Jenkins retest this please. |
wolfcrypt/src/sha.c
Outdated
| int ret = 0; | ||
|
|
||
| if (sha == NULL) | ||
| (void)devId; |
There was a problem hiding this comment.
There is already a (void)devId; below at line 588
There was a problem hiding this comment.
Removed duplicate
There was a problem hiding this comment.
Changes should be less intrusive by default. Please revert yours and leave the original else logic, which should cover 100% of the cases.
wolfcrypt/src/sha.c
Outdated
| else { | ||
| ret = esp_sha_digest_process(sha, 1); | ||
| } | ||
| #elif defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW) |
There was a problem hiding this comment.
This and the #else case are the same. Please combine and just document with a comment.
There was a problem hiding this comment.
Yes, they were the same on purpose as a placeholder for the -C3, but I agree that's probably not a great idea. Combined and comment added as requested.
wolfcrypt/src/sha.c
Outdated
| #ifdef WOLFSSL_SMALL_STACK | ||
| wc_Sha* tmpSha; | ||
| #else | ||
| wc_Sha tmpSha[sizeof(wc_Sha)]; |
There was a problem hiding this comment.
This is not valid. Please use wc_Sha tmpSha[1]; and do not duplicate code below.
There was a problem hiding this comment.
eek. I don't know what I was thinking that day! We certainly don't need a massive array of those, eh? Good catch, thank you. Fixed.
wolfcrypt/src/sha512.c
Outdated
| sha384->devCtx = NULL; | ||
| #endif | ||
| #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW) | ||
| if (sha384->ctx.mode != ESP32_SHA_INIT) { |
There was a problem hiding this comment.
Ah yes, there was no reason for that indent. Fixed.
wolfcrypt/src/sha.c
Outdated
| !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) | ||
| #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW) | ||
| if (sha->ctx.mode == ESP32_SHA_INIT) { | ||
| ESP_LOGV("sha", "wc_ShaUpdate try hardware"); |
There was a problem hiding this comment.
Should you have a log string declared at top and use it?
#ifdef WOLFSSL_ESPIDF
/* Define the ESP_LOGx(TAG, "" value for output messages here.
**
** Beware of possible conflict in test.c (that one now named TEST_TAG)
*/
static const char* TAG = "wc_sha";
#endif
wolfcrypt/src/sha512.c
Outdated
| #endif | ||
| #if defined(WOLFSSL_USE_ESP32WROOM32_CRYPT_HASH_HW) | ||
| if (sha384->ctx.mode != ESP32_SHA_INIT) { | ||
| ESP_LOGV("SHA384", "Set ctx mode from prior value: " |
There was a problem hiding this comment.
Same should there be a logging string? wc_sha512 in all cases. SHA2-384 is SHA2-512 truncated.
There was a problem hiding this comment.
Yes, updated.
This was the only ESP_LOG in the entire file. It was only an "interesting" case for SHA384 during debugging and only displays during verbose Espressif logging.
But you are correct: it should have been declared as a static const char* TAG
wolfcrypt/src/sha.c
Outdated
| int ret = 0; | ||
|
|
||
| if (sha == NULL) | ||
| (void)devId; |
There was a problem hiding this comment.
Changes should be less intrusive by default. Please revert yours and leave the original else logic, which should cover 100% of the cases.
|
|
||
| /* we'll keep track of our own locks. | ||
| ** actual enable/disable only occurs for ref_counts[periph] == 0 */ | ||
| byte isfirstblock; /* 0 is not first block; 1 = is first block */ |
There was a problem hiding this comment.
Consider bit-field byte isfirstblock:1;.
There was a problem hiding this comment.
Changing only isfirstblock:1 would not have much benefit alone, but I also changed lockDepth:7, reducing the struct size from 20 to 16 bytes.
There's an expected slight performance penalty: 19.946 MiB/s for SHA-512 using bit-length bytes, vs 20.020 MiB/s using integers:
Bit-sized:
SHA 21 MiB took 1.000 seconds, 21.484 MiB/s Cycles per byte = 7.10
SHA-256 21 MiB took 1.000 seconds, 20.825 MiB/s Cycles per byte = 7.32
SHA-512 20 MiB took 1.000 seconds, 19.946 MiB/s Cycles per byte = 7.65
Integers:
SHA 21 MiB took 1.000 seconds, 21.411 MiB/s Cycles per byte = 7.12
SHA-256 21 MiB took 1.000 seconds, 20.728 MiB/s Cycles per byte = 7.36
SHA-512 20 MiB took 1.000 seconds, 20.020 MiB/s Cycles per byte = 7.62
Do you think it's worthwhile to have a gate like WOLFSSL_SP_SMALL to make these optional, and of so... which would you use?
* various Espressif HW crypto, SHA2, AES, MP updates. * code review updates & cleanup * clean trailing whitespace * cleanup per code review * removed additional unused WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW * Code review updates; pack & order WC_ESP32SHA * clean up TAG text for Espressif ESP_LOG()
Description
This PR includes the bulk of the Espressif-specific wolfcrypt updates as related to HW acceleration, separated out into this PR from my ED25519_SHA2_fix branch.
Code is considerably more multi-thread RTOS friendly with a improved robust fallback to software when the HW engine is busy. There's a new breadcrumb
initializerattribute for keeping track of the address of thectxthat initialized a given instance: this is quite handy for detecting an unexpected copy of actxobject and in particular ensuring only one instance can have active hardware-accelerated encryption active at a given time.This is not the final update, but the as the changes have been accumulating for literally months, this is a good working version.
See #6234 for Espressif Roadmap and related updates.
This PR resolves:
Fixes zd# n/a
Testing
How did you test?
Run Espressif benchmark and wolfssl test apps.
optional linux test:
Checklist