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(¶, sizeof(para), 0, sizeof(para));
193 hichain->cb.get_protocol_params(&hichain->identity, hichain->operation_code, &pin, ¶);
194 if (check_param_is_valid(¶) == 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, ¶.self_auth_id, ¶.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, ¶->self_auth_id,
210 ¶->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