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 <unistd.h>
22 #include <pthread.h>
23 #include "ohos_errno.h"
24 #include "ohos_types.h"
25 #include "hal_token.h"
26 
27 #define BITS_PER_BYTE 8
28 // sector size is 4096 Bytes
29 #define SECTOR_ALIGN_BYTES 4096
30 // token's max length is 151 Bytes, we using 256 Bytes to erase each token aera
31 #define MAX_TOKEN_AREA_SIZE 256
32 #define TOKEN_SIZE 151
33 // 4 Bytes for token flag
34 // if token's both area are available, when read token, always return area which flag is bigger;
35 // and recover area which flag is small while write token.
36 #define TOKEN_FLAG_SIZE 4
37 #define TOKEN_WITH_FLAG_SIZE (TOKEN_SIZE + TOKEN_FLAG_SIZE)
38 // 4 Bytes for token magic number, if data not in {1,2,3,4} order means the token area is not initialled.
39 // if token area is initialled, the token magic number's next Byte data is token actual value.
40 static const char g_tokenMagicNum[] = {1, 2, 3, 4};
41 #define TOKEN_MAGIC_NUM_SIZE (sizeof(g_tokenMagicNum) / sizeof(g_tokenMagicNum[0]))
42 
43 #define TOKEN_FILE_PATH "/storage/data/device_attest"
44 #define TOKEN_A_FILE_NAME "tokenA"
45 #define TOKEN_B_FILE_NAME "tokenB"
46 #define PATH_MAX  255
47 
48 #define HAL_TOKEN_OK (0)
49 #define HAL_TOKEN_ERR (-1)
50 #define HAL_TOKEN_UNPRESET (-2)
51 
52 pthread_mutex_t tokenMutex = PTHREAD_MUTEX_INITIALIZER; // 创建互斥锁
53 static int tokenLock = 0;
54 
GenTokenFilePath(const char* dirPath, const char* fileName)55 static char* GenTokenFilePath(const char* dirPath, const char* fileName)
56 {
57     if (dirPath == NULL || fileName == NULL) {
58         return NULL;
59     }
60 
61     uint32_t filePathLen = strlen(dirPath) + 1 + strlen(fileName) + 1;
62     if (filePathLen > PATH_MAX) {
63         return NULL;
64     }
65     char* filePath = (char *)malloc(filePathLen);
66     if (filePath == NULL) {
67         return NULL;
68     }
69 
70     (void)memset_s(filePath, filePathLen, 0, filePathLen);
71     if (sprintf_s(filePath, filePathLen, "%s%s%s", dirPath, "/", fileName) < 0) {
72         free(filePath);
73         return NULL;
74     }
75     return filePath;
76 }
77 
GetTokenFileSize(const char* path, const char* fileName, uint32_t* result)78 static int32_t GetTokenFileSize(const char* path, const char* fileName, uint32_t* result)
79 {
80     if (path == NULL || fileName == NULL || result == NULL) {
81         return HAL_TOKEN_ERR;
82     }
83 
84     char* filePath = GenTokenFilePath(path, fileName);
85     if (filePath == NULL) {
86         return HAL_TOKEN_ERR;
87     }
88 
89     char* formatPath = realpath(filePath, NULL);
90     if (formatPath == NULL) {
91         return HAL_TOKEN_ERR;
92     }
93 
94     FILE* fp = fopen(formatPath, "r");
95     if (fp == NULL) {
96         free(formatPath);
97         return HAL_TOKEN_ERR;
98     }
99     if (fseek(fp, 0, SEEK_END) < 0) {
100         free(formatPath);
101         (void)fclose(fp);
102         return HAL_TOKEN_ERR;
103     }
104     *result = ftell(fp);
105     free(formatPath);
106     (void)fclose(fp);
107     return HAL_TOKEN_OK;
108 }
109 
ReadTokenFile(const char* path, const char* fileName, char* buffer, uint32_t bufferLen)110 static int32_t ReadTokenFile(const char* path, const char* fileName, char* buffer, uint32_t bufferLen)
111 {
112     if (path == NULL || fileName == NULL || buffer == NULL || bufferLen == 0) {
113         return HAL_TOKEN_ERR;
114     }
115 
116     uint32_t fileSize = 0;
117     if (GetTokenFileSize(path, fileName, &fileSize) != 0 || fileSize > bufferLen) {
118         return HAL_TOKEN_ERR;
119     }
120 
121     char* filePath = GenTokenFilePath(path, fileName);
122     if (filePath == NULL) {
123         return HAL_TOKEN_ERR;
124     }
125 
126     char* formatPath = realpath(filePath, NULL);
127     free(filePath);
128     if (formatPath == NULL) {
129         return HAL_TOKEN_ERR;
130     }
131 
132     FILE* fp = fopen(formatPath, "rb");
133     if (fp == NULL) {
134         free(formatPath);
135         return HAL_TOKEN_ERR;
136     }
137     if (fread(buffer, fileSize, 1, fp) != 1) {
138         free(formatPath);
139         (void)fclose(fp);
140         return HAL_TOKEN_ERR;
141     }
142     free(formatPath);
143     (void)fclose(fp);
144     return HAL_TOKEN_OK;
145 }
146 
WriteTokenFile(const char* path, const char* fileName, const char* data, uint32_t dataLen)147 static int32_t WriteTokenFile(const char* path, const char* fileName, const char* data, uint32_t dataLen)
148 {
149     if (path == NULL || fileName == NULL || data == NULL || dataLen == 0) {
150         return HAL_TOKEN_ERR;
151     }
152 
153     char* formatPath = realpath(path, NULL);
154     if (formatPath == NULL) {
155         return HAL_TOKEN_ERR;
156     }
157 
158     char* filePath = GenTokenFilePath(formatPath, fileName);
159     free(formatPath);
160     if (filePath == NULL) {
161         return HAL_TOKEN_ERR;
162     }
163 
164     FILE* fp = fopen(filePath, "wb+");
165     if (fp == NULL) {
166         free(filePath);
167         return HAL_TOKEN_ERR;
168     }
169     if (fwrite(data, dataLen, 1, fp) != 1) {
170         (void)fclose(fp);
171         free(filePath);
172         return HAL_TOKEN_ERR;
173     }
174     (void)fclose(fp);
175     free(filePath);
176     return HAL_TOKEN_OK;
177 }
178 
ReadTokenRawData(const char* path, const char* fileName, char* buffer, uint32_t bufferLen)179 static int32_t ReadTokenRawData(const char* path, const char* fileName, char* buffer, uint32_t bufferLen)
180 {
181     tokenLock = pthread_mutex_lock(&tokenMutex);
182     if (tokenLock == 0) {
183         int ret = ReadTokenFile(path, fileName, buffer, bufferLen);
184         if (ret < 0) {
185             pthread_mutex_unlock(&tokenMutex);
186             return HAL_TOKEN_ERR;
187         }
188     }
189     pthread_mutex_unlock(&tokenMutex);
190     return HAL_TOKEN_OK;
191 }
192 
WriteTokenRawData(const char* path, const char* fileName, const char* data, uint32_t dataLen)193 static int32_t WriteTokenRawData(const char* path, const char* fileName, const char* data, uint32_t dataLen)
194 {
195     tokenLock = pthread_mutex_lock(&tokenMutex);
196     if (tokenLock == 0) {
197         int ret = WriteTokenFile(path, fileName, data, dataLen);
198         if (ret < 0) {
199             pthread_mutex_unlock(&tokenMutex);
200             return HAL_TOKEN_ERR;
201         }
202     }
203     pthread_mutex_unlock(&tokenMutex);
204     return HAL_TOKEN_OK;
205 }
206 
ReadTokenWithFlag(const char* path, const char* fileName, char* TokenWithFlag, uint32_t len)207 static int32_t ReadTokenWithFlag(const char* path, const char* fileName, char* TokenWithFlag, uint32_t len)
208 {
209     const uint32_t buffLen = TOKEN_MAGIC_NUM_SIZE + TOKEN_WITH_FLAG_SIZE + 1;
210     if (len < TOKEN_WITH_FLAG_SIZE) {
211         return HAL_TOKEN_ERR;
212     }
213     char *buf = malloc(buffLen);
214     if (buf == NULL) {
215         return HAL_TOKEN_ERR;
216     }
217 
218     (void)memset_s(buf, buffLen, 0, buffLen);
219 
220     if (ReadTokenRawData(path, fileName, buf, buffLen) != 0) {
221         free(buf);
222         return HAL_TOKEN_ERR;
223     }
224     int32_t tokenValid = 1;
225 
226     for (uint32_t i = 0; i < TOKEN_MAGIC_NUM_SIZE; i++) {
227         if (buf[i] != g_tokenMagicNum[i]) {
228             tokenValid = 0;
229             break;
230         }
231     }
232     if (tokenValid == 0) {
233         free(buf);
234         return HAL_TOKEN_ERR;
235     }
236     if (memcpy_s(TokenWithFlag, TOKEN_WITH_FLAG_SIZE, buf + TOKEN_MAGIC_NUM_SIZE, TOKEN_WITH_FLAG_SIZE) != 0) {
237         return HAL_TOKEN_ERR;
238     }
239     free(buf);
240     return HAL_TOKEN_OK;
241 }
242 
WriteTokenWithFlag(const char* path, const char* fileName, const char* TokenWithFlag, uint32_t len)243 static int32_t WriteTokenWithFlag(const char* path, const char* fileName, const char* TokenWithFlag, uint32_t len)
244 {
245     const uint32_t buffLen = TOKEN_MAGIC_NUM_SIZE + TOKEN_WITH_FLAG_SIZE + 1;
246     char buf[buffLen];
247     (void)memset_s(buf, buffLen, 0, buffLen);
248 
249     for (uint32_t i = 0; i < TOKEN_MAGIC_NUM_SIZE; i++) {
250         buf[i] = g_tokenMagicNum[i];
251     }
252     if (memcpy_s(buf + TOKEN_MAGIC_NUM_SIZE, TOKEN_WITH_FLAG_SIZE, TokenWithFlag, TOKEN_WITH_FLAG_SIZE) != 0) {
253         return HAL_TOKEN_ERR;
254     }
255     if (WriteTokenRawData(path, fileName, buf, len) != 0) {
256         return HAL_TOKEN_ERR;
257     }
258     return HAL_TOKEN_OK;
259 }
260 
GetTokenFlag(const char tokenWithFlag[])261 static uint32_t GetTokenFlag(const char tokenWithFlag[])
262 {
263     uint32_t result = 0;
264     for (uint32_t i = 0; i < TOKEN_FLAG_SIZE; i++) {
265         result |= ((uint8_t)tokenWithFlag[TOKEN_SIZE + i]) << ((TOKEN_FLAG_SIZE - 1 - i) * BITS_PER_BYTE);
266     }
267     return result;
268 }
SetTokenFlag(uint8_t flag[], uint32_t value)269 static void SetTokenFlag(uint8_t flag[], uint32_t value)
270 {
271     for (uint32_t i = 0; i < TOKEN_FLAG_SIZE; i++) {
272         flag[i] = (value >> (BITS_PER_BYTE * (TOKEN_FLAG_SIZE - 1 - i))) & 0xFF;
273     }
274 }
275 
OEMReadToken(char* token, uint32_t len)276 static int32_t OEMReadToken(char* token, uint32_t len)
277 {
278     if (token == NULL || len == 0) {
279         return HAL_TOKEN_ERR;
280     }
281     char tokenWithFlagA[TOKEN_WITH_FLAG_SIZE] = {0};
282     char tokenWithFlagB[TOKEN_WITH_FLAG_SIZE] = {0};
283     int32_t retA = ReadTokenWithFlag(TOKEN_FILE_PATH, TOKEN_A_FILE_NAME, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE);
284     int32_t retB = ReadTokenWithFlag(TOKEN_FILE_PATH, TOKEN_B_FILE_NAME, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE);
285     if ((retA != 0) && (retB != 0)) {
286         // -2 means current is no token exist on the device
287         return HAL_TOKEN_UNPRESET;
288     } else if ((retA == 0) && (retB != 0)) {
289         // token area A has data, area B is NULL, return A;
290         return memcpy_s(token, len, tokenWithFlagA, len);
291     } else if ((retA != 0) && (retB == 0)) {
292         // token area B has data, area A is NULL, return B;
293         return memcpy_s(token, len, tokenWithFlagB, len);
294     } else {
295         // token area A and B both have data, return area which flag is larger than the other one.
296         uint32_t flagA = GetTokenFlag(tokenWithFlagA);
297         uint32_t flagB = GetTokenFlag(tokenWithFlagB);
298         if (flagA > flagB) {
299             return memcpy_s(token, len, tokenWithFlagA, len);
300         } else {
301             return memcpy_s(token, len, tokenWithFlagB, len);
302         }
303     }
304     return HAL_TOKEN_OK;
305 }
306 
OEMWriteTokenANoToken(const char* token, uint32_t len, char* tokenWithFlagA)307 static int32_t OEMWriteTokenANoToken(const char* token, uint32_t len, char* tokenWithFlagA)
308 {
309     if (tokenWithFlagA == NULL) {
310         printf("[OEMWriteTokenANoToken]Invalid parameter.\n");
311         return HAL_TOKEN_ERR;
312     }
313     uint8_t flag[TOKEN_FLAG_SIZE] = {0};
314     if ((memcpy_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
315         (memcpy_s(tokenWithFlagA + len, TOKEN_WITH_FLAG_SIZE - len, flag, TOKEN_FLAG_SIZE) != 0)) {
316         printf("[OEMWriteTokenANoToken]:Flash write token memcpy failed.\n");
317         return HAL_TOKEN_ERR;
318     }
319     if (WriteTokenWithFlag(TOKEN_FILE_PATH, TOKEN_A_FILE_NAME, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE) != 0) {
320         printf("[OEMWriteTokenANoToken]:Flash write token area A failed.\n");
321         return HAL_TOKEN_ERR;
322     }
323     return HAL_TOKEN_OK;
324 }
325 
OEMWriteTokenB(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)326 static int32_t OEMWriteTokenB(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)
327 {
328     if (tokenWithFlagA == NULL || tokenWithFlagB == NULL) {
329         printf("[OEMWriteTokenB]Invalid parameter.\n");
330         return HAL_TOKEN_ERR;
331     }
332     uint32_t flagA = GetTokenFlag(tokenWithFlagA);
333     uint8_t flag[TOKEN_FLAG_SIZE] = {0};
334     SetTokenFlag(flag, (uint32_t)(flagA + 1));
335     (void)memset_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
336     if ((memcpy_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
337         (memcpy_s(tokenWithFlagB + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
338         printf("[OEMWriteTokenB]:Flash write token memcpy failed.\n");
339         return HAL_TOKEN_ERR;
340     }
341     if (WriteTokenWithFlag(TOKEN_FILE_PATH, TOKEN_B_FILE_NAME, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE) != 0) {
342         printf("[OEMWriteTokenB]:Flash write token area B failed.\n");
343         return HAL_TOKEN_ERR;
344     }
345     return HAL_TOKEN_OK;
346 }
347 
OEMWriteTokenA(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)348 static int32_t OEMWriteTokenA(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)
349 {
350     if (tokenWithFlagA == NULL || tokenWithFlagB == NULL) {
351         printf("[OEMWriteTokenA]Invalid parameter.\n");
352         return HAL_TOKEN_ERR;
353     }
354     uint32_t flagB = GetTokenFlag(tokenWithFlagB);
355     uint8_t flag[TOKEN_FLAG_SIZE] = {0};
356     SetTokenFlag(flag, (uint32_t)(flagB + 1));
357     (void)memset_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
358     if ((memcpy_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
359         (memcpy_s(tokenWithFlagA + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
360         printf("[OEMWriteTokenA]:Flash write token memcpy failed.\n");
361         return HAL_TOKEN_ERR;
362     }
363     if (WriteTokenWithFlag(TOKEN_FILE_PATH, TOKEN_A_FILE_NAME, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE) != 0) {
364         printf("[OEMWriteTokenA]:Flash write token area A failed.\n");
365         return HAL_TOKEN_ERR;
366     }
367     return HAL_TOKEN_OK;
368 }
369 
OEMWriteTokenSmaller(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)370 static int32_t OEMWriteTokenSmaller(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)
371 {
372     if (tokenWithFlagA == NULL || tokenWithFlagB == NULL) {
373         printf("[OEMWriteTokenSmaller]Invalid parameter.\n");
374         return HAL_TOKEN_ERR;
375     }
376     uint32_t flagA = GetTokenFlag(tokenWithFlagA);
377     uint32_t flagB = GetTokenFlag(tokenWithFlagB);
378     if (flagA > flagB) {
379         uint8_t flag[TOKEN_FLAG_SIZE] = {0};
380         SetTokenFlag(flag, (uint32_t)(flagA + 1));
381 
382         // area A's token is new, recover area B;
383         (void)memset_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
384         if ((memcpy_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
385             (memcpy_s(tokenWithFlagB + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
386             printf("[OEMWriteTokenSmaller]:Flash write tokenB memcpy failed.\n");
387             return HAL_TOKEN_ERR;
388         }
389         if (WriteTokenWithFlag(TOKEN_FILE_PATH, TOKEN_B_FILE_NAME, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE) != 0) {
390             printf("[OEMWriteTokenSmaller]:Flash write token area B failed.\n");
391             return HAL_TOKEN_ERR;
392         }
393         return HAL_TOKEN_OK;
394     } else {
395         uint8_t flag[TOKEN_FLAG_SIZE] = {0};
396         SetTokenFlag(flag, (uint32_t)(flagB + 1));
397 
398         // area B's token is new, recover area A;
399         (void)memset_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
400         if ((memcpy_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
401             (memcpy_s(tokenWithFlagA + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
402             printf("[OEMWriteTokenSmaller]:Flash write tokenA memcpy failed.\n");
403             return HAL_TOKEN_ERR;
404         }
405         if (WriteTokenWithFlag(TOKEN_FILE_PATH, TOKEN_A_FILE_NAME, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE) != 0) {
406             printf("[OEMWriteTokenSmaller]:Flash write token area A failed.\n");
407             return HAL_TOKEN_ERR;
408         }
409         return HAL_TOKEN_OK;
410     }
411 }
412 /* *
413  * @brief Write token value to the token A or B area on the flash, and this function is only for token read and write.
414  *
415  * @param token The input token data.
416  * @param len The token's length.
417  *
418  * @returns    -1 if it fails, write token failed.
419  * 0 if it succeeds and means write token to area A or area B's data.
420  */
OEMWriteToken(const char* token, uint32_t len)421 static int32_t OEMWriteToken(const char* token, uint32_t len)
422 {
423     if ((token == NULL) || (len == 0)) {
424         return HAL_TOKEN_ERR;
425     }
426     char tokenWithFlagA[TOKEN_WITH_FLAG_SIZE] = {0};
427     char tokenWithFlagB[TOKEN_WITH_FLAG_SIZE] = {0};
428     int32_t retA = ReadTokenWithFlag(TOKEN_FILE_PATH, TOKEN_A_FILE_NAME, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE);
429     int32_t retB = ReadTokenWithFlag(TOKEN_FILE_PATH, TOKEN_B_FILE_NAME, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE);
430     if ((retA != 0) && (retB != 0)) {
431         printf("[OEMWriteToken]:No token data on device.\n");
432         return OEMWriteTokenANoToken(token, len, tokenWithFlagA);
433     } else if ((retA == 0) && (retB != 0)) {
434         // token area A has data, area B is NULL, write token to B area;
435         return OEMWriteTokenB(token, len, tokenWithFlagA, tokenWithFlagB);
436     } else if ((retA != 0) && (retB == 0)) {
437         // write token to A area
438         return OEMWriteTokenA(token, len, tokenWithFlagA, tokenWithFlagB);
439     } else {
440         // write token to the area which flag is smaller than the other one.
441         return OEMWriteTokenSmaller(token, len, tokenWithFlagA, tokenWithFlagB);
442     }
443 }
444 
HalReadToken(char *token, unsigned int len)445 int HalReadToken(char *token, unsigned int len)
446 {
447     if (token == NULL) {
448         return EC_FAILURE;
449     }
450     return OEMReadToken(token, len);
451 }
452 
HalWriteToken(const char *token, unsigned int len)453 int HalWriteToken(const char *token, unsigned int len)
454 {
455     if (token == NULL) {
456         return EC_FAILURE;
457     }
458     return OEMWriteToken(token, len);
459 }
460 
HalGetAcKey(char *acKey, unsigned int len)461 int HalGetAcKey(char *acKey, unsigned int len)
462 {
463     if ((acKey == NULL) || (len == 0)) {
464         return EC_FAILURE;
465     }
466     const char manufacturekeyBuf[] = {
467         0x13, 0x42, 0x3F, 0x3F, 0x53, 0x3F, 0x72, 0x30, 0x3F, 0x3F, 0x1C, 0x3F, 0x2F, 0x3F, 0x2E, 0x42,
468         0x3F, 0x08, 0x3F, 0x57, 0x3F, 0x10, 0x3F, 0x3F, 0x29, 0x17, 0x52, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
469         0x57, 0x16, 0x3F, 0x7D, 0x4A, 0x0F, 0x3F, 0x3F, 0x3F, 0x30, 0x0C, 0x3F, 0x3F, 0x4C, 0x3F, 0x47
470     };
471     uint32_t manufacturekeyBufLen = sizeof(manufacturekeyBuf);
472     if (len < manufacturekeyBufLen) {
473         return EC_FAILURE;
474     }
475 
476     int ret = memcpy_s(acKey, len, manufacturekeyBuf, manufacturekeyBufLen);
477     return ret;
478 }
479 
HalGetProdId(char *productId, unsigned int len)480 int HalGetProdId(char *productId, unsigned int len)
481 {
482     if ((productId == NULL) || (len == 0)) {
483         return EC_FAILURE;
484     }
485     const char productIdBuf[] = "OH00000D";
486     uint32_t productIdLen = strlen(productIdBuf);
487     if (len < productIdLen) {
488         return EC_FAILURE;
489     }
490 
491     int ret = memcpy_s(productId, len, productIdBuf, productIdLen);
492     return ret;
493 }
494 
HalGetProdKey(char *productKey, unsigned int len)495 int HalGetProdKey(char *productKey, unsigned int len)
496 {
497     if ((productKey == NULL) || (len == 0)) {
498         return EC_FAILURE;
499     }
500     const char productKeyBuf[] = "test";
501     uint32_t productKeyLen = sizeof(productKeyBuf);
502     if (len < productKeyLen) {
503         return EC_FAILURE;
504     }
505 
506     int ret = memcpy_s(productKey, len, productKeyBuf, productKeyLen);
507     return ret;
508 }