1 /* Flash encryption Example
2 
3    This example code is in the Public Domain (or CC0 licensed, at your option.)
4 
5    Unless required by applicable law or agreed to in writing, this
6    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7    CONDITIONS OF ANY KIND, either express or implied.
8 */
9 #include <stdio.h>
10 #include "freertos/FreeRTOS.h"
11 #include "freertos/task.h"
12 #include "soc/efuse_reg.h"
13 #include "esp_efuse.h"
14 #include "esp_system.h"
15 #include "esp_spi_flash.h"
16 #include "esp_partition.h"
17 #include "esp_flash_encrypt.h"
18 #include "esp_efuse_table.h"
19 #include "nvs_flash.h"
20 
21 static void example_print_chip_info(void);
22 static void example_print_flash_encryption_status(void);
23 static void example_read_write_flash(void);
24 
25 static const char* TAG = "example";
26 
27 #if CONFIG_IDF_TARGET_ESP32
28 #define TARGET_CRYPT_CNT_EFUSE  ESP_EFUSE_FLASH_CRYPT_CNT
29 #define TARGET_CRYPT_CNT_WIDTH  7
30 #else
31 #define TARGET_CRYPT_CNT_EFUSE ESP_EFUSE_SPI_BOOT_CRYPT_CNT
32 #define TARGET_CRYPT_CNT_WIDTH  3
33 #endif
34 
app_main(void)35 void app_main(void)
36 {
37     printf("\nExample to check Flash Encryption status\n");
38 
39     example_print_chip_info();
40     example_print_flash_encryption_status();
41     example_read_write_flash();
42     /* Initialize the default NVS partition */
43     esp_err_t ret = nvs_flash_init();
44     if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
45         ESP_ERROR_CHECK(nvs_flash_erase());
46         ret = nvs_flash_init();
47     }
48     ESP_ERROR_CHECK(ret);
49 }
50 
51 
example_print_chip_info(void)52 static void example_print_chip_info(void)
53 {
54     /* Print chip information */
55     esp_chip_info_t chip_info;
56     esp_chip_info(&chip_info);
57     printf("This is %s chip with %d CPU core(s), WiFi%s%s, ",
58             CONFIG_IDF_TARGET,
59             chip_info.cores,
60             (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
61             (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
62 
63     printf("silicon revision %d, ", chip_info.revision);
64 
65     printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
66             (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
67 }
68 
69 
example_print_flash_encryption_status(void)70 static void example_print_flash_encryption_status(void)
71 {
72     uint32_t flash_crypt_cnt = 0;
73     esp_efuse_read_field_blob(TARGET_CRYPT_CNT_EFUSE, &flash_crypt_cnt, TARGET_CRYPT_CNT_WIDTH);
74     printf("FLASH_CRYPT_CNT eFuse value is %d\n", flash_crypt_cnt);
75 
76     esp_flash_enc_mode_t mode = esp_get_flash_encryption_mode();
77     if (mode == ESP_FLASH_ENC_MODE_DISABLED) {
78         printf("Flash encryption feature is disabled\n");
79     } else {
80         printf("Flash encryption feature is enabled in %s mode\n",
81             mode == ESP_FLASH_ENC_MODE_DEVELOPMENT ? "DEVELOPMENT" : "RELEASE");
82     }
83 }
84 
85 
example_read_write_flash(void)86 static void example_read_write_flash(void)
87 {
88     const esp_partition_t* partition = esp_partition_find_first(
89         ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "storage");
90     assert(partition);
91 
92     printf("Erasing partition \"%s\" (0x%x bytes)\n", partition->label, partition->size);
93 
94     ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size));
95 
96     /* Generate the data which will be written */
97     const size_t data_size = 32;
98     uint8_t plaintext_data[data_size];
99     for (uint8_t i = 0; i < data_size; ++i) {
100         plaintext_data[i] = i;
101     }
102 
103     printf("Writing data with esp_partition_write:\n");
104     ESP_LOG_BUFFER_HEXDUMP(TAG, plaintext_data, data_size, ESP_LOG_INFO);
105     ESP_ERROR_CHECK(esp_partition_write(partition, 0, plaintext_data, data_size));
106 
107     uint8_t read_data[data_size];
108     printf("Reading with esp_partition_read:\n");
109     ESP_ERROR_CHECK(esp_partition_read(partition, 0, read_data, data_size));
110     ESP_LOG_BUFFER_HEXDUMP(TAG, read_data, data_size, ESP_LOG_INFO);
111 
112     printf("Reading with spi_flash_read:\n");
113     ESP_ERROR_CHECK(spi_flash_read(partition->address, read_data, data_size));
114     ESP_LOG_BUFFER_HEXDUMP(TAG, read_data, data_size, ESP_LOG_INFO);
115 }
116