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