xtensa/esp32s3: Support reading encrypted partitions
Signed-off-by: chenwen@espressif.com <chenwen@espressif.com>
This commit is contained in:
parent
0a41d040ac
commit
2cb14c55f0
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user