• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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