Skip to content

Commit 78f0621

Browse files
committed
matter: samples: Implement factory reset for persistent storage
* Handle factory reset for secure/non-secure configurations. * Add `FactoryReset` method to `AccessStorage`. * Add application specific factory reset handler. Signed-off-by: Adrian Gielniewski <adrian.gielniewski@nordicsemi.no>
1 parent 62653e8 commit 78f0621

9 files changed

+130
-1
lines changed

samples/matter/common/src/persistent_storage/backends/persistent_storage_secure.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,28 @@ PSErrorCode PersistentStorageSecure::_SecureRemove(PersistentStorageNode *node)
8585
return PSErrorCode::Failure;
8686
}
8787

88+
PSErrorCode PersistentStorageSecure::_SecureFactoryReset()
89+
{
90+
PSErrorCode error = PSErrorCode::Success;
91+
92+
// Remove all keys
93+
for (auto it = std::begin(sUidMap.mMap); it != std::end(sUidMap.mMap) - sUidMap.FreeSlots(); ++it) {
94+
psa_status_t status = psa_ps_remove(it->key);
95+
if (status != PSA_SUCCESS) {
96+
// Set error but try to remove all keys
97+
error = PSErrorCode::Failure;
98+
}
99+
}
100+
101+
// Remove UidMap
102+
psa_status_t status = psa_ps_remove(kKeyOffset);
103+
if (status != PSA_SUCCESS) {
104+
error = PSErrorCode::Failure;
105+
}
106+
107+
return error;
108+
}
109+
88110
psa_storage_uid_t PersistentStorageSecure::UIDFromString(char *str, bool *alreadyInTheMap)
89111
{
90112
for (auto &it : sUidMap.mMap) {

samples/matter/common/src/persistent_storage/backends/persistent_storage_secure.h

+7
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ class PersistentStorageSecure {
2020
PSErrorCode _NonSecureLoad(PersistentStorageNode *node, void *data, size_t dataMaxSize, size_t &outSize);
2121
PSErrorCode _NonSecureHasEntry(PersistentStorageNode *node);
2222
PSErrorCode _NonSecureRemove(PersistentStorageNode *node);
23+
PSErrorCode _NonSecureRemoveSubtree(const char *prefix);
2324

2425
PSErrorCode _SecureInit();
2526
PSErrorCode _SecureStore(PersistentStorageNode *node, const void *data, size_t dataSize);
2627
PSErrorCode _SecureLoad(PersistentStorageNode *node, void *data, size_t dataMaxSize, size_t &outSize);
2728
PSErrorCode _SecureHasEntry(PersistentStorageNode *node);
2829
PSErrorCode _SecureRemove(PersistentStorageNode *node);
30+
PSErrorCode _SecureFactoryReset();
2931

3032
private:
3133
static constexpr size_t kMaxEntriesNumber = CONFIG_NCS_SAMPLE_MATTER_SECURE_STORAGE_MAX_ENTRY_NUMBER;
@@ -117,4 +119,9 @@ inline PSErrorCode PersistentStorageSecure::_NonSecureRemove(PersistentStorageNo
117119
return PSErrorCode::NotSupported;
118120
}
119121

122+
inline PSErrorCode PersistentStorageSecure::_NonSecureRemoveSubtree(const char *prefix)
123+
{
124+
return PSErrorCode::NotSupported;
125+
}
126+
120127
} /* namespace Nrf */

samples/matter/common/src/persistent_storage/backends/persistent_storage_settings.cpp

+36
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ struct ReadEntry {
2020
bool result;
2121
};
2222

23+
struct DeleteSubtreeEntry {
24+
const char *prefix;
25+
int result;
26+
};
27+
2328
/* Random magic bytes to represent an empty value.
2429
It is needed because Zephyr settings subsystem does not distinguish an empty value from no value. */
2530
constexpr uint8_t kEmptyValue[] = { 0x22, 0xa6, 0x54, 0xd1, 0x39 };
@@ -61,6 +66,24 @@ int LoadEntryCallback(const char *name, size_t entrySize, settings_read_cb readC
6166

6267
return 1;
6368
}
69+
70+
int DeleteSubtreeCallback(const char *name, size_t entrySize, settings_read_cb readCb, void *cbArg, void *param)
71+
{
72+
DeleteSubtreeEntry &entry = *static_cast<DeleteSubtreeEntry *>(param);
73+
char fullKey[SETTINGS_MAX_NAME_LEN + 1];
74+
75+
// name comes from Zephyr settings subsystem so it is guaranteed to fit in the buffer.
76+
(void)snprintf(fullKey, sizeof(fullKey), "%s/%s", entry.prefix, name);
77+
const int result = settings_delete(fullKey);
78+
79+
// Return the first error, but continue removing remaining keys anyway.
80+
if (entry.result == 0) {
81+
entry.result = result;
82+
}
83+
84+
return 0;
85+
}
86+
6487
} /* namespace */
6588

6689
namespace Nrf
@@ -160,4 +183,17 @@ bool PersistentStorageSettings::LoadEntry(const char *key, void *data, size_t da
160183

161184
return true;
162185
}
186+
187+
PSErrorCode PersistentStorageSettings::_NonSecureRemoveSubtree(const char *prefix)
188+
{
189+
DeleteSubtreeEntry entry{ prefix, 0 };
190+
int result = settings_load_subtree_direct(prefix, DeleteSubtreeCallback, &entry);
191+
192+
if (result == 0 && entry.result == 0) {
193+
return PSErrorCode::Success;
194+
}
195+
196+
return PSErrorCode::Failure;
197+
}
198+
163199
} /* namespace Nrf */

