Skip to content

Commit 0e04d8a

Browse files
dssengfabiobaltieri
authored andcommitted
settings: tfm_psa: add support for PS backend
Protected Storage is another type of secure (encrypted and authenticated) storage available using PSA interfaces. When targeting TF-M builds, allow making use of PS for storing settings Fixes #94681 Signed-off-by: Dmitrii Sharshakov <[email protected]>
1 parent 06eb147 commit 0e04d8a

File tree

3 files changed

+77
-17
lines changed

3 files changed

+77
-17
lines changed

include/zephyr/psa/ps_ids.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
* Copyright (c) 2025 Analog Devices, Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#ifndef ZEPHYR_PSA_PS_IDS_H_
7+
#define ZEPHYR_PSA_PS_IDS_H_
8+
9+
/** UID range to be used by the TF-M PSA PS Settings backend. */
10+
#define ZEPHYR_PSA_SETTINGS_TFM_PS_UID_RANGE_BEGIN 0x2C000000
11+
#define ZEPHYR_PSA_SETTINGS_TFM_PS_UID_RANGE_SIZE 0x10000 /* 64 Ki */
12+
13+
#endif /* ZEPHYR_PSA_PS_IDS_H_ */

subsys/settings/Kconfig

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,12 @@ config SETTINGS_CUSTOM
145145

146146
config SETTINGS_TFM_PSA
147147
bool "TF-M PSA"
148-
depends on TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
148+
depends on BUILD_WITH_TFM
149149
select EXPERIMENTAL
150150
help
151151
Enables PSA Settings backend. Intended for use with boards
152152
using TF-M which cannot make use of persistent storage otherwise.
153-
This backend uses the PSA Internal Trusted Storage (ITS) service to store settings data.
153+
This backend uses the PSA ITS or PS service to store settings data.
154154
Note: This settings backend compacts settings data into as few secure storage nodes as possible.
155155
After each save, the entire settings array is written to the secure storage. To avoid excessive
156156
latency on saving, settings are saved after a delay using a kernel work item.
@@ -269,6 +269,26 @@ config SETTINGS_SHELL
269269

270270
if SETTINGS_TFM_PSA
271271

272+
choice SETTINGS_TFM_PSA_BACKEND
273+
prompt "TF-M PSA Settings backend"
274+
default SETTINGS_TFM_PSA_BACKEND_ITS
275+
help
276+
PSA storage option to be used by the PSA settings backend.
277+
278+
config SETTINGS_TFM_PSA_BACKEND_PS
279+
bool "PSA Protected Storage (PS)"
280+
depends on TFM_PARTITION_PROTECTED_STORAGE
281+
help
282+
Use PSA Protected Storage as settings storage backend.
283+
284+
config SETTINGS_TFM_PSA_BACKEND_ITS
285+
bool "PSA Internal Trusted Storage (ITS)"
286+
depends on TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
287+
help
288+
Use PSA Internal Trusted Storage as settings storage backend.
289+
290+
endchoice # SETTINGS_TFM_PSA_BACKEND
291+
272292
config SETTINGS_TFM_PSA_NUM_ENTRIES
273293
int "Maximum number of settings entries"
274294
default 10
@@ -285,7 +305,7 @@ config SETTINGS_TFM_PSA_LAZY_PERSIST_DELAY_MS
285305
unacceptable for time-sensitive events.
286306
Data is always persisted to the secure storage using k_work_delayable, instead of happening in
287307
the same context as settings_save. This option sets the delay with which the
288-
work item is scheduled. The delay is useful in cases where a PSA ITS write may
308+
work item is scheduled. The delay is useful in cases where a write may
289309
block a time-sensitive event, for example Bluetooth pairing, which requires a
290310
sequence of settings writes.
291311

subsys/settings/src/settings_tfm_psa.c

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66
* SPDX-License-Identifier: Apache-2.0
77
*/
88

9-
#include <psa/internal_trusted_storage.h>
9+
#include <config_tfm.h>
1010
#include <zephyr/settings/settings.h>
1111
#include <zephyr/kernel.h>
1212
#include <zephyr/logging/log.h>
13-
#include <zephyr/psa/its_ids.h>
1413

