xtensa/esp32: ESP32 SPI Flash encryption supports 16-bytes align writing
This commit is contained in:
parent
a491d07061
commit
67ccee2c4f
@ -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 */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user