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 "key_agreement_client.h"
17 #include "base.h"
18 #include "hichain.h"
19 #include "log.h"
20 
21 #ifdef DESC
22 #undef DESC
23 #endif
24 #define DESC(...) 1
25 
26 static bool is_state_error(struct key_agreement_client *handle, enum protocol_action action);
27 
init_client(struct key_agreement_client * handle,struct client_virtual_func_group * funcs)28 void init_client(struct key_agreement_client *handle, struct client_virtual_func_group *funcs)
29 {
30     check_ptr_return(handle);
31     check_ptr_return(funcs);
32     init_protocol(&handle->protocol_base_info);
33     handle->package_funcs = *funcs;
34 }
35 
send_start_request(void * handle,void * send_data)36 int32_t send_start_request(void *handle, void *send_data)
37 {
38     check_ptr_return_val(handle, HC_INPUT_ERROR);
39     check_ptr_return_val(send_data, HC_INPUT_ERROR);
40     struct key_agreement_client *client = (struct key_agreement_client *)handle;
41     struct key_agreement_protocol *base = &client->protocol_base_info;
42 
43     DBG_OUT("Object %u begin send start request data", base->sn);
44     if (is_state_error(client, SEND_START_REQUEST)) {
45         LOGE("Object %u state error", base->sn);
46         return PROTOCOL_STATE_ERROR;
47     }
48     struct client_virtual_func_group *funcs = &client->package_funcs;
49     int32_t ret = funcs->build_start_request_data(handle, send_data);
50     if (ret != HC_OK) {
51         set_state(base, PROTOCOL_ERROR);
52         LOGE("Object %u build start request data failed, error code is %d", base->sn, ret);
53         return ret;
54     }
55     set_state(base, START_REQUEST);
56     set_last_time_sec(base);
57     DBG_OUT("Object %u send start request data success", base->sn);
58     return HC_OK;
59 }
60 
send_end_request(void * handle,void * receive_data,void * send_data)61 int32_t send_end_request(void *handle, void *receive_data, void *send_data)
62 {
63     check_ptr_return_val(handle, HC_INPUT_ERROR);
64     check_ptr_return_val(receive_data, HC_INPUT_ERROR);
65     check_ptr_return_val(send_data, HC_INPUT_ERROR);
66     struct key_agreement_client *client = (struct key_agreement_client *)handle;
67     struct key_agreement_protocol *base = &client->protocol_base_info;
68 
69     DBG_OUT("Object %u begin receive start response data and send end request data", base->sn);
70     if (is_state_error(client, SEND_END_REQUEST)) {
71         LOGE("Object %u state error", base->sn);
72         return PROTOCOL_STATE_ERROR;
73     }
74     struct client_virtual_func_group *funcs = &client->package_funcs;
75     int32_t ret = funcs->parse_start_response_data(handle, receive_data);
76     if (ret != HC_OK) {
77         set_state(base, PROTOCOL_ERROR);
78         LOGE("Object %u parse start response data failed, error code is %d", base->sn, ret);
79         return ret;
80     }
81     ret = funcs->build_end_request_data(handle, send_data);
82     if (ret != HC_OK) {
83         set_state(base, PROTOCOL_ERROR);
84         LOGE("Object %u build end request data failed, error code is %d", base->sn, ret);
85         return ret;
86     }
87 
88     set_state(base, END_REQUEST);
89     set_last_time_sec(base);
90     DBG_OUT("Object %u receive start response data and send end request data success", base->sn);
91     return HC_OK;
92 }
93 
receive_end_response(void * handle,void * receive_data)94 int32_t receive_end_response(void *handle, void *receive_data)
95 {
96     check_ptr_return_val(handle, HC_INPUT_ERROR);
97     check_ptr_return_val(receive_data, HC_INPUT_ERROR);
98     struct key_agreement_client *client = (struct key_agreement_client *)handle;
99     struct key_agreement_protocol *base = &client->protocol_base_info;
100 
101     DBG_OUT("Object %u begin receive end response data", base->sn);
102     if (is_state_error(client, RECEIVE_END_RESPONSE)) {
103         LOGE("Object %u state error", base->sn);
104         return PROTOCOL_STATE_ERROR;
105     }
106     struct client_virtual_func_group *funcs = &client->package_funcs;
107     if (funcs == NULL) {
108         set_state(base, PROTOCOL_ERROR);
109         return HC_INPUT_PTR_NULL;
110     }
111     int32_t ret = funcs->parse_end_response_data(handle, receive_data);
112     if (ret != HC_OK) {
113         set_state(base, PROTOCOL_ERROR);
114         LOGE("Object %u parse end response data failed, error code is %d", base->sn, ret);
115         return ret;
116     }
117 
118     set_state(base, PROTOCOL_FINISH);
119     set_last_time_sec(base);
120     DBG_OUT("Object %u receive end response data success", base->sn);
121     return HC_OK;
122 }
123 
is_state_error(struct key_agreement_client * handle,enum protocol_action action)124 static bool is_state_error(struct key_agreement_client *handle, enum protocol_action action)
125 {
126     struct key_agreement_protocol *base = &handle->protocol_base_info;
127     enum protocol_state state = base->state;
128     DBG_OUT("Object %u state is %d, action is %d", base->sn, state, action);
129 
130     if (action == SEND_START_REQUEST) {
131         return (state == PROTOCOL_INIT) ? false : true;
132     } else if (action == SEND_END_REQUEST) {
133         return (state == START_REQUEST) ? false : true;
134     } else if (action == RECEIVE_END_RESPONSE) {
135         return (state == END_REQUEST) ? false : true;
136     } else {
137         set_state(base, PROTOCOL_ERROR);
138         LOGE("Object %u state is error", base->sn);
139         return true;
140     }
141 }
142