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