1 /* Copyright (c) 2024 Nordic Semiconductor
2  * SPDX-License-Identifier: Apache-2.0
3  */
4 #include <zephyr/secure_storage/its/store.h>
5 #include <zephyr/secure_storage/its/store/settings_get.h>
6 #include <zephyr/init.h>
7 #include <zephyr/logging/log.h>
8 #include <zephyr/settings/settings.h>
9 #include <zephyr/sys/util.h>
10 #include <errno.h>
11 #include <stdio.h>
12 
13 LOG_MODULE_DECLARE(secure_storage, CONFIG_SECURE_STORAGE_LOG_LEVEL);
14 
init_settings_subsys(void)15 static int init_settings_subsys(void)
16 {
17 	const int ret = settings_subsys_init();
18 
19 	if (ret) {
20 		LOG_DBG("Failed. (%d)", ret);
21 	}
22 	return ret;
23 }
24 SYS_INIT(init_settings_subsys, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
25 
26 BUILD_ASSERT(CONFIG_SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_MAX_LEN <= SETTINGS_MAX_NAME_LEN);
27 
28 #ifndef CONFIG_SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_CUSTOM
29 
30 BUILD_ASSERT(CONFIG_SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_MAX_LEN ==
31 	     sizeof(CONFIG_SECURE_STORAGE_ITS_STORE_SETTINGS_PREFIX) - 1
32 	     + 1 + 1 /* caller ID + '/' */
33 	     + 2 * sizeof(psa_storage_uid_t) /* hex UID */);
34 
secure_storage_its_store_settings_get_name(secure_storage_its_uid_t uid,char name[static SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_BUF_SIZE])35 void secure_storage_its_store_settings_get_name(
36 	secure_storage_its_uid_t uid,
37 	char name[static SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_BUF_SIZE])
38 {
39 	int ret;
40 
41 #ifdef CONFIG_SECURE_STORAGE_64_BIT_UID
42 	ret = snprintf(name, SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_BUF_SIZE,
43 		       CONFIG_SECURE_STORAGE_ITS_STORE_SETTINGS_PREFIX "%x/%llx",
44 		       uid.caller_id, (unsigned long long)uid.uid);
45 #else
46 	ret = snprintf(name, SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_BUF_SIZE,
47 		       CONFIG_SECURE_STORAGE_ITS_STORE_SETTINGS_PREFIX "%x/%lx",
48 		       uid.caller_id, (unsigned long)uid.uid);
49 #endif
50 	__ASSERT_NO_MSG(ret > 0 && ret < SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_BUF_SIZE);
51 }
52 
53 #endif /* !CONFIG_SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_CUSTOM */
54 
secure_storage_its_store_set(secure_storage_its_uid_t uid,size_t data_length,const void * data)55 psa_status_t secure_storage_its_store_set(secure_storage_its_uid_t uid,
56 					  size_t data_length, const void *data)
57 {
58 	int ret;
59 	char name[SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_BUF_SIZE];
60 
61 	secure_storage_its_store_settings_get_name(uid, name);
62 
63 	ret = settings_save_one(name, data, data_length);
64 	LOG_DBG("%s %s with %zu bytes. (%d)",
65 		(ret == 0) ? "Saved" : "Failed to save", name, data_length, ret);
66 
67 	switch (ret) {
68 	case 0:
69 		return PSA_SUCCESS;
70 	case -ENOMEM:
71 	case -ENOSPC:
72 		return PSA_ERROR_INSUFFICIENT_STORAGE;
73 	default:
74 		return PSA_ERROR_STORAGE_FAILURE;
75 	}
76 }
77 
78 struct load_params {
79 	const size_t data_size;
80 	uint8_t *const data;
81 	ssize_t ret;
82 };
83 
load_direct_setting(const char * key,size_t len,settings_read_cb read_cb,void * cb_arg,void * param)84 static int load_direct_setting(const char *key, size_t len, settings_read_cb read_cb,
85 			       void *cb_arg, void *param)
86 {
87 	(void)key;
88 	struct load_params *load_params = param;
89 
90 	load_params->ret = read_cb(cb_arg, load_params->data, MIN(load_params->data_size, len));
91 	return 0;
92 }
93 
secure_storage_its_store_get(secure_storage_its_uid_t uid,size_t data_size,void * data,size_t * data_length)94 psa_status_t secure_storage_its_store_get(secure_storage_its_uid_t uid, size_t data_size,
95 					  void *data, size_t *data_length)
96 {
97 	psa_status_t ret;
98 	char name[SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_BUF_SIZE];
99 	struct load_params load_params = {.data_size = data_size, .data = data, .ret = -ENOENT};
100 
101 	secure_storage_its_store_settings_get_name(uid, name);
102 
103 	settings_load_subtree_direct(name, load_direct_setting, &load_params);
104 	if (load_params.ret > 0) {
105 		*data_length = load_params.ret;
106 		ret = PSA_SUCCESS;
107 	} else if (load_params.ret == 0 || load_params.ret == -ENOENT) {
108 		ret = PSA_ERROR_DOES_NOT_EXIST;
109 	} else {
110 		ret = PSA_ERROR_STORAGE_FAILURE;
111 	}
112 	LOG_DBG("%s %s for up to %zu bytes. (%zd)", (ret != PSA_ERROR_STORAGE_FAILURE) ?
113 		"Loaded" : "Failed to load", name, data_size, load_params.ret);
114 	return ret;
115 }
116 
secure_storage_its_store_remove(secure_storage_its_uid_t uid)117 psa_status_t secure_storage_its_store_remove(secure_storage_its_uid_t uid)
118 {
119 	int ret;
120 	char name[SECURE_STORAGE_ITS_STORE_SETTINGS_NAME_BUF_SIZE];
121 
122 	secure_storage_its_store_settings_get_name(uid, name);
123 
124 	ret = settings_delete(name);
125 	LOG_DBG("%s %s. (%d)", ret ? "Failed to delete" : "Deleted", name, ret);
126 
127 	return ret ? PSA_ERROR_STORAGE_FAILURE : PSA_SUCCESS;
128 }
129