1 /*
2 * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
3 * Copyright (c) 2022-2023 Cypress Semiconductor Corporation (an Infineon
4 * company) or an affiliate of Cypress Semiconductor Corporation. All rights
5 * reserved.
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10 #include "ffm/psa_api.h"
11 #include "spm.h"
12 #include "utilities.h"
13 #include "tfm_hal_isolation.h"
14
tfm_spm_partition_psa_read(psa_handle_t msg_handle,uint32_t invec_idx,void * buffer,size_t num_bytes)15 size_t tfm_spm_partition_psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
16 void *buffer, size_t num_bytes)
17 {
18 size_t bytes, remaining;
19 struct connection_t *handle = NULL;
20 struct partition_t *curr_partition = GET_CURRENT_COMPONENT();
21 fih_int fih_rc = FIH_FAILURE;
22
23 /* It is a fatal error if message handle is invalid */
24 handle = spm_msg_handle_to_connection(msg_handle);
25 if (!handle) {
26 tfm_core_panic();
27 }
28
29 /*
30 * It is a fatal error if message handle does not refer to a request
31 * message
32 */
33 if (handle->msg.type < PSA_IPC_CALL) {
34 tfm_core_panic();
35 }
36
37 /*
38 * It is a fatal error if invec_idx is equal to or greater than
39 * PSA_MAX_IOVEC
40 */
41 if (invec_idx >= PSA_MAX_IOVEC) {
42 tfm_core_panic();
43 }
44
45 #if PSA_FRAMEWORK_HAS_MM_IOVEC
46 /*
47 * It is a fatal error if the input vector has already been mapped using
48 * psa_map_invec().
49 */
50 if (IOVEC_IS_MAPPED(handle, (invec_idx + INVEC_IDX_BASE))) {
51 tfm_core_panic();
52 }
53
54 SET_IOVEC_ACCESSED(handle, (invec_idx + INVEC_IDX_BASE));
55 #endif
56
57 remaining = handle->msg.in_size[invec_idx] - handle->invec_accessed[invec_idx];
58 /* There was no remaining data in this input vector */
59 if (remaining == 0) {
60 return 0;
61 }
62
63 /*
64 * Copy the client data to the service buffer. It is a fatal error
65 * if the memory reference for buffer is invalid or not read-write.
66 */
67 FIH_CALL(tfm_hal_memory_check, fih_rc,
68 curr_partition->boundary, (uintptr_t)buffer,
69 num_bytes, TFM_HAL_ACCESS_READWRITE);
70 if (fih_not_eq(fih_rc, fih_int_encode(PSA_SUCCESS))) {
71 tfm_core_panic();
72 }
73
74 bytes = num_bytes < remaining ? num_bytes : remaining;
75
76 spm_memcpy(buffer, (char *)handle->invec_base[invec_idx] +
77 handle->invec_accessed[invec_idx], bytes);
78
79 /* Update the data size read */
80 handle->invec_accessed[invec_idx] += bytes;
81
82 return bytes;
83 }
84
tfm_spm_partition_psa_skip(psa_handle_t msg_handle,uint32_t invec_idx,size_t num_bytes)85 size_t tfm_spm_partition_psa_skip(psa_handle_t msg_handle, uint32_t invec_idx,
86 size_t num_bytes)
87 {
88 struct connection_t *handle = NULL;
89 size_t remaining;
90
91 /* It is a fatal error if message handle is invalid */
92 handle = spm_msg_handle_to_connection(msg_handle);
93 if (!handle) {
94 tfm_core_panic();
95 }
96
97 /*
98 * It is a fatal error if message handle does not refer to a request
99 * message
100 */
101 if (handle->msg.type < PSA_IPC_CALL) {
102 tfm_core_panic();
103 }
104
105 /*
106 * It is a fatal error if invec_idx is equal to or greater than
107 * PSA_MAX_IOVEC
108 */
109 if (invec_idx >= PSA_MAX_IOVEC) {
110 tfm_core_panic();
111 }
112
113 #if PSA_FRAMEWORK_HAS_MM_IOVEC
114 /*
115 * It is a fatal error if the input vector has already been mapped using
116 * psa_map_invec().
117 */
118 if (IOVEC_IS_MAPPED(handle, (invec_idx + INVEC_IDX_BASE))) {
119 tfm_core_panic();
120 }
121
122 SET_IOVEC_ACCESSED(handle, (invec_idx + INVEC_IDX_BASE));
123 #endif
124
125 remaining = handle->msg.in_size[invec_idx] - handle->invec_accessed[invec_idx];
126 /* There was no remaining data in this input vector */
127 if (remaining == 0) {
128 return 0;
129 }
130
131 /*
132 * If num_bytes is greater than the remaining size of the input vector then
133 * the remaining size of the input vector is used.
134 */
135 if (num_bytes > remaining) {
136 num_bytes = remaining;
137 }
138
139 /* Update the data size accessed */
140 handle->invec_accessed[invec_idx] += num_bytes;
141
142 return num_bytes;
143 }
144
tfm_spm_partition_psa_write(psa_handle_t msg_handle,uint32_t outvec_idx,const void * buffer,size_t num_bytes)145 psa_status_t tfm_spm_partition_psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
146 const void *buffer, size_t num_bytes)
147 {
148 struct connection_t *handle = NULL;
149 struct partition_t *curr_partition = GET_CURRENT_COMPONENT();
150 fih_int fih_rc = FIH_FAILURE;
151
152 /* It is a fatal error if message handle is invalid */
153 handle = spm_msg_handle_to_connection(msg_handle);
154 if (!handle) {
155 tfm_core_panic();
156 }
157
158 /*
159 * It is a fatal error if message handle does not refer to a request
160 * message
161 */
162 if (handle->msg.type < PSA_IPC_CALL) {
163 tfm_core_panic();
164 }
165
166 /*
167 * It is a fatal error if outvec_idx is equal to or greater than
168 * PSA_MAX_IOVEC
169 */
170 if (outvec_idx >= PSA_MAX_IOVEC) {
171 tfm_core_panic();
172 }
173
174 /*
175 * It is a fatal error if the call attempts to write data past the end of
176 * the client output vector
177 */
178 if (num_bytes > handle->msg.out_size[outvec_idx] - handle->outvec_written[outvec_idx]) {
179 tfm_core_panic();
180 }
181
182 #if PSA_FRAMEWORK_HAS_MM_IOVEC
183 /*
184 * It is a fatal error if the output vector has already been mapped using
185 * psa_map_outvec().
186 */
187 if (IOVEC_IS_MAPPED(handle, (outvec_idx + OUTVEC_IDX_BASE))) {
188 tfm_core_panic();
189 }
190
191 SET_IOVEC_ACCESSED(handle, (outvec_idx + OUTVEC_IDX_BASE));
192 #endif
193
194 /*
195 * Copy the service buffer to client outvecs. It is a fatal error
196 * if the memory reference for buffer is invalid or not readable.
197 */
198 FIH_CALL(tfm_hal_memory_check, fih_rc,
199 curr_partition->boundary, (uintptr_t)buffer,
200 num_bytes, TFM_HAL_ACCESS_READABLE);
201 if (fih_not_eq(fih_rc, fih_int_encode(PSA_SUCCESS))) {
202 tfm_core_panic();
203 }
204
205 spm_memcpy((char *)handle->outvec_base[outvec_idx] +
206 handle->outvec_written[outvec_idx], buffer, num_bytes);
207
208 /* Update the data size written */
209 handle->outvec_written[outvec_idx] += num_bytes;
210
211 return PSA_SUCCESS;
212 }
213