1 /*
2 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12 #include "tee_trusted_storage_api.h"
13 #include "tee_mem_mgmt_api.h"
14 #include "tee_log.h"
15 #include "ta_framework.h"
16 #include "sfs.h"
17 #include "ssa_fs.h"
18 #include "sfs_internal.h"
19 #include "securec.h"
20 #include "string.h"
21 #include "permsrv_api.h"
22 #include <tee_huk_derive_key.h>
23 #include <crypto_hal_derive_key.h>
24
reset_meta(meta_data_t * meta)25 void reset_meta(meta_data_t *meta)
26 {
27 errno_t rc;
28
29 if (meta == NULL)
30 return;
31
32 rc = memset_s(meta->ta_root_key, sizeof(meta->ta_root_key), 0, sizeof(meta->ta_root_key));
33 if (rc != EOK)
34 tloge("mem set takey failed\n");
35
36 rc = memset_s(meta->file_key, sizeof(meta->file_key), 0, sizeof(meta->file_key));
37 if (rc != EOK)
38 tloge("mem set file_key failed\n");
39
40 rc = memset_s(meta->xts_key1, sizeof(meta->xts_key1), 0, sizeof(meta->xts_key1));
41 if (rc != EOK)
42 tloge("mem set xts_key1 failed\n");
43
44 rc = memset_s(meta->xts_key2, sizeof(meta->xts_key2), 0, sizeof(meta->xts_key2));
45 if (rc != EOK)
46 tloge("mem set xts_key2 failed\n");
47
48 rc = memset_s(meta->hmac_key, sizeof(meta->hmac_key), 0, sizeof(meta->hmac_key));
49 if (rc != EOK)
50 tloge("mem set hmac_key failed\n");
51
52 rc = memset_s(meta->file_id_key, sizeof(meta->file_id_key), 0, sizeof(meta->file_id_key));
53 if (rc != EOK)
54 tloge("mem set file_id_key failed\n");
55
56 rc = memset_s(meta->master_hmac, sizeof(meta->master_hmac), 0, sizeof(meta->master_hmac));
57 if (rc != EOK)
58 tloge("mem set master_hmac failed\n");
59 }
60
tee_free_file_id(meta_data_t * meta)61 static void tee_free_file_id(meta_data_t *meta)
62 {
63 TEE_Free(meta->file_id);
64 meta->file_id = NULL;
65
66 TEE_Free(meta->joint_file_id);
67 meta->joint_file_id = NULL;
68 }
69
derive_file_id_po(meta_data_t * meta)70 static TEE_Result derive_file_id_po(meta_data_t *meta)
71 {
72 (void)meta;
73 return TEE_SUCCESS;
74 }
75
free_meta_data(meta_data_t ** ppmeta)76 void free_meta_data(meta_data_t **ppmeta)
77 {
78 if (ppmeta == NULL || *ppmeta == NULL)
79 return;
80 meta_data_t *meta = *ppmeta;
81
82 TEE_Free(meta->file_id);
83 meta->file_id = NULL;
84 TEE_Free(meta->joint_file_id);
85 meta->joint_file_id = NULL;
86 TEE_Free(meta->encrypted_file_id);
87 meta->encrypted_file_id = NULL;
88 TEE_Free(meta->backup_file_id);
89 meta->backup_file_id = NULL;
90
91 reset_meta(meta);
92
93 TEE_Free(meta);
94
95 *ppmeta = NULL;
96 }
97
set_meta_data_verion(meta_data_t * meta_data,uint32_t arch_version)98 void set_meta_data_verion(meta_data_t *meta_data, uint32_t arch_version)
99 {
100 if (meta_data == NULL)
101 return;
102
103 meta_data->arch_version = arch_version;
104
105 switch (meta_data->arch_version) {
106 case SFS_ARCH_VERSION_SSA:
107 meta_data->cur_encrypted_file_id = meta_data->encrypted_file_id;
108 meta_data->cur_backup_file_id = meta_data->backup_file_id;
109 meta_data->crypto_block_size = CRYPT_BLOCK_SIZE_V3;
110 break;
111 default:
112 tloge("invalid arch_version: %u\n", meta_data->arch_version);
113 break;
114 }
115 }
116
joint_name(const char * file_name,uint32_t name_len,meta_data_t * meta_data,char * name_out,uint32_t out_len)117 static int32_t joint_name(const char *file_name, uint32_t name_len, meta_data_t *meta_data, char *name_out,
118 uint32_t out_len)
119 {
120 int32_t rc;
121 (void)meta_data;
122
123 rc = memcpy_s(name_out, out_len, file_name, name_len);
124 if (rc != EOK) {
125 tloge("get path failed!");
126 return -1;
127 }
128
129 return 0;
130 }
131
get_files_path_info(const meta_data_t * meta,const uint8_t * old_name,uint32_t * size,int32_t * path_lable)132 static int32_t get_files_path_info(const meta_data_t *meta, const uint8_t *old_name,
133 uint32_t *size, int32_t *path_lable)
134 {
135 uint32_t size_temp;
136 uint32_t i;
137 uint32_t persistent;
138 uint32_t transient;
139
140 if (old_name == NULL) {
141 tloge("old name is null\n");
142 return -1;
143 }
144
145 size_temp = strlen((char *)(meta->joint_file_id));
146
147 /*
148 * Find the last '/', to support dir create and mutiple sec_storage partition
149 * If there is no '/' then just store the file into sec_storage,compatible for GP TestSuite
150 */
151 for (i = size_temp - 1; i > 0; i--) {
152 if (old_name[i] == '/') {
153 *path_lable = (int32_t)i;
154 break;
155 }
156 }
157 if ((int32_t)(size_temp - 1) == *path_lable || *path_lable >= (int32_t)NEW_DIR_LEN) {
158 tloge("invalid file path, the last '/' is name %d\n", *path_lable);
159 return -1;
160 }
161 if (meta->storage_id != TEE_OBJECT_STORAGE_CE) {
162 /* If there is no '/' then just store the file into sec_storage,compatible for GP TestSuite */
163 persistent = size_temp >= strlen(SFS_PARTITION_PERSISTENT) ?
164 strlen(SFS_PARTITION_PERSISTENT) : size_temp;
165 transient = size_temp >= strlen(SFS_PARTITION_TRANSIENT) ?
166 strlen(SFS_PARTITION_TRANSIENT) : size_temp;
167 if ((TEE_MemCompare((void *)SFS_PARTITION_PERSISTENT, (void *)old_name, persistent) != 0) &&
168 (TEE_MemCompare((void *)SFS_PARTITION_TRANSIENT, (void *)old_name, transient) != 0))
169 *path_lable = -1;
170 }
171 *size = size_temp;
172
173 return 0;
174 }
175
176 /* caller should make sure new_name buffer is big enough */
file_name_transfer(meta_data_t * meta,char * hash_name,uint32_t hash_name_len,bool is_file_hash)177 int32_t file_name_transfer(meta_data_t *meta, char *hash_name, uint32_t hash_name_len, bool is_file_hash)
178 {
179 uint8_t *old_name = NULL;
180 uint32_t size;
181 char *new_name = NULL;
182 int32_t path_lable = -1; /* If there is no '/' path_lable is set to -1 */
183 uint32_t add_len = IDENTIFY_SIZE + (is_file_hash ? 1 : 0);
184 errno_t rc;
185 int32_t ret;
186
187 if (meta == NULL || hash_name == NULL)
188 return -1;
189
190 old_name = meta->joint_file_id;
191
192 ret = get_files_path_info(meta, old_name, &size, &path_lable);
193 if (ret != 0)
194 return ret;
195
196 new_name = (char *)TEE_Malloc(size + 1 + add_len, 0);
197 if (new_name == NULL) {
198 tloge("malloc new name failed!\n");
199 return -1;
200 }
201
202 /* fs_identify is for TAs storage isolation */
203 rc = memmove_s(new_name, size, (void *)old_name, size);
204 if (rc != EOK) {
205 tloge("mem move new name failed!\n");
206 TEE_Free(new_name);
207 return -1;
208 }
209 rc = memmove_s(new_name + size, 1 + add_len, &meta->uuid, sizeof(meta->uuid));
210 if (rc != EOK) {
211 tloge("mem move uuid failed!\n");
212 TEE_Free(new_name);
213 return -1;
214 }
215
216 if (is_file_hash)
217 *(new_name + size + add_len - 1) = HASH_FILE_MAGIC;
218 *(new_name + size + add_len) = '\0';
219
220 /* copy partition and dir info to hash_name */
221 if (path_lable > 0) {
222 if (memmove_s(hash_name, FILE_NAME_MAX_BUF, new_name, (size_t)(path_lable + 1)) != EOK) {
223 TEE_Free(new_name);
224 tloge("mem move hash name error!\n");
225 return -1;
226 }
227 }
228 /* get file name hash, keep the partiton and dir name. */
229 if (get_hname(new_name + (path_lable + 1), (int32_t)(size + add_len - (path_lable + 1)),
230 hash_name + (path_lable + 1), hash_name_len - (path_lable + 1), meta)) {
231 TEE_Free(new_name);
232 tloge("get hash name failed\n");
233 return -1;
234 }
235
236 TEE_Free(new_name);
237
238 return 0;
239 }
240
241 #define TA_KEY_LEN 32
242 #define TA_SALT_LEN 32
243 #define KEY_DERIVE_TIMES 2
derive_ta_key(uint8_t * ta_key,uint32_t ta_key_len,TEE_UUID * uuid,uint32_t flags)244 static TEE_Result derive_ta_key(uint8_t *ta_key, uint32_t ta_key_len, TEE_UUID *uuid, uint32_t flags)
245 {
246 TEE_Result ret;
247 uint8_t key_out[TA_KEY_LEN] = {0};
248 uint8_t salt_buffer[TA_SALT_LEN] = {0};
249 uint32_t i;
250 errno_t rc;
251
252 if (ta_key == NULL || uuid == NULL) {
253 tloge("Bad parameter!\n");
254 return TEE_ERROR_BAD_PARAMETERS;
255 }
256
257 rc = memmove_s(salt_buffer, sizeof(salt_buffer), uuid, sizeof(TEE_UUID));
258 if (rc != EOK) {
259 tloge("mem move secret buffer failed\n");
260 ret = TEE_ERROR_SECURITY;
261 return ret;
262 }
263
264 for (i = TA_SALT_LEN - 1; i >= sizeof(TEE_UUID); i--)
265 salt_buffer[i] = salt_buffer[TA_SALT_LEN - 1 - i];
266
267 if ((flags & TEE_DATA_FLAG_DERIVE_32BYTES_KEY_ONCE) == TEE_DATA_FLAG_DERIVE_32BYTES_KEY_ONCE) {
268 ret = tee_internal_derive_key(salt_buffer, sizeof(salt_buffer), key_out, sizeof(key_out));
269 } else {
270 ret = tee_internal_derive_key(salt_buffer, TA_SALT_LEN/KEY_DERIVE_TIMES, key_out, TA_KEY_LEN/KEY_DERIVE_TIMES);
271 if (ret == TEE_SUCCESS)
272 ret = tee_internal_derive_key(salt_buffer + TA_SALT_LEN/KEY_DERIVE_TIMES, TA_SALT_LEN/KEY_DERIVE_TIMES,
273 key_out + TA_KEY_LEN/KEY_DERIVE_TIMES, TA_KEY_LEN/KEY_DERIVE_TIMES);
274 }
275 if (ret != TEE_SUCCESS) {
276 tloge("derive ta key failed, ret=0x%x\n", ret);
277 return ret;
278 }
279 rc = memmove_s(ta_key, ta_key_len, key_out, sizeof(key_out));
280 if (rc != EOK) {
281 tloge("mem move key buffer failed\n");
282 return TEE_ERROR_SECURITY;
283 }
284
285 return TEE_SUCCESS;
286 }
287
288 /* Maximun size of derived key is 32 bytes. */
derive_key(meta_data_t * meta,uint32_t flags)289 static TEE_Result derive_key(meta_data_t *meta, uint32_t flags)
290 {
291 TEE_Result ret;
292 uint32_t out_len = CRYPT_KEY_SIZE;
293
294 if (meta == NULL) {
295 tloge("Bad parameter!\n");
296 return TEE_ERROR_BAD_PARAMETERS;
297 }
298
299 /* derive TA rootKey */
300 ret = derive_ta_key(meta->ta_root_key, sizeof(meta->ta_root_key), &meta->uuid, flags);
301 if (ret != TEE_SUCCESS) {
302 tloge("derive ta key fail, ret=0x%x\n", ret);
303 return ret;
304 }
305
306 struct key_info_t root_key_info;
307 root_key_info.key = meta->ta_root_key;
308 root_key_info.key_len = sizeof(meta->ta_root_key);
309 /* derive file key */
310 ret = calc_hmac256(&root_key_info, (uint8_t *)FILEKEY_SALT, (uint32_t)strlen(FILEKEY_SALT),
311 meta->file_key, &out_len);
312 if (ret != TEE_SUCCESS) {
313 tloge("file_key do hash sha256 failed!\n");
314 return TEE_ERROR_GENERIC;
315 }
316
317 /* derive key to encrypt file name */
318 ret = calc_hmac256(&root_key_info, (uint8_t *)FILE_NAME_SALT, (uint32_t)strlen(FILE_NAME_SALT),
319 meta->file_id_key, &out_len);
320 if (ret != TEE_SUCCESS) {
321 tloge("fileIDkey do hash sha256 failed!\n");
322 return TEE_ERROR_GENERIC;
323 }
324
325 struct key_info_t file_key_info;
326 file_key_info.key = meta->file_key;
327 file_key_info.key_len = sizeof(meta->file_key);
328 /* derive key to encrypt or decrypt file data */
329 ret = calc_hmac256(&file_key_info, (uint8_t *)ENCRYPTION1_SALT,
330 (uint32_t)strlen(ENCRYPTION1_SALT), meta->xts_key1, &out_len);
331 if (ret != TEE_SUCCESS) {
332 tloge("xtskey do hash sha256 failed!\n");
333 return TEE_ERROR_GENERIC;
334 }
335
336 ret = calc_hmac256(&file_key_info, (uint8_t *)ENCRYPTION2_SALT,
337 (uint32_t)strlen(ENCRYPTION2_SALT), meta->xts_key2, &out_len);
338 if (ret != TEE_SUCCESS) {
339 tloge("xtskey2 do hash sha256 failed!\n");
340 return TEE_ERROR_GENERIC;
341 }
342
343 /* derive key to calculate file's hmac */
344 ret = calc_hmac256(&file_key_info, (uint8_t *)MASTER_HMAC_SALT,
345 (uint32_t)strlen(MASTER_HMAC_SALT), meta->hmac_key, &out_len);
346 if (ret != TEE_SUCCESS) {
347 tloge("hmackey do hash sha256 failed!\n");
348 return TEE_ERROR_GENERIC;
349 }
350
351 return TEE_SUCCESS;
352 }
353
encrypt_file_id(meta_data_t * meta)354 static TEE_Result encrypt_file_id(meta_data_t *meta)
355 {
356 uint8_t enc_file_id[FILE_NAME_MAX_BUF] = { 0 };
357 uint8_t bk_file_id[FILE_NAME_MAX_BUF + sizeof(SFS_BACKUP_FILE_SUFFIX)] = { 0 };
358
359 /* encrypted_file_id */
360 if (file_name_transfer(meta, (char *)enc_file_id, sizeof(enc_file_id), (bool)false) != TEE_SUCCESS) {
361 tloge("encrypt file_id fail, obj id=%s\n", meta->file_id);
362 return TEE_ERROR_GENERIC;
363 }
364 /* size of bk_file_id is big enough for enc_file_id and suffix */
365 if (snprintf_s((char *)bk_file_id, sizeof(bk_file_id), sizeof(bk_file_id) - 1, "%s%s",
366 (char *)enc_file_id, SFS_BACKUP_FILE_SUFFIX) < 0) {
367 tloge("snprintf_s bkFileId fail!\n");
368 return TEE_ERROR_SECURITY;
369 }
370
371 meta->encrypted_file_id = TEE_Malloc((size_t)strlen((char *)enc_file_id) + 1, 0);
372 if (meta->encrypted_file_id == NULL) {
373 tloge("malloc encrypted FileId, size=%u\n", (uint32_t)strlen((char *)enc_file_id) + 1);
374 return TEE_ERROR_OUT_OF_MEMORY;
375 }
376 if (memmove_s(meta->encrypted_file_id, (size_t)strlen((char *)enc_file_id) + 1, enc_file_id,
377 (size_t)strlen((char *)enc_file_id)) != EOK) {
378 tloge("mem move encFileId error!\n");
379 TEE_Free(meta->encrypted_file_id);
380 meta->encrypted_file_id = NULL;
381 return TEE_ERROR_SECURITY;
382 }
383
384 /* backup_file_id */
385 meta->backup_file_id = TEE_Malloc((size_t)strlen((char *)bk_file_id) + 1, 0);
386 if (meta->backup_file_id == NULL) {
387 tloge("malloc backup_file_id fail, size=%u\n", (uint32_t)strlen((char *)bk_file_id) + 1);
388 TEE_Free(meta->encrypted_file_id);
389 meta->encrypted_file_id = NULL;
390 return TEE_ERROR_OUT_OF_MEMORY;
391 }
392 if (memmove_s(meta->backup_file_id, (size_t)strlen((char *)bk_file_id) + 1, bk_file_id,
393 (size_t)strlen((char *)bk_file_id)) != EOK) {
394 tloge("mem move bkFileId to meta error!\n");
395 TEE_Free(meta->encrypted_file_id);
396 meta->encrypted_file_id = NULL;
397 TEE_Free(meta->backup_file_id);
398 meta->backup_file_id = NULL;
399 return TEE_ERROR_SECURITY;
400 }
401
402 return TEE_SUCCESS;
403 }
404
derive_file_id(const uint8_t * obj_id,uint32_t obj_id_len,const uint8_t * joint_file_id,uint32_t joint_len,meta_data_t * meta)405 TEE_Result derive_file_id(const uint8_t *obj_id, uint32_t obj_id_len, const uint8_t *joint_file_id, uint32_t joint_len,
406 meta_data_t *meta)
407 {
408 TEE_Result ret;
409
410 if (obj_id == NULL || meta == NULL || joint_file_id == NULL || (obj_id_len + 1) < obj_id_len) {
411 tloge("Bad parameter!\n");
412 return TEE_ERROR_BAD_PARAMETERS;
413 }
414
415 /* TA file_id */
416 meta->file_id = TEE_Malloc(obj_id_len + 1, 0);
417 if (meta->file_id == NULL) {
418 tloge("malloc file_id fail, size=%u\n", obj_id_len);
419 return TEE_ERROR_OUT_OF_MEMORY;
420 }
421 if (memmove_s(meta->file_id, obj_id_len + 1, obj_id, obj_id_len) != EOK) {
422 tloge("mem move obj id error!\n");
423 ret = TEE_ERROR_SECURITY;
424 goto out;
425 }
426 meta->file_id_len = obj_id_len;
427
428 meta->joint_file_id = TEE_Malloc(joint_len + 1, 0);
429 if (meta->joint_file_id == NULL) {
430 tloge("malloc joint_file_id fail, size=%u\n", joint_len);
431 ret = TEE_ERROR_OUT_OF_MEMORY;
432 goto out;
433 }
434 if (memmove_s(meta->joint_file_id, joint_len + 1, joint_file_id, joint_len) != EOK) {
435 tloge("mem move joint_file_id error!\n");
436 ret = TEE_ERROR_SECURITY;
437 goto out;
438 }
439
440 meta->arch_version = SFS_ARCH_VERSION_SSA;
441
442 ret = encrypt_file_id(meta);
443 if (ret != TEE_SUCCESS) {
444 tloge("derive encrypt file id error!\n");
445 goto out;
446 }
447
448 ret = derive_file_id_po(meta);
449 if (ret != TEE_SUCCESS)
450 goto out;
451
452 return TEE_SUCCESS;
453
454 out:
455 tee_free_file_id(meta);
456 return ret;
457 }
458
create_meta_data(const uint8_t * obj_id,uint32_t obj_id_len,uint32_t storage_id,uint32_t flags,const TEE_UUID * uuid,TEE_Result * error,uint32_t arch_version)459 meta_data_t *create_meta_data(const uint8_t *obj_id, uint32_t obj_id_len, uint32_t storage_id, uint32_t flags,
460 const TEE_UUID *uuid, TEE_Result *error, uint32_t arch_version)
461 {
462 TEE_Result ret;
463 errno_t rc;
464 char file_name_new[FILE_NAME_MAX_BUF] = { 0 };
465
466 if (obj_id == NULL || uuid == NULL || error == NULL) {
467 tloge("Bad parameter!\n");
468 return NULL;
469 }
470
471 meta_data_t *meta_data = TEE_Malloc(sizeof(meta_data_t), 0);
472 if (meta_data == NULL) {
473 tloge("malloc meta data fail\n");
474 *error = TEE_ERROR_OUT_OF_MEMORY;
475 return NULL;
476 }
477
478 meta_data->storage_id = storage_id;
479 rc = memmove_s(&meta_data->uuid, sizeof(meta_data->uuid), uuid, sizeof(TEE_UUID));
480 if (rc != EOK) {
481 TEE_Free(meta_data);
482 *error = TEE_ERROR_SECURITY;
483 tloge("mem move uuid error!\n");
484 return NULL;
485 }
486
487 (void)memset_s(meta_data->master_hmac, sizeof(meta_data->master_hmac), 0, sizeof(meta_data->master_hmac));
488
489 /* derive ta key to encrypt or decrypt */
490 ret = derive_key(meta_data, flags);
491 if (ret != TEE_SUCCESS) {
492 tloge("derive key fail, ret=0x%x\n", ret);
493 *error = ret;
494 goto out;
495 }
496
497 rc = joint_name((char *)obj_id, obj_id_len, meta_data, file_name_new, sizeof(file_name_new));
498 if (rc != EOK) {
499 tloge("joint name fail, ret=0x%x\n", ret);
500 *error = TEE_ERROR_GENERIC;
501 goto out;
502 }
503
504 /* init object ID */
505 ret = derive_file_id(obj_id, obj_id_len, (uint8_t *)file_name_new, strlen(file_name_new), meta_data);
506 if (ret != TEE_SUCCESS) {
507 tloge("init object Id fail, ret=0x%x\n", ret);
508 *error = ret;
509 goto out;
510 }
511
512 set_meta_data_verion(meta_data, arch_version);
513
514 *error = TEE_SUCCESS;
515 return meta_data;
516
517 out:
518 free_meta_data(&meta_data);
519
520 return NULL;
521 }
522
get_uuid_hmac(const TEE_UUID * uuid,char * uuid_hmac,uint32_t uuid_hmac_len)523 TEE_Result get_uuid_hmac(const TEE_UUID *uuid, char *uuid_hmac, uint32_t uuid_hmac_len)
524 {
525 TEE_Result ret;
526 int32_t rc;
527 meta_data_t *meta_data = NULL;
528
529 if (uuid == NULL || uuid_hmac == NULL) {
530 tloge("get uuid hmac param check fail!");
531 return TEE_ERROR_BAD_PARAMETERS;
532 }
533
534 meta_data = TEE_Malloc(sizeof(meta_data_t), 0);
535 if (meta_data == NULL) {
536 tloge("malloc meta_data fail\n");
537 return TEE_ERROR_OUT_OF_MEMORY;
538 }
539
540 rc = memmove_s(&meta_data->uuid, sizeof(meta_data->uuid), uuid, sizeof(TEE_UUID));
541 if (rc != EOK) {
542 ret = TEE_ERROR_SECURITY;
543 tloge("mem move uuid error!\n");
544 goto clean;
545 }
546
547 ret = derive_key(meta_data, TA_KEY_COMPOSED_OF_TWO_16BYTES_KEYS);
548 if (ret != TEE_SUCCESS) {
549 tloge("derive fail, ret=0x%x\n", ret);
550 goto clean;
551 }
552
553 meta_data->arch_version = SFS_ARCH_VERSION_SSA;
554 ret = get_hname((const char *)uuid, sizeof(TEE_UUID), uuid_hmac, uuid_hmac_len, meta_data);
555 if (ret != TEE_SUCCESS) {
556 tloge("get hname fail, ret=0x%x\n", ret);
557 goto clean;
558 }
559
560 clean:
561 free_meta_data(&meta_data);
562 return ret;
563 }
564