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

xiaoxiang 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 67ccee2c4f xtensa/esp32: ESP32 SPI Flash encryption supports 16-bytes 
align writing
67ccee2c4f is described below

commit 67ccee2c4f581c3c772592f3393e437cf11af186
Author: Dong Heng <[email protected]>
AuthorDate: Wed Jan 4 14:38:37 2023 +0800

    xtensa/esp32: ESP32 SPI Flash encryption supports 16-bytes align writing
---
 arch/xtensa/src/esp32/esp32_spiflash.c | 212 ++++++++++++++++++++++++++++++++-
 arch/xtensa/src/esp32/esp32_spiflash.h |  16 +++
 2 files changed, 224 insertions(+), 4 deletions(-)

diff --git a/arch/xtensa/src/esp32/esp32_spiflash.c 
b/arch/xtensa/src/esp32/esp32_spiflash.c
index 769c0f6684..477c663e0c 100644
--- a/arch/xtensa/src/esp32/esp32_spiflash.c
+++ b/arch/xtensa/src/esp32/esp32_spiflash.c
@@ -47,6 +47,7 @@
 #include "hardware/esp32_soc.h"
 #include "hardware/esp32_spi.h"
 #include "hardware/esp32_dport.h"
+#include "hardware/efuse_reg.h"
 
 #ifdef CONFIG_ESP32_SPIRAM
 #include "esp32_spiram.h"
@@ -73,6 +74,8 @@
 #define SPI_FLASH_ENCRYPT_WORDS     (32 / 4)
 #define SPI_FLASH_ERASED_STATE      (0xff)
 
+#define SPI_FLASH_ENCRYPT_MIN_SIZE  (16)
+
 #define MTD2PRIV(_dev)              ((struct esp32_spiflash_s *)_dev)
 #define MTD_SIZE(_priv)             ((_priv)->chip->chip_size)
 #define MTD_BLKSIZE(_priv)          ((_priv)->chip->page_size)
@@ -242,8 +245,10 @@ static ssize_t esp32_bread_decrypt(struct mtd_dev_s *dev,
                                    off_t startblock,
                                    size_t nblocks,
                                    uint8_t *buffer);
+#ifdef CONFIG_MTD_BYTE_WRITE
 static ssize_t esp32_write(struct mtd_dev_s *dev, off_t offset,
                            size_t nbytes, const uint8_t *buffer);
