1 /*
2 * Copyright (C) 2022 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 <unistd.h>
17 #include <limits.h>
18 #include <securec.h>
19 #include "device_attest_oem_file.h"
20
21 #define MAX_ATTEST_MALLOC_BUFF_SIZE 1024
22
OEMGenFilePath(const char * dirPath,const char * fileName)23 char* OEMGenFilePath(const char* dirPath, const char* fileName)
24 {
25 if (dirPath == NULL || fileName == NULL) {
26 return NULL;
27 }
28 if ((strlen(dirPath) >= MAX_ATTEST_MALLOC_BUFF_SIZE) ||\
29 (strlen(fileName) >= MAX_ATTEST_MALLOC_BUFF_SIZE) ||\
30 (strlen(dirPath) + strlen(fileName)) >= MAX_ATTEST_MALLOC_BUFF_SIZE) {
31 return NULL;
32 }
33 uint32_t filePathLen = strlen(dirPath) + 1 + strlen(fileName) + 1;
34 if (filePathLen > PATH_MAX) {
35 return NULL;
36 }
37 char* filePath = (char *)malloc(filePathLen);
38 if (filePath == NULL) {
39 return NULL;
40 }
41 (void)memset_s(filePath, filePathLen, 0, filePathLen);
42 if (sprintf_s(filePath, filePathLen, "%s%s%s", dirPath, "/", fileName) < 0) {
43 free(filePath);
44 return NULL;
45 }
46 return filePath;
47 }
48
OEMGetFileSize(const char * path,const char * fileName,uint32_t * result)49 int32_t OEMGetFileSize(const char* path, const char* fileName, uint32_t* result)
50 {
51 if (path == NULL || fileName == NULL || result == NULL) {
52 return DEVICE_ATTEST_OEM_ERR;
53 }
54
55 char* filePath = OEMGenFilePath(path, fileName);
56 if (filePath == NULL) {
57 return DEVICE_ATTEST_OEM_ERR;
58 }
59
60 char* formatPath = realpath(filePath, NULL);
61 if (formatPath == NULL) {
62 return DEVICE_ATTEST_OEM_ERR;
63 }
64
65 FILE* fp = fopen(formatPath, "r");
66 if (fp == NULL) {
67 free(formatPath);
68 return DEVICE_ATTEST_OEM_ERR;
69 }
70 if (fseek(fp, 0, SEEK_END) < 0) {
71 free(formatPath);
72 (void)fclose(fp);
73 return DEVICE_ATTEST_OEM_ERR;
74 }
75 *result = ftell(fp);
76 free(formatPath);
77 (void)fclose(fp);
78 return DEVICE_ATTEST_OEM_OK;
79 }
80
OEMWriteFile(const char * path,const char * fileName,const char * data,uint32_t dataLen)81 int32_t OEMWriteFile(const char* path, const char* fileName, const char* data, uint32_t dataLen)
82 {
83 if (path == NULL || fileName == NULL || data == NULL || dataLen == 0) {
84 return DEVICE_ATTEST_OEM_ERR;
85 }
86
87 char* filePath = OEMGenFilePath(path, fileName);
88 if (filePath == NULL) {
89 return DEVICE_ATTEST_OEM_ERR;
90 }
91
92 char* formatPath = realpath(filePath, NULL);
93 free(filePath);
94 if (formatPath == NULL) {
95 return DEVICE_ATTEST_OEM_ERR;
96 }
97
98 FILE* fp = fopen(formatPath, "wb+");
99 if (fp == NULL) {
100 free(formatPath);
101 return DEVICE_ATTEST_OEM_ERR;
102 }
103 int32_t ret = DEVICE_ATTEST_OEM_OK;
104 do {
105 if (fwrite(data, dataLen, 1, fp) != 1) {
106 ret = DEVICE_ATTEST_OEM_ERR;
107 break;
108 }
109 if (fflush(fp) != DEVICE_ATTEST_OEM_OK) {
110 ret = DEVICE_ATTEST_OEM_ERR;
111 break;
112 }
113 int fd = fileno(fp);
114 if (fsync(fd) != DEVICE_ATTEST_OEM_OK) {
115 ret = DEVICE_ATTEST_OEM_ERR;
116 break;
117 }
118 } while (0);
119 free(formatPath);
120 (void)fclose(fp);
121 return ret;
122 }
123
OEMReadFile(const char * path,const char * fileName,char * buffer,uint32_t bufferLen)124 int32_t OEMReadFile(const char* path, const char* fileName, char* buffer, uint32_t bufferLen)
125 {
126 if (path == NULL || fileName == NULL || buffer == NULL || bufferLen == 0) {
127 return DEVICE_ATTEST_OEM_ERR;
128 }
129
130 uint32_t fileSize = 0;
131 if (OEMGetFileSize(path, fileName, &fileSize) != 0 || fileSize > bufferLen) {
132 return DEVICE_ATTEST_OEM_ERR;
133 }
134
135 char* filePath = OEMGenFilePath(path, fileName);
136 if (filePath == NULL) {
137 return DEVICE_ATTEST_OEM_ERR;
138 }
139
140 char* formatPath = realpath(filePath, NULL);
141 free(filePath);
142 if (formatPath == NULL) {
143 return DEVICE_ATTEST_OEM_ERR;
144 }
145
146 FILE* fp = fopen(formatPath, "rb");
147 if (fp == NULL) {
148 free(formatPath);
149 return DEVICE_ATTEST_OEM_ERR;
150 }
151 if (fread(buffer, fileSize, 1, fp) != 1) {
152 free(formatPath);
153 (void)fclose(fp);
154 return DEVICE_ATTEST_OEM_ERR;
155 }
156 free(formatPath);
157 (void)fclose(fp);
158 return DEVICE_ATTEST_OEM_OK;
159 }
160
OEMCreateFile(const char * path,const char * fileName)161 int32_t OEMCreateFile(const char* path, const char* fileName)
162 {
163 if (path == NULL || fileName == NULL) {
164 return DEVICE_ATTEST_OEM_ERR;
165 }
166
167 char* formatPath = realpath(path, NULL);
168 if (formatPath == NULL) {
169 return DEVICE_ATTEST_OEM_ERR;
170 }
171 if ((strlen(formatPath) >= MAX_ATTEST_MALLOC_BUFF_SIZE) ||\
172 (strlen(fileName) >= MAX_ATTEST_MALLOC_BUFF_SIZE) ||\
173 (strlen(formatPath) + strlen(fileName)) >= MAX_ATTEST_MALLOC_BUFF_SIZE) {
174 return DEVICE_ATTEST_OEM_ERR;
175 }
176 uint32_t realPathLen = strlen(formatPath) + 1 + strlen(fileName) + 1;
177 if (realPathLen > PATH_MAX) {
178 return DEVICE_ATTEST_OEM_ERR;
179 }
180 char* realPath = (char *)malloc(realPathLen);
181 if (realPath == NULL) {
182 free(formatPath);
183 return DEVICE_ATTEST_OEM_ERR;
184 }
185 (void)memset_s(realPath, realPathLen, 0, realPathLen);
186 if (sprintf_s(realPath, realPathLen, "%s%s%s", formatPath, "/", fileName) < 0) {
187 free(formatPath);
188 free(realPath);
189 return DEVICE_ATTEST_OEM_ERR;
190 }
191 free(formatPath);
192
193 FILE* fp = fopen(realPath, "w");
194 if (fp == NULL) {
195 free(realPath);
196 return DEVICE_ATTEST_OEM_ERR;
197 }
198 free(realPath);
199 int32_t ret = DEVICE_ATTEST_OEM_OK;
200 do {
201 if (fflush(fp) != DEVICE_ATTEST_OEM_OK) {
202 ret = DEVICE_ATTEST_OEM_ERR;
203 break;
204 }
205 int fd = fileno(fp);
206 if (fsync(fd) != DEVICE_ATTEST_OEM_OK) {
207 ret = DEVICE_ATTEST_OEM_ERR;
208 break;
209 }
210 } while (0);
211 (void)fclose(fp);
212 return ret;
213 }