• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&para, sizeof(para), 0, sizeof(para));
300 
301     hichain->cb.get_protocol_params(&hichain->identity, REMOVE_ALL_AUTHINFO, &pin, &para);
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(&para, sizeof(para), 0, sizeof(para));
940     hichain->cb.get_protocol_params(&hichain->identity, GENERATE_KEY_PAIR, &pin, &para);
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, &para.self_auth_id, KEY_ALIAS_LT_KEY_PAIR);
950 #else
951         struct hc_key_alias alias = generate_key_alias(&service_id, &para.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, &para.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