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