智能家居matter協議模塊樂鑫科技wifi加密芯片flash/NVS加密方案,將啟用 Flash 加密方案的明文固件燒錄到設備端,并啟動設備端后,設備端將自動啟用Flash 加密方案。設備端自動啟用 Flash 加密方案的基本工作流程是:
1)Bootloader 讀取 eFuse 中 SPI BOOT_CRYPT_CNT 區域的值,若未啟用Flash 加密方案則啟用 Flash 加密方案。默認情況下,該區域的值為0,代表還未啟用 FIash 加密。
(2)Bootloader 檢測存儲 Flash 加密方案密的eFuse 區域BLOCK KEY中是否已經存儲密鑰若未預先燒錄密鑰,則自動生成密并寫入 BLOCK KEY,然后開啟該區域的讀/寫保護,軟件將無法讀/寫密鑰。
(3)通過智能家居matter協議模塊樂鑫科技wifi加密芯片Flash 加密方案來加密 Flash 中需要加密的數據,包括 Bootloader、app 和其他在分區表中標記 encrypted 的分區數據。
(4) Bootloader 將 eFuse 中的 SPI BOOT_CRYPT_CNT 區域的值設置為 1,表示已經啟用了Flash 加密方案。
(5)若 Flash 加密的工作模式為開發模式,則 eFuse 中的 SPI_BOOT_CRYPT_CNT 和DIS DOWNLOAD MANUAL ENCRYPT 區域將不被寫保護,從而允許關閉 Flash 加密方案,并重新燒錄加密固件。
(6)若 Flash 加密的工作模式為量產模式,則智能家居matter協議模塊樂鑫科技wifi加密芯片eFuse 中的 SPI_BOOT_CRYPT_CNT 和DIS_DOWNLOAD_MANUAL_ENCRYPT 區域將被寫保護,從而永久使用 Flash 加密方案并禁止重新燒錄固件。
(7)設備端在自動重啟后會加載并運行加密后的 Bootloader 固件和app 固件。
注意:啟用 Flash 加密方案后,eFuse 的一些標志位將默認被置位,從而關閉一些系統功能,如JTAG。繼續保留這些系統功能可能會帶來安全風險,在測試階段,如果需要保留這些標志位,請參考 ESP-IDF 編程指南中與 Flash 加密相關的說明。
啟用 Flash 加密方案后,設備端在加載運行加密的 Bootloader 固件和 app 固件時,智能家居matter協議模塊樂鑫科技wifi加密芯片先自動通過硬件模塊解密對應的數據,再將解密后的數據加載到設備端的 iRAM和 Cache 中運行。此外啟用 Flash 加密方案后,一些 API在讀/寫 Flash 上加密分區的數據時將自動加/解密數據。自動解密數據的 API 主要包括 esp_partition_read()、esp_flash_read_encrypted()、bootloader_flash_read();自動加密數據的 API 主要包括 esp_partition_write()、esp_flash_write encrypted()、bootloader_flash_write()。
特別地,啟用 Flash 加密方案后,在執行 OTA 升級時,設備端接收的是明文數據,在將接收到的明文數據寫入 Flash 時,將調用上述的esp_partition_write()函數自動加密數據,以適應 Flash 加密方案的特性。
注意:設備量產后,通過 OTA 升級功能可以遠程更新 app 固件,但無法更新 Bootloader 固件因此啟用智能家居matter協議模塊樂鑫科技wifi加密芯片Flash 加密方案后,請注意 Bootloader 的相關配置,如 Log 級別的配置。
NVS 加密方案簡介
Flash 加密方案并不直接保護存儲在 NVS分區的數據,存儲在 NVS分區的數據需要 NVS加密方案來保護其機密性。我們可以通過 menuconfig - Component config - NVS -Enable NVS encryption 選項啟用NVS 加密,或者在代碼中調用 nvs_flash_secureinit()函數啟用它。
NVS 加密方案的基本原理:在分區表中定義一塊不少于4KB的子類型為nvs_key 的分區在啟用NVS加密方案后,將使用nvs_key 分區的密加密NVS分區的數據。一種支持NVS加密的典型分區表如下所示:
1.# Name,Typer, SubType,Offset, Size,Flags
2.nvs,data,0x6000,,nvs,
3.phy_init,data,phy,,0x1000,
4.factory,app,factory,, 1M,
5.nvs_key,data,nvs_keys,,0x1000,encrypted,
NVS 加密方案與 Flash 加密方案有很多類似的地方,例如:
(1)NVS加密方案使用的加密算法是對稱加密算法 AES-XTS。如前所述,對稱加密算法要求其密鑰是保密的,這樣才能保證加密后的數據不被分析破解。NVS 加密方案的密鑰不能是明文的,因此該方案經常與 Flash 加密方案結合使用,其中智能家居matter協議模塊樂鑫科技wifi加密芯片Flash 加密方案負責保護 nvs_key的密鑰機密性,NVS 加密方案使用 nvs_key 保護NVS 分區的數據機密性。
(2)存儲NVS 加密方案密的方式有兩種:一種是手動方式,即手動生成一個密鑰,并將密鑰新寫入指定的分區,另一種是自動方式,即在首次啟用 NVS 加密方案,且對應的 nvs_key分區內容為空時,設備內部先自動調用 nvs_flash_generate_keys()函數生成密鑰,再將密鑰寫入 nvs_key分區,并使用該密鑰完成NVS 加/解密。
采用手動方式存儲 NVS 加密方案密鑰的步驟如下:
首先,生成一個包含密鑰的文件,命令如下:
$ espsecure.Py generate_flash_encryption_key_my_nvs_encryption key.bin
然后,編譯并燒錄分區表,命令如下:
$ idf.py -P (PORT) partition_table-flash
后,將密鑰燒錄到指定的分區,命令如下:
$ parttool.py -P (PORT) --partition-table-offset "nvs_key_partition offset"write_partition --partition-name="name of nvs_key partition"--input "nvs_keypartition"
(3)啟用NVS 加密方案后,以nvs_get 或nvs_set 開頭的API,在讀/寫NVS分區的數據時將自動完成數據的加/解密。
注意:啟用 Flash 加密方案后,推薦啟用NVS 加密方案(默認啟用),這是因為智能家居matter協議模塊樂鑫科技wifi加密芯片Wi-Fi驅動程序在默認的 NVS 分區中存儲了一些重要數據(如SSID 和密碼)。NVS 加密方案可在多個不同的 NVS 分區中使用不同的 nvs_key,在初始化對應的 NVS 分區時,只需要指定使用的nvs_key即可。
13.3.7 Flash 加密方案和 NVS 加密方案的示例
ESP-IDF的examples/security/flash encryption 提供了 Flash 加密方案和NVS加密方案的示例。通過運行該示例,可以觀察 Flash 加密和 NVS 加密后的 Log 信息。
如前所述,若 Flash 加密的工作模式為開發模式,則可以重復燒錄固件。我們嘗試使用下面的三條命令將固件數據燒錄到啟用了 Flash 加密方案(開發模式)的設備上。
命令1:
$ idf.py -P PORT flash monitor
命令2:
$ idf.py -p PORr encrypted-flash monitor
命令3:
$ idf.py -p PORT encrypted-app-flash monitor
上述三條命令執行的情況和結果分別是:當使用命令 1進行燒錄時,Flash 上終存儲的是明文數據,從而出現無法加載的錯誤:使用命令 2 將僅燒錄加密的 Bootloader 固件、app 固件和分區表,設備可以正常加載運行:使用命令 3 將僅燒錄加密的 app 固件,若 Bootloader 是加密的,則設備可以正常加載運行。
上述三條命令內部實際調用了 esptool.py,它們分別對應的 esptool.py 命令參數為:
$ esptool.py --chip esp32c3 -p /dev/ttyusB0 -b 460800 --before=default_reset--after= no_reset_write_flash --flash mode dio --flash freq 40m --flash size 2ME0x1000 bootloader/bootloader 0x20000 flash encryption,bin 0xa000 partition tablelpartition-table.bin
$ esptool.py --chip esp32c3 -p /dev/ttyuSB0 -b 460800 --before=default_reset--after= no_reset_write_flash --flash mode dio --flash freg 40m --flash size 2M--encrypt 0x1000 bootloader/bootloader 0x20000 flash encryption.bin 0xa000partition table/ partition-table.bin
$ esptool.py --chip esp32c3 -p /dev/ttyUSB0 -b 460800 --before=default_reset--after= no_reset_write_flash --flash_mode dio --flash_freg 40m --flash_size 2MB--encrypt 0x20000 flash_encryption.bin
通過對比 esptool.py 對應的選項和參數,我們不難得出結論:使用 esptool.py 進行燒錄時,添加選項 --encrypt 后,將在燒錄時啟用 Flash 自動加密的功能,將加密后的數據寫入 Flash 中。
啟用智能家居matter協議模塊樂鑫科技wifi加密芯片Flash 加密方案后,常見的幾種錯誤如下:
(1)啟用 Flash 加密方案后,若燒錄的是明文 Bootloader 數據,則在啟動設備后,可能出現如下的 Log:
rst:0x3 (SW_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
invalid header: 0xb414f76b
invalid header: 0xb414f76b
invalid header: 0xb414f76b
invalid header:0xb414f76b
invalid header: 0xb414f76b
invalid header: 0xb414f76b
invalid header: 0xb414f76b
(2) 啟用 Flash 加密方案后,若燒錄的是明文分區表,則在啟動設備后,可能出現如下 Log:
rst:0x3 (SW RESET),boot:0x13 (SPI FAST FLASH BOOT)
configsip: 0,SPIWP:Oxee
clk drv;0x00,q drv:0x00,d drv;0x00,cs0 drv:0x00,hd drv:0x00,wp drv:0x00
mode:DIO,clock div:2
load:0x3fff0018,len:4
load:0x3ffF001c,len:10464
ho 0 tail 12 room 4
load:0x40078000,len:19168
load:0x40080400,Ien:6664
entry 0x40080764
I(60) boot: ESP-IDF 4.0-dev-763-g2c55fae6c-dirty 2nd stage bootloader
I (60) boot: compile time 19:15:54
I (62) boot: Enabling RNG early entropy source...
I (67) boot:SPI Speed:40MHz
I(72) boot; SPI Mode: DIO
I (76) boot: SPI Flash Size : 4MB
E(80) flash_parts: partition 0 invalid magic number 0x94f6
E(86) boot: Failed to verify partition table
E(91) boot: load partition table error!
(3)啟用智能家居matter協議模塊樂鑫科技wifi加密芯片Flash 加密方案后,若燒錄的是明文 app 固件,則在啟動設備后,可能出現如下Log:
rst:0x3 (SW RESET),boot:0x13 (SPI FAST FLASH BOOT)
configsip: 0,SPIWP:Oxee
Clk_drv;0x00,q drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO,clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:8452
load:0x40078000,len:13616
load:0x40080400,len:6664
entry 0x40080764
I(56) boot: ESP-IDE v4.0-dev-850-gc4447462d-dirty 2nd stage bootloader
I (56) boot: compile time 15:37:14
I (58) boot: Enabling RNG early entropy source...
I(64) boot: SPI Speed: 40MHz
I (68) boot: SPI Mode: DIO
I (72) boot: SPI Flash size: 4MB
I (76) boot: Partition Table:
I (79) boot: ## Label Usage Type ST OffsetLength
I (87) boot: 0 nvs Wi-Fi data 01 02 0000a000 00006000
I (94) boot: 1 phy_init RF data 01 01 00010000 00001000
I (102) boot: 2 factory factory app 00 00 00020000 00100000
I (109) boot: End of partition table
I(113) esp image: image at 0x20000 has invalid magic byte
W (120) esp image: image at 0x20000 has invalid SPI mode 108
W (126) esp image: image at 0x20000 has invalid SPI size 11
E(132) boot: Factory app partition is not bootable
E (138) boot: No bootable app partitions in the partition table