This is an automated email from the ASF dual-hosted git repository.

archer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 2cb14c55f0 xtensa/esp32s3: Support reading encrypted partitions
2cb14c55f0 is described below

commit 2cb14c55f03e8bc8c3fc1f011ef164db1c3ff16c
Author: chen...@espressif.com <chen...@espressif.com>
AuthorDate: Fri Dec 15 20:49:16 2023 +0800

    xtensa/esp32s3: Support reading encrypted partitions
    
    Signed-off-by: chen...@espressif.com <chen...@espressif.com>
---
 arch/xtensa/src/esp32s3/esp32s3_partition.c | 98 ++++++++++++++++++++++-------
 arch/xtensa/src/esp32s3/esp32s3_partition.h | 13 ++++
 arch/xtensa/src/esp32s3/esp32s3_spiflash.c  | 38 +++++++++++
 arch/xtensa/src/esp32s3/esp32s3_spiflash.h  | 16 +++++
 4 files changed, 143 insertions(+), 22 deletions(-)

diff --git a/arch/xtensa/src/esp32s3/esp32s3_partition.c 
b/arch/xtensa/src/esp32s3/esp32s3_partition.c
index 3a2e254ab4..857f588021 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_partition.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_partition.c
@@ -32,6 +32,8 @@
 #include <nuttx/kmalloc.h>
 
 #include "esp32s3_spiflash_mtd.h"
+#include "esp32s3_partition.h"
+#include "esp32s3_spiflash.h"
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -70,6 +72,10 @@
 
 #define PARTITION_MOUNT_POINT CONFIG_ESP32S3_PARTITION_MOUNTPT
 
+/* Partition encrypted flag */
+
+#define PARTITION_FLAG_ENCRYPTED          (1 << 0)
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -162,9 +168,11 @@ struct mtd_dev_priv_s
   uint8_t  type;                        /* Partition type */
   uint8_t  subtype;                     /* Partition sub-type */
   uint32_t flags;                       /* Partition flags */
-
+  uint32_t offset;                      /* Partition offset in SPI Flash */
+  uint32_t size;                        /* Partition size in SPI Flash */
   struct mtd_dev_s  *ll_mtd;            /* Low-level MTD data */
   struct mtd_dev_s  *part_mtd;          /* Partition MTD data */
+  struct mtd_geometry_s   geo;          /* Partition geometry information */
 };
 
 /* OTA data entry */
@@ -621,8 +629,11 @@ int esp32s3_partition_init(void)
   int i;
   struct partition_info_priv_s *info;
   uint8_t *pbuf;
+  bool encrypt;
+  uint32_t flags;
   struct mtd_dev_s *mtd;
-  struct mtd_dev_s *mtd_part;
+  struct mtd_dev_s *mtd_ll;
+  struct mtd_dev_s *mtd_encrypt;
   struct mtd_geometry_s geo;
   struct mtd_dev_priv_s *mtd_priv;
   int ret = 0;
@@ -632,7 +643,7 @@ int esp32s3_partition_init(void)
   char path[PARTITION_LABEL_LEN + sizeof(PARTITION_MOUNT_POINT)];
 
   pbuf = kmm_malloc(PARTITION_MAX_SIZE);
-  if (pbuf == NULL)
+  if (!pbuf)
     {
       ferr("ERROR: Failed to allocate %d byte\n", PARTITION_MAX_SIZE);
       ret = -ENOMEM;
@@ -640,22 +651,27 @@ int esp32s3_partition_init(void)
     }
 
   mtd = esp32s3_spiflash_mtd();
-  if (mtd == NULL)
+  if (!mtd)
     {
       ferr("ERROR: Failed to get SPI flash MTD\n");
-      ret = -EIO;
+      ret = -ENOSYS;
       goto errout_with_mtd;
     }
 
-  ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)&geo);
-  if (ret < 0)
+  mtd_encrypt = esp32s3_spiflash_encrypt_mtd();
+  if (!mtd_encrypt)
     {
-      ferr("ERROR: Failed to get info from MTD\n");
-      ret = -EIO;
+      ferr("ERROR: Failed to get SPI flash encrypted MTD\n");
+      ret = -ENOSYS;
       goto errout_with_mtd;
     }
 
