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