samples/matter/common/src/persistent_storage/backends/persistent_storage_settings.h

+7
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ class PersistentStorageSettings {
1717
PSErrorCode _NonSecureLoad(PersistentStorageNode *node, void *data, size_t dataMaxSize, size_t &outSize);
1818
PSErrorCode _NonSecureHasEntry(PersistentStorageNode *node);
1919
PSErrorCode _NonSecureRemove(PersistentStorageNode *node);
20+
PSErrorCode _NonSecureRemoveSubtree(const char *prefix);
2021

2122
PSErrorCode _SecureInit();
2223
PSErrorCode _SecureStore(PersistentStorageNode *node, const void *data, size_t dataSize);
2324
PSErrorCode _SecureLoad(PersistentStorageNode *node, void *data, size_t dataMaxSize, size_t &outSize);
2425
PSErrorCode _SecureHasEntry(PersistentStorageNode *node);
2526
PSErrorCode _SecureRemove(PersistentStorageNode *node);
27+
PSErrorCode _SecureFactoryReset();
2628

2729
private:
2830
bool LoadEntry(const char *key, void *data = nullptr, size_t dataMaxSize = 0, size_t *outSize = nullptr);
@@ -55,4 +57,9 @@ inline PSErrorCode PersistentStorageSettings::_SecureRemove(PersistentStorageNod
5557
return PSErrorCode::NotSupported;
5658
}
5759

60+
inline PSErrorCode PersistentStorageSettings::_SecureFactoryReset()
61+
{
62+
return PSErrorCode::NotSupported;
63+
}
64+
5865
} /* namespace Nrf */

samples/matter/common/src/persistent_storage/persistent_storage.h

+24
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,27 @@ class PersistentStorage {
7272
*/
7373
PSErrorCode NonSecureRemove(PersistentStorageNode *node);
7474

75+
/**
76+
* @brief Remove subtree from the persistent storage for given key prefix.
77+
*
78+
* @param prefix key prefix
79+
* @return true if subtree has been removed successfully.
80+
* @return false an error occurred.
81+
*/
82+
PSErrorCode NonSecureRemoveSubtree(const char *prefix);
83+
7584
/* Secure storage API counterparts.*/
7685
PSErrorCode SecureInit();
7786
PSErrorCode SecureStore(PersistentStorageNode *node, const void *data, size_t dataSize);
7887
PSErrorCode SecureLoad(PersistentStorageNode *node, void *data, size_t dataMaxSize, size_t &outSize);
7988
PSErrorCode SecureHasEntry(PersistentStorageNode *node);
8089
PSErrorCode SecureRemove(PersistentStorageNode *node);
8190

91+
/**
92+
* @brief Perform factory reset and remove all keys.
93+
*/
94+
PSErrorCode SecureFactoryReset();
95+
8296
protected:
8397
PersistentStorage() = default;
8498
~PersistentStorage() = default;
@@ -133,6 +147,11 @@ inline PSErrorCode PersistentStorage::NonSecureRemove(PersistentStorageNode *nod
133147
return Impl()->_NonSecureRemove(node);
134148
}
135149

150+
inline PSErrorCode PersistentStorage::NonSecureRemoveSubtree(const char *prefix)
151+
{
152+
return Impl()->_NonSecureRemoveSubtree(prefix);
153+
}
154+
136155
/* Secure storage API. */
137156
inline PSErrorCode PersistentStorage::SecureInit()
138157
{
@@ -160,4 +179,9 @@ inline PSErrorCode PersistentStorage::SecureRemove(PersistentStorageNode *node)
160179
return Impl()->_SecureRemove(node);
161180
}
162181

182+
inline PSErrorCode PersistentStorage::SecureFactoryReset()
183+
{
184+
return Impl()->_SecureFactoryReset();
185+
}
186+
163187
} /* namespace Nrf */

