xtensa/esp32s3: Support reading encrypted partitions

Signed-off-by: chenwen@espressif.com <chenwen@espressif.com>
This commit is contained in:
chenwen@espressif.com 2023-12-15 20:49:16 +08:00 committed by archer
parent 0a41d040ac
commit 2cb14c55f0
4 changed files with 143 additions and 22 deletions

View File

@ -32,6 +32,8 @@
#include <nuttx/kmalloc.h> #include <nuttx/kmalloc.h>
#include "esp32s3_spiflash_mtd.h" #include "esp32s3_spiflash_mtd.h"
#include "esp32s3_partition.h"
#include "esp32s3_spiflash.h"
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
@ -70,6 +72,10 @@
#define PARTITION_MOUNT_POINT CONFIG_ESP32S3_PARTITION_MOUNTPT #define PARTITION_MOUNT_POINT CONFIG_ESP32S3_PARTITION_MOUNTPT
/* Partition encrypted flag */
#define PARTITION_FLAG_ENCRYPTED (1 << 0)
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
@ -162,9 +168,11 @@ struct mtd_dev_priv_s
uint8_t type; /* Partition type */ uint8_t type; /* Partition type */
uint8_t subtype; /* Partition sub-type */ uint8_t subtype; /* Partition sub-type */
uint32_t flags; /* Partition flags */ 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 *ll_mtd; /* Low-level MTD data */
struct mtd_dev_s *part_mtd; /* Partition MTD data */ struct mtd_dev_s *part_mtd; /* Partition MTD data */
struct mtd_geometry_s geo; /* Partition geometry information */
}; };
/* OTA data entry */ /* OTA data entry */
@ -621,8 +629,11 @@ int esp32s3_partition_init(void)
int i; int i;
struct partition_info_priv_s *info; struct partition_info_priv_s *info;
uint8_t *pbuf; uint8_t *pbuf;
bool encrypt;
uint32_t flags;
struct mtd_dev_s *mtd; 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_geometry_s geo;
struct mtd_dev_priv_s *mtd_priv; struct mtd_dev_priv_s *mtd_priv;
int ret = 0; int ret = 0;
@ -632,7 +643,7 @@ int esp32s3_partition_init(void)
char path[PARTITION_LABEL_LEN + sizeof(PARTITION_MOUNT_POINT)]; char path[PARTITION_LABEL_LEN + sizeof(PARTITION_MOUNT_POINT)];
pbuf = kmm_malloc(PARTITION_MAX_SIZE); pbuf = kmm_malloc(PARTITION_MAX_SIZE);
if (pbuf == NULL) if (!pbuf)
{ {
ferr("ERROR: Failed to allocate %d byte\n", PARTITION_MAX_SIZE); ferr("ERROR: Failed to allocate %d byte\n", PARTITION_MAX_SIZE);
ret = -ENOMEM; ret = -ENOMEM;
@ -640,22 +651,27 @@ int esp32s3_partition_init(void)
} }
mtd = esp32s3_spiflash_mtd(); mtd = esp32s3_spiflash_mtd();
if (mtd == NULL) if (!mtd)
{ {
ferr("ERROR: Failed to get SPI flash MTD\n"); ferr("ERROR: Failed to get SPI flash MTD\n");
ret = -EIO; ret = -ENOSYS;
goto errout_with_mtd; goto errout_with_mtd;
} }
ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)&geo); mtd_encrypt = esp32s3_spiflash_encrypt_mtd();
if (ret < 0) if (!mtd_encrypt)
{ {
ferr("ERROR: Failed to get info from MTD\n"); ferr("ERROR: Failed to get SPI flash encrypted MTD\n");
ret = -EIO; ret = -ENOSYS;
goto errout_with_mtd; 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) if (ret != PARTITION_MAX_SIZE)
{ {
ferr("ERROR: Failed to get read data from MTD\n"); 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; info = (struct partition_info_priv_s *)pbuf;
encrypt = esp32s3_flash_encryption_enabled();
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
if (info->magic != PARTITION_MAGIC) if (info->magic != PARTITION_MAGIC)
@ -674,6 +690,23 @@ int esp32s3_partition_init(void)
strlcpy(label, (char *)info->label, sizeof(label)); strlcpy(label, (char *)info->label, sizeof(label));
snprintf(path, sizeof(path), "%s%s", path_base, 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: [label]: %s\n", label);
finfo("INFO: [type]: %d\n", info->type); 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: [size]: 0x%08" PRIx32 "\n", info->size);
finfo("INFO: [flags]: 0x%08" PRIx32 "\n", info->flags); finfo("INFO: [flags]: 0x%08" PRIx32 "\n", info->flags);
finfo("INFO: [mount]: %s\n", path); 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)); mtd_priv = kmm_malloc(sizeof(struct mtd_dev_priv_s));
if (!mtd_priv) if (!mtd_priv)
{ {
ferr("ERROR: Failed to allocate %d byte\n", ferr("ERROR: Failed to allocate %d byte\n",
sizeof(struct mtd_dev_priv_s)); sizeof(struct mtd_dev_priv_s));
ret = -1; ret = -ENOMEM;
goto errout_with_mtd; 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.bread = esp32s3_part_bread;
mtd_priv->mtd.bwrite = esp32s3_part_bwrite; mtd_priv->mtd.bwrite = esp32s3_part_bwrite;
mtd_priv->mtd.erase = esp32s3_part_erase; 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.write = esp32s3_part_write;
mtd_priv->mtd.name = label; mtd_priv->mtd.name = label;
mtd_part = mtd_partition(&mtd_priv->mtd, mtd_priv->part_mtd = mtd_partition(&mtd_priv->mtd,
info->offset / geo.blocksize, info->offset / geo.blocksize,
info->size / geo.blocksize); info->size / geo.blocksize);
if (!mtd_part) if (!mtd_priv->part_mtd)
{ {
ferr("ERROR: Failed to create MTD partition\n"); ferr("ERROR: Failed to create MTD partition\n");
kmm_free(mtd_priv); kmm_free(mtd_priv);
ret = -1; ret = -ENOSPC;
goto errout_with_mtd; goto errout_with_mtd;
} }
mtd_priv->part_mtd = mtd_part; ret = register_mtddriver(path, mtd_priv->part_mtd, 0777, NULL);
ret = register_mtddriver(path, mtd_part, 0777, NULL);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: Failed to register MTD @ %s\n", path); ferr("ERROR: Failed to register MTD @ %s\n", path);
kmm_free(mtd_priv); kmm_free(mtd_priv);
ret = -1;
goto errout_with_mtd; goto errout_with_mtd;
} }

View File

@ -42,6 +42,19 @@ extern "C"
#define EXTERN extern #define EXTERN extern
#endif #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 * Public Function Prototypes
****************************************************************************/ ****************************************************************************/

View File

@ -41,6 +41,7 @@
#include "xtensa.h" #include "xtensa.h"
#include "xtensa_attr.h" #include "xtensa_attr.h"
#include "hardware/esp32s3_efuse.h"
#include "hardware/esp32s3_extmem.h" #include "hardware/esp32s3_extmem.h"
#include "hardware/esp32s3_spi_mem_reg.h" #include "hardware/esp32s3_spi_mem_reg.h"
#include "hardware/esp32s3_cache_memory.h" #include "hardware/esp32s3_cache_memory.h"
@ -1306,3 +1307,40 @@ int esp32s3_spiflash_init(void)
return ret; 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;
}

View File

@ -150,6 +150,22 @@ int spi_flash_read_encrypted(uint32_t addr, void *buffer, uint32_t size);
int esp32s3_spiflash_init(void); 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 #ifdef __cplusplus
} }
#endif #endif