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