samples/matter/common/src/persistent_storage/persistent_storage_impl.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,16 @@ class PersistentStorageImpl : public PersistentStorage
3131
friend class PersistentStorage;
3232

3333
#ifdef CONFIG_NCS_SAMPLE_MATTER_SETTINGS_STORAGE_BACKEND
34-
3534
using PersistentStorageSettings::_NonSecureHasEntry;
3635
using PersistentStorageSettings::_NonSecureInit;
3736
using PersistentStorageSettings::_NonSecureLoad;
3837
using PersistentStorageSettings::_NonSecureRemove;
38+
using PersistentStorageSettings::_NonSecureRemoveSubtree;
3939
using PersistentStorageSettings::_NonSecureStore;
4040
#endif
4141

4242
#ifdef CONFIG_NCS_SAMPLE_MATTER_SECURE_STORAGE_BACKEND
43+
using PersistentStorageSecure::_SecureFactoryReset;
4344
using PersistentStorageSecure::_SecureHasEntry;
4445
using PersistentStorageSecure::_SecureInit;
4546
using PersistentStorageSecure::_SecureLoad;

samples/matter/lock/src/access/access_storage.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,24 @@ bool AccessStorage::Init()
6565
return (Nrf::PSErrorCode::Success == Nrf::GetPersistentStorage().PSInit());
6666
}
6767

68+
bool AccessStorage::FactoryReset()
69+
{
70+
bool non_secure_result = true;
71+
bool secure_result = true;
72+
73+
#ifdef CONFIG_NCS_SAMPLE_MATTER_SETTINGS_STORAGE_BACKEND
74+
non_secure_result =
75+
Nrf::PSErrorCode::Success == Nrf::GetPersistentStorage().NonSecureRemoveSubtree(kAccessPrefix);
76+
77+
#endif
78+
#ifdef CONFIG_NCS_SAMPLE_MATTER_SECURE_STORAGE_BACKEND
79+
80+
secure_result = Nrf::PSErrorCode::Success == Nrf::GetPersistentStorage().SecureFactoryReset();
81+
#endif
82+
83+
return non_secure_result && secure_result;
84+
}
85+
6886
bool AccessStorage::PrepareKeyName(Type storageType, uint16_t index, uint16_t subindex)
6987
{
7088
memset(mKeyName, '\0', sizeof(mKeyName));

samples/matter/lock/src/access/access_storage.h

+8
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ class AccessStorage {
6363
*/
6464
bool Init();
6565

66+
/**
67+
* @brief Factory reset the persistent storage.
68+
*
69+
* @return true if success.
70+
* @return false otherwise.
71+
*/
72+
bool FactoryReset();
73+
6674
/**
6775
* @brief Store the entry into the persistent storage.
6876
*

samples/matter/lock/src/main.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "app_task.h"
88

9+
#include <access/access_storage.h>
910
#include <zephyr/logging/log.h>
1011

1112
LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL);
@@ -17,3 +18,8 @@ int main()
1718
LOG_ERR("Exited with code %" CHIP_ERROR_FORMAT, err.Format());
1819
return err == CHIP_NO_ERROR ? EXIT_SUCCESS : EXIT_FAILURE;
1920
}
21+
22+
bool AppFactoryResetHandler()
23+
{
24+
return AccessStorage::Instance().FactoryReset();
25+
}

0 commit comments

Comments
 (0)