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 "securec.h"
17 #include "commonutil.h"
18 #include "distribution.h"
19 #include "log.h"
20 #include "parsedata.h"
21 #include "jsonutil.h"
22 #include "auth_info.h"
23 #include "add_auth_info.h"
24 #include "build_object.h"
25 #include "mem_stat.h"
26 #include "huks_adapter.h"
27 #include "sec_clone_server.h"
28
29 #define LIST_TRUST_PEER_DEF_COUNT 0
30
31 #define FREE_SEND_DATA_FUNC(name) \
32 { \
33 if (((name)->cipher.val != NULL) && ((name)->cipher.length > 0)) { \
34 FREE((name)->cipher.val); \
35 (name)->cipher.val = NULL; \
36 } \
37 break; \
38 }
39
40 #define FREE_SEC_SEND_DATA_FUNC(name) \
41 { \
42 if ((name)->val != NULL) { \
43 FREE((name)->val); \
44 (name)->val = NULL; \
45 } \
46 break; \
47 }
48
49 #ifdef DESC
50 #undef DESC
51 #endif
52 #define DESC(...) 1
53
54 static void encap_inform_message(int32_t error_code, struct message *send);
55 static int32_t deserialize_message(const struct uint8_buff *data, struct message *receive);
56 static int32_t build_send_data_by_struct(const struct message *message, void **send_data, uint32_t *send_data_len);
57 static void destroy_receive_data_struct(const struct message *message);
58 static void destroy_send_data(struct message *message);
59 static void set_result(struct hichain *hichain, uint16_t rcv_msg_code, uint16_t snd_msg_code, int32_t error_code);
60 static int32_t check_identity(const struct session_identity *identity);
61 static int32_t check_call_back(const struct hc_call_back *call_back);
62 static int32_t check_auth_info(const struct hc_user_info *user_info);
63 static int32_t delete_base_key(struct service_id service_id, struct operation_parameter para);
64 static int32_t delete_public_key(hc_handle handle, struct service_id service_id, int32_t user_type);
65 #if !(defined(_CUT_STS_) || defined(_CUT_STS_SERVER_) || defined(_CUT_EXCHANGE_) || defined(_CUT_EXCHANGE_SERVER_))
66 static void build_self_lt_key_pair(const struct hichain *hichain);
67 #endif
68
69 #if DESC("api")
get_instance(const struct session_identity * identity,enum hc_type type,const struct hc_call_back * call_back)70 DLL_API_PUBLIC hc_handle get_instance(const struct session_identity *identity, enum hc_type type,
71 const struct hc_call_back *call_back)
72 {
73 LOGI("Begin get instance");
74 if (check_identity(identity) != HC_OK) {
75 LOGE("Identity error");
76 return NULL;
77 }
78 if (check_call_back(call_back) != HC_OK) {
79 LOGE("Call back error");
80 return NULL;
81 }
82
83 #if !(defined(_CUT_STS_) || defined(_CUT_STS_SERVER_) || defined(_CUT_EXCHANGE_) || defined(_CUT_EXCHANGE_SERVER_))
84 int32_t ret = key_info_init();
85 if (ret != HC_OK) {
86 LOGE("Call key info init failed, status=%d", ret);
87 return NULL;
88 }
89 #endif
90
91 struct hichain *hichain = (struct hichain *)MALLOC(sizeof(struct hichain));
92 if (hichain == NULL) {
93 LOGE("Alloc memory failed");
94 return NULL;
95 }
96 (void)memset_s(hichain, sizeof(*hichain), 0, sizeof(*hichain));
97 hichain->identity = *identity;
98 hichain->type = type;
99 hichain->state = INIT_STATE;
100 hichain->last_state = INIT_STATE;
101 hichain->cb = *call_back;
102
103 #if !(defined(_CUT_STS_) || defined(_CUT_STS_SERVER_) || defined(_CUT_EXCHANGE_) || defined(_CUT_EXCHANGE_SERVER_))
104 build_self_lt_key_pair(hichain);
105 #endif
106
107 LOGI("Get instance success");
108 return hichain;
109 }
110
destroy(hc_handle * handle)111 DLL_API_PUBLIC void destroy(hc_handle *handle)
112 {
113 LOGI("Begin destroy");
114 check_ptr_return(handle);
115 check_ptr_return(*handle);
116 struct hichain *hichain = (struct hichain *)*handle;
117
118 if (hichain->pake_server != NULL) {
119 destroy_pake_server(hichain->pake_server);
120 }
121 if (hichain->pake_client != NULL) {
122 destroy_pake_client(hichain->pake_client);
123 }
124 if (hichain->sts_server != NULL) {
125 destroy_sts_server(hichain->sts_server);
126 }
127 if (hichain->sts_client != NULL) {
128 destroy_sts_client(hichain->sts_client);
129 }
130 if (hichain->auth_info != NULL) {
131 destroy_auth_client(hichain->auth_info);
132 }
133 if (hichain->sec_clone_server != NULL) {
134 destroy_sec_clone_server(hichain->sec_clone_server);
135 }
136 FREE(hichain);
137 *handle = NULL;
138 LOGI("End destroy");
139 }
140
receive_data(hc_handle handle,struct uint8_buff * data)141 DLL_API_PUBLIC int32_t receive_data(hc_handle handle, struct uint8_buff *data)
142 {
143 LOGI("Begin receive data");
144 check_ptr_return_val(handle, HC_INPUT_ERROR);
145 check_ptr_return_val(data, HC_INPUT_ERROR);
146 check_ptr_return_val(data->val, HC_INPUT_ERROR);
147
148 LOGI("Receive data from peer");
149 struct hichain *hichain = (struct hichain *)handle;
150 struct message receive = { 0, 0, 0 };
151 struct message send = { INFORM_MESSAGE, 0, 0 };
152 void *send_data = NULL;
153 uint32_t send_data_len = 0;
154 int32_t ret = deserialize_message(data, &receive);
155 if (ret != HC_OK) {
156 goto inform;
157 }
158 struct header_analysis nav = navigate_message(receive.msg_code);
159 ret = check_message_support(hichain, &nav, &receive);
160 if (ret != HC_OK) {
161 goto inform;
162 }
163 ret = build_object(hichain, nav.modular, !nav.is_request_msg, NULL);
164 if (ret != HC_OK) {
165 goto inform;
166 }
167 ret = proc_message(hichain, &nav, &receive, &send);
168 if (ret != HC_OK) {
169 goto inform;
170 }
171 ret = connect_message(hichain, &nav, &send);
172
173 inform:
174 encap_inform_message(ret, &send);
175
176 /* serialization */
177 ret = build_send_data_by_struct(&send, &send_data, &send_data_len);
178 if (ret == HC_OK) {
179 DBG_OUT("Send data to peer");
180 hichain->cb.transmit(&hichain->identity, send_data, send_data_len);
181 FREE(send_data);
182 } else if (ret == HC_NO_MESSAGE_TO_SEND) {
183 LOGI("Had no message to send");
184 ret = HC_OK;
185 } else {
186 LOGE("build send data failed, error code is %d", ret);
187 }
188 set_result(hichain, receive.msg_code, send.msg_code, ret);
189
190 destroy_receive_data_struct(&receive);
191 destroy_send_data(&send);
192 LOGI("End receive data");
193 return ret; /* hc_error */
194 }
195
196 static int32_t triggered_sts_client(struct hichain *hichain, int32_t operation_code);
197
remove_auth_info(hc_handle handle,const struct operation_parameter * params,const struct hc_auth_id * auth_id,int32_t user_type)198 int32_t remove_auth_info(hc_handle handle, const struct operation_parameter *params,
199 const struct hc_auth_id *auth_id, int32_t user_type)
200 #if (defined(_SUPPORT_SEC_CLONE_) || defined(_SUPPORT_SEC_CLONE_SERVER_))
201 {
202 LOGI("Begin remove auth info");
203 check_ptr_return_val(handle, HC_INPUT_ERROR);
204 check_ptr_return_val(params, HC_INPUT_ERROR);
205 check_ptr_return_val(auth_id, HC_INPUT_ERROR);
206 struct hichain *hichain = (struct hichain *)handle;
207
208 int32_t ret = build_object(hichain, STS_MODULAR, true, params);
209 if (ret != HC_OK) {
210 LOGE("Build sts client sub object failed, error code is %d", ret);
211 return ret;
212 }
213
214 struct auth_info_cache auth_info = {
215 .user_type = user_type,
216 .auth_id = *auth_id
217 };
218 ret = build_object(hichain, REMOVE_MODULAR, true, &auth_info);
219 if (ret != HC_OK) {
220 LOGE("Build remove client sub object failed, error code is %d", ret);
221 return ret;
222 }
223
224 ret = triggered_sts_client(hichain, REMOVE_AUTHINFO);
225 LOGI("Triggered sts client error code is %d", ret);
226 LOGI("End remove auth info");
227 return ret;
228 }
229 #else
230 {
231 LOGE("Secclone has been cut, remove auth info not support");
232 (void)handle;
233 (void)params;
234 (void)auth_id;
235 (void)user_type;
236 return HC_UNSUPPORT;
237 }
238 #endif
239
240 static int32_t triggered_pake_client(struct hichain *hichain, int32_t operation_code);
start_pake(hc_handle handle,const struct operation_parameter * params)241 DLL_API_PUBLIC int32_t start_pake(hc_handle handle, const struct operation_parameter *params)
242 {
243 LOGI("Begin start pake");
244 check_ptr_return_val(handle, HC_INPUT_ERROR);
245 check_ptr_return_val(params, HC_INPUT_ERROR);
246 struct hichain *hichain = (struct hichain *)handle;
247
248 int32_t ret = build_object(hichain, PAKE_MODULAR, true, params);
249 if (ret != HC_OK) {
250 LOGE("Build pake client sub object failed, error code is %d", ret);
251 return ret;
252 }
253
254 ret = triggered_pake_client(hichain, BIND);
255 LOGI("Triggered pake client error code is %d", ret);
256 LOGI("End start pake");
257 return ret;
258 }
259
260 #ifndef _CUT_API_
261
authenticate_peer(hc_handle handle,struct operation_parameter * params)262 DLL_API_PUBLIC int32_t authenticate_peer(hc_handle handle, struct operation_parameter *params)
263 {
264 LOGI("Begin authenticate peer");
265 check_ptr_return_val(handle, HC_INPUT_ERROR);
266 check_ptr_return_val(params, HC_INPUT_ERROR);
267 struct hichain *hichain = (struct hichain *)handle;
268
269 int32_t ret = build_object(hichain, STS_MODULAR, true, params);
270 if (ret != HC_OK) {
271 LOGE("Build sts client sub object failed, error code is %d", ret);
272 return ret;
273 }
274
275 ret = triggered_sts_client(hichain, AUTHENTICATE);
276 LOGI("Triggered sts client error code is %d", ret);
277 LOGI("End authenticate peer");
278 return ret;
279 }
280
delete_local_auth_info(hc_handle handle,struct hc_user_info * user_info)281 DLL_API_PUBLIC int32_t delete_local_auth_info(hc_handle handle, struct hc_user_info *user_info)
282 {
283 LOGI("Begin delete local auth info");
284 check_ptr_return_val(handle, HC_INPUT_ERROR);
285 if (check_auth_info(user_info) != HC_OK) {
286 LOGE("User info is error");
287 return HC_INPUT_ERROR;
288 }
289
290 struct hichain *hichain = (struct hichain *)handle;
291 struct service_id service_id = generate_service_id(&hichain->identity);
292 if (service_id.length == 0) {
293 LOGE("Generate service id failed");
294 return HC_GEN_SERVICE_ID_FAILED;
295 }
296
297 struct hc_pin pin = { 0, {0} };
298 struct operation_parameter para;
299 (void)memset_s(¶, sizeof(para), 0, sizeof(para));
300
301 hichain->cb.get_protocol_params(&hichain->identity, REMOVE_ALL_AUTHINFO, &pin, ¶);
302 if (para.self_auth_id.length > 0) {
303 if (memcmp(para.self_auth_id.auth_id, user_info->auth_id.auth_id, para.self_auth_id.length) == 0) {
304 int32_t ret_base = delete_base_key(service_id, para);
305 int32_t ret_accessor = delete_public_key(handle, service_id, KEY_ALIAS_ACCESSOR_PK);
306 int32_t ret_controller = delete_public_key(handle, service_id, KEY_ALIAS_CONTROLLER_PK);
307 if ((ret_base != HC_OK) || (ret_accessor != HC_OK) || (ret_controller != HC_OK)) {
308 LOGE("delete all key failed");
309 return ERROR_CODE_FAILED;
310 }
311 return HC_OK;
312 }
313 }
314
315 enum huks_key_alias_type alias_type = (user_info->user_type == HC_USER_TYPE_ACCESSORY ?
316 KEY_ALIAS_ACCESSOR_PK : KEY_ALIAS_CONTROLLER_PK);
317 struct hc_key_alias alias = generate_key_alias(&service_id, &(user_info->auth_id), alias_type);
318 if (alias.length == 0) {
319 LOGE("Generate key alias failed");
320 return HC_GEN_ALIAS_FAILED;
321 }
322 int32_t ret = check_lt_public_key_exist(&alias);
323 if (ret != HC_OK) {
324 LOGE("Check lt public key not exist!");
325 return HC_OK; /* ipc 65541 time out, temporarily return ok */
326 }
327 ret = delete_lt_public_key(&alias);
328 if (ret != HC_OK) {
329 LOGE("delete lt public key is %d", ret);
330 return ret;
331 }
332 LOGI("End delete local auth info");
333 return HC_OK;
334 }
335
is_trust_peer(hc_handle handle,struct hc_user_info * user_info)336 DLL_API_PUBLIC int32_t is_trust_peer(hc_handle handle, struct hc_user_info *user_info)
337 {
338 LOGI("Begin is trust peer");
339 check_ptr_return_val(handle, HC_NOT_TRUST_PEER);
340 if (check_auth_info(user_info) != HC_OK) {
341 LOGE("User info is error");
342 return HC_NOT_TRUST_PEER;
343 }
344
345 struct hichain *hichain = (struct hichain *)handle;
346 struct service_id service_id = generate_service_id(&hichain->identity);
347 if (service_id.length == 0) {
348 LOGE("Generate service id failed");
349 return HC_GEN_SERVICE_ID_FAILED;
350 }
351 enum huks_key_alias_type alias_type = (user_info->user_type == HC_USER_TYPE_ACCESSORY ?
352 KEY_ALIAS_ACCESSOR_PK : KEY_ALIAS_CONTROLLER_PK);
353 struct hc_key_alias alias = generate_key_alias(&service_id, &(user_info->auth_id), alias_type);
354 if (alias.length == 0) {
355 LOGE("Generate key alias failed");
356 return HC_GEN_ALIAS_FAILED;
357 }
358 int32_t ret = check_lt_public_key_exist(&alias);
359 if (ret != ERROR_CODE_SUCCESS) {
360 LOGE("Check lt public key exist is %d", ret);
361 return HC_NOT_TRUST_PEER;
362 }
363 struct huks_key_type key_type;
364 struct hc_auth_id auth_id;
365
366 (void)memset_s(&key_type, sizeof(key_type), 0, sizeof(key_type));
367 ret = get_lt_key_info(&alias, &key_type, &auth_id);
368 if (ret != ERROR_CODE_SUCCESS) {
369 LOGE("Check lt public key exist is %d", ret);
370 return HC_NOT_TRUST_PEER;
371 }
372 LOGI("End is trust peer");
373 if (key_type.user_type == (uint8_t)HC_USER_TYPE_ACCESSORY) {
374 return HC_ACCESSORY_TRUST_PEER;
375 }
376 if (key_type.pair_type == (uint8_t)HC_PAIR_TYPE_BIND) {
377 return HC_BINDED_TRUST_PEER;
378 } else {
379 return HC_AUTHED_TRUST_PEER;
380 }
381 }
382
list_trust_peers(hc_handle handle,int32_t trust_user_type,struct hc_auth_id * owner_auth_id,struct hc_auth_id ** auth_id_list)383 DLL_API_PUBLIC uint32_t list_trust_peers(hc_handle handle, int32_t trust_user_type,
384 struct hc_auth_id *owner_auth_id, struct hc_auth_id **auth_id_list)
385 {
386 LOGI("Begin list trust peers");
387 struct hichain *hichain = (struct hichain *)handle;
388
389 check_ptr_return_val(hichain, LIST_TRUST_PEER_DEF_COUNT);
390 check_ptr_return_val(auth_id_list, LIST_TRUST_PEER_DEF_COUNT);
391 check_ptr_return_val(*auth_id_list, LIST_TRUST_PEER_DEF_COUNT);
392 if ((trust_user_type != HC_USER_TYPE_ACCESSORY) && (trust_user_type != HC_USER_TYPE_CONTROLLER)) {
393 LOGE("user type is not support");
394 return LIST_TRUST_PEER_DEF_COUNT;
395 }
396
397 if (owner_auth_id != NULL) {
398 struct service_id srv_id = generate_service_id(&hichain->identity);
399 if (srv_id.length == 0) {
400 LOGE("Generate service id failed");
401 return 0;
402 }
403 enum huks_key_alias_type alias_type = (trust_user_type == HC_USER_TYPE_ACCESSORY ?
404 KEY_ALIAS_ACCESSOR_PK : KEY_ALIAS_CONTROLLER_PK);
405 struct hc_key_alias owner_alias = generate_key_alias(&srv_id, owner_auth_id, alias_type);
406 if (owner_alias.length == 0) {
407 LOGE("Generate key alias failed");
408 return 0;
409 }
410 if (check_lt_public_key_exist(&owner_alias) != ERROR_CODE_SUCCESS) {
411 LOGE("not found this owner");
412 return 0;
413 }
414 if (check_key_alias_is_owner(&owner_alias) != ERROR_CODE_SUCCESS) {
415 LOGE("hc_auth_id is not owner");
416 return 0;
417 }
418 }
419
420 uint32_t count = LIST_TRUST_PEER_DEF_COUNT;
421 int32_t ret = get_lt_public_key_list(owner_auth_id, trust_user_type, *auth_id_list, &count);
422 LOGI("End list trust peers");
423 if ((ret != ERROR_CODE_SUCCESS) || (count == LIST_TRUST_PEER_DEF_COUNT)) {
424 return LIST_TRUST_PEER_DEF_COUNT;
425 }
426 return count;
427 }
428
429 #endif /* _CUT_XXX_ */
430 #endif /* DESC */
431
432 struct msg_result_map {
433 enum message_code msg_code;
434 enum hc_result result;
435 enum hichain_state state;
436 };
437
set_result_by_map(struct hichain * hichain,const struct msg_result_map * map)438 static void set_result_by_map(struct hichain *hichain, const struct msg_result_map *map)
439 {
440 if (map == NULL) {
441 return;
442 }
443 if (map->state != OPERATION_STATE) {
444 goto out;
445 }
446 if ((hichain->operation_code != AUTHENTICATE) && (hichain->operation_code != AUTH_KEY_AGREEMENT)) {
447 goto out;
448 }
449 if (hichain->state != OVER_STATE) {
450 hichain->last_state = hichain->state;
451 hichain->state = OVER_STATE;
452 }
453 hichain->cb.set_service_result(&hichain->identity, END_SUCCESS);
454 return;
455 out:
456 if (hichain->state != map->state) {
457 hichain->last_state = hichain->state;
458 hichain->state = map->state;
459 }
460 hichain->cb.set_service_result(&hichain->identity, map->result);
461 }
462
select_result_map(uint16_t rcv_msg_code,const struct msg_result_map * map,uint32_t n)463 const struct msg_result_map *select_result_map(uint16_t rcv_msg_code, const struct msg_result_map *map, uint32_t n)
464 {
465 for (uint32_t i = 0; i < n; i++) {
466 if (rcv_msg_code == map[i].msg_code) {
467 return &map[i];
468 }
469 }
470 return NULL;
471 }
472
set_result(struct hichain * hichain,uint16_t rcv_msg_code,uint16_t snd_msg_code,int32_t error_code)473 static void set_result(struct hichain *hichain, uint16_t rcv_msg_code, uint16_t snd_msg_code, int32_t error_code)
474 {
475 if (error_code != HC_OK) {
476 LOGE("Error code is not ok, and set end failed");
477 goto error;
478 }
479 if (snd_msg_code == INFORM_MESSAGE) {
480 LOGE("Send an inform message, and set end failed");
481 goto error;
482 }
483 const struct msg_result_map map[] = { { PAKE_REQUEST, KEY_AGREEMENT_PROCESSING, KEY_AGREEMENT_STATE },
484 { PAKE_RESPONSE, KEY_AGREEMENT_PROCESSING, KEY_AGREEMENT_STATE },
485 { PAKE_CLIENT_CONFIRM, KEY_AGREEMENT_END, OPERATION_STATE },
486 { PAKE_SERVER_CONFIRM_RESPONSE, KEY_AGREEMENT_END, OPERATION_STATE },
487 { EXCHANGE_REQUEST, END_SUCCESS, OVER_STATE },
488 { EXCHANGE_RESPONSE, END_SUCCESS, OVER_STATE },
489 { AUTH_START_REQUEST, KEY_AGREEMENT_PROCESSING, KEY_AGREEMENT_STATE },
490 { AUTH_START_RESPONSE, KEY_AGREEMENT_PROCESSING, KEY_AGREEMENT_STATE },
491 { AUTH_ACK_REQUEST, KEY_AGREEMENT_END, OPERATION_STATE },
492 { AUTH_ACK_RESPONSE, KEY_AGREEMENT_END, OPERATION_STATE },
493 { ADD_AUTHINFO_REQUEST, END_SUCCESS, OVER_STATE },
494 { ADD_AUTHINFO_RESPONSE, END_SUCCESS, OVER_STATE },
495 { REMOVE_AUTHINFO_REQUEST, END_SUCCESS, OVER_STATE },
496 { REMOVE_AUTHINFO_RESPONSE, END_SUCCESS, OVER_STATE },
497 { SEC_CLONE_START_REQUEST, OPERATION_PROCESSING, OPERATION_STATE },
498 { SEC_CLONE_ACK_REQUEST, END_SUCCESS, OVER_STATE },
499 { INFORM_MESSAGE, END_FAILED, OVER_STATE },
500 { INVALID_MESSAGE, KEY_AGREEMENT_PROCESSING, KEY_AGREEMENT_STATE } };
501 const struct msg_result_map *map_ptr = select_result_map(rcv_msg_code, map,
502 sizeof(map) / sizeof(struct msg_result_map));
503
504 set_result_by_map(hichain, map_ptr);
505 return;
506 error:
507 hichain->last_state = hichain->state;
508 hichain->state = OVER_STATE;
509 hichain->cb.set_service_result(&hichain->identity, END_FAILED);
510 }
511
encap_inform_message(int32_t error_code,struct message * send)512 static void encap_inform_message(int32_t error_code, struct message *send)
513 {
514 if ((error_code == HC_OK) || (send->msg_code != INFORM_MESSAGE) || (send->payload != NULL)) {
515 return;
516 }
517
518 #if (defined(_CUT_EXCHANGE_) || defined(_CUT_EXCHANGE_SERVER_))
519 if (error_code == HC_UNSUPPORT) {
520 send->msg_code = INVALID_MESSAGE;
521 return;
522 }
523 #endif
524 int32_t *err = (int32_t *)MALLOC(sizeof(int32_t));
525 if (err == NULL) {
526 LOGE("Malloc for encape inform message failed");
527 return;
528 }
529
530 *err = error_code;
531 send->payload = err;
532 }
533
triggered_pake_client(struct hichain * hichain,int32_t operation_code)534 static int32_t triggered_pake_client(struct hichain *hichain, int32_t operation_code)
535 #if !(defined(_CUT_PAKE_) || defined(_CUT_PAKE_CLIENT_))
536 {
537 hichain->operation_code = operation_code;
538 hichain->pake_client->operation_code = operation_code;
539
540 struct message send = {
541 .msg_code = PAKE_REQUEST,
542 .rsv = 0,
543 .payload = NULL
544 };
545 int32_t ret = send_pake_start_request(hichain->pake_client, &send);
546 if (ret != HC_OK) {
547 LOGE("Object %u build sts start request failed, error code is %d", pake_client_sn(hichain->pake_client), ret);
548 return HC_BUILD_SEND_DATA_FAILED;
549 }
550
551 void *send_data = NULL;
552 uint32_t send_data_len = 0;
553
554 ret = build_send_data_by_struct(&send, &send_data, &send_data_len);
555 if (ret != HC_OK) {
556 LOGW("build send data failed, error code is %d", ret);
557 } else {
558 DBG_OUT("send_data:%s", (uint8_t *)send_data);
559 hichain->cb.transmit(&hichain->identity, send_data, send_data_len);
560 FREE(send_data);
561 }
562
563 set_result(hichain, INVALID_MESSAGE, PAKE_REQUEST, ret);
564 destroy_send_data(&send);
565 return ret;
566 }
567 #else
568 {
569 (void)hichain;
570 (void)operation_code;
571 LOGE("Pake client has been cut, triggered pake client not support");
572 return HC_UNSUPPORT;
573 }
574 #endif
575
triggered_sts_client(struct hichain * hichain,int32_t operation_code)576 static int32_t triggered_sts_client(struct hichain *hichain, int32_t operation_code)
577 #if !(defined(_CUT_STS_) || defined(_CUT_STS_CLIENT_))
578 {
579 hichain->operation_code = operation_code;
580 hichain->sts_client->operation_code = operation_code;
581
582 struct message send = {
583 .msg_code = AUTH_START_REQUEST,
584 .rsv = 0,
585 .payload = NULL
586 };
587 int32_t ret = send_sts_start_request(hichain->sts_client, &send);
588 if (ret != HC_OK) {
589 LOGE("Object %u build sts start request failed, error code is %d", sts_client_sn(hichain->sts_client), ret);
590 return HC_BUILD_SEND_DATA_FAILED;
591 }
592
593 void *send_data = NULL;
594 uint32_t send_data_len = 0;
595
596 ret = build_send_data_by_struct(&send, &send_data, &send_data_len);
597 if (ret != HC_OK) {
598 LOGW("build send data failed, error code is %d", ret);
599 } else {
600 DBG_OUT("send_data:%s", (uint8_t *)send_data);
601 hichain->cb.transmit(&hichain->identity, send_data, send_data_len);
602 FREE(send_data);
603 }
604
605 set_result(hichain, INVALID_MESSAGE, AUTH_START_REQUEST, ret);
606 destroy_send_data(&send);
607 return ret;
608 }
609 #else
610 {
611 (void)hichain;
612 (void)operation_code;
613 LOGE("stsclient has been cut, triggered_sts_client not support");
614 return HC_UNSUPPORT;
615 }
616 #endif
617
618 static int32_t build_struct_by_receive_data(uint32_t msg_code, const char *payload_data,
619 enum json_object_data_type type, struct message *message);
deserialize_message(const struct uint8_buff * data,struct message * receive)620 static int32_t deserialize_message(const struct uint8_buff *data, struct message *receive)
621 {
622 /* message head deserialization */
623 struct pass_through_data *pass_through_data = parse_data((const char *)data->val);
624 if (pass_through_data == NULL) {
625 LOGE("Parse data failed");
626 return HC_BUILD_OBJECT_FAILED;
627 }
628
629 #if (defined(_CUT_EXCHANGE_) || defined(_CUT_EXCHANGE_SERVER_))
630 if (pass_through_data->message_code == EXCHANGE_REQUEST) {
631 free_data(pass_through_data);
632 pass_through_data = NULL;
633 return HC_UNSUPPORT;
634 }
635 #endif
636
637 /* message payload deserialization */
638 int32_t ret = build_struct_by_receive_data(pass_through_data->message_code, pass_through_data->payload_data,
639 JSON_STRING_DATA, receive);
640 if (ret != HC_OK) {
641 LOGE("Build struct by receive data failed, error code is %d", ret);
642 }
643 free_data(pass_through_data);
644 pass_through_data = NULL;
645 return ret;
646 }
647
648 typedef void *(*parse_message_func)(const char *pay_load, enum json_object_data_type type);
649 struct parse_message_map {
650 enum message_code msg_code;
651 parse_message_func parse_message;
652 };
653
build_struct_by_receive_data(uint32_t msg_code,const char * payload_data,enum json_object_data_type type,struct message * message)654 static int32_t build_struct_by_receive_data(uint32_t msg_code, const char *payload_data,
655 enum json_object_data_type type, struct message *message)
656 {
657 const struct parse_message_map map[] = { { PAKE_RESPONSE, parse_pake_response },
658 { PAKE_SERVER_CONFIRM_RESPONSE, parse_pake_server_confirm },
659 { AUTH_START_RESPONSE, parse_auth_start_response },
660 { AUTH_ACK_RESPONSE, parse_auth_ack_response },
661 { REMOVE_AUTHINFO_REQUEST, parse_rmv_auth_info_request },
662 { REMOVE_AUTHINFO_RESPONSE, parse_rmv_auth_info_response },
663 { EXCHANGE_RESPONSE, parse_exchange_response },
664 { SEC_CLONE_START_REQUEST, sec_clone_parse_client_request },
665 { SEC_CLONE_ACK_REQUEST, sec_clone_parse_client_ack } };
666
667 for (uint32_t i = 0; i < sizeof(map) / sizeof(struct parse_message_map); i++) {
668 if (map[i].msg_code != msg_code) {
669 continue;
670 }
671 void *payload = map[i].parse_message(payload_data, type);
672
673 if (payload == NULL) {
674 return HC_BUILD_OBJECT_FAILED;
675 }
676 message->msg_code = map[i].msg_code;
677 message->payload = payload;
678 return HC_OK;
679 }
680
681 LOGE("Unsupport parse 0x%04x message", message->msg_code);
682 return HC_UNKNOW_MESSAGE;
683 }
684
685 typedef void (*free_message_func)(void *obj);
686 struct free_message_map {
687 enum message_code msg_code;
688 free_message_func free_message;
689 };
690
destroy_receive_data_struct(const struct message * message)691 static void destroy_receive_data_struct(const struct message *message)
692 {
693 const struct free_message_map map[] = { { PAKE_REQUEST, free_pake_request },
694 { PAKE_RESPONSE, free_pake_response },
695 { PAKE_CLIENT_CONFIRM, free_pake_client_confirm },
696 { PAKE_SERVER_CONFIRM_RESPONSE, free_pake_server_confirm },
697 { AUTH_START_REQUEST, free_auth_start_request },
698 { AUTH_START_RESPONSE, free_auth_start_response },
699 { AUTH_ACK_REQUEST, free_auth_ack_request },
700 { AUTH_ACK_RESPONSE, free_auth_ack_response },
701 { REMOVE_AUTHINFO_REQUEST, free_rmv_auth_info_request },
702 { REMOVE_AUTHINFO_RESPONSE, free_rmv_auth_info_response },
703 { EXCHANGE_REQUEST, free_exchange_request },
704 { EXCHANGE_RESPONSE, free_exchange_response },
705 { SEC_CLONE_START_REQUEST, sec_clone_free_client_request },
706 { SEC_CLONE_ACK_REQUEST, sec_clone_free_client_ack } };
707
708 for (uint32_t i = 0; i < sizeof(map) / sizeof(struct free_message_map); i++) {
709 if (map[i].msg_code == message->msg_code) {
710 map[i].free_message(message->payload);
711 }
712 }
713 }
714
715 typedef char *(*make_message_func)(void *data);
716 struct make_message_map {
717 enum message_code msg_code;
718 make_message_func make_message;
719 };
720
build_send_data_by_struct(const struct message * message,void ** send_data,uint32_t * send_data_len)721 static int32_t build_send_data_by_struct(const struct message *message, void **send_data, uint32_t *send_data_len)
722 {
723 const struct make_message_map map[] = { { PAKE_REQUEST, make_pake_request },
724 { PAKE_CLIENT_CONFIRM, make_pake_client_confirm },
725 { AUTH_START_REQUEST, make_auth_start_request },
726 { AUTH_ACK_REQUEST, make_auth_ack_request },
727 { REMOVE_AUTHINFO_REQUEST, make_rmv_auth_info_request },
728 { REMOVE_AUTHINFO_RESPONSE, make_rmv_auth_info_response },
729 { EXCHANGE_REQUEST, make_exchange_request },
730 { SEC_CLONE_START_RESPONSE, sec_clone_make_srv_proof },
731 { SEC_CLONE_ACK_RESPONSE, sec_clone_make_clone_ret },
732 { INFORM_MESSAGE, make_inform_message } };
733
734 if (message->msg_code == INVALID_MESSAGE) {
735 return HC_NO_MESSAGE_TO_SEND;
736 }
737
738 if (message->payload == NULL) {
739 LOGE("Message payload is null");
740 return HC_BUILD_SEND_DATA_FAILED;
741 }
742
743 for (uint32_t i = 0; i < sizeof(map) / sizeof(struct make_message_map); i++) {
744 if (map[i].msg_code != message->msg_code) {
745 continue;
746 }
747 *send_data = map[i].make_message(message->payload);
748 if (*send_data == NULL) {
749 return HC_BUILD_SEND_DATA_FAILED;
750 }
751 *send_data_len = strlen(*send_data);
752 return HC_OK;
753 }
754
755 LOGE("Unsupport encape 0x%04x message", message->msg_code);
756 return HC_INNER_ERROR;
757 }
758
destroy_send_data(struct message * message)759 static void destroy_send_data(struct message *message)
760 {
761 if (message->payload == NULL) {
762 return;
763 }
764
765 switch (message->msg_code) {
766 case ADD_AUTHINFO_RESPONSE: {
767 add_response_data *add_res_data = message->payload;
768 FREE_SEND_DATA_FUNC(add_res_data); /* add_res_data */
769 }
770 case ADD_AUTHINFO_REQUEST: {
771 add_request_data *add_req_data = message->payload;
772 FREE_SEND_DATA_FUNC(add_req_data); /* add_req_data */
773 }
774 case REMOVE_AUTHINFO_RESPONSE: {
775 remove_response_data *rmv_auth_info_res_data = message->payload;
776 FREE_SEND_DATA_FUNC(rmv_auth_info_res_data); /* rmv_auth_info_res_data */
777 }
778 case REMOVE_AUTHINFO_REQUEST: {
779 remove_request_data *rmv_auth_info_req_data = message->payload;
780 FREE_SEND_DATA_FUNC(rmv_auth_info_req_data); /* rmv_auth_info_req_data */
781 }
782 case EXCHANGE_RESPONSE: {
783 exchange_response_data *exchange_response = message->payload;
784 FREE_SEND_DATA_FUNC(exchange_response); /* exchange_response */
785 }
786 case EXCHANGE_REQUEST: {
787 exchange_request_data *exchange_requeset = message->payload;
788 FREE_SEND_DATA_FUNC(exchange_requeset); /* exchange_requeset */
789 }
790 case SEC_CLONE_START_RESPONSE: {
791 struct uint8_buff *data = message->payload;
792 FREE_SEC_SEND_DATA_FUNC(data); /* data */
793 }
794 case SEC_CLONE_ACK_RESPONSE: {
795 struct uint8_buff *data = message->payload;
796 FREE_SEC_SEND_DATA_FUNC(data); /* data */
797 }
798 default:
799 break;
800 }
801
802 if (message->payload != NULL) {
803 FREE(message->payload);
804 message->payload = NULL;
805 }
806 }
807
check_identity(const struct session_identity * identity)808 static int32_t check_identity(const struct session_identity *identity)
809 {
810 check_ptr_return_val(identity, HC_INPUT_ERROR);
811 if (identity->package_name.length > HC_PACKAGE_NAME_BUFF_LEN) {
812 LOGE("Package name length error, %u > %u", identity->package_name.length, HC_PACKAGE_NAME_BUFF_LEN);
813 return HC_INPUT_ERROR;
814 }
815 if (identity->service_type.length > HC_SERVICE_TYPE_BUFF_LEN) {
816 LOGE("Service type length error, %u > %u", identity->service_type.length, HC_SERVICE_TYPE_BUFF_LEN);
817 return HC_INPUT_ERROR;
818 }
819 return HC_OK;
820 }
821
check_call_back(const struct hc_call_back * call_back)822 static int32_t check_call_back(const struct hc_call_back *call_back)
823 {
824 check_ptr_return_val(call_back, HC_INPUT_ERROR);
825 check_ptr_return_val(call_back->transmit, HC_INPUT_ERROR);
826 check_ptr_return_val(call_back->get_protocol_params, HC_INPUT_ERROR);
827 check_ptr_return_val(call_back->set_session_key, HC_INPUT_ERROR);
828 check_ptr_return_val(call_back->set_service_result, HC_INPUT_ERROR);
829 check_ptr_return_val(call_back->confirm_receive_request, HC_INPUT_ERROR);
830 return HC_OK;
831 }
832
check_auth_info(const struct hc_user_info * user_info)833 static int32_t check_auth_info(const struct hc_user_info *user_info)
834 {
835 check_ptr_return_val(user_info, HC_INPUT_ERROR);
836 if (user_info->auth_id.length > HC_AUTH_ID_BUFF_LEN) {
837 LOGE("Auth id length is error, %u > %u", user_info->auth_id.length, HC_AUTH_ID_BUFF_LEN);
838 return HC_INPUT_ERROR;
839 }
840 if ((user_info->user_type != HC_USER_TYPE_CONTROLLER) && (user_info->user_type != HC_USER_TYPE_ACCESSORY)) {
841 LOGE("User type %d is not controller or accessory", user_info->user_type);
842 return HC_INPUT_ERROR;
843 }
844 return HC_OK;
845 }
846
delete_base_key(struct service_id service_id,struct operation_parameter para)847 static int32_t delete_base_key(struct service_id service_id, struct operation_parameter para)
848 {
849 LOGI("delete base key");
850 struct hc_key_alias alias_list[HC_BASE_KEY_NUM];
851 int32_t size = sizeof(struct hc_key_alias);
852 int32_t length = HC_BASE_KEY_NUM * size;
853 (void)memset_s(alias_list, length, 0, length);
854
855 int32_t pos = 0;
856 struct hc_key_alias base_alias = generate_key_alias(&service_id, &(para.peer_auth_id), KEY_ALIAS_KEK);
857 (void)memcpy_s(alias_list + pos, length - pos * size, &base_alias, size);
858 pos++;
859 base_alias = generate_key_alias(&service_id, &(para.peer_auth_id), KEY_ALIAS_DEK);
860 (void)memcpy_s(alias_list + pos, length - pos * size, &base_alias, size);
861 pos++;
862 base_alias = generate_key_alias(&service_id, &(para.peer_auth_id), KEY_ALIAS_LT_KEY_PAIR);
863 (void)memcpy_s(alias_list + pos, length - pos * size, &base_alias, size);
864 pos++;
865 base_alias = generate_key_alias(&service_id, &(para.self_auth_id), KEY_ALIAS_LT_KEY_PAIR);
866 (void)memcpy_s(alias_list + pos, length - pos * size, &base_alias, size);
867 pos++;
868 base_alias = generate_key_alias(&service_id, &(para.self_auth_id), KEY_ALIAS_TMP);
869 (void)memcpy_s(alias_list + pos, length - pos * size, &base_alias, size);
870
871 for (uint32_t loop = 0; loop < HC_BASE_KEY_NUM; loop++) {
872 if (alias_list[loop].length == 0) {
873 LOGE("Generate key alias failed");
874 continue;
875 }
876 int32_t ret = check_lt_public_key_exist(&alias_list[loop]);
877 if (ret != HC_OK) {
878 LOGE("not found key alias %d", loop);
879 continue;
880 }
881 ret = delete_lt_public_key(&alias_list[loop]);
882 if (ret != HC_OK) {
883 LOGE("delete auth_alias public key is %d", ret);
884 return ret;
885 }
886 }
887
888 return HC_OK;
889 }
890
delete_public_key(hc_handle handle,struct service_id service_id,int32_t user_type)891 static int32_t delete_public_key(hc_handle handle, struct service_id service_id, int32_t user_type)
892 {
893 LOGI("delete public key");
894 uint32_t length = HC_PUB_KEY_ALIAS_MAX_NUM * sizeof(struct hc_auth_id);
895 struct hc_auth_id *auth_id_list = (struct hc_auth_id *)MALLOC(length);
896 if (auth_id_list == NULL) {
897 LOGE("malloc auth id list failed");
898 return HC_MALLOC_FAILED;
899 }
900 (void)memset_s(auth_id_list, length, 0, length);
901
902 uint32_t peers_num = list_trust_peers(handle, user_type, NULL, &auth_id_list);
903 LOGI("peers_num %u", peers_num);
904 for (uint32_t loop = 0; loop < peers_num; loop++) {
905 struct hc_key_alias key_alias = generate_key_alias(&service_id, &auth_id_list[loop], user_type);
906 if (key_alias.length == 0) {
907 LOGE("Generate key alias failed");
908 continue;
909 }
910 int32_t ret = check_lt_public_key_exist(&key_alias);
911 if (ret != HC_OK) {
912 continue;
913 }
914 ret = delete_lt_public_key(&key_alias);
915 if (ret != HC_OK) {
916 LOGE("delete key_alias public key is %d", ret);
917 if (auth_id_list != NULL) {
918 FREE(auth_id_list);
919 auth_id_list = NULL;
920 }
921 return ret;
922 }
923 }
924
925 if (auth_id_list != NULL) {
926 FREE(auth_id_list);
927 auth_id_list = NULL;
928 }
929
930 return HC_OK;
931 }
932
933 #if !(defined(_CUT_STS_) || defined(_CUT_STS_SERVER_)|| defined(_CUT_EXCHANGE_)|| defined(_CUT_EXCHANGE_SERVER_))
build_self_lt_key_pair(const struct hichain * hichain)934 static void build_self_lt_key_pair(const struct hichain *hichain)
935 {
936 struct hc_pin pin = { 0, {0} };
937 struct operation_parameter para;
938
939 (void)memset_s(¶, sizeof(para), 0, sizeof(para));
940 hichain->cb.get_protocol_params(&hichain->identity, GENERATE_KEY_PAIR, &pin, ¶);
941
942 if (para.self_auth_id.length > 0) {
943 struct service_id service_id = generate_service_id(&hichain->identity);
944 if (service_id.length == 0) {
945 LOGE("Generate service id failed");
946 return;
947 }
948 #if (defined(_SUPPORT_SEC_CLONE_) || defined(_SUPPORT_SEC_CLONE_SERVER_))
949 struct hc_key_alias alias = generate_key_alias(&service_id, ¶.self_auth_id, KEY_ALIAS_LT_KEY_PAIR);
950 #else
951 struct hc_key_alias alias = generate_key_alias(&service_id, ¶.self_auth_id, KEY_ALIAS_ACCESSOR_PK);
952 #endif
953 if (alias.length == 0) {
954 LOGE("Generate key alias failed");
955 return;
956 }
957 int32_t ret = check_lt_public_key_exist(&alias);
958 if (ret != HC_OK) {
959 ret = generate_lt_key_pair(&alias, ¶.self_auth_id);
960 if (ret != HC_OK) {
961 LOGE("Generate self ltpk return value is %d", ret);
962 return;
963 }
964 DBG_OUT("Generate self ltpk ok");
965 }
966 }
967 }
968 #endif
969