diff --git a/tests/bsim/bluetooth/mesh/src/test_persistence.c b/tests/bsim/bluetooth/mesh/src/test_persistence.c index 4bf1f9faa93..568df63d919 100644 --- a/tests/bsim/bluetooth/mesh/src/test_persistence.c +++ b/tests/bsim/bluetooth/mesh/src/test_persistence.c @@ -12,6 +12,9 @@ #include "mesh/keys.h" #include +#include +#include + #define LOG_MODULE_NAME test_persistence #include @@ -247,6 +250,7 @@ static const struct stack_cfg { }, }; static const struct stack_cfg *current_stack_cfg; +static bool persist_stuck_key; static void test_args_parse(int argc, char *argv[]) { @@ -267,6 +271,13 @@ static void test_args_parse(int argc, char *argv[]) .name = "{0, 1}", .option = "stack-cfg", .descript = "" + }, + { + .dest = &persist_stuck_key, + .type = 'b', + .name = "{0, 1}", + .option = "persist-stuck-key", + .descript = "PSA ITS has a gotten stuck key" } }; @@ -458,10 +469,68 @@ static void provisioner_setup(void) provisioner_ready = true; } +static void fake_key_setup(void) +{ + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status; + psa_key_id_t key_id = ZEPHYR_PSA_BT_MESH_KEY_ID_RANGE_BEGIN; + psa_key_id_t key_id_imported; + const uint8_t in[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10}; + uint8_t out[16] = {0}; + size_t out_len; + + psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_PERSISTENT); + psa_set_key_id(&key_attributes, key_id); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_EXPORT); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&key_attributes, 128); + + status = psa_import_key(&key_attributes, in, 16, &key_id_imported); + psa_reset_key_attributes(&key_attributes); + if (status != PSA_SUCCESS) { + FAIL("Failed to import fake key"); + } + + if (key_id_imported != key_id) { + FAIL("Imported key ID does not match expected key ID"); + } + + status = psa_export_key(key_id_imported, out, sizeof(out), &out_len); + if (status != PSA_SUCCESS) { + FAIL("Failed to export fake key"); + } + + if (memcmp(out, in, sizeof(in)) != 0 || out_len != sizeof(in)) { + FAIL("Exported key does not match imported key"); + } +} + +static void fake_key_destruction_check(void) +{ + psa_status_t status; + psa_key_id_t key_id = ZEPHYR_PSA_BT_MESH_KEY_ID_RANGE_BEGIN; + uint8_t out[16] = {0}; + size_t out_len; + + status = psa_export_key(key_id, out, sizeof(out), &out_len); + if (status != PSA_SUCCESS) { + FAIL("Failed to export former fake key ID"); + } + + if (memcmp(out, test_devkey, sizeof(out)) != 0 || out_len != sizeof(test_devkey)) { + FAIL("Exported fake key does not match test device key"); + } +} + static void test_provisioning_data_save(void) { bt_mesh_test_cfg_set(NULL, WAIT_TIME); + if (persist_stuck_key) { + fake_key_setup(); + } + if (device_setup_and_self_provision()) { FAIL("Mesh setup failed. Settings should not be loaded."); } @@ -476,6 +545,10 @@ static void test_provisioning_data_load(void) /* In this test stack should boot as provisioned */ bt_mesh_test_cfg_set(NULL, WAIT_TIME); + if (persist_stuck_key) { + fake_key_destruction_check(); + } + if (device_setup_and_self_provision() != -EALREADY) { FAIL("Device should boot up as already provisioned"); } diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/persistence/prov_with_stuck_key.sh b/tests/bsim/bluetooth/mesh/tests_scripts/persistence/prov_with_stuck_key.sh new file mode 100755 index 00000000000..90d65d5cf41 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/persistence/prov_with_stuck_key.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Copyright 2025 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test checks that mesh provisioning data is saved and loaded correctly +# if a key with ID from mesh PSA key ID range exists in the PSA ITS, +# it is destroyed and the correct key is used instead. +# +# Test must be added in pair and in sequence. +# First test: saves data; second test: verifies it. +# +# Test procedure: +# 1. Fake key is created in the PSA ITS to emulate gotten stuck key. +# 2. Device Under Test (DUT) initializes the Mesh stack, +# and starts provisioning and configuration itself. +# 3. Test scenario emulates hardware reset by running the second test +# with stored data from the first test. +# 4. DUT checks that the stuck key was substituted by the real key. +# 5. DUT starts mesh with loading stored data and checks that if they were restored correctly. + +overlay=overlay_pst_conf +RunTestFlash mesh_pst_prov_data_check_stuck_key persistence_provisioning_data_save -flash_erase \ + -- -argstest persist-stuck-key=1 + +overlay=overlay_pst_conf +RunTestFlash mesh_pst_prov_data_check_stuck_key persistence_provisioning_data_load -flash_rm \ + -- -argstest persist-stuck-key=1 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/persistence/provisioning.sh b/tests/bsim/bluetooth/mesh/tests_scripts/persistence/provisioning.sh index d8edd471cac..34581b4c6e1 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/persistence/provisioning.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/persistence/provisioning.sh @@ -4,14 +4,22 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh -# Note: +# Test checks that mesh provisioning data is saved and loaded correctly. +# # Tests must be added in pairs and in sequence. # First test: saves data; second test: verifies it. +# +# Test procedure: +# 1. Device Under Test (DUT) initializes the Mesh stack, +# and starts provisioning and configuration itself. +# 2. Test scenario emulates hardware reset by running the second test +# with stored data from the first test. +# 3. DUT starts mesh with loading stored data and checks that if they were restored correctly. -# SKIP=(persistence_provisioning_data_save) overlay=overlay_pst_conf -RunTestFlash mesh_pst_prov_data_check persistence_provisioning_data_save -flash_erase +RunTestFlash mesh_pst_prov_data_check persistence_provisioning_data_save -flash_erase \ + -- -argstest persist-stuck-key=0 -# SKIP=(persistence_provisioning_data_load) overlay=overlay_pst_conf -RunTestFlash mesh_pst_prov_data_check persistence_provisioning_data_load -flash_rm +RunTestFlash mesh_pst_prov_data_check persistence_provisioning_data_load -flash_rm \ + -- -argstest persist-stuck-key=0