- I (279) cpu_start: Unicore app
- I (287) cpu_start: Pro cpu start user code
- I (287) cpu_start: cpu freq: 160000000 Hz
- I (288) app_init: Application information:
- I (290) app_init: Project name: icollector
- I (295) app_init: App version: 4c30755-dirty
- I (301) app_init: Compile time: Jan 17 2025 16:33:19
- I (307) app_init: ELF file SHA256: ec0e0f887...
- I (312) app_init: ESP-IDF: v5.3.1
- I (317) efuse_init: Min chip rev: v0.3
- I (322) efuse_init: Max chip rev: v1.99
- I (327) efuse_init: Chip rev: v0.4
- I (331) heap_init: Initializing. RAM available for dynamic allocation:
- I (339) heap_init: At 3FC9F0D0 len 00020F30 (131 KiB): RAM
- I (345) heap_init: At 3FCC0000 len 0001C710 (113 KiB): Retention RAM
- I (352) heap_init: At 3FCDC710 len 00002950 (10 KiB): Retention RAM
- I (359) heap_init: At 50000204 len 00001DE4 (7 KiB): RTCRAM
- I (366) spi_flash: detected chip: generic
- I (370) spi_flash: flash io: dio
- W (374) flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)
- I (382) nvs_sec_provider: NVS Encryption - Registering HMAC-based scheme...
- I (389) sleep: Configure to isolate all GPIO pins in sleep state
- I (395) sleep: Enable automatic switching of GPIO sleep configuration
- I (403) main_task: Started on CPU0
- I (403) main_task: Calling app_main()
- I (403) gpio: GPIO[0]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
- I (413) MAIN: Collector code: 0076A727843C
- I (423) CERT_MANAGER: NVS security cfg set up successfully.
- I (453) STORAGE: Partition size: total: 956561, used: 502
- I (453) gpio: GPIO[9]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2
- I (463) WIFI STATION: Content retrieved from last successful connection. Using it...
- I (463) WIFI STATION: Trying to connect to wifi access point...
- I (513) nvs: NVS partition "nvs" is encrypted.
- I (513) pp: pp rom version: 9387209
- I (513) net80211: net80211 rom version: 9387209
- (... wifi related stuff)
- I (17353) CERT_MANAGER: NVS Partition labeled "nvs_storage" found.
- I (17353) CERT_MANAGER: Flash initialized successfully.
- I (17353) CERT_MANAGER: NVS handle opened successfully.
- E (17363) CERT_MANAGER: Failed to retrieve PEM: ESP_ERR_NVS_NOT_FOUND
- E (17363) MQTT: Could not retrieve certification data. Retrying...
- I (17373) CERT_MANAGER: NVS Partition labeled "nvs_storage" found.
- (.. loops)
Heres my current workflow:
- # 1. Create keys:
- espsecure.py generate_flash_encryption_key flash_encryption_key.bin
- nvs_partition_gen.py generate-key --key_protect_hmac --kp_hmac_keygen \
- --kp_hmac_keyfile hmac_key.bin --keyfile nvs_encr_key.bin
- # 2. Burn keys:
- espefuse.py -p /dev/ttyACM0 burn_key BLOCK_KEY2 flash_encryption_key.bin XTS_AES_128_KEY
- espefuse.py -p /dev/ttyACM0 burn_key BLOCK_KEY3 keys/hmac_key.bin HMAC_UP
- # 3. Create nvs partition image:
- nvs_partition_gen.py encrypt certs/cert_data.csv nvs_encr_partition.bin 0x8000 --inputkey keys/nvs_encr_key.bin
- # 4. Encrypt build:
- espsecure.py encrypt_flash_data --aes_xts --keyfile flash_encryption_key.bin \
- --address 0x0 --output bootloader-enc.bin build/bootloader/bootloader.bin
- espsecure.py encrypt_flash_data --aes_xts --keyfile flash_encryption_key.bin \
- --address 0x8000 --output partition-table-enc.bin build/partition_table/partition-table.bin
- espsecure.py encrypt_flash_data --aes_xts --keyfile flash_encryption_key.bin \
- --address 0x19000 --output ota_data_initial-enc.bin build/ota_data_initial.bin
- espsecure.py encrypt_flash_data --aes_xts --keyfile flash_encryption_key.bin \
- --address 0x20000 --output app-enc.bin build/app.bin
- espsecure.py encrypt_flash_data --aes_xts --keyfile flash_encryption_key.bin \
- --address 0xf000 --output final_nvs_encr_partition.bin nvs_encr_partition.bin
- # 5. Flash encrypted data:
- esptool.py --chip esp32c3 -p /dev/ttyACM0 -b 460800 --before=default_reset \
- --after=no_reset --no-stub write_flash --flash_mode dio --flash_freq 80m --flash_size keep \
- 0x0 bootloader-enc.bin \
- 0xf000 final_nvs_encr_partition.bin \
- 0x8000 partition-table-enc.bin \
- 0x19000 ota_data_initial-enc.bin \
- 0x20000 app-enc.bin
Functions involved in the process:
Context: secure_nvs_cfg_init is called in the app_main on start up and retrieve_certification_data is called after wifi has been setup and I will use certificates to setup mqtt client.
- esp_err_t secure_nvs_cfg_init(void)
- {
- esp_err_t err = ESP_FAIL;
- nvs_sec_scheme_t *sec_scheme_handle = NULL;
- nvs_sec_config_hmac_t sec_scheme_cfg = NVS_SEC_PROVIDER_CFG_HMAC_DEFAULT();
- err = nvs_sec_provider_register_hmac(&sec_scheme_cfg, &sec_scheme_handle);
- if (err != ESP_OK) {
- ESP_LOGE(TAG, "Failed to register HMAC scheme for NVS encription: [0x%02X] (%s)", err, esp_err_to_name(err));
- return err;
- }
- err = nvs_flash_read_security_cfg_v2(sec_scheme_handle, &nvs_sec_cfg);
- if (err != ESP_OK)
- {
- ESP_LOGE(TAG, "Failed to read NVS security cfg: [0x%02X] (%s)", err, esp_err_to_name(err));
- }
- else
- {
- ESP_LOGI(TAG, "NVS security cfg set up successfully.");
- }
- return err;
- }
- bool retrieve_certification_data(char* certificate_id, char* pem, char* private_key, char* ca_cert, char* type)
- {
- nvs_handle_t nvs_handle;
- esp_err_t err = nvs_flash_secure_init_partition(NVS_CUSTOM_PARTITION_LABEL, &nvs_sec_cfg);
- if (err != ESP_OK)
- {
- ESP_LOGE(TAG, "Error: %s", esp_err_to_name(err));
- return false;
- }
- // const esp_partition_t* nvs_storage_partition_pointer = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NVS_CUSTOM_PARTITION_LABEL);
- // if (nvs_storage_partition_pointer == NULL)
- // {
- // ESP_LOGI(TAG, "NVS Partition with name \"%s\" not found.", NVS_CUSTOM_PARTITION_LABEL);
- // nvs_flash_deinit_partition(NVS_CUSTOM_PARTITION_LABEL);
- // return false;
- // }
- // else
- // {
- // ESP_LOGI(TAG, "NVS Partition labeled \"%s\" found.", nvs_storage_partition_pointer->label);
- // }
- // err = nvs_flash_init_partition_ptr(nvs_storage_partition_pointer);
- // if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
- // {
- // ESP_LOGI(TAG, "Flash could not be initialized successfully. Error: %s", esp_err_to_name(err));
- // nvs_flash_deinit_partition(NVS_CUSTOM_PARTITION_LABEL);
- // return false;
- // }
- // if (err == ESP_OK)
- // {
- // ESP_LOGI(TAG, "Flash initialized successfully.");
- // }
- err = nvs_open_from_partition(
- NVS_CUSTOM_PARTITION_LABEL, // nvs_storage_partition_pointer->label,
- "cert_storage",
- NVS_READWRITE,
- &nvs_handle
- );
- if (err != ESP_OK)
- {
- ESP_LOGE(TAG, "Failed to open NVS handle: %s", esp_err_to_name(err));
- nvs_flash_deinit_partition(NVS_CUSTOM_PARTITION_LABEL);
- return false;
- }
- else
- {
- ESP_LOGI(TAG, "NVS handle opened successfully.");
- }
- if (certificate_id != NULL)
- {
- size_t certificate_id_size = CERTIFICATE_ID_SIZE;
- err = nvs_get_str(nvs_handle, "cert_id", certificate_id, &certificate_id_size);
- if (err != ESP_OK)
- {
- ESP_LOGE(TAG, "Failed to retrieve certificate_id: %s", esp_err_to_name(err));
- nvs_close(nvs_handle);
- nvs_flash_deinit_partition(NVS_CUSTOM_PARTITION_LABEL);
- return false;
- }
- certificate_id[certificate_id_size - 1] = '\0';
- }
- size_t pem_size = CERTIFICATE_PAYLOAD_SIZE;
- err = nvs_get_str(nvs_handle, "pem", pem, &pem_size);
- if (err != ESP_OK)
- {
- ESP_LOGE(TAG, "Failed to retrieve PEM: %s", esp_err_to_name(err));
- nvs_close(nvs_handle);
- nvs_flash_deinit_partition(NVS_CUSTOM_PARTITION_LABEL);
- return false;
- }
- pem[pem_size - 1] = '\0';
- size_t private_key_size = CERTIFICATE_PAYLOAD_SIZE;
- err = nvs_get_str(nvs_handle, "private_key", private_key, &private_key_size);
- if (err != ESP_OK)
- {
- ESP_LOGE(TAG, "Failed to retrieve private key: %s", esp_err_to_name(err));
- nvs_close(nvs_handle);
- nvs_flash_deinit_partition(NVS_CUSTOM_PARTITION_LABEL);
- return false;
- }
- private_key[private_key_size - 1] = '\0';
- if (ca_cert != NULL)
- {
- size_t ca_cert_size = CERTIFICATE_PAYLOAD_SIZE;
- err = nvs_get_str(nvs_handle, "ca_cert", ca_cert, &ca_cert_size);
- if (err != ESP_OK)
- {
- ESP_LOGE(TAG, "Failed to retrieve ca cert: %s", esp_err_to_name(err));
- nvs_close(nvs_handle);
- nvs_flash_deinit_partition(NVS_CUSTOM_PARTITION_LABEL);
- return false;
- }
- ca_cert[ca_cert_size - 1] = '\0';
- }
- if (type != NULL)
- {
- size_t type_size = 10;
- err = nvs_get_str(nvs_handle, "type", type, &type_size);
- if (err != ESP_OK)
- {
- ESP_LOGE(TAG, "Failed to retrieve certification data type: %s", esp_err_to_name(err));
- nvs_close(nvs_handle);
- nvs_flash_deinit_partition(NVS_CUSTOM_PARTITION_LABEL);
- return false;
- }
- type[type_size - 1] = '\0';
- }
- nvs_close(nvs_handle);
- nvs_flash_deinit_partition(NVS_CUSTOM_PARTITION_LABEL);
- ESP_LOGI(TAG, "Certificate data successfully retrieved.");
- return true;
- }