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