TF-M Reference Manual  1.2.0
TrustedFirmware-M
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tfm_its_req_mngr.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "tfm_its_req_mngr.h"
9 
10 #include <stdint.h>
11 
12 #include "psa/storage_common.h"
14 #include "its_utils.h"
15 #include "ps_object_defs.h"
16 
17 #ifdef TFM_PSA_API
18 #include "psa/service.h"
20 #else
21 #include <stdbool.h>
22 #include "tfm_secure_api.h"
23 #include "tfm_memory_utils.h"
24 #include "tfm_api.h"
25 #endif
26 
27 #ifndef TFM_PSA_API
28 static uint8_t *p_data;
29 
33 static bool its_is_init = false;
34 
35 psa_status_t tfm_its_set_req(psa_invec *in_vec, size_t in_len,
36  psa_outvec *out_vec, size_t out_len)
37 {
39  size_t data_length;
40  psa_storage_create_flags_t create_flags;
41  int32_t client_id;
42 
43  (void)out_vec;
44 
45  if (!its_is_init) {
47  }
48 
49  if ((in_len != 3) || (out_len != 0)) {
50  /* The number of arguments is incorrect */
52  }
53 
54  if (in_vec[0].len != sizeof(uid) ||
55  in_vec[2].len != sizeof(create_flags)) {
56  /* The size of one of the arguments is incorrect */
58  }
59 
60  uid = *((psa_storage_uid_t *)in_vec[0].base);
61 
62  p_data = (uint8_t *)in_vec[1].base;
63  data_length = in_vec[1].len;
64 
65  create_flags = *(psa_storage_create_flags_t *)in_vec[2].base;
66 
67  /* Get the caller's client ID */
68  if (tfm_core_get_caller_client_id(&client_id) != (int32_t)TFM_SUCCESS) {
70  }
71 
72  return tfm_its_set(client_id, uid, data_length, create_flags);
73 }
74 
75 psa_status_t tfm_its_get_req(psa_invec *in_vec, size_t in_len,
76  psa_outvec *out_vec, size_t out_len)
77 {
79  size_t data_offset;
80  size_t data_size;
81  size_t *p_data_length;
82  int32_t client_id;
83 
84  if (!its_is_init) {
86  }
87 
88  if ((in_len != 2) || (out_len != 1)) {
89  /* The number of arguments is incorrect */
91  }
92 
93  if (in_vec[0].len != sizeof(uid) ||
94  in_vec[1].len != sizeof(data_offset)) {
95  /* The size of one of the arguments is incorrect */
97  }
98 
99  uid = *((psa_storage_uid_t *)in_vec[0].base);
100 
101  data_offset = *(size_t *)in_vec[1].base;
102 
103  p_data = (uint8_t *)out_vec[0].base;
104  data_size = out_vec[0].len;
105 
106  p_data_length = &out_vec[0].len;
107 
108  /* Get the caller's client ID */
109  if (tfm_core_get_caller_client_id(&client_id) != (int32_t)TFM_SUCCESS) {
111  }
112 
113  return tfm_its_get(client_id, uid, data_offset, data_size, p_data_length);
114 }
115 
117  psa_outvec *out_vec, size_t out_len)
118 {
119  psa_storage_uid_t uid;
120  struct psa_storage_info_t *p_info;
121  int32_t client_id;
122 
123  if (!its_is_init) {
125  }
126 
127  if ((in_len != 1) || (out_len != 1)) {
128  /* The number of arguments is incorrect */
130  }
131 
132  if (in_vec[0].len != sizeof(uid) ||
133  out_vec[0].len != sizeof(*p_info)) {
134  /* The size of one of the arguments is incorrect */
136  }
137 
138  uid = *((psa_storage_uid_t *)in_vec[0].base);
139 
140  p_info = (struct psa_storage_info_t *)out_vec[0].base;
141 
142  /* Get the caller's client ID */
143  if (tfm_core_get_caller_client_id(&client_id) != (int32_t)TFM_SUCCESS) {
145  }
146 
147  return tfm_its_get_info(client_id, uid, p_info);
148 }
149 
151  psa_outvec *out_vec, size_t out_len)
152 {
153  psa_storage_uid_t uid;
154  int32_t client_id;
155 
156  (void)out_vec;
157 
158  if (!its_is_init) {
160  }
161 
162  if ((in_len != 1) || (out_len != 0)) {
163  /* The number of arguments is incorrect */
165  }
166 
167  if (in_vec[0].len != sizeof(uid)) {
168  /* The input argument size is incorrect */
170  }
171 
172  uid = *((psa_storage_uid_t *)in_vec[0].base);
173 
174  /* Get the caller's client ID */
175  if (tfm_core_get_caller_client_id(&client_id) != (int32_t)TFM_SUCCESS) {
177  }
178 
179  return tfm_its_remove(client_id, uid);
180 }
181 
182 #else /* !defined(TFM_PSA_API) */
183 typedef psa_status_t (*its_func_t)(void);
184 static psa_msg_t msg;
185 
186 static psa_status_t tfm_its_set_ipc(void)
187 {
188  psa_storage_uid_t uid;
189  size_t data_length;
190  psa_storage_create_flags_t create_flags;
191  size_t num;
192 
193  if (msg.in_size[0] != sizeof(uid) ||
194  msg.in_size[2] != sizeof(create_flags)) {
195  /* The size of one of the arguments is incorrect */
197  }
198 
199  data_length = msg.in_size[1];
200 
201  num = psa_read(msg.handle, 0, &uid, sizeof(uid));
202  if (num != sizeof(uid)) {
204  }
205 
206  num = psa_read(msg.handle, 2, &create_flags, sizeof(create_flags));
207  if (num != sizeof(create_flags)) {
209  }
210 
211  return tfm_its_set(msg.client_id, uid, data_length, create_flags);
212 }
213 
214 static psa_status_t tfm_its_get_ipc(void)
215 {
216  psa_storage_uid_t uid;
217  size_t data_offset;
218  size_t data_size;
219  size_t data_length;
220  size_t num;
221 
222  if (msg.in_size[0] != sizeof(uid) ||
223  msg.in_size[1] != sizeof(data_offset)) {
224  /* The size of one of the arguments is incorrect */
226  }
227 
228  data_size = msg.out_size[0];
229 
230  num = psa_read(msg.handle, 0, &uid, sizeof(uid));
231  if (num != sizeof(uid)) {
233  }
234 
235  num = psa_read(msg.handle, 1, &data_offset, sizeof(data_offset));
236  if (num != sizeof(data_offset)) {
238  }
239 
240  return tfm_its_get(msg.client_id, uid, data_offset, data_size,
241  &data_length);
242 }
243 
244 static psa_status_t tfm_its_get_info_ipc(void)
245 {
246  psa_status_t status;
247  psa_storage_uid_t uid;
248  struct psa_storage_info_t info;
249  size_t num;
250 
251  if (msg.in_size[0] != sizeof(uid) ||
252  msg.out_size[0] != sizeof(info)) {
253  /* The size of one of the arguments is incorrect */
255  }
256 
257  num = psa_read(msg.handle, 0, &uid, sizeof(uid));
258  if (num != sizeof(uid)) {
260  }
261 
262  status = tfm_its_get_info(msg.client_id, uid, &info);
263  if (status == PSA_SUCCESS) {
264  psa_write(msg.handle, 0, &info, sizeof(info));
265  }
266 
267  return status;
268 }
269 
270 static psa_status_t tfm_its_remove_ipc(void)
271 {
272  psa_storage_uid_t uid;
273  size_t num;
274 
275  if (msg.in_size[0] != sizeof(uid)) {
276  /* The input argument size is incorrect */
278  }
279 
280  num = psa_read(msg.handle, 0, &uid, sizeof(uid));
281  if (num != sizeof(uid)) {
283  }
284 
285  return tfm_its_remove(msg.client_id, uid);
286 }
287 
288 /*
289  * Fixme: Temporarily implement abort as infinite loop,
290  * will replace it later.
291  */
292 static void tfm_abort(void)
293 {
294  while (1)
295  ;
296 }
297 
298 static void its_signal_handle(psa_signal_t signal, its_func_t pfn)
299 {
300  psa_status_t status;
301 
302  status = psa_get(signal, &msg);
303  if (status != PSA_SUCCESS) {
304  return;
305  }
306 
307  switch (msg.type) {
308  case PSA_IPC_CONNECT:
309  psa_reply(msg.handle, PSA_SUCCESS);
310  break;
311  case PSA_IPC_CALL:
312  status = pfn();
313  psa_reply(msg.handle, status);
314  break;
315  case PSA_IPC_DISCONNECT:
316  psa_reply(msg.handle, PSA_SUCCESS);
317  break;
318  default:
319  tfm_abort();
320  }
321 }
322 #endif /* !defined(TFM_PSA_API) */
323 
325 {
326 #ifdef TFM_PSA_API
327  psa_signal_t signals = 0;
328 
329  if (tfm_its_init() != PSA_SUCCESS) {
330  tfm_abort();
331  }
332 
333  while (1) {
334  signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
335  if (signals & TFM_ITS_SET_SIGNAL) {
336  its_signal_handle(TFM_ITS_SET_SIGNAL, tfm_its_set_ipc);
337  } else if (signals & TFM_ITS_GET_SIGNAL) {
338  its_signal_handle(TFM_ITS_GET_SIGNAL, tfm_its_get_ipc);
339  } else if (signals & TFM_ITS_GET_INFO_SIGNAL) {
340  its_signal_handle(TFM_ITS_GET_INFO_SIGNAL, tfm_its_get_info_ipc);
341  } else if (signals & TFM_ITS_REMOVE_SIGNAL) {
342  its_signal_handle(TFM_ITS_REMOVE_SIGNAL, tfm_its_remove_ipc);
343  } else {
344  tfm_abort();
345  }
346  }
347 #else
348  if (tfm_its_init() != PSA_SUCCESS) {
350  }
351  its_is_init = true;
352  return PSA_SUCCESS;
353 #endif
354 }
355 
356 size_t its_req_mngr_read(uint8_t *buf, size_t num_bytes)
357 {
358 #ifdef TFM_PSA_API
359  return psa_read(msg.handle, 1, buf, num_bytes);
360 #else
361  (void)tfm_memcpy(buf, p_data, num_bytes);
362  p_data += num_bytes;
363  return num_bytes;
364 #endif
365 }
366 
367 void its_req_mngr_write(const uint8_t *buf, size_t num_bytes)
368 {
369 #ifdef TFM_PSA_API
370  psa_write(msg.handle, 0, buf, num_bytes);
371 #else
372  (void)tfm_memcpy(p_data, buf, num_bytes);
373  p_data += num_bytes;
374 #endif
375 }
#define TFM_ITS_REMOVE_SIGNAL
uint32_t psa_signal_t
Definition: service.h:50
#define PSA_BLOCK
Definition: service.h:31
#define TFM_ITS_SET_SIGNAL
#define PSA_SUCCESS
Definition: crypto_values.h:35
size_t len
Definition: client.h:68
psa_status_t tfm_its_get_info(int32_t client_id, psa_storage_uid_t uid, struct psa_storage_info_t *p_info)
Retrieve the metadata about the provided uid.
#define TFM_ITS_GET_INFO_SIGNAL
psa_status_t tfm_its_get_req(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len)
Handles the get request.
size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx, void *buffer, size_t num_bytes)
Read a message parameter or part of a message parameter from a client input vector.
Definition: psa_service.c:40
#define PSA_ERROR_GENERIC_ERROR
Definition: crypto_values.h:43
psa_status_t tfm_its_req_mngr_init(void)
#define PSA_IPC_DISCONNECT
Definition: service.h:47
psa_status_t tfm_its_remove_req(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len)
Handles the remove request.
psa_status_t tfm_its_set_req(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len)
Handles the set request.
psa_status_t tfm_its_remove(int32_t client_id, psa_storage_uid_t uid)
Remove the provided uid and its associated data from the storage.
#define PSA_ERROR_PROGRAMMER_ERROR
Definition: error.h:32
#define PSA_WAIT_ANY
Definition: service.h:36
int32_t tfm_core_get_caller_client_id(int32_t *caller_client_id)
Definition: arch.c:28
void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, const void *buffer, size_t num_bytes)
Write a message response to a client output vector.
Definition: psa_service.c:58
psa_status_t tfm_its_get(int32_t client_id, psa_storage_uid_t uid, size_t data_offset, size_t data_size, size_t *p_data_length)
Retrieve data associated with a provided UID.
psa_status_t tfm_its_set(int32_t client_id, psa_storage_uid_t uid, size_t data_length, psa_storage_create_flags_t create_flags)
Create a new, or modify an existing, uid/value pair.
void psa_reply(psa_handle_t msg_handle, psa_status_t status)
Complete handling of a specific message and unblock the client.
Definition: psa_service.c:67
psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
Return the Secure Partition interrupt signals that have been asserted from a subset of signals provid...
Definition: psa_service.c:15
size_t len
Definition: client.h:76
__STATIC_INLINE void * tfm_memcpy(void *dest, const void *src, size_t num)
void its_req_mngr_write(const uint8_t *buf, size_t num_bytes)
Writes asset data to the caller.
uint64_t psa_storage_uid_t
#define PSA_IPC_CONNECT
Definition: service.h:45
psa_status_t tfm_its_init(void)
Initializes the internal trusted storage system.
psa_status_t tfm_its_get_info_req(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len)
Handles the get info request.
#define PSA_IPC_CALL
Definition: client.h:59
#define TFM_ITS_GET_SIGNAL
uint32_t psa_storage_create_flags_t
psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg)
Retrieve the message which corresponds to a given RoT Service signal and remove the message from the ...
Definition: psa_service.c:24
int32_t psa_status_t
Function return status.
Definition: crypto_types.h:43
size_t its_req_mngr_read(uint8_t *buf, size_t num_bytes)
Reads asset data from the caller.