1 /*
2 * Copyright (c) 2020 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "build_object.h"
17 #include "securec.h"
18 #include "log.h"
19 #include "auth_info.h"
20
21 struct object_map {
22 int32_t modular;
23 bool is_client;
24 void **object;
25 };
26
27 struct object_relation {
28 int32_t src_modular;
29 int32_t dst_modular;
30 bool src_is_client;
31 bool dst_is_client;
32 };
33
34 static void **get_object(const struct object_map *map, uint32_t n, int32_t modular, bool is_client);
35 static bool check_mutex_object_is_null(const struct object_map *map, uint32_t n, int32_t modular, bool is_client);
36 static bool check_depend_object_is_not_null(const struct object_map *map, uint32_t n, int32_t modular, bool is_client);
37 static void *build_object_by_modular(struct hichain *hichain, int32_t modular, bool is_client, const void *params);
38 static bool check_param_is_valid(const struct operation_parameter *para);
build_object(struct hichain * hichain,int32_t modular,bool is_client,const void * params)39 int32_t build_object(struct hichain *hichain, int32_t modular, bool is_client, const void *params)
40 {
41 const struct object_map map[] = { { PAKE_MODULAR, true, (void **)&hichain->pake_client },
42 { PAKE_MODULAR, false, (void **)&hichain->pake_server },
43 { STS_MODULAR, true, (void **)&hichain->sts_client },
44 { STS_MODULAR, false, (void **)&hichain->sts_server },
45 { ADD_MODULAR, true, (void **)&hichain->auth_info },
46 { REMOVE_MODULAR, true, (void **)&hichain->auth_info },
47 { SEC_CLONE_MODULAR, false, (void **)&hichain->sec_clone_server } };
48 void **object = get_object(map, sizeof(map) / sizeof(map[0]), modular, is_client);
49 if ((object == NULL) || (*object != NULL)) {
50 DBG_OUT("No sub-objects need to be applied for");
51 return HC_OK;
52 }
53 if (check_mutex_object_is_null(map, sizeof(map) / sizeof(map[0]), modular, is_client) == false) {
54 LOGE("The mutex sub-object have been created, create %d:%d sub-object failed", modular, is_client);
55 return HC_REPEATED_REFERENCE;
56 }
57 if (check_depend_object_is_not_null(map, sizeof(map) / sizeof(map[0]), modular, is_client) == false) {
58 LOGE("The depend sub-object is not created, create %d:%d sub-object failed", modular, is_client);
59 return HC_NEED_DEPEND;
60 }
61 *object = build_object_by_modular(hichain, modular, is_client, params);
62 if (*object == NULL) {
63 LOGE("Create %d:%d sub-object failed", modular, is_client);
64 return HC_BUILD_OBJECT_FAILED;
65 }
66 DBG_OUT("Create %d:%d sub-object success", modular, is_client);
67 return HC_OK;
68 }
69
get_object(const struct object_map * map,uint32_t n,int32_t modular,bool is_client)70 static void **get_object(const struct object_map *map, uint32_t n, int32_t modular, bool is_client)
71 {
72 for (uint32_t i = 0; i < n; i++) {
73 if ((modular == map[i].modular) && (is_client == map[i].is_client)) {
74 return map[i].object;
75 }
76 }
77
78 return NULL;
79 }
80
81 typedef const struct object_relation *object_relation_ptr;
82
select_relation_map(const struct object_relation * map,uint32_t n,int32_t modular,bool is_client,object_relation_ptr * select_map)83 static uint32_t select_relation_map(const struct object_relation *map, uint32_t n, int32_t modular, bool is_client,
84 object_relation_ptr *select_map)
85 {
86 uint32_t count = 0;
87
88 for (uint32_t i = 0; i < n; i++) {
89 if ((modular == map[i].src_modular) && (is_client == map[i].src_is_client)) {
90 select_map[count] = &map[i];
91 count++;
92 }
93 }
94 return count;
95 }
96
check_mutex_object_is_null(const struct object_map * map,uint32_t n,int32_t modular,bool is_client)97 static bool check_mutex_object_is_null(const struct object_map *map, uint32_t n, int32_t modular, bool is_client)
98 {
99 const struct object_relation mutex_map[] = { { PAKE_MODULAR, STS_MODULAR, true, false },
100 { STS_MODULAR, PAKE_MODULAR, false, true },
101 { PAKE_MODULAR, STS_MODULAR, true, true },
102 { STS_MODULAR, PAKE_MODULAR, true, true },
103 { PAKE_MODULAR, STS_MODULAR, false, false },
104 { STS_MODULAR, PAKE_MODULAR, false, false },
105 { PAKE_MODULAR, STS_MODULAR, false, true },
106 { STS_MODULAR, PAKE_MODULAR, true, false },
107 { STS_MODULAR, STS_MODULAR, true, false },
108 { STS_MODULAR, STS_MODULAR, false, true },
109 { ADD_MODULAR, STS_MODULAR, true, false },
110 { STS_MODULAR, ADD_MODULAR, false, true },
111 { REMOVE_MODULAR, STS_MODULAR, true, false },
112 { STS_MODULAR, REMOVE_MODULAR, false, true },
113 { PAKE_MODULAR, SEC_CLONE_MODULAR, false, false },
114 { SEC_CLONE_MODULAR, PAKE_MODULAR, false, false } };
115 object_relation_ptr select_map[sizeof(mutex_map) / sizeof(mutex_map[0])] = {0};
116 uint32_t count = select_relation_map(mutex_map, sizeof(mutex_map) / sizeof(mutex_map[0]), modular,
117 is_client, select_map);
118 if (count == 0) { /* no muutex sub object */
119 return true;
120 }
121 for (uint32_t i = 0; i < n; i++) {
122 if ((map[i].modular == modular) && (map[i].is_client == is_client)) { /* skip sub object that will be created */
123 continue;
124 }
125 if (*map[i].object == NULL) { /* null sub object is correct even mutex */
126 continue;
127 }
128 for (uint32_t j = 0; j < count; j++) {
129 if ((map[i].modular == select_map[j]->dst_modular) && (map[i].is_client == select_map[j]->dst_is_client)) {
130 return false; /* mutex sub object and not null */
131 }
132 }
133 }
134 return true;
135 }
136
check_depend_object_is_not_null(const struct object_map * map,uint32_t n,int32_t modular,bool is_client)137 static bool check_depend_object_is_not_null(const struct object_map *map, uint32_t n, int32_t modular, bool is_client)
138 {
139 const struct object_relation depend_map[] = { { ADD_MODULAR, STS_MODULAR, true, true },
140 { REMOVE_MODULAR, STS_MODULAR, true, true },
141 { SEC_CLONE_MODULAR, STS_MODULAR, false, false } };
142 object_relation_ptr select_map[sizeof(depend_map) / sizeof(depend_map[0])] = {0};
143 uint32_t count = select_relation_map(depend_map, sizeof(depend_map) / sizeof(depend_map[0]),
144 modular, is_client, select_map);
145 if (count == 0) { /* no dependent sub object */
146 return true;
147 }
148 for (uint32_t i = 0; i < n; i++) {
149 if ((map[i].modular == modular) && (map[i].is_client == is_client)) { /* skip sub object that will be created */
150 continue;
151 }
152 if (*map[i].object != NULL) { /* null sub object is correct even dependent */
153 continue;
154 }
155 for (uint32_t j = 0; j < count; j++) {
156 if ((map[i].modular == select_map[j]->dst_modular) && (map[i].is_client == select_map[j]->dst_is_client)) {
157 return false; /* depentend sub object and not null */
158 }
159 }
160 }
161 return true;
162 }
163
164 typedef void *(*build_sub_object)(struct hichain *hichain, const void *params);
165 struct build_sub_object_map {
166 int32_t modular;
167 bool is_client;
168 build_sub_object build_func;
169 };
170
171 static void *build_pake_client_object(struct hichain *hichain, const void *params);
172 static void *build_pake_server_object(struct hichain *hichain, const void *params);
173 static void *build_sts_client_object(struct hichain *hichain, const void *params);
174 static void *build_sts_server_object(struct hichain *hichain, const void *params);
175 static void *build_auth_info_client_object(struct hichain *hichain, const void *params);
176 static void *build_sec_clone_server_object(struct hichain *hichain, const void *params);
build_object_by_modular(struct hichain * hichain,int32_t modular,bool is_client,const void * params)177 static void *build_object_by_modular(struct hichain *hichain, int32_t modular, bool is_client, const void *params)
178 {
179 const struct build_sub_object_map map[] = { { PAKE_MODULAR, true, build_pake_client_object },
180 { PAKE_MODULAR, false, build_pake_server_object },
181 { STS_MODULAR, true, build_sts_client_object },
182 { STS_MODULAR, false, build_sts_server_object },
183 { ADD_MODULAR, true, build_auth_info_client_object },
184 { REMOVE_MODULAR, true, build_auth_info_client_object },
185 { SEC_CLONE_MODULAR, false, build_sec_clone_server_object } };
186 for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
187 if ((map[i].modular == modular) && (map[i].is_client == is_client)) {
188 return map[i].build_func(hichain, params);
189 }
190 }
191 return NULL;
192 }
193
build_pake_client_object(struct hichain * hichain,const void * params)194 static void *build_pake_client_object(struct hichain *hichain, const void *params)
195 {
196 (void)params;
197 struct hc_pin pin = { 0, {0} };
198 struct operation_parameter para;
199
200 (void)memset_s(¶, sizeof(para), 0, sizeof(para));
201 hichain->cb.get_protocol_params(&hichain->identity, hichain->operation_code, &pin, ¶);
202 if (check_param_is_valid(¶) == false) {
203 LOGE("Param invalid");
204 return NULL;
205 }
206 if (pin.length > HC_PIN_BUFF_LEN) {
207 LOGE("PIN invalid");
208 return NULL;
209 }
210 return build_pake_client(&hichain->identity, &pin, para.key_length, ¶.self_auth_id, ¶.peer_auth_id);
211 }
212
build_pake_server_object(struct hichain * hichain,const void * params)213 static void *build_pake_server_object(struct hichain *hichain, const void *params)
214 {
215 (void)params;
216 struct hc_pin pin = { 0, {0} };
217 struct operation_parameter para;
218
219 (void)memset_s(¶, sizeof(para), 0, sizeof(para));
220 hichain->cb.get_protocol_params(&hichain->identity, hichain->operation_code, &pin, ¶);
221 if (check_param_is_valid(¶) == false) {
222 LOGE("Param invalid");
223 return NULL;
224 }
225 if (pin.length > HC_PIN_BUFF_LEN) {
226 LOGE("PIN invalid");
227 return NULL;
228 }
229 return build_pake_server(&pin, para.key_length, ¶.peer_auth_id, ¶.self_auth_id);
230 }
231
build_sts_client_object(struct hichain * hichain,const void * params)232 static void *build_sts_client_object(struct hichain *hichain, const void *params)
233 {
234 struct operation_parameter *para = (struct operation_parameter *)params;
235
236 return build_sts_client(hichain, para->key_length, ¶->self_auth_id,
237 ¶->peer_auth_id);
238 }
239
build_sts_server_object(struct hichain * hichain,const void * params)240 static void *build_sts_server_object(struct hichain *hichain, const void *params)
241 {
242 (void)params;
243 struct hc_pin pin = { 0, {0} };
244 struct operation_parameter para;
245
246 (void)memset_s(¶, sizeof(para), 0, sizeof(para));
247 hichain->cb.get_protocol_params(&hichain->identity, hichain->operation_code, &pin, ¶);
248 if (check_param_is_valid(¶) == false) {
249 LOGE("Protocol param invalid");
250 return NULL;
251 }
252 return build_sts_server(hichain, para.key_length, ¶.peer_auth_id, ¶.self_auth_id);
253 }
254
build_auth_info_client_object(struct hichain * hichain,const void * params)255 static void *build_auth_info_client_object(struct hichain *hichain, const void *params)
256 {
257 struct auth_info_cache *para = (struct auth_info_cache *)params;
258
259 hichain->auth_info = build_auth_client_info(para->auth_id, para->user_type);
260
261 return hichain->auth_info;
262 }
263
build_sec_clone_server_object(struct hichain * hichain,const void * params)264 static void *build_sec_clone_server_object(struct hichain *hichain, const void *params)
265 {
266 (void)params;
267 return build_sec_clone_server(hichain);
268 }
269
check_param_is_valid(const struct operation_parameter * para)270 static bool check_param_is_valid(const struct operation_parameter *para)
271 {
272 check_ptr_return_val(para, false);
273 if (para->self_auth_id.length > HC_AUTH_ID_BUFF_LEN) {
274 LOGE("Self auth id length error");
275 return false;
276 }
277 if (para->peer_auth_id.length > HC_AUTH_ID_BUFF_LEN) {
278 LOGE("Peer auth id length error");
279 return false;
280 }
281 if (para->key_length > HC_SESSION_KEY_LEN) {
282 LOGE("Key length error");
283 return false;
284 }
285 return true;
286 }
287