1514
/* TF-M config file containing ITS_MAX_ASSET_SIZE */
1615
#include <config_base.h>
@@ -36,17 +35,40 @@ static const struct settings_store_itf settings_psa_itf = {
3635

3736
static struct settings_store default_settings_psa = {.cs_itf = &settings_psa_itf};
3837

38+
#if defined(CONFIG_SETTINGS_TFM_PSA_BACKEND_PS)
39+
#include <psa/protected_storage.h>
40+
#include <zephyr/psa/ps_ids.h>
41+
42+
#define SETTINGS_PSA_MAX_ASSET_SIZE PS_MAX_ASSET_SIZE
43+
#define SETTINGS_PSA_UID_RANGE_BEGIN ZEPHYR_PSA_SETTINGS_TFM_PS_UID_RANGE_BEGIN
44+
#define SETTINGS_PSA_UID_RANGE_SIZE ZEPHYR_PSA_SETTINGS_TFM_PS_UID_RANGE_SIZE
45+
#define SETTINGS_PSA_SET psa_ps_set
46+
#define SETTINGS_PSA_GET psa_ps_get
47+
48+
#elif defined(CONFIG_SETTINGS_TFM_PSA_BACKEND_ITS)
49+
#include <psa/internal_trusted_storage.h>
50+
#include <zephyr/psa/its_ids.h>
51+
52+
#define SETTINGS_PSA_MAX_ASSET_SIZE ITS_MAX_ASSET_SIZE
53+
#define SETTINGS_PSA_UID_RANGE_BEGIN ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN
54+
#define SETTINGS_PSA_UID_RANGE_SIZE ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_SIZE
55+
#define SETTINGS_PSA_SET psa_its_set
56+
#define SETTINGS_PSA_GET psa_its_get
57+
58+
#else
59+
#error "No PSA backend selected"
60+
#endif /* CONFIG_SETTINGS_TFM_PSA_BACKEND */
61+
3962
/* Ensure Key configured max size does not exceed reserved Key range */
40-
BUILD_ASSERT(sizeof(entries) / ITS_MAX_ASSET_SIZE <=
41-
ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN,
42-
"entries array exceeds reserved ITS UID range");
63+
BUILD_ASSERT(sizeof(entries) / SETTINGS_PSA_MAX_ASSET_SIZE <=
64+
SETTINGS_PSA_UID_RANGE_SIZE,
65+
"entries array exceeds reserved PSA storage UID range");
4366

4467
static int store_entries(void)
4568
{
4669
psa_status_t status;
47-
psa_storage_uid_t uid = ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN;
70+
psa_storage_uid_t uid = SETTINGS_PSA_UID_RANGE_BEGIN;
4871
size_t remaining = sizeof(entries);
49-
size_t chunk_size = ITS_MAX_ASSET_SIZE;
5072
const uint8_t *data_ptr = (const uint8_t *)&entries;
5173

5274
/*
@@ -55,9 +77,12 @@ static int store_entries(void)
5577
* number of allocated UIDs and to allocate bytes in the most efficient way.
5678
*/
5779
while (remaining > 0) {
58-
size_t write_size = (remaining > chunk_size) ? chunk_size : remaining;
80+
size_t write_size = SETTINGS_PSA_MAX_ASSET_SIZE;
81+
if (remaining < SETTINGS_PSA_MAX_ASSET_SIZE) {
82+
write_size = remaining;
83+
}
5984

60-
status = psa_its_set(uid, write_size, data_ptr, PSA_STORAGE_FLAG_NONE);
85+
status = SETTINGS_PSA_SET(uid, write_size, data_ptr, PSA_STORAGE_FLAG_NONE);
6186
if (status) {
6287
LOG_ERR("Error storing %d bytes of metadata! Bytes Remaining: %d, status: "
6388
"%d",
@@ -70,7 +95,7 @@ static int store_entries(void)
7095
uid++;
7196
}
7297

73-
LOG_DBG("PSA storage entries stored successfully - bytes_saved: %d num_entries: %d max_uid: %lld",
98+
LOG_DBG("PSA entries stored successfully - bytes_saved: %d num_entries: %d max_uid: %lld",
7499
sizeof(entries), entries_count, uid);
75100

76101
return 0;
@@ -80,9 +105,8 @@ static int load_entries(void)
80105
{
81106
psa_status_t status;
82107
size_t bytes_read;
83-
psa_storage_uid_t uid = ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN;
108+
psa_storage_uid_t uid = SETTINGS_PSA_UID_RANGE_BEGIN;
84109
size_t remaining = sizeof(entries);
85-
size_t chunk_size = ITS_MAX_ASSET_SIZE;
86110
uint8_t *data_ptr = (uint8_t *)&entries;
87111

88112
/*
@@ -91,9 +115,12 @@ static int load_entries(void)
91115
* number of allocated UIDs and to allocate bytes in the most efficient way.
92116
*/
93117
while (remaining > 0) {
94-
size_t to_read = (remaining > chunk_size) ? chunk_size : remaining;
118+
size_t read_size = SETTINGS_PSA_MAX_ASSET_SIZE;
119+
if (remaining < SETTINGS_PSA_MAX_ASSET_SIZE) {
120+
read_size = remaining;
121+
}
95122

96-
status = psa_its_get(uid, 0, to_read, data_ptr, &bytes_read);
123+
status = SETTINGS_PSA_GET(uid, 0, read_size, data_ptr, &bytes_read);
97124
if (status) {
98125
return status;
99126
}

0 commit comments

Comments
 (0)