diff --git a/.gitlab/ci/dependencies/dependencies.yml b/.gitlab/ci/dependencies/dependencies.yml index 8220351063..2cd4cd47c0 100644 --- a/.gitlab/ci/dependencies/dependencies.yml +++ b/.gitlab/ci/dependencies/dependencies.yml @@ -141,6 +141,7 @@ build:integration_test: - flash_multi - ecdsa - ccs811 # pytest*ccs811* + - nvs_encr_hmac patterns: - "{0}-{1}-{2}" - "{0}-{2}" diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index 61b91ac9cc..a04b20b9a9 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -320,6 +320,15 @@ - "components/efuse/**/*" - "components/mbedtls/port/ecdsa/*" +.patterns-component_ut-nvs_encr_hmac: &patterns-component_ut-nvs_encr_hmac + - "components/nvs_flash/**/*" + - "components/nvs_sec_provider/**/*" + +.patterns-example_test-nvs_encr_hmac: &patterns-example_test-nvs_encr_hmac + - "components/nvs_flash/**/*" + - "components/nvs_sec_provider/**/*" + - "examples/security/nvs_encryption_hmac/**/*" + ############## # if anchors # ############## @@ -627,6 +636,8 @@ changes: *patterns-component_ut - <<: *if-dev-push changes: *patterns-component_ut-flash_multi + - <<: *if-dev-push + changes: *patterns-component_ut-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-component_ut-sdio - <<: *if-dev-push @@ -662,6 +673,8 @@ changes: *patterns-component_ut - <<: *if-dev-push changes: *patterns-component_ut-flash_multi + - <<: *if-dev-push + changes: *patterns-component_ut-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-component_ut-sdio - <<: *if-dev-push @@ -696,6 +709,8 @@ changes: *patterns-component_ut - <<: *if-dev-push changes: *patterns-component_ut-flash_multi + - <<: *if-dev-push + changes: *patterns-component_ut-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-component_ut-sdio - <<: *if-dev-push @@ -730,6 +745,8 @@ changes: *patterns-component_ut - <<: *if-dev-push changes: *patterns-component_ut-flash_multi + - <<: *if-dev-push + changes: *patterns-component_ut-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-component_ut-sdio - <<: *if-dev-push @@ -764,6 +781,8 @@ changes: *patterns-component_ut - <<: *if-dev-push changes: *patterns-component_ut-flash_multi + - <<: *if-dev-push + changes: *patterns-component_ut-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-component_ut-sdio - <<: *if-dev-push @@ -798,6 +817,8 @@ changes: *patterns-component_ut - <<: *if-dev-push changes: *patterns-component_ut-flash_multi + - <<: *if-dev-push + changes: *patterns-component_ut-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-component_ut-sdio - <<: *if-dev-push @@ -832,6 +853,8 @@ changes: *patterns-component_ut - <<: *if-dev-push changes: *patterns-component_ut-flash_multi + - <<: *if-dev-push + changes: *patterns-component_ut-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-component_ut-sdio - <<: *if-dev-push @@ -866,6 +889,8 @@ changes: *patterns-component_ut - <<: *if-dev-push changes: *patterns-component_ut-flash_multi + - <<: *if-dev-push + changes: *patterns-component_ut-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-component_ut-sdio - <<: *if-dev-push @@ -1145,6 +1170,8 @@ changes: *patterns-example_test-ethernet - <<: *if-dev-push changes: *patterns-example_test-i154 + - <<: *if-dev-push + changes: *patterns-example_test-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-example_test-sdio - <<: *if-dev-push @@ -1188,6 +1215,8 @@ changes: *patterns-example_test-ethernet - <<: *if-dev-push changes: *patterns-example_test-i154 + - <<: *if-dev-push + changes: *patterns-example_test-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-example_test-sdio - <<: *if-dev-push @@ -1230,6 +1259,8 @@ changes: *patterns-example_test-ethernet - <<: *if-dev-push changes: *patterns-example_test-i154 + - <<: *if-dev-push + changes: *patterns-example_test-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-example_test-sdio - <<: *if-dev-push @@ -1273,6 +1304,8 @@ changes: *patterns-example_test-ethernet - <<: *if-dev-push changes: *patterns-example_test-i154 + - <<: *if-dev-push + changes: *patterns-example_test-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-example_test-sdio - <<: *if-dev-push @@ -1315,6 +1348,8 @@ changes: *patterns-example_test-ethernet - <<: *if-dev-push changes: *patterns-example_test-i154 + - <<: *if-dev-push + changes: *patterns-example_test-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-example_test-sdio - <<: *if-dev-push @@ -1357,6 +1392,8 @@ changes: *patterns-example_test-ethernet - <<: *if-dev-push changes: *patterns-example_test-i154 + - <<: *if-dev-push + changes: *patterns-example_test-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-example_test-sdio - <<: *if-dev-push @@ -1399,6 +1436,8 @@ changes: *patterns-example_test-ethernet - <<: *if-dev-push changes: *patterns-example_test-i154 + - <<: *if-dev-push + changes: *patterns-example_test-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-example_test-sdio - <<: *if-dev-push @@ -1441,6 +1480,8 @@ changes: *patterns-example_test-ethernet - <<: *if-dev-push changes: *patterns-example_test-i154 + - <<: *if-dev-push + changes: *patterns-example_test-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-example_test-sdio - <<: *if-dev-push @@ -1544,6 +1585,8 @@ changes: *patterns-component_ut - <<: *if-dev-push changes: *patterns-component_ut-flash_multi + - <<: *if-dev-push + changes: *patterns-component_ut-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-component_ut-sdio - <<: *if-dev-push @@ -1562,6 +1605,8 @@ changes: *patterns-example_test-ethernet - <<: *if-dev-push changes: *patterns-example_test-i154 + - <<: *if-dev-push + changes: *patterns-example_test-nvs_encr_hmac - <<: *if-dev-push changes: *patterns-example_test-sdio - <<: *if-dev-push @@ -1997,6 +2042,19 @@ - <<: *if-dev-push changes: *patterns-component_ut-flash_multi +.rules:test:component_ut-esp32c3-nvs_encr_hmac: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-component_ut + - <<: *if-label-component_ut_esp32c3 + - <<: *if-label-target_test + - <<: *if-dev-push + changes: *patterns-component_ut-nvs_encr_hmac + .rules:test:component_ut-esp32c3-sdio: rules: - <<: *if-revert-branch @@ -2501,6 +2559,19 @@ when: never - <<: *if-example_test-ota-include_nightly_run-rule +.rules:test:example_test-esp32c3-nvs_encr_hmac: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-protected + - <<: *if-label-build-only + when: never + - <<: *if-label-example_test + - <<: *if-label-example_test_esp32c3 + - <<: *if-label-target_test + - <<: *if-dev-push + changes: *patterns-example_test-nvs_encr_hmac + .rules:test:example_test-esp32c3-sdio: rules: - <<: *if-revert-branch diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index ca1cdb0c36..97203f7367 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -410,6 +410,14 @@ pytest_examples_esp32c3_flash_encryption: - build_pytest_examples_esp32c3 tags: [ esp32c3, flash_encryption ] +pytest_examples_esp32c3_nvs_encr_hmac: + extends: + - .pytest_examples_dir_template + - .rules:test:example_test-esp32c3-nvs_encr_hmac + needs: + - build_pytest_examples_esp32c3 + tags: [ esp32c3, nvs_encr_hmac ] + pytest_examples_esp32s2_usb_device: extends: - .pytest_examples_dir_template @@ -844,6 +852,14 @@ pytest_components_esp32c3_flash_encryption: - build_pytest_components_esp32c3 tags: [ esp32c3, flash_encryption ] +pytest_components_esp32c3_nvs_encr_hmac: + extends: + - .pytest_components_dir_template + - .rules:test:component_ut-esp32c3-nvs_encr_hmac + needs: + - build_pytest_components_esp32c3 + tags: [ esp32c3, nvs_encr_hmac ] + pytest_components_esp32c3_flash_multi: extends: - .pytest_components_dir_template diff --git a/components/nvs_flash/test_apps/main/CMakeLists.txt b/components/nvs_flash/test_apps/main/CMakeLists.txt index 1553014c85..093fc198ba 100644 --- a/components/nvs_flash/test_apps/main/CMakeLists.txt +++ b/components/nvs_flash/test_apps/main/CMakeLists.txt @@ -1,8 +1,10 @@ idf_component_register(SRC_DIRS "." - PRIV_REQUIRES cmock test_utils nvs_flash bootloader_support spi_flash - EMBED_TXTFILES encryption_keys.bin partition_encrypted.bin sample.bin + PRIV_REQUIRES cmock test_utils nvs_flash nvs_sec_provider + bootloader_support spi_flash + EMBED_TXTFILES encryption_keys.bin partition_encrypted.bin + partition_encrypted_hmac.bin sample.bin WHOLE_ARCHIVE) -if(CONFIG_NVS_ENCRYPTION) +if(CONFIG_NVS_ENCRYPTION OR CONFIG_SOC_HMAC_SUPPORTED) target_link_libraries(${COMPONENT_LIB} PUBLIC idf::mbedtls) endif() diff --git a/components/nvs_flash/test_apps/main/partition_encrypted_hmac.bin b/components/nvs_flash/test_apps/main/partition_encrypted_hmac.bin new file mode 100644 index 0000000000..6b9a14c867 Binary files /dev/null and b/components/nvs_flash/test_apps/main/partition_encrypted_hmac.bin differ diff --git a/components/nvs_flash/test_apps/main/partition_plaintext.bin b/components/nvs_flash/test_apps/main/partition_plaintext.bin new file mode 100644 index 0000000000..76fe712226 Binary files /dev/null and b/components/nvs_flash/test_apps/main/partition_plaintext.bin differ diff --git a/components/nvs_flash/test_apps/main/test_nvs.c b/components/nvs_flash/test_apps/main/test_nvs.c index 9a7b19b76d..45abee6831 100644 --- a/components/nvs_flash/test_apps/main/test_nvs.c +++ b/components/nvs_flash/test_apps/main/test_nvs.c @@ -19,13 +19,19 @@ #include "nvs.h" #include "nvs_flash.h" +#include "nvs_sec_provider.h" #include "unity.h" +#include "memory_checks.h" #ifdef CONFIG_NVS_ENCRYPTION #include "mbedtls/aes.h" #endif +#ifdef CONFIG_SOC_HMAC_SUPPORTED +#include "esp_hmac.h" +#endif + static const char* TAG = "test_nvs"; TEST_CASE("Partition name no longer than 16 characters", "[nvs]") @@ -89,7 +95,58 @@ TEST_CASE("nvs_flash_init_partition_ptr() works correctly", "[nvs]") nvs_flash_deinit(); } -#endif + +#ifdef CONFIG_SOC_HMAC_SUPPORTED +/* TODO: This test does not run in CI as the runner assigned has + * flash encryption enabled by default. Enabling flash encryption + * 'selects' NVS encryption; a new runner needs to be setup + * for testing the HMAC NVS encryption scheme without flash encryption + * enabled for this test. + */ +TEST_CASE("test nvs encryption with HMAC-based scheme without toggling any config options", "[nvs_encr_hmac]") +{ + nvs_handle_t handle; + + nvs_sec_cfg_t cfg = {}; + nvs_sec_scheme_t *sec_scheme_handle = NULL; + + nvs_sec_config_hmac_t sec_scheme_cfg = {}; + hmac_key_id_t hmac_key = HMAC_KEY0; + sec_scheme_cfg.hmac_key_id = hmac_key; + + TEST_ESP_OK(nvs_sec_provider_register_hmac(&sec_scheme_cfg, &sec_scheme_handle)); + + esp_err_t err = nvs_flash_read_security_cfg_v2(sec_scheme_handle, &cfg); + if (err != ESP_OK) { + if (err == ESP_ERR_NVS_SEC_HMAC_KEY_NOT_FOUND) { + TEST_ESP_OK(nvs_flash_generate_keys_v2(sec_scheme_handle, &cfg)); + } + TEST_ESP_OK(err); + } + + TEST_ESP_OK(nvs_flash_secure_init(&cfg)); + memset(&cfg, 0x00, sizeof(nvs_sec_cfg_t)); + + int32_t foo = 0; + + TEST_ESP_OK(nvs_open("uninit_ns", NVS_READWRITE, &handle)); + TEST_ESP_OK(nvs_set_i32(handle, "foo", 0x12345678)); + TEST_ESP_OK(nvs_commit(handle)); + nvs_close(handle); + + TEST_ESP_OK(nvs_open("uninit_ns", NVS_READWRITE, &handle)); + TEST_ESP_OK(nvs_get_i32(handle, "foo", &foo)); + nvs_close(handle); + + TEST_ASSERT_EQUAL_INT32(foo, 0x12345678); + + TEST_ESP_OK(nvs_sec_provider_deregister(sec_scheme_handle)); + + TEST_ESP_OK(nvs_flash_deinit()); + TEST_ESP_OK(nvs_flash_erase()); +} +#endif // CONFIG_SOC_HMAC_SUPPORTED +#endif // !CONFIG_NVS_ENCRYPTION // test could have different output on host tests TEST_CASE("nvs deinit with open handle", "[nvs]") @@ -334,29 +391,31 @@ TEST_CASE("check for memory leaks in nvs_set_blob", "[nvs]") #ifdef CONFIG_NVS_ENCRYPTION TEST_CASE("check underlying xts code for 32-byte size sector encryption", "[nvs]") { - uint8_t eky_hex[2 * NVS_KEY_SIZE] = { 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, - /* Tweak key below*/ - 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, - 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, - 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, - 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22 }; + uint8_t eky_hex[2 * NVS_KEY_SIZE] = { /* Encryption key below*/ + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + /* Tweak key below*/ + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22 }; + uint8_t ba_hex[16] = { 0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; uint8_t ptxt_hex[32] = { 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, - 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, - 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, - 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 }; + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 }; uint8_t ctxt_hex[32] = { 0xe6,0x22,0x33,0x4f,0x18,0x4b,0xbc,0xe1, - 0x29,0xa2,0x5b,0x2a,0xc7,0x6b,0x3d,0x92, - 0xab,0xf9,0x8e,0x22,0xdf,0x5b,0xdd,0x15, - 0xaf,0x47,0x1f,0x3d,0xb8,0x94,0x6a,0x85 }; + 0x29,0xa2,0x5b,0x2a,0xc7,0x6b,0x3d,0x92, + 0xab,0xf9,0x8e,0x22,0xdf,0x5b,0xdd,0x15, + 0xaf,0x47,0x1f,0x3d,0xb8,0x94,0x6a,0x85 }; mbedtls_aes_xts_context ectx[1]; mbedtls_aes_xts_context dctx[1]; @@ -375,27 +434,34 @@ TEST_CASE("check underlying xts code for 32-byte size sector encryption", "[nvs] TEST_CASE("Check nvs key partition APIs (read and generate keys)", "[nvs]") { nvs_sec_cfg_t cfg, cfg2; - - const esp_partition_t* key_part = esp_partition_find_first( - ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS, NULL); - +#if CONFIG_NVS_SEC_KEY_PROTECT_USING_FLASH_ENC if (!esp_flash_encryption_enabled()) { TEST_IGNORE_MESSAGE("flash encryption disabled, skipping nvs_key partition related tests"); } + const esp_partition_t* key_part = esp_partition_find_first( + ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS, NULL); + TEST_ESP_OK(esp_partition_erase_range(key_part, 0, key_part->size)); TEST_ESP_ERR(ESP_ERR_NVS_KEYS_NOT_INITIALIZED, nvs_flash_read_security_cfg(key_part, &cfg)); TEST_ESP_OK(nvs_flash_generate_keys(key_part, &cfg)); TEST_ESP_OK(nvs_flash_read_security_cfg(key_part, &cfg2)); +#elif CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC + nvs_sec_scheme_t *scheme_cfg = nvs_flash_get_default_security_scheme(); + assert(scheme_cfg != NULL); + TEST_ESP_OK(nvs_flash_generate_keys_v2(scheme_cfg, &cfg)); + + TEST_ESP_OK(nvs_flash_read_security_cfg_v2(scheme_cfg, &cfg2)); +#endif TEST_ASSERT_TRUE(!memcmp(&cfg, &cfg2, sizeof(nvs_sec_cfg_t))); } - TEST_CASE("test nvs apis with encryption enabled", "[nvs]") { +#if CONFIG_NVS_SEC_KEY_PROTECT_USING_FLASH_ENC if (!esp_flash_encryption_enabled()) { TEST_IGNORE_MESSAGE("flash encryption disabled, skipping nvs_api tests with encryption enabled"); } @@ -404,19 +470,23 @@ TEST_CASE("test nvs apis with encryption enabled", "[nvs]") assert(key_part && "partition table must have an NVS Key partition"); + ESP_ERROR_CHECK(esp_partition_erase_range(key_part, 0, key_part->size)); +#endif + const esp_partition_t* nvs_partition = esp_partition_find_first( ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL); assert(nvs_partition && "partition table must have an NVS partition"); - ESP_ERROR_CHECK( esp_partition_erase_range(key_part, 0, key_part->size) ); - bool done = false; do { - ESP_ERROR_CHECK( esp_partition_erase_range(nvs_partition, 0, nvs_partition->size) ); - nvs_sec_cfg_t cfg; - esp_err_t err = nvs_flash_read_security_cfg(key_part, &cfg); + esp_err_t err = ESP_FAIL; + +#if CONFIG_NVS_SEC_KEY_PROTECT_USING_FLASH_ENC + ESP_ERROR_CHECK(esp_partition_erase_range(nvs_partition, 0, nvs_partition->size)); + + err = nvs_flash_read_security_cfg(key_part, &cfg); if(err == ESP_ERR_NVS_KEYS_NOT_INITIALIZED) { uint8_t value[4096] = {[0 ... 4095] = 0xff}; @@ -430,6 +500,23 @@ TEST_CASE("test nvs apis with encryption enabled", "[nvs]") ESP_ERROR_CHECK(err); done = true; } +#elif CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC + nvs_sec_scheme_t *scheme_cfg = nvs_flash_get_default_security_scheme(); + assert(scheme_cfg != NULL); + + err = nvs_flash_read_security_cfg_v2(scheme_cfg, &cfg); + if (err != ESP_OK) { + if (err == ESP_ERR_NVS_SEC_HMAC_KEY_NOT_FOUND) { + TEST_ESP_OK(nvs_flash_generate_keys_v2(scheme_cfg, &cfg)); + } else { + ESP_ERROR_CHECK(err); + } + } else { + ESP_ERROR_CHECK(err); + done = true; + } +#endif + TEST_ESP_OK(nvs_flash_secure_init(&cfg)); nvs_handle_t handle_1; @@ -484,45 +571,59 @@ TEST_CASE("test nvs apis with encryption enabled", "[nvs]") TEST_CASE("test nvs apis for nvs partition generator utility with encryption enabled", "[nvs_part_gen]") { - - if (!esp_flash_encryption_enabled()) { - TEST_IGNORE_MESSAGE("flash encryption disabled, skipping nvs_api tests with encryption enabled"); - } - nvs_handle_t handle; nvs_sec_cfg_t xts_cfg; - - extern const char nvs_key_start[] asm("_binary_encryption_keys_bin_start"); - extern const char nvs_key_end[] asm("_binary_encryption_keys_bin_end"); - - extern const char nvs_data_start[] asm("_binary_partition_encrypted_bin_start"); - - extern const char sample_bin_start[] asm("_binary_sample_bin_start"); - - const esp_partition_t* key_part = esp_partition_find_first( - ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS, NULL); + esp_err_t err = ESP_FAIL; const esp_partition_t* nvs_part = esp_partition_find_first( ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL); - assert(key_part && "partition table must have a KEY partition"); - TEST_ASSERT_TRUE((nvs_key_end - nvs_key_start - 1) == SPI_FLASH_SEC_SIZE); - assert(nvs_part && "partition table must have an NVS partition"); printf("\n nvs_part size:%" PRId32 "\n", nvs_part->size); + ESP_ERROR_CHECK(esp_partition_erase_range(nvs_part, 0, nvs_part->size)); + + extern const char sample_bin_start[] asm("_binary_sample_bin_start"); + +#if CONFIG_NVS_SEC_KEY_PROTECT_USING_FLASH_ENC + if (!esp_flash_encryption_enabled()) { + TEST_IGNORE_MESSAGE("flash encryption disabled, skipping nvs_api tests with encryption enabled"); + } + + extern const char nvs_key_start[] asm("_binary_encryption_keys_bin_start"); + extern const char nvs_key_end[] asm("_binary_encryption_keys_bin_end"); + extern const char nvs_data_sch0_start[] asm("_binary_partition_encrypted_bin_start"); + + const esp_partition_t* key_part = esp_partition_find_first( + ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS, NULL); + + assert(key_part && "partition table must have a KEY partition"); + TEST_ASSERT_TRUE((nvs_key_end - nvs_key_start - 1) == SPI_FLASH_SEC_SIZE); + ESP_ERROR_CHECK(esp_partition_erase_range(key_part, 0, key_part->size)); - ESP_ERROR_CHECK( esp_partition_erase_range(nvs_part, 0, nvs_part->size) ); for (int i = 0; i < key_part->size; i+= SPI_FLASH_SEC_SIZE) { ESP_ERROR_CHECK( esp_partition_write(key_part, i, nvs_key_start + i, SPI_FLASH_SEC_SIZE) ); } for (int i = 0; i < nvs_part->size; i+= SPI_FLASH_SEC_SIZE) { - ESP_ERROR_CHECK( esp_partition_write(nvs_part, i, nvs_data_start + i, SPI_FLASH_SEC_SIZE) ); + ESP_ERROR_CHECK( esp_partition_write(nvs_part, i, nvs_data_sch0_start + i, SPI_FLASH_SEC_SIZE) ); } - esp_err_t err = nvs_flash_read_security_cfg(key_part, &xts_cfg); + err = nvs_flash_read_security_cfg(key_part, &xts_cfg); +#elif CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC + extern const char nvs_data_sch1_start[] asm("_binary_partition_encrypted_hmac_bin_start"); + + for (int i = 0; i < nvs_part->size; i+= SPI_FLASH_SEC_SIZE) { + ESP_ERROR_CHECK( esp_partition_write(nvs_part, i, nvs_data_sch1_start + i, SPI_FLASH_SEC_SIZE) ); + } + + nvs_sec_scheme_t *scheme_cfg = nvs_flash_get_default_security_scheme(); + assert(scheme_cfg != NULL); + + err = nvs_flash_read_security_cfg_v2(scheme_cfg, &xts_cfg); +#endif + ESP_ERROR_CHECK(err); TEST_ESP_OK(nvs_flash_secure_init(&xts_cfg)); @@ -583,4 +684,46 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena TEST_ESP_OK(nvs_flash_deinit()); } + +#if CONFIG_NVS_SEC_KEY_PROTECT_USING_FLASH_ENC +TEST_CASE("test nvs encryption with Flash Encryption-based scheme with v2 apis", "[nvs]") +{ + nvs_handle_t handle; + + nvs_sec_cfg_t cfg = {}; + nvs_sec_scheme_t *sec_scheme_handle = NULL; + nvs_sec_config_flash_enc_t sec_scheme_cfg = NVS_SEC_PROVIDER_CFG_FLASH_ENC_DEFAULT(); + + TEST_ESP_OK(nvs_sec_provider_register_flash_enc(&sec_scheme_cfg, &sec_scheme_handle)); + + esp_err_t err = nvs_flash_read_security_cfg_v2(sec_scheme_handle, &cfg); + if (err != ESP_OK) { + if (err == ESP_ERR_NVS_KEYS_NOT_INITIALIZED) { + TEST_ESP_OK(nvs_flash_generate_keys_v2(sec_scheme_handle, &cfg)); + } + TEST_ESP_OK(err); + } + + TEST_ESP_OK(nvs_flash_secure_init(&cfg)); + memset(&cfg, 0x00, sizeof(nvs_sec_cfg_t)); + + int32_t foo = 0; + + TEST_ESP_OK(nvs_open("uninit_ns", NVS_READWRITE, &handle)); + TEST_ESP_OK(nvs_set_i32(handle, "foo", 0x12345678)); + nvs_close(handle); + + TEST_ESP_OK(nvs_open("uninit_ns", NVS_READWRITE, &handle)); + TEST_ESP_OK(nvs_get_i32(handle, "foo", &foo)); + nvs_close(handle); + + TEST_ASSERT_EQUAL_INT32(foo, 0x12345678); + + TEST_ESP_OK(nvs_sec_provider_deregister(sec_scheme_handle)); + + TEST_ESP_OK(nvs_flash_deinit()); + TEST_ESP_OK(nvs_flash_erase()); +} +#endif + #endif diff --git a/components/nvs_flash/test_apps/partitions_nvs_encr_keys_flash_enc.csv b/components/nvs_flash/test_apps/partitions_nvs_encr_flash_enc.csv similarity index 100% rename from components/nvs_flash/test_apps/partitions_nvs_encr_keys_flash_enc.csv rename to components/nvs_flash/test_apps/partitions_nvs_encr_flash_enc.csv diff --git a/components/nvs_flash/test_apps/pytest_nvs_flash.py b/components/nvs_flash/test_apps/pytest_nvs_flash.py index ed07f4f729..1da98e2da0 100644 --- a/components/nvs_flash/test_apps/pytest_nvs_flash.py +++ b/components/nvs_flash/test_apps/pytest_nvs_flash.py @@ -4,23 +4,31 @@ import pytest from pytest_embedded_idf.dut import IdfDut +CONFIGS_NVS_ENCR_FLASH_ENC = [ + pytest.param('nvs_encr_flash_enc_esp32', marks=[pytest.mark.esp32]), + pytest.param('nvs_encr_flash_enc_esp32c3', marks=[pytest.mark.esp32c3]), +] + @pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', ['default'], indirect=True) def test_nvs_flash(dut: IdfDut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('![nvs_encr_hmac]') + dut.expect_unity_test_output(timeout=120) + + +@pytest.mark.esp32c3 +@pytest.mark.nvs_encr_hmac +@pytest.mark.parametrize('config', ['nvs_encr_hmac_esp32c3'], indirect=True) +def test_nvs_flash_encr_hmac(dut: IdfDut) -> None: dut.run_all_single_board_cases() -CONFIGS_NVS_ENCR_KEYS_FLASH_ENC = [ - pytest.param('nvs_encr_keys_flash_enc_esp32', marks=[pytest.mark.esp32]), - pytest.param('nvs_encr_keys_flash_enc_esp32c3', marks=[pytest.mark.esp32c3]), -] - - -@pytest.mark.parametrize('config', CONFIGS_NVS_ENCR_KEYS_FLASH_ENC, indirect=True) @pytest.mark.flash_encryption -def test_nvs_flash_encr_keys_flash_enc(dut: IdfDut) -> None: +@pytest.mark.parametrize('config', CONFIGS_NVS_ENCR_FLASH_ENC, indirect=True) +def test_nvs_flash_encr_flash_enc(dut: IdfDut) -> None: # Erase the nvs_key partition dut.serial.erase_partition('nvs_key') dut.run_all_single_board_cases() diff --git a/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_keys_flash_enc_esp32 b/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_flash_enc_esp32 similarity index 65% rename from components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_keys_flash_enc_esp32 rename to components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_flash_enc_esp32 index 28b989f246..ac5486ed7f 100644 --- a/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_keys_flash_enc_esp32 +++ b/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_flash_enc_esp32 @@ -3,8 +3,8 @@ CONFIG_IDF_TARGET="esp32" # Partition Table CONFIG_PARTITION_TABLE_CUSTOM=y -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_nvs_encr_keys_flash_enc.csv" -CONFIG_PARTITION_TABLE_FILENAME="partitions_nvs_encr_keys_flash_enc.csv" +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_nvs_encr_flash_enc.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_nvs_encr_flash_enc.csv" CONFIG_PARTITION_TABLE_OFFSET=0x9000 # Enabling Flash Encryption @@ -16,3 +16,7 @@ CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y + +# Enabling NVS Encryption (Flash Encryption-based scheme) +CONFIG_NVS_ENCRYPTION=y +CONFIG_NVS_SEC_KEY_PROTECT_USING_FLASH_ENC=y diff --git a/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_keys_flash_enc_esp32c3 b/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_flash_enc_esp32c3 similarity index 65% rename from components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_keys_flash_enc_esp32c3 rename to components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_flash_enc_esp32c3 index 6a986fa54d..ae23bea21d 100644 --- a/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_keys_flash_enc_esp32c3 +++ b/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_flash_enc_esp32c3 @@ -3,8 +3,8 @@ CONFIG_IDF_TARGET="esp32c3" # Partition Table CONFIG_PARTITION_TABLE_CUSTOM=y -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_nvs_encr_keys_flash_enc.csv" -CONFIG_PARTITION_TABLE_FILENAME="partitions_nvs_encr_keys_flash_enc.csv" +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_nvs_encr_flash_enc.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_nvs_encr_flash_enc.csv" CONFIG_PARTITION_TABLE_OFFSET=0x9000 # Enabling Flash Encryption @@ -16,3 +16,7 @@ CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y + +# Enabling NVS Encryption (Flash Encryption-based scheme) +CONFIG_NVS_ENCRYPTION=y +CONFIG_NVS_SEC_KEY_PROTECT_USING_FLASH_ENC=y diff --git a/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_hmac_esp32c3 b/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_hmac_esp32c3 new file mode 100644 index 0000000000..f208fae5ec --- /dev/null +++ b/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_hmac_esp32c3 @@ -0,0 +1,24 @@ +# Restricting to ESP32C3 +CONFIG_IDF_TARGET="esp32c3" + +# NOTE: The runner for this test-app has flash-encryption enabled +# Partition Table +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_nvs_encr_flash_enc.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_nvs_encr_flash_enc.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x9000 + +# Enabling Flash Encryption +CONFIG_SECURE_FLASH_ENC_ENABLED=y +CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y +CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=y +CONFIG_SECURE_BOOT_ALLOW_JTAG=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y +CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y + +# Enabling NVS Encryption (HMAC-based scheme) +CONFIG_NVS_ENCRYPTION=y +CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC=y +CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID=0 diff --git a/components/nvs_flash/test_nvs_host/Makefile b/components/nvs_flash/test_nvs_host/Makefile index be4e5c46b3..0ac5df21fc 100644 --- a/components/nvs_flash/test_nvs_host/Makefile +++ b/components/nvs_flash/test_nvs_host/Makefile @@ -33,7 +33,7 @@ else COMPILER := gcc endif -CPPFLAGS += -I../private_include -I../include -I../src -I../../esp_rom/include -I../../esp_rom/include/linux -I../../log/include -I./ -I../../esp_common/include -I../../esp32/include -I ../../mbedtls/mbedtls/include -I ../../spi_flash/include -I ../../esp_partition/include -I ../../hal/include -I ../../xtensa/include -I ../../../tools/catch -fprofile-arcs -ftest-coverage -g2 -ggdb +CPPFLAGS += -I../private_include -I../include -I../src -I../../esp_rom/include -I../../esp_rom/include/linux -I../../log/include -I./ -I../../esp_common/include -I../../esp32/include -I ../../mbedtls/mbedtls/include -I ../../spi_flash/include -I ../../esp_partition/include -I ../../hal/include -I ../../xtensa/include -I ../../soc/linux/include -I ../../../tools/catch -fprofile-arcs -ftest-coverage -g2 -ggdb CFLAGS += -fprofile-arcs -ftest-coverage -DLINUX_TARGET -DLINUX_HOST_LEGACY_TEST CXXFLAGS += -std=c++11 -Wall -Werror -DLINUX_TARGET -DLINUX_HOST_LEGACY_TEST LDFLAGS += -lstdc++ -Wall -fprofile-arcs -ftest-coverage @@ -93,10 +93,14 @@ clean: clean-coverage rm -f ../nvs_partition_generator/partition_single_page.bin rm -f ../nvs_partition_generator/partition_multipage_blob.bin rm -f ../nvs_partition_generator/partition_encrypted.bin + rm -f ../nvs_partition_generator/partition_encrypted_hmac.bin rm -f ../nvs_partition_generator/partition_encrypted_using_keygen.bin rm -f ../nvs_partition_generator/partition_encrypted_using_keyfile.bin + rm -f ../nvs_partition_generator/partition_encrypted_using_keygen_hmac.bin rm -f ../nvs_partition_generator/partition_decrypted.bin + rm -f ../nvs_partition_generator/partition_decrypted_hmac.bin rm -f ../nvs_partition_generator/partition_encoded.bin + rm -f ../nvs_partition_generator/Test-1-partition-encrypted-hmac.bin rm -f ../nvs_partition_generator/Test-1-partition-encrypted.bin rm -f ../nvs_partition_generator/Test-1-partition.bin rm -f ../../../tools/mass_mfg/samples/sample_values_multipage_blob_created.csv diff --git a/components/nvs_flash/test_nvs_host/test_nvs.cpp b/components/nvs_flash/test_nvs_host/test_nvs.cpp index 6550927015..1fae2c15e3 100644 --- a/components/nvs_flash/test_nvs_host/test_nvs.cpp +++ b/components/nvs_flash/test_nvs_host/test_nvs.cpp @@ -11,6 +11,7 @@ #include "nvs_partition_manager.hpp" #include "nvs_partition.hpp" #include "mbedtls/aes.h" +#include "mbedtls/md.h" #include #include #include @@ -1567,12 +1568,24 @@ TEST_CASE("test decrypt functionality for encrypted data", "[nvs_part_gen]") status = system("python ../nvs_partition_generator/nvs_partition_gen.py encrypt ../nvs_partition_generator/sample_multipage_blob.csv partition_encrypted.bin 0x5000 --inputkey ../nvs_partition_generator/testdata/sample_encryption_keys.bin --outdir ../nvs_partition_generator"); CHECK(status == 0); + //encrypting data from sample_multipage_blob.csv (hmac-based scheme) + status = system("python ../nvs_partition_generator/nvs_partition_gen.py encrypt ../nvs_partition_generator/sample_multipage_blob.csv partition_encrypted_hmac.bin 0x5000 --keygen --key_protect_hmac --kp_hmac_inputkey ../nvs_partition_generator/testdata/sample_hmac_key.bin --outdir ../nvs_partition_generator"); + CHECK(status == 0); + //decrypting data from partition_encrypted.bin status = system("python ../nvs_partition_generator/nvs_partition_gen.py decrypt ../nvs_partition_generator/partition_encrypted.bin ../nvs_partition_generator/testdata/sample_encryption_keys.bin ../nvs_partition_generator/partition_decrypted.bin"); CHECK(status == 0); status = system("diff ../nvs_partition_generator/partition_decrypted.bin ../nvs_partition_generator/partition_encoded.bin"); CHECK(status == 0); + + //decrypting data from partition_encrypted_hmac.bin + status = system("python ../nvs_partition_generator/nvs_partition_gen.py decrypt ../nvs_partition_generator/partition_encrypted_hmac.bin ../nvs_partition_generator/testdata/sample_encryption_keys_hmac.bin ../nvs_partition_generator/partition_decrypted_hmac.bin"); + CHECK(status == 0); + + status = system("diff ../nvs_partition_generator/partition_decrypted_hmac.bin ../nvs_partition_generator/partition_encoded.bin"); + CHECK(status == 0); + CHECK(WEXITSTATUS(status) == 0); @@ -1757,6 +1770,201 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena } +static void compute_nvs_keys_with_hmac(nvs_sec_cfg_t *cfg, void *hmac_key) +{ + unsigned char key_bytes[32] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20 }; + if (hmac_key != NULL){ + memcpy(key_bytes, hmac_key, 32); + } + + unsigned char ekey_seed[32], tkey_seed[32]; + + for (unsigned int i = 0; i < sizeof(ekey_seed); i+=4) { + ekey_seed[i] = 0x5A; + ekey_seed[i + 1] = 0x5A; + ekey_seed[i + 2] = 0xBE; + ekey_seed[i + 3] = 0xAE; + } + + for (unsigned int i = 0; i < sizeof(tkey_seed); i+=4) { + tkey_seed[i] = 0xA5; + tkey_seed[i + 1] = 0xA5; + tkey_seed[i + 2] = 0xDE; + tkey_seed[i + 3] = 0xCE; + } + + const mbedtls_md_type_t alg = MBEDTLS_MD_SHA256; + + mbedtls_md_context_t ctx; + mbedtls_md_init(&ctx); + + const mbedtls_md_info_t *info = mbedtls_md_info_from_type(alg); + mbedtls_md_setup(&ctx, info, 1); + mbedtls_md_hmac_starts(&ctx, key_bytes, sizeof(key_bytes)); + + mbedtls_md_hmac_update(&ctx, ekey_seed, sizeof(ekey_seed)); + mbedtls_md_hmac_finish(&ctx, cfg->eky); + + mbedtls_md_hmac_reset(&ctx); + mbedtls_md_hmac_update(&ctx, tkey_seed, sizeof(tkey_seed)); + mbedtls_md_hmac_finish(&ctx, cfg->tky); + + assert(memcmp(cfg->eky, cfg->tky, NVS_KEY_SIZE)); + + mbedtls_md_free(&ctx); +} + +TEST_CASE("test nvs apis for nvs partition generator utility with encryption enabled using keygen (user-provided HMAC-key)", "[nvs_part_gen]") +{ + int childpid = fork(); + int status; + + if (childpid == 0) { + exit(execlp("cp", " cp", + "-rf", + "../nvs_partition_generator/testdata", + ".", NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + childpid = fork(); + + if (childpid == 0) { + exit(execlp("rm", " rm", + "-rf", + "../nvs_partition_generator/keys", NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + childpid = fork(); + if (childpid == 0) { + exit(execlp("python", "python", + "../nvs_partition_generator/nvs_partition_gen.py", + "encrypt", + "../nvs_partition_generator/sample_multipage_blob.csv", + "partition_encrypted_using_keygen_hmac.bin", + "0x4000", + "--keygen", + "--key_protect_hmac", + "--kp_hmac_inputkey", + "../nvs_partition_generator/testdata/sample_hmac_key.bin", + "--outdir", + "../nvs_partition_generator", NULL)); + + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + } + } + } + + SpiFlashEmulator emu("../nvs_partition_generator/partition_encrypted_using_keygen_hmac.bin"); + + nvs_sec_cfg_t cfg; + compute_nvs_keys_with_hmac(&cfg, NULL); + + check_nvs_part_gen_args(&emu, NVS_DEFAULT_PART_NAME, 4, "../nvs_partition_generator/testdata/sample_multipage_blob.bin", true, &cfg); + +} + +TEST_CASE("test nvs apis for nvs partition generator utility with encryption enabled using keygen (dynamically generated HMAC-key)", "[nvs_part_gen]") +{ + int childpid = fork(); + int status; + + if (childpid == 0) { + exit(execlp("cp", " cp", + "-rf", + "../nvs_partition_generator/testdata", + ".", NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + childpid = fork(); + + if (childpid == 0) { + exit(execlp("rm", " rm", + "-rf", + "../nvs_partition_generator/keys", NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + childpid = fork(); + if (childpid == 0) { + exit(execlp("python", "python", + "../nvs_partition_generator/nvs_partition_gen.py", + "encrypt", + "../nvs_partition_generator/sample_multipage_blob.csv", + "partition_encrypted_using_keygen_hmac.bin", + "0x4000", + "--keygen", + "--key_protect_hmac", + "--kp_hmac_keygen", + "--outdir", + "../nvs_partition_generator", NULL)); + + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + } + } + } + + + DIR *dir; + struct dirent *file; + char *filename; + char *files; + char *file_ext; + char *hmac_key_file; + + dir = opendir("../nvs_partition_generator/keys"); + while ((file = readdir(dir)) != NULL) { + filename = file->d_name; + file_ext = NULL; + files = strrchr(filename, '.'); + if (files != NULL) { + file_ext = files + 1; + if (strncmp(file_ext, "bin", 3) != 0) { + continue; + } + } + if (strstr(filename, "hmac") != NULL) { + hmac_key_file = filename; + } + } + + std::string hmac_key_path = std::string("../nvs_partition_generator/keys/") + std::string(hmac_key_file); + SpiFlashEmulator emu("../nvs_partition_generator/partition_encrypted_using_keygen_hmac.bin"); + + char hmac_key_buf[32]; + FILE *fp; + fp = fopen(hmac_key_path.c_str(), "rb"); + fread(hmac_key_buf, sizeof(hmac_key_buf), 1, fp); + fclose(fp); + + nvs_sec_cfg_t cfg; + compute_nvs_keys_with_hmac(&cfg, hmac_key_buf); + + check_nvs_part_gen_args(&emu, NVS_DEFAULT_PART_NAME, 4, "../nvs_partition_generator/testdata/sample_multipage_blob.bin", true, &cfg); + +} + TEST_CASE("check and read data from partition generated via manufacturing utility with encryption enabled using sample inputkey", "[mfg_gen]") { int childpid = fork(); @@ -1969,6 +2177,221 @@ TEST_CASE("check and read data from partition generated via manufacturing utilit } } + +TEST_CASE("check and read data from partition generated via manufacturing utility with encryption enabled using new generated key (user-provided HMAC-key)", "[mfg_gen]") +{ + int childpid = fork(); + int status; + + if (childpid == 0) { + exit(execlp("bash", " bash", + "-c", + "rm -rf ../../../tools/mass_mfg/host_test | \ + cp -rf ../../../tools/mass_mfg/testdata mfg_testdata | \ + cp -rf ../nvs_partition_generator/testdata . | \ + mkdir -p ../../../tools/mass_mfg/host_test", NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + childpid = fork(); + if (childpid == 0) { + exit(execlp("python", "python", + "../../../tools/mass_mfg/mfg_gen.py", + "generate", + "../../../tools/mass_mfg/samples/sample_config.csv", + "../../../tools/mass_mfg/samples/sample_values_multipage_blob.csv", + "Test", + "0x4000", + "--version", + "2", + "--keygen", + "--key_protect_hmac", + "--kp_hmac_inputkey", + "mfg_testdata/sample_hmac_key.bin", + "--outdir", + "../../../tools/mass_mfg/host_test",NULL)); + + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + childpid = fork(); + if (childpid == 0) { + exit(execlp("python", "python", + "../nvs_partition_generator/nvs_partition_gen.py", + "encrypt", + "../../../tools/mass_mfg/host_test/csv/Test-1.csv", + "../nvs_partition_generator/Test-1-partition-encrypted-hmac.bin", + "0x4000", + "--version", + "2", + "--keygen", + "--key_protect_hmac", + "--kp_hmac_inputkey", + "mfg_testdata/sample_hmac_key.bin", NULL)); + + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + } + + } + + } + + SpiFlashEmulator emu1("../../../tools/mass_mfg/host_test/bin/Test-1.bin"); + + nvs_sec_cfg_t cfg; + compute_nvs_keys_with_hmac(&cfg, NULL); + + check_nvs_part_gen_args_mfg(&emu1, NVS_DEFAULT_PART_NAME, 4, "mfg_testdata/sample_multipage_blob.bin", true, &cfg); + + SpiFlashEmulator emu2("../nvs_partition_generator/Test-1-partition-encrypted-hmac.bin"); + + check_nvs_part_gen_args_mfg(&emu2, NVS_DEFAULT_PART_NAME, 4, "testdata/sample_multipage_blob.bin", true, &cfg); + + + childpid = fork(); + if (childpid == 0) { + exit(execlp("bash", " bash", + "-c", + "rm -rf ../../../tools/mass_mfg/host_test | \ + rm -rf mfg_testdata | \ + rm -rf testdata", NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + } + +} + +TEST_CASE("check and read data from partition generated via manufacturing utility with encryption enabled using new generated key (dynamically generated HMAC-key)", "[mfg_gen]") +{ + int childpid = fork(); + int status; + + if (childpid == 0) { + exit(execlp("bash", " bash", + "-c", + "rm -rf ../../../tools/mass_mfg/host_test | \ + cp -rf ../../../tools/mass_mfg/testdata mfg_testdata | \ + cp -rf ../nvs_partition_generator/testdata . | \ + mkdir -p ../../../tools/mass_mfg/host_test", NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + childpid = fork(); + if (childpid == 0) { + exit(execlp("python", "python", + "../../../tools/mass_mfg/mfg_gen.py", + "generate-key", + "--outdir", + "../../../tools/mass_mfg/host_test", + "--key_protect_hmac", + "--kp_hmac_keygen", + "--kp_hmac_keyfile", + "hmac_key_host_test.bin", + "--keyfile", + "encr_keys_host_test.bin", NULL)); + + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + childpid = fork(); + if (childpid == 0) { + exit(execlp("python", "python", + "../../../tools/mass_mfg/mfg_gen.py", + "generate", + "../../../tools/mass_mfg/samples/sample_config.csv", + "../../../tools/mass_mfg/samples/sample_values_multipage_blob.csv", + "Test", + "0x4000", + "--outdir", + "../../../tools/mass_mfg/host_test", + "--version", + "2", + "--inputkey", + "../../../tools/mass_mfg/host_test/keys/encr_keys_host_test.bin", NULL)); + + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + childpid = fork(); + if (childpid == 0) { + exit(execlp("python", "python", + "../nvs_partition_generator/nvs_partition_gen.py", + "encrypt", + "../../../tools/mass_mfg/host_test/csv/Test-1.csv", + "../nvs_partition_generator/Test-1-partition-encrypted-hmac.bin", + "0x4000", + "--version", + "2", + "--inputkey", + "../../../tools/mass_mfg/host_test/keys/encr_keys_host_test.bin", NULL)); + + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + } + + } + + } + + } + + + SpiFlashEmulator emu1("../../../tools/mass_mfg/host_test/bin/Test-1.bin"); + + char hmac_key_buf[32]; + FILE *fp; + + fp = fopen("../../../tools/mass_mfg/host_test/keys/hmac_key_host_test.bin", "rb"); + fread(hmac_key_buf, sizeof(hmac_key_buf), 1, fp); + + fclose(fp); + + nvs_sec_cfg_t cfg; + compute_nvs_keys_with_hmac(&cfg, hmac_key_buf); + + check_nvs_part_gen_args_mfg(&emu1, NVS_DEFAULT_PART_NAME, 4, "mfg_testdata/sample_multipage_blob.bin", true, &cfg); + + SpiFlashEmulator emu2("../nvs_partition_generator/Test-1-partition-encrypted-hmac.bin"); + + check_nvs_part_gen_args_mfg(&emu2, NVS_DEFAULT_PART_NAME, 4, "testdata/sample_multipage_blob.bin", true, &cfg); + + childpid = fork(); + if (childpid == 0) { + exit(execlp("bash", " bash", + "-c", + "rm -rf keys | \ + rm -rf mfg_testdata | \ + rm -rf testdata | \ + rm -rf ../../../tools/mass_mfg/host_test", NULL)); + } else { + CHECK(childpid > 0); + waitpid(childpid, &status, 0); + CHECK(WEXITSTATUS(status) == 0); + + } + +} + #endif /* Add new tests above */ diff --git a/conftest.py b/conftest.py index da6f07ba46..385fe9fb26 100644 --- a/conftest.py +++ b/conftest.py @@ -124,6 +124,7 @@ ENV_MARKERS = { 'ecdsa_efuse': 'Runner with test ECDSA private keys programmed in efuse', 'ccs811': 'Runner with CCS811 connected', 'ethernet_w5500': 'SPI Ethernet module with two W5500', + 'nvs_encr_hmac': 'Runner with test HMAC key programmed in efuse', # multi-dut markers 'ieee802154': 'ieee802154 related tests should run on ieee802154 runners.', 'openthread_br': 'tests should be used for openthread border router.',