+#endif
 static ssize_t esp32_bwrite(struct mtd_dev_s *dev, off_t startblock,
                             size_t nblocks, const uint8_t *buffer);
 static ssize_t esp32_bwrite_encrypt(struct mtd_dev_s *dev,
@@ -252,6 +257,8 @@ static ssize_t esp32_bwrite_encrypt(struct mtd_dev_s *dev,
                                     const uint8_t *buffer);
 static int esp32_ioctl(struct mtd_dev_s *dev, int cmd,
                        unsigned long arg);
+static int esp32_ioctl_encrypt(struct mtd_dev_s *dev, int cmd,
+                               unsigned long arg);
 
 /****************************************************************************
  * Private Data
@@ -289,7 +296,7 @@ static struct esp32_spiflash_s g_esp32_spiflash1_encrypt =
             .bread  = esp32_bread_decrypt,
             .bwrite = esp32_bwrite_encrypt,
             .read   = esp32_read_decrypt,
-            .ioctl  = esp32_ioctl,
+            .ioctl  = esp32_ioctl_encrypt,
 #ifdef CONFIG_MTD_BYTE_WRITE
             .write  = NULL,
 #endif
@@ -1731,6 +1738,7 @@ static ssize_t esp32_bread_decrypt(struct mtd_dev_s *dev,
  *
  ****************************************************************************/
 
+#ifdef CONFIG_MTD_BYTE_WRITE
 static ssize_t esp32_write(struct mtd_dev_s *dev, off_t offset,
                            size_t nbytes, const uint8_t *buffer)
 {
@@ -1770,6 +1778,7 @@ static ssize_t esp32_write(struct mtd_dev_s *dev, off_t 
offset,
 
   return ret;
 }
+#endif
 
 /****************************************************************************
  * Name: esp32_bwrite
@@ -1839,9 +1848,21 @@ static ssize_t esp32_bwrite_encrypt(struct mtd_dev_s 
*dev,
                                     const uint8_t *buffer)
 {
   ssize_t ret;
+  ssize_t n;
+  off_t addr;
+  uint8_t *wbuf;
+  uint8_t *rbuf;
+  uint8_t tmp_buf[SPI_FLASH_ENCRYPT_UNIT_SIZE];
+  size_t wbytes = 0;
   struct esp32_spiflash_s *priv = MTD2PRIV(dev);
-  uint32_t addr = MTD_BLK2SIZE(priv, startblock);
-  uint32_t size = MTD_BLK2SIZE(priv, nblocks);
+  uint32_t offset = MTD_BLK2SIZE(priv, startblock);
+  uint32_t nbytes = MTD_BLK2SIZE(priv, nblocks);
+
+  if ((offset % SPI_FLASH_ENCRYPT_MIN_SIZE) ||
+      (nbytes % SPI_FLASH_ENCRYPT_MIN_SIZE))
+    {
+      return -EINVAL;
+    }
 
 #ifdef CONFIG_ESP32_SPIFLASH_DEBUG
   finfo("esp32_bwrite_encrypt(%p, 0x%x, %d, %p)\n",
@@ -1854,7 +1875,77 @@ static ssize_t esp32_bwrite_encrypt(struct mtd_dev_s 
*dev,
       return ret;
     }
 
-  ret = esp32_writedata_encrypted(priv, addr, buffer, size);
+  while (nbytes)
+    {
+      if (offset % SPI_FLASH_ENCRYPT_UNIT_SIZE)
+        {
+          wbuf = tmp_buf;
+          rbuf = tmp_buf;
+          addr = offset - SPI_FLASH_ENCRYPT_MIN_SIZE;
+
+          n = SPI_FLASH_ENCRYPT_MIN_SIZE;
+
+          ret = esp32_readdata_encrypted(priv, addr, rbuf, n);
+          if (ret < 0)
+            {
+              ferr("esp32_readdata_encrypted failed ret=%d\n", ret);
+              break;
+            }
+
+          memcpy(wbuf + n, buffer, n);
+        }
+      else if (nbytes % SPI_FLASH_ENCRYPT_UNIT_SIZE)
+        {
+          wbuf = tmp_buf;
+          if (offset % SPI_FLASH_ENCRYPT_UNIT_SIZE)
+            {
+              rbuf = tmp_buf;
+              addr = offset - SPI_FLASH_ENCRYPT_MIN_SIZE;
+            }
+          else
+            {
+              rbuf = tmp_buf + SPI_FLASH_ENCRYPT_MIN_SIZE;
+              addr = offset;
+            }
+
+          n = SPI_FLASH_ENCRYPT_MIN_SIZE;
+
+          ret = esp32_readdata_encrypted(priv, addr, rbuf, n);
+          if (ret < 0)
+            {
+              ferr("esp32_readdata_encrypted failed ret=%d\n", ret);
+              break;
+            }
+
+          if (offset % SPI_FLASH_ENCRYPT_UNIT_SIZE)
+            {
+              memcpy(wbuf + n, buffer, n);
+            }
+          else
+            {
+              memcpy(wbuf, buffer, n);
+            }
+        }
+      else
+        {
+          n = SPI_FLASH_ENCRYPT_UNIT_SIZE;
+          wbuf = (uint8_t *)buffer;
+          addr = offset;
+        }
+
+      ret = esp32_writedata_encrypted(priv, addr, wbuf,
+                                      SPI_FLASH_ENCRYPT_UNIT_SIZE);
+      if (ret < 0)
+        {
+          ferr("esp32_writedata_encrypted failed ret=%d\n", ret);
+          break;
+        }
+
+      offset += n;
+      nbytes -= n;
+      buffer += n;
+      wbytes += n;
+    }
 
   nxmutex_unlock(&g_lock);
   if (ret == OK)
@@ -1943,6 +2034,82 @@ static int esp32_ioctl(struct mtd_dev_s *dev, int cmd,
   return ret;
 }
 
+/****************************************************************************
+ * Name: esp32_ioctl_encrypt
+ *
+ * Description:
+ *   Set/Get option to/from ESP32 SPI Flash Hardware Encryption MTD
+ *   device data.
+ *
+ * Input Parameters:
+ *   dev - ESP32 MTD device data
+ *   cmd - operation command
+ *   arg - operation argument
+ *
+ * Returned Value:
+ *   0 if success or a negative value if fail.
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl_encrypt(struct mtd_dev_s *dev, int cmd,
+                               unsigned long arg)
+{
+  int ret = -EINVAL;
+  struct esp32_spiflash_s *priv = MTD2PRIV(dev);
+
+  finfo("cmd: %d\n", cmd);
+
+  switch (cmd)
+    {
+      case MTDIOC_GEOMETRY:
+        {
+          struct mtd_geometry_s *geo = (struct mtd_geometry_s *)arg;
+          if (geo)
+            {
+              geo->blocksize    = SPI_FLASH_ENCRYPT_MIN_SIZE;
+              geo->erasesize    = MTD_ERASESIZE(priv);
+              geo->neraseblocks = MTD_SIZE(priv) / geo->erasesize;
+              ret               = OK;
+
+              finfo("blocksize: %d erasesize: %d neraseblocks: %d\n",
+                    geo->blocksize, geo->erasesize, geo->neraseblocks);
+            }
+        }
+        break;
+
+      case BIOC_PARTINFO:
+        {
+          struct partition_info_s *info =
+            (struct partition_info_s *)arg;
+          if (info != NULL)
+            {
+              info->sectorsize  = SPI_FLASH_ENCRYPT_MIN_SIZE;
+              info->numsectors  = MTD_SIZE(priv) / info->sectorsize;
+              info->startsector = 0;
+              info->parent[0]   = '\0';
+              ret               = OK;
+            }
+        }
+        break;
+
+      case MTDIOC_ERASESTATE:
+        {
+          uint8_t *result = (uint8_t *)arg;
+          *result = SPI_FLASH_ERASED_STATE;
+
+          ret = OK;
+        }
+        break;
+
+      default:
+        ret = -ENOTTY;
+        break;
+    }
+
+  finfo("return %d\n", ret);
+  return ret;
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -2065,4 +2232,41 @@ struct mtd_dev_s *esp32_spiflash_encrypt_get_mtd(void)
   return &priv->mtd;
 }
 
+/****************************************************************************
+ * Name: esp32_flash_encryption_enabled
+ *
+ * Description:
+ *   Check if ESP32 enables SPI Flash encryption.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   True: SPI Flash encryption is enable, False if not.
+ *
+ ****************************************************************************/
+
+bool esp32_flash_encryption_enabled(void)
+{
+  bool enabled = false;
+  uint32_t regval;
+  uint32_t flash_crypt_cnt;
+
+  regval = getreg32(EFUSE_BLK0_RDATA0_REG);
+  flash_crypt_cnt = (regval >> EFUSE_RD_FLASH_CRYPT_CNT_S) &
+                    EFUSE_RD_FLASH_CRYPT_CNT_V;
+
+  while (flash_crypt_cnt)
+    {
+      if (flash_crypt_cnt & 1)
+        {
+          enabled = !enabled;
+        }
+
+      flash_crypt_cnt >>= 1;
+    }
+
+  return enabled;
+}
+
 #endif /* CONFIG_ESP32_SPIFLASH */
diff --git a/arch/xtensa/src/esp32/esp32_spiflash.h 
b/arch/xtensa/src/esp32/esp32_spiflash.h
index 0023f18d01..a2eb5f5ffa 100644
--- a/arch/xtensa/src/esp32/esp32_spiflash.h
+++ b/arch/xtensa/src/esp32/esp32_spiflash.h
@@ -101,6 +101,22 @@ struct mtd_dev_s *esp32_spiflash_get_mtd(void);
 
 struct mtd_dev_s *esp32_spiflash_encrypt_get_mtd(void);
 
+/****************************************************************************
+ * Name: esp32_flash_encryption_enabled
+ *
+ * Description:
+ *   Check if ESP32 enables SPI Flash encryption.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   True: SPI Flash encryption is enable, False if not.
+ *
+ ****************************************************************************/
+
+bool esp32_flash_encryption_enabled(void);
+
 #ifdef __cplusplus
 }
 #endif

Reply via email to