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
13 #include "load_sec_file.h"
14 #include <sys/ioctl.h> /* for ioctl */
15 #include <sys/prctl.h>
16 #include "securec.h"
17 #include "tc_ns_client.h"
18 #include "tee_log.h"
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
24 #ifdef LOG_TAG
25 #undef LOG_TAG
26 #endif
27 #define LOG_TAG "load_secfile"
28 #define MAX_BUFFER_LEN (8 * 1024 * 1024)
29 #define H_OFFSET 32
30
GetImgLen(FILE * fp,long * totalLlen)31 static int GetImgLen(FILE *fp, long *totalLlen)
32 {
33 int ret;
34
35 ret = fseek(fp, 0, SEEK_END);
36 if (ret != 0) {
37 tloge("fseek end error\n");
38 return -1;
39 }
40 *totalLlen = ftell(fp);
41 if (*totalLlen <= 0 || *totalLlen > MAX_BUFFER_LEN) {
42 tloge("file is not exist or size is too large, filesize = %" PUBLIC "ld\n", *totalLlen);
43 return -1;
44 }
45 ret = fseek(fp, 0, SEEK_SET);
46 if (ret != 0) {
47 tloge("fseek head error\n");
48 return -1;
49 }
50 return ret;
51 }
52
53 /* input param uuid may be NULL, so don need to check if uuid is NULL */
LoadSecFile(int tzFd,FILE * fp,enum SecFileType fileType,const TEEC_UUID * uuid)54 int32_t LoadSecFile(int tzFd, FILE *fp, enum SecFileType fileType, const TEEC_UUID *uuid)
55 {
56 int32_t ret;
57 char *fileBuffer = NULL;
58 struct SecLoadIoctlStruct ioctlArg = {{ 0 }, { 0 }, { NULL } };
59
60 if (tzFd < 0 || fp == NULL) {
61 tloge("param erro!\n");
62 return -1;
63 }
64
65 do {
66 long totalLen = 0;
67 ret = GetImgLen(fp, &totalLen);
68 if (ret != 0) {
69 break;
70 }
71
72 if (totalLen <= 0 || totalLen > MAX_BUFFER_LEN) {
73 ret = -1;
74 tloge("totalLen is invalid\n");
75 break;
76 }
77
78 /* alloc a less than 8M heap memory, it needn't slice. */
79 fileBuffer = malloc(totalLen);
80 if (fileBuffer == NULL) {
81 tloge("alloc TA file buffer(size=%" PUBLIC "ld) failed\n", totalLen);
82 ret = -1;
83 break;
84 }
85
86 /* read total ta file to file buffer */
87 long fileSize = (long)fread(fileBuffer, 1, totalLen, fp);
88 if (fileSize != totalLen) {
89 tloge("read ta file failed, read size/total size=%" PUBLIC "ld/%" PUBLIC "ld\n", fileSize, totalLen);
90 ret = -1;
91 break;
92 }
93
94 ioctlArg.secFileInfo.fileType = fileType;
95 ioctlArg.secFileInfo.fileSize = (uint32_t)totalLen;
96 ioctlArg.memref.file_addr = (uint32_t)(uintptr_t)fileBuffer;
97 ioctlArg.memref.file_h_addr = (uint32_t)(((uint64_t)(uintptr_t)fileBuffer) >> H_OFFSET);
98 if (uuid != NULL && memcpy_s((void *)(&ioctlArg.uuid), sizeof(ioctlArg.uuid), uuid, sizeof(*uuid)) != EOK) {
99 tloge("memcpy uuid fail\n");
100 break;
101 }
102
103 ret = ioctl(tzFd, (int)TC_NS_CLIENT_IOCTL_LOAD_APP_REQ, &ioctlArg);
104 if (ret != 0) {
105 tloge("ioctl to load sec file failed, ret = 0x%" PUBLIC "x\n", ret);
106 }
107 } while (false);
108
109 if (fileBuffer != NULL) {
110 free(fileBuffer);
111 }
112 return ret;
113 }
114
115 #ifdef __cplusplus
116 }
117 #endif
118