Skip to content

Commit 37cffb6

Browse files
kapi-nonordicjm
authored andcommitted
bluetooth: fast_pair: storage: add storage module for eik
Added a new Fast Pair storage module for the Ephemeral Identity Key (EIK) that uses the settings subsystem. The EIK storage module is used by the Find My Device Network (FMDN) extension. Signed-off-by: Kamil Piszczek <[email protected]> Signed-off-by: Aleksander Strzebonski <[email protected]>
1 parent 998c209 commit 37cffb6

File tree

5 files changed

+331
-0
lines changed

5 files changed

+331
-0
lines changed

subsys/bluetooth/services/fast_pair/fp_storage/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ endif()
2525
if(CONFIG_BT_FAST_PAIR_STORAGE_FMDN_CLOCK)
2626
target_sources(fp_storage PRIVATE fp_storage_clock.c)
2727
endif()
28+
if(CONFIG_BT_FAST_PAIR_STORAGE_FMDN_EIK)
29+
target_sources(fp_storage PRIVATE fp_storage_eik.c)
30+
endif()
2831

2932
target_include_directories(fp_storage PUBLIC include)
3033
target_include_directories(fp_storage PUBLIC ../include/common)

subsys/bluetooth/services/fast_pair/fp_storage/Kconfig.fp_storage

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ config BT_FAST_PAIR_STORAGE_FMDN_CLOCK
9797
help
9898
Add Fast Pair storage source files for the Beacon Clock used in the FMDN extension.
9999

