1 /*
2 * Copyright (c) 2020 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 <stdio.h>
17 #include <stdlib.h>
18 #include <stdint.h>
19 #include <string.h>
20 #include "securec.h"
21 #include "hi_flash.h"
22 #include "ohos_errno.h"
23 #include "ohos_types.h"
24 #include "hal_token.h"
25
26 #define BITS_PER_BYTE 8
27 // sector size is 4096 Bytes
28 #define SECTOR_ALIGN_BYTES 4096
29 #define TOKEN_SIZE 151
30
31 // using 256 Bytes to erase each token aera
32 #define MAX_TOKEN_AREA_SIZE 256
33
34 // 4 Bytes for token flag
35 // if token's both area are available, when read token, always return area which flag is bigger;
36 // and recover area which flag is small while write token.
37 #define TOKEN_FLAG_SIZE 4
38 #define TOKEN_WITH_FLAG_SIZE (TOKEN_SIZE + TOKEN_FLAG_SIZE)
39
40 #define TOKEN_ADDR 0x001F0000 // 实际的toekn地址
41
42 #define TOKEN_A_ADDR TOKEN_ADDR
43
44 #define TOKEN_B_ADDR (TOKEN_A_ADDR + SECTOR_ALIGN_BYTES)
45
46 #define TOKEN_DEBUG 1
47
48 #define HAL_TOKEN_OK 0
49 #define HAL_TOKEN_ERR (-1)
50 #define HAL_TOKEN_UNPRESET (-2)
51
52 #define FLASH_OPERAT_LEN 4
53 #define MALLOC_PARA 350
54 // 4 Bytes for token magic number, if data not in {1,2,3,4} order means the token area is not initialled.
55 // if token area is initialled, the token magic number's next Byte data is token actual value.
56 static const char g_tokenMagicNum[] = {1, 2, 3, 4};
57 #define TOKEN_MAGIC_NUM_SIZE (sizeof(g_tokenMagicNum) / sizeof(g_tokenMagicNum[0]))
58
59 #if TOKEN_DEBUG
60 #define TOKEN_LOG(...) printf(__VA_ARGS__)
61 #else
62 #define TOKEN_LOG(...)
63 #endif
64
65
flashRead(uint32_t addr,uint32_t size,uint8_t * buffer)66 static int32_t flashRead(uint32_t addr, uint32_t size, uint8_t *buffer)
67 {
68 uint32_t len = 0;
69 if ((size % FLASH_OPERAT_LEN) != 0) {
70 len = size / FLASH_OPERAT_LEN * FLASH_OPERAT_LEN + FLASH_OPERAT_LEN;
71 } else {
72 len = size;
73 }
74 return hi_flash_read(addr, len, buffer);
75 }
76
flashWrite(uint32_t addr,uint32_t size,uint8_t * buffer)77 static int32_t flashWrite(uint32_t addr, uint32_t size, uint8_t *buffer)
78 {
79 uint32_t len = 0;
80 if ((size % FLASH_OPERAT_LEN) != 0) {
81 len = size / FLASH_OPERAT_LEN * FLASH_OPERAT_LEN + FLASH_OPERAT_LEN;
82 } else {
83 len = size;
84 }
85 return hi_flash_write(addr, len, buffer, 0);
86 }
87
flashErase(uint32_t start_addr)88 static int32_t flashErase(uint32_t start_addr)
89 {
90 return hi_flash_erase(start_addr, SECTOR_ALIGN_BYTES);
91 }
92
FlashWriteTokenRawData(uint32_t start,const char * tokenRawData,uint32_t len)93 static int32_t FlashWriteTokenRawData(uint32_t start, const char* tokenRawData, uint32_t len)
94 {
95 if (start % SECTOR_ALIGN_BYTES != 0) {
96 printf("[FlashWriteTokenRawData]:Unsupport address not align yet, may cause data overlap error.\n");
97 return HAL_TOKEN_ERR;
98 }
99 if (tokenRawData == NULL || len <= 0) {
100 printf("[FlashWriteTokenRawData]:Invalid parameter.\n");
101 return HAL_TOKEN_ERR;
102 }
103 if (flashErase(start) != 0) {
104 return HAL_TOKEN_ERR;
105 }
106 return flashWrite(start, len, tokenRawData);
107 }
108
FlashReadTokenRawData(uint32_t start,char * tokenRawData,uint32_t len)109 static int32_t FlashReadTokenRawData(uint32_t start, char* tokenRawData, uint32_t len)
110 {
111 if (start % SECTOR_ALIGN_BYTES != 0) {
112 printf("[FlashReadTokenRawData]:Unsupport start address not align yet, may cause data overlap error.\n");
113 return HAL_TOKEN_ERR;
114 }
115 if (tokenRawData == NULL || len <= 0) {
116 printf("[FlashReadTokenRawData]:Invalid parameter.\n");
117 return HAL_TOKEN_ERR;
118 }
119 return flashRead(start, len, tokenRawData);
120 }
121
ReadTokenWithFlag(uint32_t start,char * result,uint32_t len)122 static int32_t ReadTokenWithFlag(uint32_t start, char* result, uint32_t len)
123 {
124 const uint32_t buffLen = TOKEN_MAGIC_NUM_SIZE + TOKEN_WITH_FLAG_SIZE + 1;
125 if (len < TOKEN_WITH_FLAG_SIZE) {
126 return HAL_TOKEN_ERR;
127 }
128 char *buf = hi_malloc(MALLOC_PARA, buffLen);
129 if (buf == NULL) {
130 return HAL_TOKEN_ERR;
131 }
132
133 (void)memset_s(buf, buffLen, 0, buffLen);
134 if (FlashReadTokenRawData(start, buf, buffLen) != 0) {
135 printf("[ReadTokenWithFlag]:Read flash token area failed.\n");
136 hi_free(MALLOC_PARA, buf);
137 return HAL_TOKEN_ERR;
138 }
139
140 int32_t tokenValid = 1;
141 // check is initialed or not
142 for (uint32_t i = 0; i < TOKEN_MAGIC_NUM_SIZE; i++) {
143 if (buf[i] != g_tokenMagicNum[i]) {
144 tokenValid = 0;
145 break;
146 }
147 }
148 // token area is invalid
149 if (tokenValid == 0) {
150 printf("[ReadTokenWithFlag]:The token area is invalid.\n");
151 hi_free(MALLOC_PARA, buf);
152 return HAL_TOKEN_ERR;
153 }
154 if (memcpy_s(result, TOKEN_WITH_FLAG_SIZE, buf + TOKEN_MAGIC_NUM_SIZE, TOKEN_WITH_FLAG_SIZE) != 0) {
155 return HAL_TOKEN_ERR;
156 }
157 hi_free(MALLOC_PARA, buf);
158 printf("[ReadTokenWithFlag]:Read token success!\n");
159 return HAL_TOKEN_OK;
160 }
161
WriteTokenWithFlag(uint32_t start,const char * tokenWithFlag,uint32_t len)162 static int32_t WriteTokenWithFlag(uint32_t start, const char* tokenWithFlag, uint32_t len)
163 {
164 const uint32_t buffLen = TOKEN_MAGIC_NUM_SIZE + TOKEN_WITH_FLAG_SIZE + 1;
165 char buf[buffLen];
166 (void)memset_s(buf, buffLen, 0, buffLen);
167 for (uint32_t i = 0; i < TOKEN_MAGIC_NUM_SIZE; i++) {
168 buf[i] = g_tokenMagicNum[i];
169 }
170 if (memcpy_s(buf + TOKEN_MAGIC_NUM_SIZE, TOKEN_WITH_FLAG_SIZE, tokenWithFlag, TOKEN_WITH_FLAG_SIZE) != 0) {
171 return HAL_TOKEN_ERR;
172 }
173 if (FlashWriteTokenRawData(start, buf, buffLen) != 0) {
174 printf("[WriteTokenWithFlag]: Write flash token area failed.\n");
175 return HAL_TOKEN_ERR;
176 }
177 return HAL_TOKEN_OK;
178 }
179
GetTokenFlag(const char tokenWithFlag[])180 static uint32_t GetTokenFlag(const char tokenWithFlag[])
181 {
182 uint32_t result = 0;
183 for (uint32_t i = 0; i < TOKEN_FLAG_SIZE; i++) {
184 result |= ((uint8_t)tokenWithFlag[TOKEN_SIZE + i]) << ((TOKEN_FLAG_SIZE - 1 - i) * BITS_PER_BYTE);
185 }
186 return result;
187 }
188
SetTokenFlag(uint8_t flag[],uint32_t value)189 static void SetTokenFlag(uint8_t flag[], uint32_t value)
190 {
191 for (uint32_t i = 0; i < TOKEN_FLAG_SIZE; i++) {
192 flag[i] = (value >> (BITS_PER_BYTE * (TOKEN_FLAG_SIZE - 1 - i))) & 0xFF;
193 }
194 }
195
196 /* *
197 * @brief Read token value from the flash token A or B area, and this function is only for token read and write.
198 *
199 * @param token The data buffer malloced by caller.
200 * @param len The data buffer length.
201 *
202 * @returns -1 if it fails, the actual data is unknown.
203 * 0 if it succeeds and means read token from area A or area B's data.
204 * -2 if it succeeds and means current is no token exist on the device.
205 */
OEMReadToken(char * token,uint32_t len)206 static int32_t OEMReadToken(char* token, uint32_t len)
207 {
208 if (token == NULL || len == 0) {
209 return HAL_TOKEN_ERR;
210 }
211 char tokenWithFlagA[TOKEN_WITH_FLAG_SIZE] = {0};
212 char tokenWithFlagB[TOKEN_WITH_FLAG_SIZE] = {0};
213 int32_t retA = ReadTokenWithFlag(TOKEN_A_ADDR, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE);
214 int32_t retB = ReadTokenWithFlag(TOKEN_B_ADDR, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE);
215 if ((retA != 0) && (retB != 0)) {
216 printf("[OEMReadToken]:No token.\n");
217 return HAL_TOKEN_UNPRESET;
218 } else if ((retA == 0) && (retB != 0)) {
219 // token area A has data, area B is NULL, return A;
220 return memcpy_s(token, len, tokenWithFlagA, len);
221 } else if ((retA != 0) && (retB == 0)) {
222 // token area B has data, area A is NULL, return B;
223 return memcpy_s(token, len, tokenWithFlagB, len);
224 } else {
225 // token area A and B both have data, return area which flag is larger than the other one.
226 uint32_t flagA = GetTokenFlag(tokenWithFlagA);
227 uint32_t flagB = GetTokenFlag(tokenWithFlagB);
228 if (flagA > flagB) {
229 return memcpy_s(token, len, tokenWithFlagA, len);
230 } else {
231 return memcpy_s(token, len, tokenWithFlagB, len);
232 }
233 }
234 }
235
OEMWriteTokenANoToken(const char * token,uint32_t len,char * tokenWithFlagA)236 static int32_t OEMWriteTokenANoToken(const char* token, uint32_t len, char* tokenWithFlagA)
237 {
238 if (tokenWithFlagA == NULL) {
239 printf("[OEMWriteTokenANoToken]Invalid parameter.\n");
240 return HAL_TOKEN_ERR;
241 }
242 uint8_t flag[TOKEN_FLAG_SIZE] = {0};
243 if ((memcpy_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
244 (memcpy_s(tokenWithFlagA + len, TOKEN_WITH_FLAG_SIZE - len, flag, TOKEN_FLAG_SIZE) != 0)) {
245 printf("[OEMWriteTokenANoToken]:Flash write token memcpy failed.\n");
246 return HAL_TOKEN_ERR;
247 }
248 if (WriteTokenWithFlag(TOKEN_A_ADDR, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE) != 0) {
249 printf("[OEMWriteTokenANoToken]:Flash write token area A failed.\n");
250 return HAL_TOKEN_ERR;
251 }
252 return HAL_TOKEN_OK;
253 }
254
OEMWriteTokenB(const char * token,uint32_t len,char * tokenWithFlagA,char * tokenWithFlagB)255 static int32_t OEMWriteTokenB(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)
256 {
257 if (tokenWithFlagA == NULL || tokenWithFlagB == NULL) {
258 printf("[OEMWriteTokenB]Invalid parameter.\n");
259 return HAL_TOKEN_ERR;
260 }
261 uint32_t flagA = GetTokenFlag(tokenWithFlagA);
262 uint8_t flag[TOKEN_FLAG_SIZE] = {0};
263 SetTokenFlag(flag, (uint32_t)(flagA + 1));
264 (void)memset_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
265 if ((memcpy_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
266 (memcpy_s(tokenWithFlagB + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
267 printf("[OEMWriteTokenB]:Flash write token memcpy failed.\n");
268 return HAL_TOKEN_ERR;
269 }
270 if (WriteTokenWithFlag(TOKEN_B_ADDR, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE) != 0) {
271 printf("[OEMWriteTokenB]:Flash write token area B failed.\n");
272 return HAL_TOKEN_ERR;
273 }
274 return HAL_TOKEN_OK;
275 }
276
OEMWriteTokenA(const char * token,uint32_t len,char * tokenWithFlagA,char * tokenWithFlagB)277 static int32_t OEMWriteTokenA(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)
278 {
279 if (tokenWithFlagA == NULL || tokenWithFlagB == NULL) {
280 printf("[OEMWriteTokenA]Invalid parameter.\n");
281 return HAL_TOKEN_ERR;
282 }
283 uint32_t flagB = GetTokenFlag(tokenWithFlagB);
284 uint8_t flag[TOKEN_FLAG_SIZE] = {0};
285 SetTokenFlag(flag, (uint32_t)(flagB + 1));
286 (void)memset_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
287 if ((memcpy_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
288 (memcpy_s(tokenWithFlagA + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
289 printf("[OEMWriteTokenA]:Flash write token memcpy failed.\n");
290 return HAL_TOKEN_ERR;
291 }
292 if (WriteTokenWithFlag(TOKEN_A_ADDR, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE) != 0) {
293 printf("[OEMWriteTokenA]:Flash write token area A failed.\n");
294 return HAL_TOKEN_ERR;
295 }
296 return HAL_TOKEN_OK;
297 }
298
OEMWriteTokenSmaller(const char * token,uint32_t len,char * tokenWithFlagA,char * tokenWithFlagB)299 static int32_t OEMWriteTokenSmaller(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)
300 {
301 if (tokenWithFlagA == NULL || tokenWithFlagB == NULL) {
302 printf("[OEMWriteTokenSmaller]Invalid parameter.\n");
303 return HAL_TOKEN_ERR;
304 }
305 uint32_t flagA = GetTokenFlag(tokenWithFlagA);
306 uint32_t flagB = GetTokenFlag(tokenWithFlagB);
307 if (flagA > flagB) {
308 uint8_t flag[TOKEN_FLAG_SIZE] = {0};
309 SetTokenFlag(flag, (uint32_t)(flagA + 1));
310
311 // area A's token is new, recover area B;
312 (void)memset_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
313 if ((memcpy_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
314 (memcpy_s(tokenWithFlagB + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
315 printf("[OEMWriteTokenSmaller]:Flash write tokenB memcpy failed.\n");
316 return HAL_TOKEN_ERR;
317 }
318 if (WriteTokenWithFlag(TOKEN_B_ADDR, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE) != 0) {
319 printf("[OEMWriteTokenSmaller]:Flash write token area B failed.\n");
320 return HAL_TOKEN_ERR;
321 }
322 return HAL_TOKEN_OK;
323 } else {
324 uint8_t flag[TOKEN_FLAG_SIZE] = {0};
325 SetTokenFlag(flag, (uint32_t)(flagB + 1));
326
327 // area B's token is new, recover area A;
328 (void)memset_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
329 if ((memcpy_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
330 (memcpy_s(tokenWithFlagA + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
331 printf("[OEMWriteTokenSmaller]:Flash write tokenA memcpy failed.\n");
332 return HAL_TOKEN_ERR;
333 }
334 if (WriteTokenWithFlag(TOKEN_A_ADDR, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE) != 0) {
335 printf("[OEMWriteTokenSmaller]:Flash write token area A failed.\n");
336 return HAL_TOKEN_ERR;
337 }
338 return HAL_TOKEN_OK;
339 }
340 }
341
342 /* *
343 * @brief Write token value to the token A or B area on the flash, and this function is only for token read and write.
344 *
345 * @param token The input token data.
346 * @param len The token's length.
347 *
348 * @returns -1 if it fails, write token failed.
349 * 0 if it succeeds and means write token to area A or area B's data.
350 */
OEMWriteToken(const char * token,uint32_t len)351 static int32_t OEMWriteToken(const char* token, uint32_t len)
352 {
353 if ((token == NULL) || (len == 0)) {
354 return HAL_TOKEN_ERR;
355 }
356 char tokenWithFlagA[TOKEN_WITH_FLAG_SIZE] = {0};
357 char tokenWithFlagB[TOKEN_WITH_FLAG_SIZE] = {0};
358 int32_t retA = ReadTokenWithFlag(TOKEN_A_ADDR, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE);
359 int32_t retB = ReadTokenWithFlag(TOKEN_B_ADDR, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE);
360 if ((retA != 0) && (retB != 0)) {
361 printf("[OEMWriteToken]:No token data on device.\n");
362 return OEMWriteTokenANoToken(token, len, tokenWithFlagA);
363 } else if ((retA == 0) && (retB != 0)) {
364 // token area A has data, area B is NULL, write token to B area;
365 return OEMWriteTokenB(token, len, tokenWithFlagA, tokenWithFlagB);
366 } else if ((retA != 0) && (retB == 0)) {
367 // write token to A area
368 return OEMWriteTokenA(token, len, tokenWithFlagA, tokenWithFlagB);
369 } else {
370 // write token to the area which flag is smaller than the other one.
371 return OEMWriteTokenSmaller(token, len, tokenWithFlagA, tokenWithFlagB);
372 }
373 }
374
HalReadToken(char * token,unsigned int len)375 int HalReadToken(char *token, unsigned int len)
376 {
377 if (token == NULL) {
378 return EC_FAILURE;
379 }
380 return OEMReadToken(token, len);
381 }
382
HalWriteToken(const char * token,unsigned int len)383 int HalWriteToken(const char *token, unsigned int len)
384 {
385 if (token == NULL) {
386 return EC_FAILURE;
387 }
388 return OEMWriteToken(token, len);
389 }
390
HalGetAcKey(char * acKey,unsigned int len)391 int HalGetAcKey(char *acKey, unsigned int len)
392 {
393 if ((acKey == NULL) || (len == 0)) {
394 return EC_FAILURE;
395 }
396 const char manufacturekeyBuf[] = {
397 0x13, 0x42, 0x3F, 0x3F, 0x53, 0x3F, 0x72, 0x30, 0x3F, 0x3F, 0x1C, 0x3F, 0x2F, 0x3F, 0x2E, 0x42,
398 0x3F, 0x08, 0x3F, 0x57, 0x3F, 0x10, 0x3F, 0x3F, 0x29, 0x17, 0x52, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
399 0x57, 0x16, 0x3F, 0x7D, 0x4A, 0x0F, 0x3F, 0x3F, 0x3F, 0x30, 0x0C, 0x3F, 0x3F, 0x4C, 0x3F, 0x47
400 };
401 uint32_t manufacturekeyBufLen = sizeof(manufacturekeyBuf);
402 if (len < manufacturekeyBufLen) {
403 return EC_FAILURE;
404 }
405
406 int ret = memcpy_s(acKey, len, manufacturekeyBuf, manufacturekeyBufLen);
407 return ret;
408 }
409
HalGetProdId(char * productId,unsigned int len)410 int HalGetProdId(char *productId, unsigned int len)
411 {
412 if ((productId == NULL) || (len == 0)) {
413 return EC_FAILURE;
414 }
415 const char productIdBuf[] = "OH00004O";
416 uint32_t productIdLen = strlen(productIdBuf);
417 if (len < productIdLen) {
418 return EC_FAILURE;
419 }
420
421 int ret = memcpy_s(productId, len, productIdBuf, productIdLen);
422 return ret;
423 }
424
HalGetProdKey(char * productKey,unsigned int len)425 int HalGetProdKey(char *productKey, unsigned int len)
426 {
427 if ((productKey == NULL) || (len == 0)) {
428 return EC_FAILURE;
429 }
430 const char productKeyBuf[] = "test";
431 uint32_t productKeyLen = sizeof(productKeyBuf);
432 if (len < productKeyLen) {
433 return EC_FAILURE;
434 }
435
436 int ret = memcpy_s(productKey, len, productKeyBuf, productKeyLen);
437 return ret;
438 }
439
440