README.md
1# Flash Encryption
2
3The example checks if the flash encryption feature is enabled/disabled and if enabled prints the flash encryption mode (DEVELOPMENT / RELEASE) and FLASH_CRYPT_CNT (for ESP32) or SPI_BOOT_CRYPT_CNT (for ESP32-S2 and newer targets) eFuse value.
4
5The example also demonstrates writing and reading encrypted partitions in flash.
6
7## How to use example
8
9### Hardware Required
10
11### Configure the project
12
13```
14idf.py menuconfig
15```
16#### Configuration for flash encryption
17* Enable the flash encryption mode (Development or Release) under Security Features. Default usage mode is Development (recommended during test and development phase).
18
19Note: After enabling flash encryption, the bootloader size increases, which means that the offset of the partition table must be changed to 0x9000 from 0x8000 to prevent the bootloader from overlapping with the partition table. In this example, the default offset of the partition table is 0x9000.
20
21For better security, the NVS encryption is enabled by default when the flash encryption is enabled. If you choose to disable the NVS encryption, you can skip the NVS configuration step given below.
22
23#### Configuration for NVS encryption
24For using NVS encryption, the partition table must contain the [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition). Two partition tables containing the NVS keys partition are provided for NVS encryption under the partition table option . They can be selected with the project configuration menu (`menuconfig -> Partition Table`). This particular example uses a custom partition table as it requires a `storage` partition along with the `nvs_keys` partition.
25
26The configuration for NVS encryption involves generating the XTS encryption keys in the [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition) partition. It can be done with one of the following method.
27
281. Generate the XTS encryption keys on the ESP chip:
29
30 When NVS encryption is enabled the `nvs_flash_init` API function can internally generate the XTS encryption keys on the ESP chip. The API function finds the first [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition) i.e. a partition of type `data` and subtype `nvs_keys`.
31 Then the API function automatically generates and stores the
32 nvs keys in that partition. New keys are generated and stored only when the respective key partiton is empty. (Consult the [`nvs_flash_init`](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#_CPPv414nvs_flash_initv) API documentation in the ESP-IDF programming guide for more details)
33
342. Use pre-generated XTS encryption keys:
35 This method will be required by the user when the `XTS encryption keys` in [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition) are not generated by the application.
36 The pre generated `Sample XTS encryption keys` can be stored on the flash with help of the following two commands
37
38 i) Build and flash the partition table:
39 ```
40 idf.py partition-table partition-table-flash
41 ```
42 ii) Store the `sample_encryption_keys.bin` in the `nvs_key`partition (on the flash) with the help of [parttool.py](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/partition-tables.html#partition-tool-parttool-py):
43 ```
44 parttool.py --port /dev/ttyUSB0 --partition-table-offset 0x9000 write_partition --partition-name="nvs_key" --input sample_encryption_keys.bin
45 ```
46 The sample [NVS key partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#nvs-key-partition) partition used in this example is generated with the help of [NVS Partition Generator Utility](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_partition_gen.html#nvs-partition-generator-utility)
47 .
48
49### Build and Flash
50
51When building the project and flashing it to the board FOR THE FIRST TIME after enabling flash encryption feature in menuconfig, run following command to program the target and monitor the output:
52
53```
54idf.py -p PORT flash monitor
55```
56
57(To exit the serial monitor, type ``Ctrl-]``.)
58
59See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
60
61When reprogramming the device subsequently use following command for encrypted write of new plaintext application:
62
63```
64idf.py -p PORT encrypted-app-flash monitor
65```
66
67Please note above command programs only the app partition. In order to reprogram all partitions (bootloader, partition table and application) in encrypted form use:
68
69```
70idf.py -p PORT encrypted-flash monitor
71```
72
73## Example Output
74
75When running the example without enabling flash encryption, the output would be as follows (on ESP32):
76
77```
78Example to check Flash Encryption status
79This is ESP32 chip with 2 CPU cores, WiFi/BT/BLE, silicon revision 0, 2MB external flash
80FLASH_CRYPT_CNT eFuse value is 0
81Flash encryption feature is disabled
82Erasing partition "storage" (0x1000 bytes)
83Writing data with esp_partition_write:
84I (378) example: 0x3ffb4dc0 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................|
85I (378) example: 0x3ffb4dd0 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................|
86Reading with esp_partition_read:
87I (388) example: 0x3ffb4da0 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................|
88I (398) example: 0x3ffb4db0 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................|
89Reading with spi_flash_read:
90I (408) example: 0x3ffb4da0 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................|
91I (418) example: 0x3ffb4db0 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................|
92```
93
94After enabling flash encryption in Development mode, the output shows the process of enabling the flash encryption:
95
96```
97I (168) boot: Checking flash encryption...
98I (168) flash_encrypt: Generating new flash encryption key...
99I (187) flash_encrypt: Read & write protecting new key...
100I (187) flash_encrypt: Setting CRYPT_CONFIG efuse to 0xF
101W (188) flash_encrypt: Not disabling UART bootloader encryption
102I (195) flash_encrypt: Disable UART bootloader decryption...
103I (201) flash_encrypt: Disable UART bootloader MMU cache...
104I (208) flash_encrypt: Disable JTAG...
105I (212) flash_encrypt: Disable ROM BASIC interpreter fallback...
106....
107....
108....
109I (13229) flash_encrypt: Flash encryption completed
110I (13229) boot: Resetting with flash encryption enabled...
111```
112
113Once the flash encryption is enabled the device will reset itself. At this stage the flash contents are in encrypted form. The output would be similar to:
114
115```
116Example to check Flash Encryption status
117This is ESP32 chip with 2 CPU cores, WiFi/BT/BLE, silicon revision 0, 4MB external flash
118FLASH_CRYPT_CNT eFuse value is 1
119Flash encryption feature is enabled in DEVELOPMENT mode
120Erasing partition "storage" (0x1000 bytes)
121Writing data with esp_partition_write:
122I (451) example: 0x3ffb4dc0 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................|
123I (451) example: 0x3ffb4dd0 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................|
124Reading with esp_partition_read:
125I (461) example: 0x3ffb4da0 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |................|
126I (471) example: 0x3ffb4db0 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f |................|
127Reading with spi_flash_read:
128I (491) example: 0x3ffb4b30 35 9b f2 07 b4 6d 40 89 28 b4 1e 22 98 7b 4a 36 |5....m@.(..".{J6|
129I (491) example: 0x3ffb4b40 ba 89 81 67 77 a3 60 5e 0a e7 51 01 b3 58 c2 f6 |...gw.`^..Q..X..|
130```
131
132If the NVS encryption is enabled, then the output will show the status of the encrypted partition as follows
133
134```
135I (667) example_nvs: NVS partition "nvs" is encrypted.
136```
137## Troubleshooting
138
139It is also possible to use esptool.py utility to read the eFuse values and check if flash encryption is enabled or not
140
141```
142python $IDF_PATH/components/esptool_py/esptool/espefuse.py --port PORT summary
143```
144
145If FLASH_CRYPT_CNT (for ESP32) or SPI_BOOT_CRYPT_CNT (for ESP32-S2 and newer targets) eFuse value is non-zero flash encryption is enabled
146