100+
config BT_FAST_PAIR_STORAGE_FMDN_EIK
101+
bool
102+
help
103+
Add Fast Pair storage source files for the EIK used in the FMDN extension.
104+
100105
module = FP_STORAGE
101106
module-str = Fast Pair storage library
102107
source "${ZEPHYR_BASE}/subsys/logging/Kconfig.template.log_config"
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#include <errno.h>
8+
#include <string.h>
9+
#include <zephyr/settings/settings.h>
10+
11+
#include "fp_storage_eik.h"
12+
#include "fp_storage_eik_priv.h"
13+
#include "fp_storage_manager.h"
14+
15+
#include <zephyr/logging/log.h>
16+
LOG_MODULE_DECLARE(fp_storage, CONFIG_FP_STORAGE_LOG_LEVEL);
17+
18+
static bool provisioned;
19+
static uint8_t ephemeral_identity_key[FP_STORAGE_EIK_LEN];
20+
21+
static int settings_rc;
22+
static bool is_enabled;
23+
24+
int fp_storage_eik_save(const uint8_t *eik)
25+
{
26+
int err;
27+
28+
if (!is_enabled) {
29+
return -EACCES;
30+
}
31+
32+
err = settings_save_one(SETTINGS_EIK_FULL_NAME,
33+
eik,
34+
FP_STORAGE_EIK_LEN);
35+
if (err) {
36+
LOG_ERR("FP Storage EIK: settings_save_one failed: %d", err);
37+
return err;
38+
}
39+
40+
memcpy(ephemeral_identity_key, eik, sizeof(ephemeral_identity_key));
41+
provisioned = true;
42+
43+
return 0;
44+
}
45+
46+
int fp_storage_eik_delete(void)
47+
{
48+
int err;
49+
50+
if (!is_enabled) {
51+
return -EACCES;
52+
}
53+
54+
err = settings_delete(SETTINGS_EIK_FULL_NAME);
55+
if (err) {
56+
LOG_ERR("FP Storage EIK: settings_delete failed: %d", err);
57+
return err;
58+
}
59+
60+
memset(ephemeral_identity_key, 0, sizeof(ephemeral_identity_key));
61+
provisioned = false;
62+
63+
return 0;
64+
}
65+
66+
int fp_storage_eik_is_provisioned(void)
67+
{
68+
if (!is_enabled) {
69+
return -EACCES;
70+
}
71+
72+
return provisioned ? 1 : 0;
73+
}
74+
75+
int fp_storage_eik_get(uint8_t *eik)
76+
{
77+
if (!is_enabled) {
78+
return -EACCES;
79+
}
80+
81+
if (!provisioned) {
82+
return -ENODATA;
83+
}
84+
85+
memcpy(eik, ephemeral_identity_key, FP_STORAGE_EIK_LEN);
86+
87+
return 0;
88+
}
89+
90+
static int fp_settings_eik_load(size_t len, settings_read_cb read_cb, void *cb_arg)
91+
{
92+
int rc;
93+
94+
if (len != sizeof(ephemeral_identity_key)) {
95+
return -EINVAL;
96+
}
97+
98+
rc = read_cb(cb_arg, ephemeral_identity_key, sizeof(ephemeral_identity_key));
99+
if (rc < 0) {
100+
return rc;
101+
}
102+
103+
if (rc != sizeof(ephemeral_identity_key)) {
104+
return -EINVAL;
105+
}
106+
107+
provisioned = true;
108+
109+
return 0;
110+
}
111+
112+
static int fp_storage_eik_set(const char *name, size_t len, settings_read_cb read_cb, void *cb_arg)
113+
{
114+
int err;
115+
116+
LOG_DBG("FP Storage EIK: the EIK node is being set by Settings");
117+
118+
if (!strncmp(name, SETTINGS_EIK_KEY_NAME, sizeof(SETTINGS_EIK_KEY_NAME))) {
119+
err = fp_settings_eik_load(len, read_cb, cb_arg);
120+
} else {
121+
err = -ENOENT;
122+
}
123+
124+
/* The first reported settings set error will be remembered by the module.
125+
* The error will then be returned when calling fp_storage_eik_init.
126+
*/
127+
if (err && !settings_rc) {
128+
settings_rc = err;
129+
}
130+
131+
return 0;
132+
}
133+
134+
static int fp_storage_eik_init(void)
135+
{
136+
if (is_enabled) {
137+
LOG_WRN("FP Storage EIK: module already initialized");
138+
return 0;
139+
}
140+
141+
if (settings_rc) {
142+
return settings_rc;
143+
}
144+
145+
is_enabled = true;
146+
147+
return 0;
148+
}
149+
150+
static int fp_storage_eik_uninit(void)
151+
{
152+
is_enabled = false;
153+
154+
return 0;
155+
}
156+
157+
void fp_storage_eik_ram_clear(void)
158+
{
159+
memset(ephemeral_identity_key, 0, sizeof(ephemeral_identity_key));
160+
provisioned = false;
161+
162+
settings_rc = 0;
163+
164+
is_enabled = false;
165+
}
166+
167+
static int fp_storage_eik_reset_perform(void)
168+
{
169+
int err;
170+
bool was_enabled = is_enabled;
171+
172+
err = settings_delete(SETTINGS_EIK_FULL_NAME);
173+
if (err) {
174+
LOG_ERR("FP Storage EIK: settings_delete failed: %d", err);
175+
return err;
176+
}
177+
178+
fp_storage_eik_ram_clear();
179+
if (was_enabled) {
180+
err = fp_storage_eik_init();
181+
if (err) {
182+
return err;
183+
}
184+
}
185+
186+
return 0;
187+
}
188+
189+
static void fp_storage_eik_reset_prepare(void)
190+
{
191+
/* intentionally left empty */
192+
}
193+
194+
SETTINGS_STATIC_HANDLER_DEFINE(fp_storage_eik,
195+
SETTINGS_EIK_SUBTREE_NAME,
196+
NULL,
197+
fp_storage_eik_set,
198+
NULL,
199+
NULL);
200+
201+
FP_STORAGE_MANAGER_MODULE_REGISTER(fp_storage_eik,
202+
fp_storage_eik_reset_perform,
203+
fp_storage_eik_reset_prepare,
204+
fp_storage_eik_init,
205+
fp_storage_eik_uninit);
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#ifndef _FP_STORAGE_EIK_H_
8+
#define _FP_STORAGE_EIK_H_
9+
10+
#include <sys/types.h>
11+
12+
/**
13+
* @defgroup fp_storage_eik Fast Pair Ephemeral Identity Key (EIK) storage for the FMDN extension
14+
* @brief Internal API of Fast Pair Ephemeral Identity Key (EIK) storage for the FMDN extension
15+
*
16+
* The module must be initialized before using API functions.
17+
*
18+
* @{
19+
*/
20+
21+
#ifdef __cplusplus
22+
extern "C" {
23+
#endif
24+
25+
/* Length in bytes of the Ephemeral Identity Key (EIK). */
26+
#define FP_STORAGE_EIK_LEN 32
27+
28+
/** Save the new the Ephemeral Identity Key (EIK) or update the existing one.
29+
*
30+
* @param[in] eik Ephemeral Identity Key (32 bytes) to be saved.
31+
*
32+
* @return 0 If the operation was successful. Otherwise, a (negative) error code is returned.
33+
*/
34+
int fp_storage_eik_save(const uint8_t *eik);
35+
36+
/** Delete the Ephemeral Identity Key (EIK) from the device storage.
37+
*
38+
* @return 0 If the operation was successful. Otherwise, a (negative) error code is returned.
39+
*/
40+
int fp_storage_eik_delete(void);
41+
42+
/** Check if the Ephemeral Identity Key (EIK) is available in the device storage.
43+
*
44+
* @return 1 If the EIK is available in the device storage (provisioned state).
45+
* 0 If the EIK is not available in the device storage (unprovisioned state).
46+
* Otherwise, a negative value is returned which indicates an error.
47+
*/
48+
int fp_storage_eik_is_provisioned(void);
49+
50+
/** Get the Ephemeral Identity Key (EIK) value.
51+
*
52+
* @param[out] eik Ephemeral Identity Key value (32 bytes).
53+
*
54+
* @return 0 If the operation was successful. Otherwise, a (negative) error code is returned.
55+
*/
56+
int fp_storage_eik_get(uint8_t *eik);
57+
58+
#ifdef __cplusplus
59+
}
60+
#endif
61+
62+
/**
63+
* @}
64+
*/
65+
66+
#endif /* _FP_STORAGE_EIK_H_ */
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#ifndef _FP_STORAGE_EIK_PRIV_H_
8+
#define _FP_STORAGE_EIK_PRIV_H_
9+
10+
#include <zephyr/sys/__assert.h>
11+
#include <zephyr/settings/settings.h>
12+
13+
/**
14+
* @defgroup fp_storage_eik_priv Fast Pair storage of Ephemeral Identity Key (EIK) module private
15+
* @brief Private data of the Fast Pair storage of Ephemeral Identity Key (EIK) module
16+
*
17+
* Private definitions of the Fast Pair storage of Ephemeral Identity Key (EIK) module.
18+
* Used only by the module and by the unit test.
19+
* @{
20+
*/
21+
22+
#ifdef __cplusplus
23+
extern "C" {
24+
#endif
25+
26+
/** Settings subtree name for Fast Pair EIK storage. */
27+
#define SETTINGS_EIK_SUBTREE_NAME "fp_eik"
28+
29+
/** Settings key name for EIK. */
30+
#define SETTINGS_EIK_KEY_NAME "eik"
31+
32+
/** String used as a separator in settings keys. */
33+
#define SETTINGS_NAME_SEPARATOR_STR "/"
34+
35+
/** Full settings key name for EIK (including subtree name). */
36+
#define SETTINGS_EIK_FULL_NAME \
37+
(SETTINGS_EIK_SUBTREE_NAME SETTINGS_NAME_SEPARATOR_STR SETTINGS_EIK_KEY_NAME)
38+
39+
BUILD_ASSERT(SETTINGS_NAME_SEPARATOR == '/');
40+
41+
/** Clear storage data loaded to RAM. */
42+
void fp_storage_eik_ram_clear(void);
43+
44+
#ifdef __cplusplus
45+
}
46+
#endif
47+
48+
/**
49+
* @}
50+
*/
51+
52+
#endif /* _FP_STORAGE_EIK_PRIV_H_ */

0 commit comments

Comments
 (0)