This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 940e292cd102346494b4a5c4bb35c7d269da5c2c Author: Eren Terzioglu <[email protected]> AuthorDate: Fri Jun 26 20:37:59 2026 +0200 arch/risc-v/espressif: Add SHA512 and SHA224 support Add SHA512 and SHA224 support for supported devices Signed-off-by: Eren Terzioglu <[email protected]> --- arch/risc-v/src/common/espressif/esp_crypto.c | 154 +++++++++++++++++ arch/risc-v/src/common/espressif/esp_sha.c | 232 +++++++++++++++++++++++++- arch/risc-v/src/common/espressif/esp_sha.h | 79 +++++++++ 3 files changed, 462 insertions(+), 3 deletions(-) diff --git a/arch/risc-v/src/common/espressif/esp_crypto.c b/arch/risc-v/src/common/espressif/esp_crypto.c index 6dec8339af6..4e1527561fd 100644 --- a/arch/risc-v/src/common/espressif/esp_crypto.c +++ b/arch/risc-v/src/common/espressif/esp_crypto.c @@ -33,6 +33,7 @@ #include <nuttx/kmalloc.h> #include <nuttx/crypto/crypto.h> +#include "soc/soc_caps.h" #include "esp_sha.h" #include "esp_aes.h" @@ -46,6 +47,12 @@ static void sha1_final(uint8_t *out, void *ctx); static void sha256_init(void *ctx); static int sha256_update(void *ctx, const uint8_t *in, size_t len); static void sha256_final(uint8_t *out, void *ctx); +static void sha224_init(void *ctx); +#ifdef CONFIG_ARCH_CHIP_ESP32P4 +static void sha512_init(void *ctx); +static int sha512_update(void *ctx, const uint8_t *in, size_t len); +static void sha512_final(uint8_t *out, void *ctx); +#endif static int esp_freesession(uint64_t tid); /**************************************************************************** @@ -76,6 +83,40 @@ const struct auth_hash g_auth_hash_sha256_esp = sha256_final }; +const struct auth_hash g_auth_hash_sha224_esp = +{ + CRYPTO_SHA2_224, "SHA224", + 0, 28, 12, sizeof(struct esp_sha256_context_s), + 0, + sha224_init, NULL, NULL, + sha256_update, + sha256_final +}; + +#ifdef CONFIG_ARCH_CHIP_ESP32P4 + +const struct auth_hash g_auth_hash_sha512_esp = +{ + CRYPTO_SHA2_512, "SHA512", + 0, 64, 12, sizeof(struct esp_sha512_context_s), + 0, + sha512_init, NULL, NULL, + sha512_update, + sha512_final +}; + +const struct auth_hash g_auth_hash_hmac_sha512_esp = +{ + CRYPTO_SHA2_512_HMAC, "HMAC-SHA2-512", + 64, 64, 16, sizeof(struct esp_sha512_context_s), + HMAC_SHA2_512_BLOCK_LEN, + sha512_init, NULL, NULL, + sha512_update, + sha512_final +}; + +#endif /* CONFIG_ARCH_CHIP_ESP32P4 */ + const struct auth_hash g_auth_hash_hmac_sha1_esp = { CRYPTO_SHA1_HMAC, "HMAC-SHA1", @@ -206,6 +247,25 @@ static void sha256_init(void *ctx) esp_sha256_starts(ctx, false); } +/**************************************************************************** + * Name: sha224_init + * + * Description: + * Initializes a SHA-224 context. + * + * Input Parameters: + * ctx - The SHA-224 context to initialize + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void sha224_init(void *ctx) +{ + esp_sha256_starts(ctx, true); +} + /**************************************************************************** * Name: sha256_update * @@ -253,6 +313,75 @@ static void sha256_final(uint8_t *out, void *ctx) (unsigned char *)out); } +#ifdef CONFIG_ARCH_CHIP_ESP32P4 + +/**************************************************************************** + * Name: sha512_init + * + * Description: + * Initializes a SHA-512 context. + * + * Input Parameters: + * ctx - The SHA-512 context to initialize + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void sha512_init(void *ctx) +{ + esp_sha512_starts(ctx, false); +} + +/**************************************************************************** + * Name: sha512_update + * + * Description: + * Feeds an input buffer into an ongoing SHA-512 checksum calculation. + * + * Input Parameters: + * ctx - The SHA-512 context to use + * in - The buffer holding the input data + * len - The length of the input data in Bytes + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +static int sha512_update(void *ctx, const uint8_t *in, size_t len) +{ + return esp_sha512_update((struct esp_sha512_context_s *)ctx, + (const unsigned char *)in, + (size_t)len); +} + +/**************************************************************************** + * Name: sha512_final + * + * Description: + * Finishes the SHA-512 operation, and writes the result to + * the output buffer. + * + * Input Parameters: + * out - The SHA-512 checksum result + * ctx - The SHA-512 context to use + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void sha512_final(uint8_t *out, void *ctx) +{ + esp_sha512_finish((struct esp_sha512_context_s *)ctx, + (unsigned char *)out); +} + +#endif /* CONFIG_ARCH_CHIP_ESP32P4 */ + /**************************************************************************** * Name: hash * @@ -343,6 +472,9 @@ static int authcompute(struct cryptop *crp, struct cryptodesc *crd, { case CRYPTO_SHA1_HMAC: case CRYPTO_SHA2_256_HMAC: +#ifdef CONFIG_ARCH_CHIP_ESP32P4 + case CRYPTO_SHA2_512_HMAC: +#endif if (data->hw_octx == NULL) { return -EINVAL; @@ -464,6 +596,14 @@ static int esp_newsession(uint32_t *sid, struct cryptoini *cri) case CRYPTO_SHA2_256: axf = &g_auth_hash_sha256_esp; goto sha_common; + case CRYPTO_SHA2_224: + axf = &g_auth_hash_sha224_esp; + goto sha_common; +#ifdef CONFIG_ARCH_CHIP_ESP32P4 + case CRYPTO_SHA2_512: + axf = &g_auth_hash_sha512_esp; + goto sha_common; +#endif sha_common: data->hw_ictx = kmm_malloc(axf->ctxsize); if (data->hw_ictx == NULL) @@ -481,6 +621,11 @@ static int esp_newsession(uint32_t *sid, struct cryptoini *cri) case CRYPTO_SHA2_256_HMAC: axf = &g_auth_hash_hmac_sha256_esp; goto hmac_common; +#ifdef CONFIG_ARCH_CHIP_ESP32P4 + case CRYPTO_SHA2_512_HMAC: + axf = &g_auth_hash_hmac_sha512_esp; + goto hmac_common; +#endif hmac_common: data->hw_ictx = kmm_malloc(axf->ctxsize); if (data->hw_ictx == NULL) @@ -595,6 +740,7 @@ static int esp_freesession(uint64_t tid) { case CRYPTO_SHA1_HMAC: case CRYPTO_SHA2_256_HMAC: + case CRYPTO_SHA2_512_HMAC: axf = data->hw_axf; if (data->hw_ictx) { @@ -695,6 +841,8 @@ static int esp_process(struct cryptop *crp) #endif case CRYPTO_SHA1: case CRYPTO_SHA2_256: + case CRYPTO_SHA2_224: + case CRYPTO_SHA2_512: if ((crp->crp_etype = hash(crp, crd, data, crp->crp_buf)) != 0) { @@ -703,6 +851,7 @@ static int esp_process(struct cryptop *crp) break; case CRYPTO_SHA1_HMAC: case CRYPTO_SHA2_256_HMAC: + case CRYPTO_SHA2_512_HMAC: if ((crp->crp_etype = authcompute(crp, crd, data, crp->crp_buf)) != 0) { @@ -746,6 +895,11 @@ void hwcr_init(void) algs[CRYPTO_SHA2_256] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_SHA2_256_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; + algs[CRYPTO_SHA2_224] = CRYPTO_ALG_FLAG_SUPPORTED; +#ifdef CONFIG_ARCH_CHIP_ESP32P4 + algs[CRYPTO_SHA2_512] = CRYPTO_ALG_FLAG_SUPPORTED; + algs[CRYPTO_SHA2_512_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; +#endif #ifdef CONFIG_CRYPTO_AES algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_AES_CTR] = CRYPTO_ALG_FLAG_SUPPORTED; diff --git a/arch/risc-v/src/common/espressif/esp_sha.c b/arch/risc-v/src/common/espressif/esp_sha.c index 7ed9393c791..394f41cc7ba 100644 --- a/arch/risc-v/src/common/espressif/esp_sha.c +++ b/arch/risc-v/src/common/espressif/esp_sha.c @@ -65,8 +65,21 @@ (b)[(i) + 3] = (unsigned char) ((n)); \ } +#define PUT_UINT64_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \ + (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 7] = (unsigned char) ( (n) ); \ +} + #define SHA1_BLK_SIZE (20) #define SHA2_BLK_SIZE (32) +#define SHA224_BLK_SIZE (28) /**************************************************************************** * Private Data @@ -82,6 +95,22 @@ static const unsigned char esp_sha_padding[64] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +#ifdef CONFIG_ARCH_CHIP_ESP32P4 + +static const unsigned char sha512_padding[128] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +#endif /* CONFIG_ARCH_CHIP_ESP32P4 */ + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -107,7 +136,7 @@ static const unsigned char esp_sha_padding[64] = ****************************************************************************/ static int esp_sha_hash_block(enum esp_sha_type_e type, - bool *first_block, uint32_t *state, + bool *first_block, void *state, const uint8_t *data, size_t len, uint8_t *buf, size_t buf_len) { @@ -118,7 +147,16 @@ static int esp_sha_hash_block(enum esp_sha_type_e type, int i; int j; - blk_len = 64; + if (type < ESP_SHA3_384) + + { + blk_len = 64; + } + else + { + blk_len = 128; + } + blk_word_len = blk_len / 4; num_block = len / blk_len; @@ -551,7 +589,14 @@ int esp_sha256_finish(struct esp_sha256_context_s *ctx, return ret; } - memcpy(output, ctx->state, SHA2_BLK_SIZE); + if (ctx->mode == ESP_SHA2_224) + { + memcpy(output, ctx->state, SHA224_BLK_SIZE); + } + else + { + memcpy(output, ctx->state, SHA2_BLK_SIZE); + } return ret; } @@ -579,6 +624,187 @@ void esp_sha256_free(struct esp_sha256_context_s *ctx) memset(ctx, 0, sizeof(struct esp_sha256_context_s)); } +#ifdef CONFIG_ARCH_CHIP_ESP32P4 + +/**************************************************************************** + * Name: esp_sha512_starts + * + * Description: + * Starts a SHA-384 or SHA-512 checksum calculation. + * + * Input Parameters: + * ctx - The SHA-512 context to initialize + * is384 - Determines which function to use + * + * Returned Value: + * OK is returned on success. + * + ****************************************************************************/ + +int esp_sha512_starts(struct esp_sha512_context_s *ctx, bool is384) +{ + memset(ctx, 0, sizeof(struct esp_sha512_context_s)); + + if (is384) + { + ctx->mode = ESP_SHA3_384; + } + else + { + ctx->mode = ESP_SHA3_512; + } + + return OK; +} + +/**************************************************************************** + * Name: esp_sha512_update + * + * Description: + * Feeds an input buffer into an ongoing SHA-384 or SHA-512 + * checksum calculation. + * + * Input Parameters: + * ctx - The SHA-512 context to use + * input - The buffer holding the input data + * ilen - The length of the input data in Bytes + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +int esp_sha512_update(struct esp_sha512_context_s *ctx, + const unsigned char *input, + size_t ilen) +{ + int ret = 0; + size_t fill; + uint32_t left; + uint32_t len; + uint32_t local_len = 0; + + if (ilen == 0) + { + return OK; + } + + left = ctx->total[0] & 0x7f; + fill = 128 - left; + + ctx->total[0] += ilen; + + if (ctx->total[0] < ilen) + { + ctx->total[1]++; + } + + if (left && ilen >= fill) + { + memcpy((void *) (ctx->buffer + left), input, fill); + + input += fill; + ilen -= fill; + left = 0; + local_len = 128; + } + + len = (ilen / 128) * 128; + + if (len || local_len) + { + ret = nxmutex_lock(&g_sha_lock); + if (ret < 0) + { + return ret; + } + + sha_hal_set_mode(ctx->mode); + if (ctx->sha_state == ESP_SHA_STATE_INIT) + { + ctx->first_block = true; + ctx->sha_state = ESP_SHA_STATE_IN_PROCESS; + } + else if (ctx->sha_state == ESP_SHA_STATE_IN_PROCESS) + { + ctx->first_block = false; + sha_hal_write_digest(ctx->mode, ctx->state); + } + + ret = esp_sha_hash_block(ctx->mode, &ctx->first_block, ctx->state, + input, len, ctx->buffer, local_len); + ret |= nxmutex_unlock(&g_sha_lock); + + if (ret != 0) + { + return ret; + } + } + + if (ilen > 0) + { + memcpy((void *) (ctx->buffer + left), input + len, ilen - len); + } + + return OK; +} + +/**************************************************************************** + * Name: esp_sha512_finish + * + * Description: + * Finishes the SHA-384 or SHA-512 operation, and writes the result to + * the output buffer. + * + * Input Parameters: + * ctx - The SHA-512 context to use + * output - The SHA-512 checksum result + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +int esp_sha512_finish(struct esp_sha512_context_s *ctx, + unsigned char output[64]) +{ + int ret; + uint32_t last; + uint32_t padn; + uint64_t high; + uint64_t low; + unsigned char msglen[16]; + + high = (ctx->total[0] >> 61) | (ctx->total[1] << 3); + low = (ctx->total[0] << 3); + + PUT_UINT64_BE(high, msglen, 0); + PUT_UINT64_BE(low, msglen, 8); + + last = ctx->total[0] & 0x7f; + padn = (last < 112) ? (112 - last) : (240 - last); + + ret = esp_sha512_update(ctx, sha512_padding, padn); + if (ret != 0) + { + return ret; + } + + ret = esp_sha512_update(ctx, msglen, 16); + if (ret != 0) + { + return ret; + } + + memcpy(output, ctx->state, 64); + + return ret; +} + +#endif /* CONFIG_ARCH_CHIP_ESP32P4 */ + /**************************************************************************** * Name: esp_sha_init * diff --git a/arch/risc-v/src/common/espressif/esp_sha.h b/arch/risc-v/src/common/espressif/esp_sha.h index 40983564dcb..669cb252a6f 100644 --- a/arch/risc-v/src/common/espressif/esp_sha.h +++ b/arch/risc-v/src/common/espressif/esp_sha.h @@ -85,6 +85,22 @@ struct esp_sha256_context_s enum esp_sha_state_e sha_state; }; +#ifdef CONFIG_ARCH_CHIP_ESP32P4 + +/* SHA-512 context structure */ + +struct esp_sha512_context_s +{ + uint64_t total[2]; /* number of bytes processed */ + uint64_t state[8]; /* intermediate digest state */ + unsigned char buffer[128]; /* data block being processed */ + bool first_block; /* if first then true, else false */ + enum esp_sha_type_e mode; + enum esp_sha_state_e sha_state; +}; + +#endif /* CONFIG_ARCH_CHIP_ESP32P4 */ + /**************************************************************************** * Name: esp_sha_init * @@ -249,6 +265,69 @@ int esp_sha256_update(struct esp_sha256_context_s *ctx, int esp_sha256_finish(struct esp_sha256_context_s *ctx, unsigned char output[32]); +#ifdef CONFIG_ARCH_CHIP_ESP32P4 + +/**************************************************************************** + * Name: esp_sha512_starts + * + * Description: + * Starts a SHA-384 or SHA-512 checksum calculation. + * + * Input Parameters: + * ctx - The SHA-512 context to initialize + * is384 - Determines which function to use + * + * Returned Value: + * OK is returned on success. + * + ****************************************************************************/ + +int esp_sha512_starts(struct esp_sha512_context_s *ctx, bool is384); + +/**************************************************************************** + * Name: esp_sha512_update + * + * Description: + * Feeds an input buffer into an ongoing SHA-384 or SHA-512 + * checksum calculation. + * + * Input Parameters: + * ctx - The SHA-512 context to use + * input - The buffer holding the input data + * ilen - The length of the input data in Bytes + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +int esp_sha512_update(struct esp_sha512_context_s *ctx, + const unsigned char *input, + size_t ilen); + +/**************************************************************************** + * Name: esp_sha512_finish + * + * Description: + * Finishes the SHA-384 or SHA-512 operation, and writes the result to + * the output buffer. + * + * Input Parameters: + * ctx - The SHA-512 context to use + * output - The SHA-512 checksum result + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +int esp_sha512_finish(struct esp_sha512_context_s *ctx, + unsigned char output[64]); + +#endif /* CONFIG_ARCH_CHIP_ESP32P4 */ + #ifdef __cplusplus } #endif