-  ret = MTD_READ(mtd, PARTITION_TABLE_OFFSET, PARTITION_MAX_SIZE, pbuf);
+  /* Even without SPI Flash encryption, we can also use encrypted
+   * MTD to read no-encrypted data.
+   */
+
+  ret = MTD_READ(mtd_encrypt, PARTITION_TABLE_OFFSET,
+                 PARTITION_MAX_SIZE, pbuf);
   if (ret != PARTITION_MAX_SIZE)
     {
       ferr("ERROR: Failed to get read data from MTD\n");
@@ -664,7 +680,7 @@ int esp32s3_partition_init(void)
     }
 
   info = (struct partition_info_priv_s *)pbuf;
-
+  encrypt = esp32s3_flash_encryption_enabled();
   for (i = 0; i < num; i++)
     {
       if (info->magic != PARTITION_MAGIC)
@@ -674,6 +690,23 @@ int esp32s3_partition_init(void)
 
       strlcpy(label, (char *)info->label, sizeof(label));
       snprintf(path, sizeof(path), "%s%s", path_base, label);
+      mtd_ll = mtd;
+
+      /* If SPI Flash encryption is enable, "APP", "OTA data" and "NVS keys"
+       * are force to set as encryption partition.
+       */
+
+      flags = info->flags;
+      if (encrypt)
+        {
+          if ((info->type == PARTITION_TYPE_DATA &&
+              info->subtype == PARTITION_SUBTYPE_DATA_OTA) ||
+              (info->type == PARTITION_TYPE_DATA &&
+              info->subtype == PARTITION_SUBTYPE_DATA_NVS_KEYS))
+            {
+              flags |= PARTITION_FLAG_ENCRYPTED;
+            }
+        }
 
       finfo("INFO: [label]:   %s\n", label);
       finfo("INFO: [type]:    %d\n", info->type);
@@ -682,17 +715,41 @@ int esp32s3_partition_init(void)
       finfo("INFO: [size]:    0x%08" PRIx32 "\n", info->size);
       finfo("INFO: [flags]:   0x%08" PRIx32 "\n", info->flags);
       finfo("INFO: [mount]:   %s\n", path);
+      if (flags & PARTITION_FLAG_ENCRYPTED)
+        {
+          mtd_ll = mtd_encrypt;
+          finfo("INFO: [encrypted]\n\n");
+        }
+      else
+        {
+          mtd_ll = mtd;
+          finfo("INFO: [no-encrypted]\n\n");
+        }
+
+      ret = MTD_IOCTL(mtd_ll, MTDIOC_GEOMETRY, (unsigned long)&geo);
+      if (ret < 0)
+        {
+          ferr("ERROR: Failed to get info from MTD\n");
+          goto errout_with_mtd;
+        }
 
       mtd_priv = kmm_malloc(sizeof(struct mtd_dev_priv_s));
       if (!mtd_priv)
         {
           ferr("ERROR: Failed to allocate %d byte\n",
                sizeof(struct mtd_dev_priv_s));
-          ret = -1;
+          ret = -ENOMEM;
           goto errout_with_mtd;
         }
 
-      mtd_priv->ll_mtd = mtd;
+      mtd_priv->offset  = info->offset;
+      mtd_priv->size    = info->size;
+      mtd_priv->type    = info->type;
+      mtd_priv->subtype = info->subtype;
+      mtd_priv->flags   = flags;
+      mtd_priv->ll_mtd  = mtd_ll;
+      memcpy(&mtd_priv->geo, &geo, sizeof(geo));
+
       mtd_priv->mtd.bread  = esp32s3_part_bread;
       mtd_priv->mtd.bwrite = esp32s3_part_bwrite;
       mtd_priv->mtd.erase  = esp32s3_part_erase;
@@ -701,25 +758,22 @@ int esp32s3_partition_init(void)
       mtd_priv->mtd.write  = esp32s3_part_write;
       mtd_priv->mtd.name   = label;
 
-      mtd_part = mtd_partition(&mtd_priv->mtd,
-                               info->offset / geo.blocksize,
-                               info->size / geo.blocksize);
-      if (!mtd_part)
+      mtd_priv->part_mtd = mtd_partition(&mtd_priv->mtd,
+                                         info->offset / geo.blocksize,
+                                         info->size / geo.blocksize);
+      if (!mtd_priv->part_mtd)
         {
           ferr("ERROR: Failed to create MTD partition\n");
           kmm_free(mtd_priv);
-          ret = -1;
+          ret = -ENOSPC;
           goto errout_with_mtd;
         }
 
-      mtd_priv->part_mtd = mtd_part;
-
-      ret = register_mtddriver(path, mtd_part, 0777, NULL);
+      ret = register_mtddriver(path, mtd_priv->part_mtd, 0777, NULL);
       if (ret < 0)
         {
           ferr("ERROR: Failed to register MTD @ %s\n", path);
           kmm_free(mtd_priv);
-          ret = -1;
           goto errout_with_mtd;
         }
 
diff --git a/arch/xtensa/src/esp32s3/esp32s3_partition.h 
b/arch/xtensa/src/esp32s3/esp32s3_partition.h
index 50b614fbc6..25d561eb35 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_partition.h
+++ b/arch/xtensa/src/esp32s3/esp32s3_partition.h
@@ -42,6 +42,19 @@ extern "C"
 #define EXTERN extern
 #endif
 
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Partition DATA type and subtype */
+
+#define PARTITION_TYPE_DATA               (0x01)
+#define PARTITION_SUBTYPE_DATA_OTA        (0x00)
+#define PARTITION_SUBTYPE_DATA_RF         (0x01)
+#define PARTITION_SUBTYPE_DATA_WIFI       (0x02)
+#define PARTITION_SUBTYPE_DATA_NVS_KEYS   (0x04)
+#define PARTITION_SUBTYPE_DATA_EFUSE_EM   (0x05)
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiflash.c 
b/arch/xtensa/src/esp32s3/esp32s3_spiflash.c
index 515ccaecdb..87297483c6 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_spiflash.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_spiflash.c
@@ -41,6 +41,7 @@
 
 #include "xtensa.h"
 #include "xtensa_attr.h"
+#include "hardware/esp32s3_efuse.h"
 #include "hardware/esp32s3_extmem.h"
 #include "hardware/esp32s3_spi_mem_reg.h"
 #include "hardware/esp32s3_cache_memory.h"
@@ -1306,3 +1307,40 @@ int esp32s3_spiflash_init(void)
 
   return ret;
 }
