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

Reply via email to