xtensa/esp32s3: porting of spi_flash_chip_generic_write_encrypted from ESP-IDF
This commit is contained in:
parent
4bd2c0443b
commit
55da7d89b5
2 changed files with 519 additions and 5 deletions
|
@ -235,6 +235,518 @@ static inline bool IRAM_ATTR stack_is_psram(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Choose type of chip you want to encrypt manully
|
||||
*
|
||||
* esp-idf/components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h
|
||||
*
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FLASH_ENCRYPTION_MANU = 0, /* !< Manually encrypt the flash chip. */
|
||||
PSRAM_ENCRYPTION_MANU = 1 /* !< Manually encrypt the psram chip. */
|
||||
} flash_encrypt_ll_type_t;
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encrypt_ll_enable
|
||||
*
|
||||
* Description:
|
||||
* Enable the flash encryption function under spi boot mode and
|
||||
* download boot mode.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_flash_encrypt_ll_enable(void)
|
||||
{
|
||||
REG_SET_BIT(SYSTEM_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG,
|
||||
SYSTEM_ENABLE_DOWNLOAD_MANUAL_ENCRYPT |
|
||||
SYSTEM_ENABLE_SPI_MANUAL_ENCRYPT);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encrypt_ll_disable
|
||||
*
|
||||
* Description:
|
||||
* Disable the flash encryption mode.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_flash_encrypt_ll_disable(void)
|
||||
{
|
||||
REG_CLR_BIT(SYSTEM_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG,
|
||||
SYSTEM_ENABLE_SPI_MANUAL_ENCRYPT);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encrypt_ll_type
|
||||
*
|
||||
* Description:
|
||||
* Choose type of chip you want to encrypt manully
|
||||
*
|
||||
* Input Parameters:
|
||||
* type - The type of chip to be encrypted
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_flash_encrypt_ll_type(flash_encrypt_ll_type_t type)
|
||||
{
|
||||
DEBUGASSERT(type == FLASH_ENCRYPTION_MANU); /* Our hardware only support flash encryption */
|
||||
REG_WRITE(AES_XTS_DESTINATION_REG, type);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encrypt_ll_buffer_length
|
||||
*
|
||||
* Description:
|
||||
* Configure the data size of a single encryption.
|
||||
*
|
||||
* Input Parameters:
|
||||
* size - Size of the desired block.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size)
|
||||
{
|
||||
REG_WRITE(AES_XTS_SIZE_REG, size >> 5); /* Desired block should not be larger than the block size. */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encrypt_ll_plaintext_save
|
||||
*
|
||||
* Description:
|
||||
* Save 32-bit piece of plaintext.
|
||||
*
|
||||
* Input Parameters:
|
||||
* address - the address of written flash partition.
|
||||
* buffer - Buffer to store the input data.
|
||||
* size - Buffer size.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline
|
||||
void spi_flash_encrypt_ll_plaintext_save(uint32_t address,
|
||||
const uint32_t * buffer,
|
||||
uint32_t size)
|
||||
{
|
||||
uint32_t plaintext_offs =
|
||||
(address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX);
|
||||
DEBUGASSERT(
|
||||
plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX);
|
||||
memcpy((void *)(AES_XTS_PLAIN_BASE + plaintext_offs), buffer, size);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encrypt_ll_address_save
|
||||
*
|
||||
* Description:
|
||||
* Copy the flash address to XTS_AES physical address
|
||||
*
|
||||
* Input Parameters:
|
||||
* flash_addr - flash address to write.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_flash_encrypt_ll_address_save(uint32_t flash_addr)
|
||||
{
|
||||
REG_WRITE(AES_XTS_PHYSICAL_ADDR_REG, flash_addr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encrypt_ll_calculate_start
|
||||
*
|
||||
* Description:
|
||||
* Start flash encryption
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_flash_encrypt_ll_calculate_start(void)
|
||||
{
|
||||
REG_WRITE(AES_XTS_TRIGGER_REG, 1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encrypt_ll_calculate_wait_idle
|
||||
*
|
||||
* Description:
|
||||
* Wait for flash encryption termination
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_flash_encrypt_ll_calculate_wait_idle(void)
|
||||
{
|
||||
while (REG_READ(AES_XTS_STATE_REG) == 0x1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encrypt_ll_done
|
||||
*
|
||||
* Description:
|
||||
* Finish the flash encryption and make encrypted result accessible to SPI.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_flash_encrypt_ll_done(void)
|
||||
{
|
||||
REG_WRITE(AES_XTS_RELEASE_REG, 1);
|
||||
while (REG_READ(AES_XTS_STATE_REG) != 0x3)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encrypt_ll_destroy
|
||||
*
|
||||
* Description:
|
||||
* Set to destroy encrypted result
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_flash_encrypt_ll_destroy(void)
|
||||
{
|
||||
REG_WRITE(AES_XTS_DESTROY_REG, 1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encrypt_ll_check
|
||||
*
|
||||
* Description:
|
||||
* Check if is qualified to encrypt the buffer
|
||||
*
|
||||
* Input Parameters:
|
||||
* address - the address of written flash partition.
|
||||
* length - Buffer size.
|
||||
*
|
||||
* Returned Value:
|
||||
* True if the address is qualified.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline bool spi_flash_encrypt_ll_check(uint32_t address,
|
||||
uint32_t length)
|
||||
{
|
||||
return ((address % length) == 0) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* from: esp-idf/components/hal/spi_flash_encrypt_hal_iram.c
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encryption_hal_enable
|
||||
*
|
||||
* Description:
|
||||
* Enable flash encryption
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void spi_flash_encryption_hal_enable(void)
|
||||
{
|
||||
spi_flash_encrypt_ll_enable();
|
||||
spi_flash_encrypt_ll_type(FLASH_ENCRYPTION_MANU);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encryption_hal_disable
|
||||
*
|
||||
* Description:
|
||||
* Disable flash encryption
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void spi_flash_encryption_hal_disable(void)
|
||||
{
|
||||
spi_flash_encrypt_ll_disable();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encryption_hal_prepare
|
||||
*
|
||||
* Description:
|
||||
* Prepare flash encryption
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void spi_flash_encryption_hal_prepare(uint32_t address,
|
||||
const uint32_t * buffer, uint32_t size)
|
||||
{
|
||||
spi_flash_encrypt_ll_buffer_length(size);
|
||||
spi_flash_encrypt_ll_address_save(address);
|
||||
spi_flash_encrypt_ll_plaintext_save(address, buffer, size);
|
||||
spi_flash_encrypt_ll_calculate_start();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encryption_hal_done
|
||||
*
|
||||
* Description:
|
||||
* wait flash encryption and mark down
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void spi_flash_encryption_hal_done(void)
|
||||
{
|
||||
spi_flash_encrypt_ll_calculate_wait_idle();
|
||||
spi_flash_encrypt_ll_done();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encryption_hal_destroy
|
||||
*
|
||||
* Description:
|
||||
* Set to destroy encrypted result
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void spi_flash_encryption_hal_destroy(void)
|
||||
{
|
||||
spi_flash_encrypt_ll_destroy();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_encryption_hal_destroy
|
||||
*
|
||||
* Description:
|
||||
* Check if is qualified to encrypt the buffer
|
||||
*
|
||||
* Input Parameters:
|
||||
* address - the address of written flash partition.
|
||||
* length - Buffer size.
|
||||
*
|
||||
* Returned Value:
|
||||
* True if the address is qualified.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool spi_flash_encryption_hal_check(uint32_t address, uint32_t length)
|
||||
{
|
||||
return spi_flash_encrypt_ll_check(address, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* These are the pointer to HW flash encryption.
|
||||
* Default using hardware encryption.
|
||||
*
|
||||
* esp-idf/components/spi_flash/spi_flash_chip_generic.c
|
||||
*
|
||||
*/
|
||||
|
||||
DRAM_ATTR static spi_flash_encryption_t esp_flash_encryption_default
|
||||
__attribute__((__unused__)) =
|
||||
{
|
||||
.flash_encryption_enable = spi_flash_encryption_hal_enable,
|
||||
.flash_encryption_disable = spi_flash_encryption_hal_disable,
|
||||
.flash_encryption_data_prepare = spi_flash_encryption_hal_prepare,
|
||||
.flash_encryption_done = spi_flash_encryption_hal_done,
|
||||
.flash_encryption_destroy = spi_flash_encryption_hal_destroy,
|
||||
.flash_encryption_check = spi_flash_encryption_hal_check,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_flash_write_encrypted_manu
|
||||
*
|
||||
* Description:
|
||||
* Workaround of spi_flash_write_encrypted
|
||||
* by using of spi_flash_chip_generic_write_encrypted
|
||||
*
|
||||
* Input Parameters:
|
||||
* address - Destination address in Flash. Must be a multiple of 16
|
||||
* bytes.
|
||||
* buffer - Pointer to the source buffer.
|
||||
* length - Length of data, in bytes. Must be a multiple of 16 bytes.
|
||||
*
|
||||
* Returned Values:
|
||||
* Zero (OK) is returned or a negative error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int spi_flash_write_encrypted_manu(uint32_t address, const void *buffer,
|
||||
uint32_t length)
|
||||
{
|
||||
spi_flash_encryption_t *esp_flash_encryption =
|
||||
&esp_flash_encryption_default;
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
/* Check if the buffer and length can qualify the requirements */
|
||||
|
||||
if (esp_flash_encryption->flash_encryption_check(address, length) != true)
|
||||
{
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
const uint8_t *data_bytes = (const uint8_t *)buffer;
|
||||
esp_flash_encryption->flash_encryption_enable();
|
||||
while (length > 0)
|
||||
{
|
||||
int block_size;
|
||||
|
||||
/* Write the largest block if possible */
|
||||
|
||||
if (address % 64 == 0 && length >= 64)
|
||||
{
|
||||
block_size = 64;
|
||||
}
|
||||
else if (address % 32 == 0 && length >= 32)
|
||||
{
|
||||
block_size = 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
block_size = 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the flash chip (same time as AES operation, for performance)
|
||||
*/
|
||||
|
||||
esp_flash_encryption->flash_encryption_data_prepare(address,
|
||||
(uint32_t *)
|
||||
data_bytes,
|
||||
block_size);
|
||||
|
||||
/* err = chip->chip_drv->set_chip_write_protect(chip, false); */
|
||||
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waiting for encrypting buffer to finish and
|
||||
* making result visible for SPI1
|
||||
*/
|
||||
|
||||
esp_flash_encryption->flash_encryption_done();
|
||||
|
||||
/**
|
||||
* Note: For encryption function, after write flash command is sent.
|
||||
* The hardware will write the encrypted buffer
|
||||
* prepared in XTS_FLASH_ENCRYPTION register
|
||||
* in function `flash_encryption_data_prepare`, instead of the origin
|
||||
* buffer named `data_bytes`.
|
||||
*/
|
||||
|
||||
/**
|
||||
* err = chip->chip_drv->write(chip, (uint32_t *)data_bytes,
|
||||
* address, length);
|
||||
*/
|
||||
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* err =
|
||||
* chip->chip_drv->wait_idle(chip,
|
||||
* chip->chip_drv->timeout->
|
||||
* page_program_timeout);
|
||||
*/
|
||||
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
spi_flash_write(address, data_bytes, block_size);
|
||||
|
||||
/**
|
||||
* Note: we don't wait for idle status here, because this way
|
||||
* the AES peripheral can start encrypting the next
|
||||
* block while the SPI flash chip is busy completing the write
|
||||
*/
|
||||
|
||||
esp_flash_encryption->flash_encryption_destroy();
|
||||
|
||||
length -= block_size;
|
||||
data_bytes += block_size;
|
||||
address += block_size;
|
||||
}
|
||||
|
||||
esp_flash_encryption->flash_encryption_disable();
|
||||
return err;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_spiflash_work
|
||||
*
|
||||
|
@ -286,9 +798,9 @@ static void esp32s3_spiflash_work(void *arg)
|
|||
}
|
||||
else if (work_arg->op_code == SPIFLASH_OP_CODE_ENCRYPT_WRITE)
|
||||
{
|
||||
work_arg->ret = spi_flash_write_encrypted(work_arg->op_arg.addr,
|
||||
work_arg->op_arg.buffer,
|
||||
work_arg->op_arg.size);
|
||||
work_arg->ret = spi_flash_write_encrypted_manu(work_arg->op_arg.addr,
|
||||
work_arg->op_arg.buffer,
|
||||
work_arg->op_arg.size);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -686,7 +1198,7 @@ static int esp32s3_writedata_encrypt(struct mtd_dev_s *dev, off_t offset,
|
|||
else
|
||||
#endif
|
||||
{
|
||||
ret = spi_flash_write_encrypted(offset, buffer, size);
|
||||
ret = spi_flash_write_encrypted_manu(offset, buffer, size);
|
||||
}
|
||||
|
||||
nxmutex_unlock(&g_lock);
|
||||
|
@ -899,7 +1411,7 @@ static ssize_t esp32s3_bwrite_encrypt(struct mtd_dev_s *dev,
|
|||
else
|
||||
#endif
|
||||
{
|
||||
ret = spi_flash_write_encrypted(addr, buffer, size);
|
||||
ret = spi_flash_write_encrypted_manu(addr, buffer, size);
|
||||
}
|
||||
|
||||
nxmutex_unlock(&g_lock);
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include <nuttx/bits.h>
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "soc/system_reg.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
/****************************************************************************
|
||||
|
|
Loading…
Reference in a new issue