+
+/****************************************************************************
+ * Name: esp32s3_flash_encryption_enabled
+ *
+ * Description:
+ *   Check if ESP32-S3 enables SPI Flash encryption.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   True: SPI Flash encryption is enable, False if not.
+ *
+ ****************************************************************************/
+
+bool esp32s3_flash_encryption_enabled(void)
+{
+  bool enabled = false;
+  uint32_t regval;
+  uint32_t flash_crypt_cnt;
+
+  regval = getreg32(EFUSE_RD_REPEAT_DATA1_REG);
+  flash_crypt_cnt = (regval >> EFUSE_SPI_BOOT_CRYPT_CNT_S) &
+                    EFUSE_SPI_BOOT_CRYPT_CNT_V;
+
+  while (flash_crypt_cnt)
+    {
+      if (flash_crypt_cnt & 1)
+        {
+          enabled = !enabled;
+        }
+
+      flash_crypt_cnt >>= 1;
+    }
+
+  return enabled;
+}
diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiflash.h 
b/arch/xtensa/src/esp32s3/esp32s3_spiflash.h
index 642c98c20b..b7a395ebee 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_spiflash.h
+++ b/arch/xtensa/src/esp32s3/esp32s3_spiflash.h
@@ -150,6 +150,22 @@ int spi_flash_read_encrypted(uint32_t addr, void *buffer, 
uint32_t size);
 
 int esp32s3_spiflash_init(void);
 
+/****************************************************************************
+ * Name: esp32s3_flash_encryption_enabled
+ *
+ * Description:
+ *   Check if ESP32-S3 enables SPI Flash encryption.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   True: SPI Flash encryption is enable, False if not.
+ *
+ ****************************************************************************/
+
+bool esp32s3_flash_encryption_enabled(void);
+
 #ifdef __cplusplus
 }
 #endif

Reply via email to