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