一、Flash 加密功能用於加密與 ESP32-S2 搭載使用的 SPI Flash 中的內容。啟用 Flash 加密功能后,物理讀取 SPI Flash 便無法恢復大部分 Flash 內容。通過明文數據燒錄 ESP32-S2 可應用加密功能,(若已啟用加密功能)引導加載程序會在首次啟動時對數據進行加密。
啟用 Flash 加密后,系統將默認加密下列類型的 Flash 數據:
- 引導加載程序
- 分區表
- 所有 “app” 類型的分區
其他類型的 Flash 數據將視情況進行加密:
- 安全啟動引導加載程序摘要(如果已啟用安全啟動)
- 分區表中標有“加密”標記的分區
二、開發模式:可使用 ESP32-S2 內部生成的密鑰或外部主機生成的密鑰在開發中運行 Flash 加密。
三、發布模式:在釋放模式下,UART 引導加載程序無法執行 Flash 加密操作,只能 使用 OTA 方案下載新的明文映像,該方案將在寫入 Flash 前加密明文映像。
四、使用主機生成的 Flash 加密密鑰:
1.可在主機中預生成 Flash 加密密鑰,並將其燒錄到 ESP32-S2 的 eFuse 密鑰塊中。這樣,無需明文 Flash 更新便可以在主機上預加密數據並將其燒錄到 ESP32-S2 中。該功能允許在 開發模式 和 發布模式 modes 兩模式下加密燒錄。
- 確保您的 ESP32-S2 設備有 Flash 加密過程中使用的 eFuse 中所示 Flash 加密 eFuse 的默認設置。
- 使用 espsecure.py 隨機生成一個密鑰:
espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin
- 將該密鑰燒錄到設備上(一次性)。 該步驟須在第一次加密啟動前完成,否則 ESP32-S2 將隨機生成一個軟件無權限訪問或修改的密鑰:
espefuse.py --port PORT burn_key flash_encryption my_flash_encryption_key.bin
- 在第二階段引導加載程序中啟用 Flash 加密支持。請前往 Project Configuration Menu,選擇 “Security Features”。
- 選擇 Enable flash encryption on boot。
- 模式默認設置為 開發模式。
- 在引導加載程序 config 下選擇適當詳細程度的日志。
- 保存配置並退出。
2.構建並燒錄完整的映像包括:引導加載程序、分區表和 app。這些分區最初以未加密形式寫入 Flash
idf.py flash monitor
3.下次啟動時,第二階段引導加載程序將加密 Flash 的 app 分區並重置該分區。現在,示例應用程序將在運行時解密並執行命令。在此階段,如果用戶希望將新的明文應用程序映像更新到 Flash,應調用以下命令
idf.py encrypted-app-flash monitor
五、讀取加密的Flash
如在不使用 Flash 緩存 MMU 映射的情況下讀取數據,推薦使用分區讀取函數 esp_partition_read()。使用該函數時,只有從加密分區讀取的數據才會被解密。其他分區的數據將以未加密形式讀取。這樣,軟件便能同樣訪問加密和未加密的 Flash。通過其他 SPI 讀取 API 讀取的數據均未解密:
- 通過函數 spi_flash_read() 讀取的數據均未解密。
- 通過 ROM 函數 SPIRead() 讀取的數據均未解密(esp-idf app 不支持該函數)。
- 使用非易失性存儲器 (NVS) API 存儲的數據始終從 Flash 加密的角度進行存儲和讀取解密。如有需要,則由庫提供加密功能。
六、寫入加密的Flash
在可能的情況下,推薦使用分區寫入函數 esp_partition_write。使用該函數時,只有向加密分區寫入的數據才會被加密。而寫入其他分區的數據均未加密。這樣,軟件便可同樣訪問加密和未加密的 Flash。當 write_encrypted 參數設置為“是”時,函數 esp_spi_flash_write 將寫入數據。否則,數據將以未加密形式寫入。ROM 函數 esp_rom_spiflash_write_encrypted 將在 Flash 中寫入加密數據,而 ROM 函數 SPIWrite 將在 Flash 中寫入未加密數據(esp-idf app 不支持上述函數)。由於數據均采用塊加密方式,加密數據最小的寫入大小為 16 字節(16字節對齊)。
七、關閉Flash加密
若因某些原因意外啟用了 Flash 加密,則接下來燒錄明文數據時將使 ESP32-S2 軟磚(設備不斷重啟,並報錯 flash read err, 1000)。可通過寫入 FLASH_CRYPT_CNT eFuse 再次關閉 Flash 加密(僅適用於開發模式下):
- 首先,前往 Project Configuration Menu,在“安全性能”目錄下關閉 啟用 Flash 加密啟動。
- 退出 menuconfig 並保存最新配置。
- 再次運行 idf.py menuconfig 並復核是否確認已關閉該選項!如果該選項仍處於已啟用狀態,則引導加載程序會在啟動后立即重新啟用加密。
- 在未啟用 Flash 加密的狀態下,運行 idf.py flash 構建並燒錄新的引導加載程序與 app。
- 運行 espefuse.py (components/esptool_py/esptool 中)以關閉 FLASH_CRYPT_CNT:
espefuse.py burn_efuse FLASH_CRYPT_CNT
重置 ESP32-S2,Flash 加密應處於關閉狀態,引導加載程序將正常啟動。
原文:https://docs.espressif.com/projects/esp-idf/zh_CN/v4.2/esp32s2/security/flash-encryption.html