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