1 /*
2 * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "tfm_ps_req_mngr.h"
9
10 #include <stdbool.h>
11 #include <stdint.h>
12 #include <string.h>
13
14 #include "psa/protected_storage.h"
15
16 #include "tfm_api.h"
17 #include "tfm_protected_storage.h"
18 #include "psa/service.h"
19 #include "psa_manifest/tfm_protected_storage.h"
20 #include "tfm_ps_defs.h"
21
22 static const psa_msg_t *p_msg;
23
tfm_ps_set_req(const psa_msg_t * msg)24 static psa_status_t tfm_ps_set_req(const psa_msg_t *msg)
25 {
26 psa_storage_uid_t uid;
27 int32_t client_id;
28 psa_storage_create_flags_t create_flags;
29 size_t num = 0;
30
31 client_id = msg->client_id;
32
33 if (msg->in_size[0] != sizeof(uid) ||
34 msg->in_size[2] != sizeof(create_flags)) {
35 /* The size of one of the arguments is incorrect */
36 return PSA_ERROR_PROGRAMMER_ERROR;
37 }
38
39 num = psa_read(msg->handle, 0, &uid, sizeof(uid));
40 if (num != sizeof(uid)) {
41 return PSA_ERROR_PROGRAMMER_ERROR;
42 }
43
44 num = psa_read(msg->handle, 2, &create_flags, sizeof(create_flags));
45 if (num != sizeof(create_flags)) {
46 return PSA_ERROR_PROGRAMMER_ERROR;
47 }
48
49 return tfm_ps_set(client_id, uid, msg->in_size[1], create_flags);
50 }
51
tfm_ps_get_req(const psa_msg_t * msg)52 static psa_status_t tfm_ps_get_req(const psa_msg_t *msg)
53 {
54 psa_storage_uid_t uid;
55 uint32_t data_offset;
56 size_t num = 0;
57 size_t p_data_length;
58
59 if (msg->in_size[0] != sizeof(uid) ||
60 msg->in_size[1] != sizeof(data_offset)) {
61 /* The size of one of the arguments is incorrect */
62 return PSA_ERROR_PROGRAMMER_ERROR;
63 }
64
65 num = psa_read(msg->handle, 0, &uid, sizeof(uid));
66 if (num != sizeof(psa_storage_uid_t)) {
67 return PSA_ERROR_PROGRAMMER_ERROR;
68 }
69
70 num = psa_read(msg->handle, 1, &data_offset, sizeof(data_offset));
71 if (num != sizeof(data_offset)) {
72 return PSA_ERROR_PROGRAMMER_ERROR;
73 }
74
75 return tfm_ps_get(msg->client_id, uid, data_offset, msg->out_size[0],
76 &p_data_length);
77 }
78
tfm_ps_get_info_req(const psa_msg_t * msg)79 static psa_status_t tfm_ps_get_info_req(const psa_msg_t *msg)
80 {
81 psa_storage_uid_t uid;
82
83 struct psa_storage_info_t info;
84 size_t num = 0;
85 psa_status_t status;
86
87 if (msg->in_size[0] != sizeof(uid) ||
88 msg->out_size[0] != sizeof(info)) {
89 /* The size of one of the arguments is incorrect */
90 return PSA_ERROR_PROGRAMMER_ERROR;
91 }
92
93 num = psa_read(msg->handle, 0, &uid, sizeof(uid));
94 if (num != sizeof(uid)) {
95 return PSA_ERROR_PROGRAMMER_ERROR;
96 }
97
98 status = tfm_ps_get_info(msg->client_id, uid, &info);
99
100 if (status == PSA_SUCCESS) {
101 psa_write(msg->handle, 0, &info, sizeof(info));
102 }
103 return status;
104 }
105
tfm_ps_remove_req(const psa_msg_t * msg)106 static psa_status_t tfm_ps_remove_req(const psa_msg_t *msg)
107 {
108 psa_storage_uid_t uid;
109 size_t num = 0;
110
111 if (msg->in_size[0] != sizeof(uid)) {
112 /* The size of one of the arguments is incorrect */
113 return PSA_ERROR_PROGRAMMER_ERROR;
114 }
115
116 num = psa_read(msg->handle, 0, &uid, sizeof(uid));
117 if (num != sizeof(uid)) {
118 return PSA_ERROR_PROGRAMMER_ERROR;
119 }
120
121 return tfm_ps_remove(msg->client_id, uid);
122 }
123
tfm_ps_get_support_req(const psa_msg_t * msg)124 static psa_status_t tfm_ps_get_support_req(const psa_msg_t *msg)
125 {
126 size_t out_size;
127 uint32_t support_flags;
128
129 out_size = msg->out_size[0];
130 if (out_size != sizeof(support_flags)) {
131 /* The output argument size is incorrect */
132 return PSA_ERROR_PROGRAMMER_ERROR;
133 }
134
135 support_flags = tfm_ps_get_support();
136 psa_write(msg->handle, 0, &support_flags, out_size);
137 return PSA_SUCCESS;
138 }
139
tfm_protected_storage_service_sfn(const psa_msg_t * msg)140 psa_status_t tfm_protected_storage_service_sfn(const psa_msg_t *msg)
141 {
142 p_msg = msg;
143
144 switch (msg->type) {
145 case TFM_PS_SET:
146 return tfm_ps_set_req(msg);
147 case TFM_PS_GET:
148 return tfm_ps_get_req(msg);
149 case TFM_PS_GET_INFO:
150 return tfm_ps_get_info_req(msg);
151 case TFM_PS_REMOVE:
152 return tfm_ps_remove_req(msg);
153 case TFM_PS_GET_SUPPORT:
154 return tfm_ps_get_support_req(msg);
155 default:
156 return PSA_ERROR_PROGRAMMER_ERROR;
157 }
158
159 return PSA_ERROR_GENERIC_ERROR;
160 }
161
tfm_ps_entry(void)162 psa_status_t tfm_ps_entry(void)
163 {
164 return tfm_ps_init();
165 }
166
ps_req_mngr_read_asset_data(uint8_t * out_data,uint32_t size)167 psa_status_t ps_req_mngr_read_asset_data(uint8_t *out_data, uint32_t size)
168 {
169 size_t num = 0;
170
171 num = psa_read(p_msg->handle, 1, out_data, size);
172 if (num != size) {
173 return PSA_ERROR_PROGRAMMER_ERROR;
174 }
175 return PSA_SUCCESS;
176 }
177
ps_req_mngr_write_asset_data(const uint8_t * in_data,uint32_t size)178 void ps_req_mngr_write_asset_data(const uint8_t *in_data, uint32_t size)
179 {
180 psa_write(p_msg->handle, 0, in_data, size);
181 }
182