diff --git a/arch/xtensa/src/esp32s3/esp32s3_partition.c b/arch/xtensa/src/esp32s3/esp32s3_partition.c index 3a2e254ab4..857f588021 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_partition.c +++ b/arch/xtensa/src/esp32s3/esp32s3_partition.c @@ -32,6 +32,8 @@ #include #include "esp32s3_spiflash_mtd.h" +#include "esp32s3_partition.h" +#include "esp32s3_spiflash.h" /**************************************************************************** * Pre-processor Definitions @@ -70,6 +72,10 @@ #define PARTITION_MOUNT_POINT CONFIG_ESP32S3_PARTITION_MOUNTPT +/* Partition encrypted flag */ + +#define PARTITION_FLAG_ENCRYPTED (1 << 0) + /**************************************************************************** * Private Types ****************************************************************************/ @@ -162,9 +168,11 @@ struct mtd_dev_priv_s uint8_t type; /* Partition type */ uint8_t subtype; /* Partition sub-type */ 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 *part_mtd; /* Partition MTD data */ + struct mtd_geometry_s geo; /* Partition geometry information */ }; /* OTA data entry */ @@ -621,8 +629,11 @@ int esp32s3_partition_init(void) int i; struct partition_info_priv_s *info; uint8_t *pbuf; + bool encrypt; + uint32_t flags; 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_dev_priv_s *mtd_priv; int ret = 0; @@ -632,7 +643,7 @@ int esp32s3_partition_init(void) char path[PARTITION_LABEL_LEN + sizeof(PARTITION_MOUNT_POINT)]; pbuf = kmm_malloc(PARTITION_MAX_SIZE); - if (pbuf == NULL) + if (!pbuf) { ferr("ERROR: Failed to allocate %d byte\n", PARTITION_MAX_SIZE); ret = -ENOMEM; @@ -640,22 +651,27 @@ int esp32s3_partition_init(void) } mtd = esp32s3_spiflash_mtd(); - if (mtd == NULL) + if (!mtd) { ferr("ERROR: Failed to get SPI flash MTD\n"); - ret = -EIO; + ret = -ENOSYS; goto errout_with_mtd; } - ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)&geo); - if (ret < 0) + mtd_encrypt = esp32s3_spiflash_encrypt_mtd(); + if (!mtd_encrypt) { - ferr("ERROR: Failed to get info from MTD\n"); - ret = -EIO; + ferr("ERROR: Failed to get SPI flash encrypted MTD\n"); + ret = -ENOSYS; 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) { 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; - + encrypt = esp32s3_flash_encryption_enabled(); for (i = 0; i < num; i++) { if (info->magic != PARTITION_MAGIC) @@ -674,6 +690,23 @@ int esp32s3_partition_init(void) strlcpy(label, (char *)info->label, sizeof(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: [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: [flags]: 0x%08" PRIx32 "\n", info->flags); 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)); if (!mtd_priv) { ferr("ERROR: Failed to allocate %d byte\n", sizeof(struct mtd_dev_priv_s)); - ret = -1; + ret = -ENOMEM; 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.bwrite = esp32s3_part_bwrite; 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.name = label; - mtd_part = mtd_partition(&mtd_priv->mtd, - info->offset / geo.blocksize, - info->size / geo.blocksize); - if (!mtd_part) + mtd_priv->part_mtd = mtd_partition(&mtd_priv->mtd, + info->offset / geo.blocksize, + info->size / geo.blocksize); + if (!mtd_priv->part_mtd) { ferr("ERROR: Failed to create MTD partition\n"); kmm_free(mtd_priv); - ret = -1; + ret = -ENOSPC; goto errout_with_mtd; } - mtd_priv->part_mtd = mtd_part; - - ret = register_mtddriver(path, mtd_part, 0777, NULL); + ret = register_mtddriver(path, mtd_priv->part_mtd, 0777, NULL); if (ret < 0) { ferr("ERROR: Failed to register MTD @ %s\n", path); kmm_free(mtd_priv); - ret = -1; goto errout_with_mtd; } diff --git a/arch/xtensa/src/esp32s3/esp32s3_partition.h b/arch/xtensa/src/esp32s3/esp32s3_partition.h index 50b614fbc6..25d561eb35 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_partition.h +++ b/arch/xtensa/src/esp32s3/esp32s3_partition.h @@ -42,6 +42,19 @@ extern "C" #define EXTERN extern #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 ****************************************************************************/ diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiflash.c b/arch/xtensa/src/esp32s3/esp32s3_spiflash.c index 515ccaecdb..87297483c6 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_spiflash.c +++ b/arch/xtensa/src/esp32s3/esp32s3_spiflash.c @@ -41,6 +41,7 @@ #include "xtensa.h" #include "xtensa_attr.h" +#include "hardware/esp32s3_efuse.h" #include "hardware/esp32s3_extmem.h" #include "hardware/esp32s3_spi_mem_reg.h" #include "hardware/esp32s3_cache_memory.h" @@ -1306,3 +1307,40 @@ int esp32s3_spiflash_init(void) 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; +} diff --git a/arch/xtensa/src/esp32s3/esp32s3_spiflash.h b/arch/xtensa/src/esp32s3/esp32s3_spiflash.h index 642c98c20b..b7a395ebee 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_spiflash.h +++ b/arch/xtensa/src/esp32s3/esp32s3_spiflash.h @@ -150,6 +150,22 @@ int spi_flash_read_encrypted(uint32_t addr, void *buffer, uint32_t size); 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 } #endif