-
Notifications
You must be signed in to change notification settings - Fork 820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Various Espressif HW crypto, SHA2, AES, MP updates. #6287
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add static
. These don't need to be available outside benchmark.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. Done.
wolfcrypt/benchmark/benchmark.c
Outdated
@@ -1006,8 +1020,13 @@ static const char* bench_desc_words[][15] = { | |||
/* reminder: unsigned long long max = 18,446,744,073,709,551,615 */ | |||
|
|||
/* 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might consider uint64_t
to match gptimer_get_raw_count
. Does it need ;;
? Just one ;
please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check indents here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah yes, I neglected to format the code copied from #5950
I've cleaned up this, and others too.
@@ -164,7 +185,27 @@ static void esp_aes_bk(const byte* in, byte* out) | |||
#endif | |||
|
|||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copy paste has unicode here before 19.4.3. Please correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same variable declarations at top.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should below occur even if esp_sha512_digest_process
returns a failure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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) { }
?
wc_esp_wait_until_idle(); | ||
#if CONFIG_IDF_TARGET_ESP32S3 | ||
uint32_t *pMessageSource = (uint32_t *)data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Variables declared at top please.
wc_esp_wait_until_idle(); | ||
|
||
/* read hash result into buffer & flip endiness */ | ||
uint32_t* pHashDestination = (uint32_t*)hash; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
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 wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) | ||
{ | ||
int ret = 0; | ||
|
||
if (sha == NULL) | ||
(void)devId; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is already a (void)devId;
below at line 588
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed duplicate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
@@ -812,6 +864,9 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash) | |||
else { | |||
ret = esp_sha_digest_process(sha, 1); | |||
} | |||
#elif defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and the #else case
are the same. Please combine and just document with a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not valid. Please use wc_Sha tmpSha[1];
and do not duplicate code below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
@@ -1426,10 +1456,19 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) | |||
sha384->devId = devId; | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check indent here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, there was no reason for that indent. Fixed.
wolfcrypt/src/sha.c
Outdated
if (sha->ctx.mode == ESP32_SHA_INIT) { | ||
ESP_LOGV("sha", "wc_ShaUpdate try hardware"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. updated.
wolfcrypt/src/sha512.c
Outdated
@@ -1426,10 +1456,19 @@ int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) | |||
sha384->devId = devId; | |||
sha384->devCtx = NULL; | |||
#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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) | ||
{ | ||
int ret = 0; | ||
|
||
if (sha == NULL) | ||
(void)devId; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider bit-field byte isfirstblock:1;
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
initializer
attribute for keeping track of the address of thectx
that initialized a given instance: this is quite handy for detecting an unexpected copy of actx
object 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