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/logging/log.h>
6 #include <zephyr/fs/zms.h>
7 #include <zephyr/storage/flash_map.h>
8 #ifdef CONFIG_SECURE_STORAGE_ITS_IMPLEMENTATION_ZEPHYR
9 #include <zephyr/secure_storage/its/transform.h>
10 #endif
11 
12 LOG_MODULE_DECLARE(secure_storage, CONFIG_SECURE_STORAGE_LOG_LEVEL);
13 
14 BUILD_ASSERT(CONFIG_SECURE_STORAGE_ITS_STORE_ZMS_SECTOR_SIZE
15 	     > 2 * CONFIG_SECURE_STORAGE_ITS_MAX_DATA_SIZE);
16 
17 #define PARTITION_DT_NODE DT_CHOSEN(secure_storage_its_partition)
18 
19 static struct zms_fs s_zms = {
20 	.flash_device = FIXED_PARTITION_NODE_DEVICE(PARTITION_DT_NODE),
21 	.offset = FIXED_PARTITION_NODE_OFFSET(PARTITION_DT_NODE),
22 	.sector_size = CONFIG_SECURE_STORAGE_ITS_STORE_ZMS_SECTOR_SIZE,
23 };
24 
init_zms(void)25 static int init_zms(void)
26 {
27 	int ret;
28 
29 	s_zms.sector_count = FIXED_PARTITION_NODE_SIZE(PARTITION_DT_NODE) / s_zms.sector_size;
30 
31 	ret = zms_mount(&s_zms);
32 	if (ret) {
33 		LOG_DBG("Failed. (%d)", ret);
34 	}
35 	return ret;
36 }
37 SYS_INIT(init_zms, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
38 
39 /* Bit position of the ITS caller ID in the ZMS entry ID. */
40 #define ITS_CALLER_ID_POS 30
41 /* Make sure that every ITS caller ID fits in ZMS entry IDs at the defined position. */
42 BUILD_ASSERT(1 << (32 - ITS_CALLER_ID_POS) >= SECURE_STORAGE_ITS_CALLER_COUNT);
43 
has_forbidden_bits_set(secure_storage_its_uid_t uid)44 static bool has_forbidden_bits_set(secure_storage_its_uid_t uid)
45 {
46 	if (uid.uid & GENMASK64(63, ITS_CALLER_ID_POS)) {
47 		LOG_DBG("UID %u/0x%llx cannot be used as it has bits set past "
48 			"the first " STRINGIFY(ITS_CALLER_ID_POS) " ones.",
49 			uid.caller_id, (unsigned long long)uid.uid);
50 		return true;
51 	}
52 	return false;
53 }
54 
zms_id_from(secure_storage_its_uid_t uid)55 static uint32_t zms_id_from(secure_storage_its_uid_t uid)
56 {
57 	return (uint32_t)uid.uid | (uid.caller_id << ITS_CALLER_ID_POS);
58 }
59 
secure_storage_its_store_set(secure_storage_its_uid_t uid,size_t data_length,const void * data)60 psa_status_t secure_storage_its_store_set(secure_storage_its_uid_t uid,
61 					  size_t data_length, const void *data)
62 {
63 	psa_status_t psa_ret;
64 	ssize_t zms_ret;
65 	const uint32_t zms_id = zms_id_from(uid);
66 
67 	if (has_forbidden_bits_set(uid)) {
68 		return PSA_ERROR_INVALID_ARGUMENT;
69 	}
70 
71 	zms_ret = zms_write(&s_zms, zms_id, data, data_length);
72 	if (zms_ret == data_length) {
73 		psa_ret = PSA_SUCCESS;
74 	} else if (zms_ret == -ENOSPC) {
75 		psa_ret = PSA_ERROR_INSUFFICIENT_STORAGE;
76 	} else {
77 		psa_ret = PSA_ERROR_STORAGE_FAILURE;
78 	}
79 	LOG_DBG("%s 0x%x with %zu bytes. (%zd)", (psa_ret == PSA_SUCCESS) ?
80 		"Wrote" : "Failed to write", zms_id, data_length, zms_ret);
81 	return psa_ret;
82 }
83 
secure_storage_its_store_get(secure_storage_its_uid_t uid,size_t data_size,void * data,size_t * data_length)84 psa_status_t secure_storage_its_store_get(secure_storage_its_uid_t uid, size_t data_size,
85 					  void *data, size_t *data_length)
86 {
87 	psa_status_t psa_ret;
88 	ssize_t zms_ret;
89 	const uint32_t zms_id = zms_id_from(uid);
90 
91 	if (has_forbidden_bits_set(uid)) {
92 		return PSA_ERROR_INVALID_ARGUMENT;
93 	}
94 
95 	zms_ret = zms_read(&s_zms, zms_id, data, data_size);
96 	if (zms_ret > 0) {
97 		*data_length = zms_ret;
98 		psa_ret = PSA_SUCCESS;
99 	} else if (zms_ret == -ENOENT) {
100 		psa_ret = PSA_ERROR_DOES_NOT_EXIST;
101 	} else {
102 		psa_ret = PSA_ERROR_STORAGE_FAILURE;
103 	}
104 	LOG_DBG("%s 0x%x for up to %zu bytes. (%zd)", (psa_ret != PSA_ERROR_STORAGE_FAILURE) ?
105 		"Read" : "Failed to read", zms_id, data_size, zms_ret);
106 	return psa_ret;
107 }
108 
secure_storage_its_store_remove(secure_storage_its_uid_t uid)109 psa_status_t secure_storage_its_store_remove(secure_storage_its_uid_t uid)
110 {
111 	int zms_ret;
112 	const uint32_t zms_id = zms_id_from(uid);
113 
114 	if (has_forbidden_bits_set(uid)) {
115 		return PSA_ERROR_INVALID_ARGUMENT;
116 	}
117 
118 	zms_ret = zms_delete(&s_zms, zms_id);
119 	LOG_DBG("%s 0x%x. (%d)", zms_ret ? "Failed to delete" : "Deleted", zms_id, zms_ret);
120 	BUILD_ASSERT(PSA_SUCCESS == 0);
121 	return zms_ret;
122 }
123