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                                       { REMOVE_MODULAR, true, (void **)&hichain->auth_info },
46                                       { SEC_CLONE_MODULAR, false, (void **)&hichain->sec_clone_server } };
47     void **object = get_object(map, sizeof(map) / sizeof(map[0]), modular, is_client);
48     if ((object == NULL) || (*object != NULL)) {
49         DBG_OUT("No sub-objects need to be applied for");
50         return HC_OK;
51     }
52     if (check_mutex_object_is_null(map, sizeof(map) / sizeof(map[0]), modular, is_client) == false) {
53         LOGE("The mutex sub-object have been created, create %d:%d sub-object failed", modular, is_client);
54         return HC_REPEATED_REFERENCE;
55     }
56     if (check_depend_object_is_not_null(map, sizeof(map) / sizeof(map[0]), modular, is_client) == false) {
57         LOGE("The depend sub-object is not created, create %d:%d sub-object failed", modular, is_client);
58         return HC_NEED_DEPEND;
59     }
60     *object = build_object_by_modular(hichain, modular, is_client, params);
61     if (*object == NULL) {
62         LOGE("Create %d:%d sub-object failed", modular, is_client);
63         return HC_BUILD_OBJECT_FAILED;
64     }
65     DBG_OUT("Create %d:%d sub-object success", modular, is_client);
66     return HC_OK;
67 }
68 
get_object(const struct object_map * map,uint32_t n,int32_t modular,bool is_client)69 static void **get_object(const struct object_map *map, uint32_t n, int32_t modular, bool is_client)
70 {
71     for (uint32_t i = 0; i < n; i++) {
72         if ((modular == map[i].modular) && (is_client == map[i].is_client)) {
73             return map[i].object;
74         }
75     }
76 
77     return NULL;
78 }
79 
80 typedef const struct object_relation *object_relation_ptr;
81 
select_relation_map(const struct object_relation * map,uint32_t n,int32_t modular,bool is_client,object_relation_ptr * select_map)82 static uint32_t select_relation_map(const struct object_relation *map, uint32_t n, int32_t modular, bool is_client,
83     object_relation_ptr *select_map)
84 {
85     uint32_t count = 0;
86 
87     for (uint32_t i = 0; i < n; i++) {
88         if ((modular == map[i].src_modular) && (is_client == map[i].src_is_client)) {
89             select_map[count] = &map[i];
90             count++;
91         }
92     }
93     return count;
94 }
95 
check_mutex_object_is_null(const struct object_map * map,uint32_t n,int32_t modular,bool is_client)96 static bool check_mutex_object_is_null(const struct object_map *map, uint32_t n, int32_t modular, bool is_client)
97 {
98     const struct object_relation mutex_map[] = { { PAKE_MODULAR, STS_MODULAR, true, false },
99                                                  { STS_MODULAR, PAKE_MODULAR, false, true },
100                                                  { PAKE_MODULAR, STS_MODULAR, true, true },
101                                                  { STS_MODULAR, PAKE_MODULAR, true, true },
102                                                  { PAKE_MODULAR, STS_MODULAR, false, false },
103                                                  { STS_MODULAR, PAKE_MODULAR, false, false },
104                                                  { PAKE_MODULAR, STS_MODULAR, false, true },
105                                                  { STS_MODULAR, PAKE_MODULAR, true, false },
106                                                  { STS_MODULAR, STS_MODULAR, true, false },
107                                                  { STS_MODULAR, STS_MODULAR, false, true },
108                                                  { ADD_MODULAR, STS_MODULAR, true, false },
109                                                  { STS_MODULAR, ADD_MODULAR, false, true },
110                                                  { REMOVE_MODULAR, STS_MODULAR, true, false },
111                                                  { STS_MODULAR, REMOVE_MODULAR, false, true },
112                                                  { PAKE_MODULAR, SEC_CLONE_MODULAR, false, false },
113                                                  { SEC_CLONE_MODULAR, PAKE_MODULAR, false, false } };
114     object_relation_ptr select_map[sizeof(mutex_map) / sizeof(mutex_map[0])] = {0};
115     uint32_t count = select_relation_map(mutex_map, sizeof(mutex_map) / sizeof(mutex_map[0]), modular,
116         is_client, select_map);
117     if (count == 0) { /* no muutex sub object */
118         return true;
119     }
120     for (uint32_t i = 0; i < n; i++) {
121         if ((map[i].modular == modular) && (map[i].is_client == is_client)) { /* skip sub object that will be created */
122             continue;
123         }
124         if (*map[i].object == NULL) { /* null sub object is correct even mutex */
125             continue;
126         }
127         for (uint32_t j = 0; j < count; j++) {
128             if ((map[i].modular == select_map[j]->dst_modular) && (map[i].is_client == select_map[j]->dst_is_client)) {
129                 return false; /* mutex sub object and not null */
130             }
131         }
132     }
133     return true;
134 }
135 
check_depend_object_is_not_null(const struct object_map * map,uint32_t n,int32_t modular,bool is_client)136 static bool check_depend_object_is_not_null(const struct object_map *map, uint32_t n, int32_t modular, bool is_client)
137 {
138     const struct object_relation depend_map[] = { { ADD_MODULAR, STS_MODULAR, true, true },
139                                                   { REMOVE_MODULAR, STS_MODULAR, true, true },
140                                                   { SEC_CLONE_MODULAR, STS_MODULAR, false, false } };
141     object_relation_ptr select_map[sizeof(depend_map) / sizeof(depend_map[0])] = {0};
142     uint32_t count = select_relation_map(depend_map, sizeof(depend_map) / sizeof(depend_map[0]),
143                                          modular, is_client, select_map);
144     if (count == 0) { /* no dependent sub object */
145         return true;
146     }
147     for (uint32_t i = 0; i < n; i++) {
148         if ((map[i].modular == modular) && (map[i].is_client == is_client)) { /* skip sub object that will be created */
149             continue;
150         }
151         if (*map[i].object != NULL) { /* null sub object is correct even dependent */
152             continue;
153         }
154         for (uint32_t j = 0; j < count; j++) {
155             if ((map[i].modular == select_map[j]->dst_modular) && (map[i].is_client == select_map[j]->dst_is_client)) {
156                 return false; /* depentend sub object and not null */
157             }
158         }
159     }
160     return true;
161 }
162 
163 typedef void *(*build_sub_object)(struct hichain *hichain, const void *params);
164 struct build_sub_object_map {
165     int32_t modular;
166     bool is_client;
167     build_sub_object build_func;
168 };
169 
170 static void *build_pake_client_object(struct hichain *hichain, const void *params);
171 static void *build_sts_client_object(struct hichain *hichain, const void *params);
172 static void *build_auth_info_client_object(struct hichain *hichain, const void *params);
build_object_by_modular(struct hichain * hichain,int32_t modular,bool is_client,const void * params)173 static void *build_object_by_modular(struct hichain *hichain, int32_t modular, bool is_client, const void *params)
174 {
175     const struct build_sub_object_map map[] = { { PAKE_MODULAR, true, build_pake_client_object },
176                                                 { STS_MODULAR, true, build_sts_client_object },
177                                                 { REMOVE_MODULAR, true, build_auth_info_client_object } };
178     for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
179         if ((map[i].modular == modular) && (map[i].is_client == is_client)) {
180             return map[i].build_func(hichain, params);
181         }
182     }
183     return NULL;
184 }
185 
build_pake_client_object(struct hichain * hichain,const void * params)186 static void *build_pake_client_object(struct hichain *hichain, const void *params)
187 {
188     (void)params;
189     struct hc_pin pin = { 0, {0} };
190     struct operation_parameter para;
191 
192     (void)memset_s(&para, sizeof(para), 0, sizeof(para));
193     hichain->cb.get_protocol_params(&hichain->identity, hichain->operation_code, &pin, &para);
194     if (check_param_is_valid(&para) == false) {
195         LOGE("Param invalid");
196         return NULL;
197     }
198     if (pin.length > HC_PIN_BUFF_LEN) {
199         LOGE("PIN invalid");
200         return NULL;
201     }
202     return build_pake_client(&hichain->identity, &pin, para.key_length, &para.self_auth_id, &para.peer_auth_id);
203 }
204 
build_sts_client_object(struct hichain * hichain,const void * params)205 static void *build_sts_client_object(struct hichain *hichain, const void *params)
206 {
207     struct operation_parameter *para = (struct operation_parameter *)params;
208 
209     return build_sts_client(hichain, para->key_length, &para->self_auth_id,
210                             &para->peer_auth_id);
211 }
212 
build_auth_info_client_object(struct hichain * hichain,const void * params)213 static void *build_auth_info_client_object(struct hichain *hichain, const void *params)
214 {
215     struct auth_info_cache *para = (struct auth_info_cache *)params;
216 
217     hichain->auth_info = build_auth_client_info(para->auth_id, para->user_type);
218 
219     return hichain->auth_info;
220 }
221 
222 
check_param_is_valid(const struct operation_parameter * para)223 static bool check_param_is_valid(const struct operation_parameter *para)
224 {
225     check_ptr_return_val(para, false);
226     if (para->self_auth_id.length > HC_AUTH_ID_BUFF_LEN) {
227         LOGE("Self auth id length error");
228         return false;
229     }
230     if (para->peer_auth_id.length > HC_AUTH_ID_BUFF_LEN) {
231         LOGE("Peer auth id length error");
232         return false;
233     }
234     if (para->key_length > HC_SESSION_KEY_LEN) {
235         LOGE("Key length error");
236         return false;
237     }
238     return true;
239 }
240