10a7ce71fSopenharmony_ci/*
20a7ce71fSopenharmony_ci * Copyright (c) 2020 Huawei Device Co., Ltd.
30a7ce71fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
40a7ce71fSopenharmony_ci * you may not use this file except in compliance with the License.
50a7ce71fSopenharmony_ci * You may obtain a copy of the License at
60a7ce71fSopenharmony_ci *
70a7ce71fSopenharmony_ci *    http://www.apache.org/licenses/LICENSE-2.0
80a7ce71fSopenharmony_ci *
90a7ce71fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
100a7ce71fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
110a7ce71fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120a7ce71fSopenharmony_ci * See the License for the specific language governing permissions and
130a7ce71fSopenharmony_ci * limitations under the License.
140a7ce71fSopenharmony_ci */
150a7ce71fSopenharmony_ci
160a7ce71fSopenharmony_ci#include <stdio.h>
170a7ce71fSopenharmony_ci#include <stdlib.h>
180a7ce71fSopenharmony_ci#include <stdint.h>
190a7ce71fSopenharmony_ci#include <string.h>
200a7ce71fSopenharmony_ci#include <securec.h>
210a7ce71fSopenharmony_ci#include <unistd.h>
220a7ce71fSopenharmony_ci#include <pthread.h>
230a7ce71fSopenharmony_ci#include "ohos_errno.h"
240a7ce71fSopenharmony_ci#include "ohos_types.h"
250a7ce71fSopenharmony_ci#include "hal_token.h"
260a7ce71fSopenharmony_ci
270a7ce71fSopenharmony_ci#define BITS_PER_BYTE 8
280a7ce71fSopenharmony_ci// sector size is 4096 Bytes
290a7ce71fSopenharmony_ci#define SECTOR_ALIGN_BYTES 4096
300a7ce71fSopenharmony_ci// token's max length is 151 Bytes, we using 256 Bytes to erase each token aera
310a7ce71fSopenharmony_ci#define MAX_TOKEN_AREA_SIZE 256
320a7ce71fSopenharmony_ci#define TOKEN_SIZE 151
330a7ce71fSopenharmony_ci// 4 Bytes for token flag
340a7ce71fSopenharmony_ci// if token's both area are available, when read token, always return area which flag is bigger;
350a7ce71fSopenharmony_ci// and recover area which flag is small while write token.
360a7ce71fSopenharmony_ci#define TOKEN_FLAG_SIZE 4
370a7ce71fSopenharmony_ci#define TOKEN_WITH_FLAG_SIZE (TOKEN_SIZE + TOKEN_FLAG_SIZE)
380a7ce71fSopenharmony_ci// 4 Bytes for token magic number, if data not in {1,2,3,4} order means the token area is not initialled.
390a7ce71fSopenharmony_ci// if token area is initialled, the token magic number's next Byte data is token actual value.
400a7ce71fSopenharmony_cistatic const char g_tokenMagicNum[] = {1, 2, 3, 4};
410a7ce71fSopenharmony_ci#define TOKEN_MAGIC_NUM_SIZE (sizeof(g_tokenMagicNum) / sizeof(g_tokenMagicNum[0]))
420a7ce71fSopenharmony_ci
430a7ce71fSopenharmony_ci#define TOKEN_FILE_PATH "/storage/data/device_attest"
440a7ce71fSopenharmony_ci#define TOKEN_A_FILE_NAME "tokenA"
450a7ce71fSopenharmony_ci#define TOKEN_B_FILE_NAME "tokenB"
460a7ce71fSopenharmony_ci#define PATH_MAX  255
470a7ce71fSopenharmony_ci
480a7ce71fSopenharmony_ci#define HAL_TOKEN_OK (0)
490a7ce71fSopenharmony_ci#define HAL_TOKEN_ERR (-1)
500a7ce71fSopenharmony_ci#define HAL_TOKEN_UNPRESET (-2)
510a7ce71fSopenharmony_ci
520a7ce71fSopenharmony_cipthread_mutex_t tokenMutex = PTHREAD_MUTEX_INITIALIZER; // 创建互斥锁
530a7ce71fSopenharmony_cistatic int tokenLock = 0;
540a7ce71fSopenharmony_ci
550a7ce71fSopenharmony_cistatic char* GenTokenFilePath(const char* dirPath, const char* fileName)
560a7ce71fSopenharmony_ci{
570a7ce71fSopenharmony_ci    if (dirPath == NULL || fileName == NULL) {
580a7ce71fSopenharmony_ci        return NULL;
590a7ce71fSopenharmony_ci    }
600a7ce71fSopenharmony_ci
610a7ce71fSopenharmony_ci    uint32_t filePathLen = strlen(dirPath) + 1 + strlen(fileName) + 1;
620a7ce71fSopenharmony_ci    if (filePathLen > PATH_MAX) {
630a7ce71fSopenharmony_ci        return NULL;
640a7ce71fSopenharmony_ci    }
650a7ce71fSopenharmony_ci    char* filePath = (char *)malloc(filePathLen);
660a7ce71fSopenharmony_ci    if (filePath == NULL) {
670a7ce71fSopenharmony_ci        return NULL;
680a7ce71fSopenharmony_ci    }
690a7ce71fSopenharmony_ci
700a7ce71fSopenharmony_ci    (void)memset_s(filePath, filePathLen, 0, filePathLen);
710a7ce71fSopenharmony_ci    if (sprintf_s(filePath, filePathLen, "%s%s%s", dirPath, "/", fileName) < 0) {
720a7ce71fSopenharmony_ci        free(filePath);
730a7ce71fSopenharmony_ci        return NULL;
740a7ce71fSopenharmony_ci    }
750a7ce71fSopenharmony_ci    return filePath;
760a7ce71fSopenharmony_ci}
770a7ce71fSopenharmony_ci
780a7ce71fSopenharmony_cistatic int32_t GetTokenFileSize(const char* path, const char* fileName, uint32_t* result)
790a7ce71fSopenharmony_ci{
800a7ce71fSopenharmony_ci    if (path == NULL || fileName == NULL || result == NULL) {
810a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
820a7ce71fSopenharmony_ci    }
830a7ce71fSopenharmony_ci
840a7ce71fSopenharmony_ci    char* filePath = GenTokenFilePath(path, fileName);
850a7ce71fSopenharmony_ci    if (filePath == NULL) {
860a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
870a7ce71fSopenharmony_ci    }
880a7ce71fSopenharmony_ci
890a7ce71fSopenharmony_ci    char* formatPath = realpath(filePath, NULL);
900a7ce71fSopenharmony_ci    if (formatPath == NULL) {
910a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
920a7ce71fSopenharmony_ci    }
930a7ce71fSopenharmony_ci
940a7ce71fSopenharmony_ci    FILE* fp = fopen(formatPath, "r");
950a7ce71fSopenharmony_ci    if (fp == NULL) {
960a7ce71fSopenharmony_ci        free(formatPath);
970a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
980a7ce71fSopenharmony_ci    }
990a7ce71fSopenharmony_ci    if (fseek(fp, 0, SEEK_END) < 0) {
1000a7ce71fSopenharmony_ci        free(formatPath);
1010a7ce71fSopenharmony_ci        (void)fclose(fp);
1020a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1030a7ce71fSopenharmony_ci    }
1040a7ce71fSopenharmony_ci    *result = ftell(fp);
1050a7ce71fSopenharmony_ci    free(formatPath);
1060a7ce71fSopenharmony_ci    (void)fclose(fp);
1070a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
1080a7ce71fSopenharmony_ci}
1090a7ce71fSopenharmony_ci
1100a7ce71fSopenharmony_cistatic int32_t ReadTokenFile(const char* path, const char* fileName, char* buffer, uint32_t bufferLen)
1110a7ce71fSopenharmony_ci{
1120a7ce71fSopenharmony_ci    if (path == NULL || fileName == NULL || buffer == NULL || bufferLen == 0) {
1130a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1140a7ce71fSopenharmony_ci    }
1150a7ce71fSopenharmony_ci
1160a7ce71fSopenharmony_ci    uint32_t fileSize = 0;
1170a7ce71fSopenharmony_ci    if (GetTokenFileSize(path, fileName, &fileSize) != 0 || fileSize > bufferLen) {
1180a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1190a7ce71fSopenharmony_ci    }
1200a7ce71fSopenharmony_ci
1210a7ce71fSopenharmony_ci    char* filePath = GenTokenFilePath(path, fileName);
1220a7ce71fSopenharmony_ci    if (filePath == NULL) {
1230a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1240a7ce71fSopenharmony_ci    }
1250a7ce71fSopenharmony_ci
1260a7ce71fSopenharmony_ci    char* formatPath = realpath(filePath, NULL);
1270a7ce71fSopenharmony_ci    free(filePath);
1280a7ce71fSopenharmony_ci    if (formatPath == NULL) {
1290a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1300a7ce71fSopenharmony_ci    }
1310a7ce71fSopenharmony_ci
1320a7ce71fSopenharmony_ci    FILE* fp = fopen(formatPath, "rb");
1330a7ce71fSopenharmony_ci    if (fp == NULL) {
1340a7ce71fSopenharmony_ci        free(formatPath);
1350a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1360a7ce71fSopenharmony_ci    }
1370a7ce71fSopenharmony_ci    if (fread(buffer, fileSize, 1, fp) != 1) {
1380a7ce71fSopenharmony_ci        free(formatPath);
1390a7ce71fSopenharmony_ci        (void)fclose(fp);
1400a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1410a7ce71fSopenharmony_ci    }
1420a7ce71fSopenharmony_ci    free(formatPath);
1430a7ce71fSopenharmony_ci    (void)fclose(fp);
1440a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
1450a7ce71fSopenharmony_ci}
1460a7ce71fSopenharmony_ci
1470a7ce71fSopenharmony_cistatic int32_t WriteTokenFile(const char* path, const char* fileName, const char* data, uint32_t dataLen)
1480a7ce71fSopenharmony_ci{
1490a7ce71fSopenharmony_ci    if (path == NULL || fileName == NULL || data == NULL || dataLen == 0) {
1500a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1510a7ce71fSopenharmony_ci    }
1520a7ce71fSopenharmony_ci
1530a7ce71fSopenharmony_ci    char* formatPath = realpath(path, NULL);
1540a7ce71fSopenharmony_ci    if (formatPath == NULL) {
1550a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1560a7ce71fSopenharmony_ci    }
1570a7ce71fSopenharmony_ci
1580a7ce71fSopenharmony_ci    char* filePath = GenTokenFilePath(formatPath, fileName);
1590a7ce71fSopenharmony_ci    free(formatPath);
1600a7ce71fSopenharmony_ci    if (filePath == NULL) {
1610a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1620a7ce71fSopenharmony_ci    }
1630a7ce71fSopenharmony_ci
1640a7ce71fSopenharmony_ci    FILE* fp = fopen(filePath, "wb+");
1650a7ce71fSopenharmony_ci    if (fp == NULL) {
1660a7ce71fSopenharmony_ci        free(filePath);
1670a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1680a7ce71fSopenharmony_ci    }
1690a7ce71fSopenharmony_ci    if (fwrite(data, dataLen, 1, fp) != 1) {
1700a7ce71fSopenharmony_ci        (void)fclose(fp);
1710a7ce71fSopenharmony_ci        free(filePath);
1720a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1730a7ce71fSopenharmony_ci    }
1740a7ce71fSopenharmony_ci    (void)fclose(fp);
1750a7ce71fSopenharmony_ci    free(filePath);
1760a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
1770a7ce71fSopenharmony_ci}
1780a7ce71fSopenharmony_ci
1790a7ce71fSopenharmony_cistatic int32_t ReadTokenRawData(const char* path, const char* fileName, char* buffer, uint32_t bufferLen)
1800a7ce71fSopenharmony_ci{
1810a7ce71fSopenharmony_ci    tokenLock = pthread_mutex_lock(&tokenMutex);
1820a7ce71fSopenharmony_ci    if (tokenLock == 0) {
1830a7ce71fSopenharmony_ci        int ret = ReadTokenFile(path, fileName, buffer, bufferLen);
1840a7ce71fSopenharmony_ci        if (ret < 0) {
1850a7ce71fSopenharmony_ci            pthread_mutex_unlock(&tokenMutex);
1860a7ce71fSopenharmony_ci            return HAL_TOKEN_ERR;
1870a7ce71fSopenharmony_ci        }
1880a7ce71fSopenharmony_ci    }
1890a7ce71fSopenharmony_ci    pthread_mutex_unlock(&tokenMutex);
1900a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
1910a7ce71fSopenharmony_ci}
1920a7ce71fSopenharmony_ci
1930a7ce71fSopenharmony_cistatic int32_t WriteTokenRawData(const char* path, const char* fileName, const char* data, uint32_t dataLen)
1940a7ce71fSopenharmony_ci{
1950a7ce71fSopenharmony_ci    tokenLock = pthread_mutex_lock(&tokenMutex);
1960a7ce71fSopenharmony_ci    if (tokenLock == 0) {
1970a7ce71fSopenharmony_ci        int ret = WriteTokenFile(path, fileName, data, dataLen);
1980a7ce71fSopenharmony_ci        if (ret < 0) {
1990a7ce71fSopenharmony_ci            pthread_mutex_unlock(&tokenMutex);
2000a7ce71fSopenharmony_ci            return HAL_TOKEN_ERR;
2010a7ce71fSopenharmony_ci        }
2020a7ce71fSopenharmony_ci    }
2030a7ce71fSopenharmony_ci    pthread_mutex_unlock(&tokenMutex);
2040a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
2050a7ce71fSopenharmony_ci}
2060a7ce71fSopenharmony_ci
2070a7ce71fSopenharmony_cistatic int32_t ReadTokenWithFlag(const char* path, const char* fileName, char* TokenWithFlag, uint32_t len)
2080a7ce71fSopenharmony_ci{
2090a7ce71fSopenharmony_ci    const uint32_t buffLen = TOKEN_MAGIC_NUM_SIZE + TOKEN_WITH_FLAG_SIZE + 1;
2100a7ce71fSopenharmony_ci    if (len < TOKEN_WITH_FLAG_SIZE) {
2110a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2120a7ce71fSopenharmony_ci    }
2130a7ce71fSopenharmony_ci    char *buf = malloc(buffLen);
2140a7ce71fSopenharmony_ci    if (buf == NULL) {
2150a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2160a7ce71fSopenharmony_ci    }
2170a7ce71fSopenharmony_ci
2180a7ce71fSopenharmony_ci    (void)memset_s(buf, buffLen, 0, buffLen);
2190a7ce71fSopenharmony_ci
2200a7ce71fSopenharmony_ci    if (ReadTokenRawData(path, fileName, buf, buffLen) != 0) {
2210a7ce71fSopenharmony_ci        free(buf);
2220a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2230a7ce71fSopenharmony_ci    }
2240a7ce71fSopenharmony_ci    int32_t tokenValid = 1;
2250a7ce71fSopenharmony_ci
2260a7ce71fSopenharmony_ci    for (uint32_t i = 0; i < TOKEN_MAGIC_NUM_SIZE; i++) {
2270a7ce71fSopenharmony_ci        if (buf[i] != g_tokenMagicNum[i]) {
2280a7ce71fSopenharmony_ci            tokenValid = 0;
2290a7ce71fSopenharmony_ci            break;
2300a7ce71fSopenharmony_ci        }
2310a7ce71fSopenharmony_ci    }
2320a7ce71fSopenharmony_ci    if (tokenValid == 0) {
2330a7ce71fSopenharmony_ci        free(buf);
2340a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2350a7ce71fSopenharmony_ci    }
2360a7ce71fSopenharmony_ci    if (memcpy_s(TokenWithFlag, TOKEN_WITH_FLAG_SIZE, buf + TOKEN_MAGIC_NUM_SIZE, TOKEN_WITH_FLAG_SIZE) != 0) {
2370a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2380a7ce71fSopenharmony_ci    }
2390a7ce71fSopenharmony_ci    free(buf);
2400a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
2410a7ce71fSopenharmony_ci}
2420a7ce71fSopenharmony_ci
2430a7ce71fSopenharmony_cistatic int32_t WriteTokenWithFlag(const char* path, const char* fileName, const char* TokenWithFlag, uint32_t len)
2440a7ce71fSopenharmony_ci{
2450a7ce71fSopenharmony_ci    const uint32_t buffLen = TOKEN_MAGIC_NUM_SIZE + TOKEN_WITH_FLAG_SIZE + 1;
2460a7ce71fSopenharmony_ci    char buf[buffLen];
2470a7ce71fSopenharmony_ci    (void)memset_s(buf, buffLen, 0, buffLen);
2480a7ce71fSopenharmony_ci
2490a7ce71fSopenharmony_ci    for (uint32_t i = 0; i < TOKEN_MAGIC_NUM_SIZE; i++) {
2500a7ce71fSopenharmony_ci        buf[i] = g_tokenMagicNum[i];
2510a7ce71fSopenharmony_ci    }
2520a7ce71fSopenharmony_ci    if (memcpy_s(buf + TOKEN_MAGIC_NUM_SIZE, TOKEN_WITH_FLAG_SIZE, TokenWithFlag, TOKEN_WITH_FLAG_SIZE) != 0) {
2530a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2540a7ce71fSopenharmony_ci    }
2550a7ce71fSopenharmony_ci    if (WriteTokenRawData(path, fileName, buf, len) != 0) {
2560a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2570a7ce71fSopenharmony_ci    }
2580a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
2590a7ce71fSopenharmony_ci}
2600a7ce71fSopenharmony_ci
2610a7ce71fSopenharmony_cistatic uint32_t GetTokenFlag(const char tokenWithFlag[])
2620a7ce71fSopenharmony_ci{
2630a7ce71fSopenharmony_ci    uint32_t result = 0;
2640a7ce71fSopenharmony_ci    for (uint32_t i = 0; i < TOKEN_FLAG_SIZE; i++) {
2650a7ce71fSopenharmony_ci        result |= ((uint8_t)tokenWithFlag[TOKEN_SIZE + i]) << ((TOKEN_FLAG_SIZE - 1 - i) * BITS_PER_BYTE);
2660a7ce71fSopenharmony_ci    }
2670a7ce71fSopenharmony_ci    return result;
2680a7ce71fSopenharmony_ci}
2690a7ce71fSopenharmony_cistatic void SetTokenFlag(uint8_t flag[], uint32_t value)
2700a7ce71fSopenharmony_ci{
2710a7ce71fSopenharmony_ci    for (uint32_t i = 0; i < TOKEN_FLAG_SIZE; i++) {
2720a7ce71fSopenharmony_ci        flag[i] = (value >> (BITS_PER_BYTE * (TOKEN_FLAG_SIZE - 1 - i))) & 0xFF;
2730a7ce71fSopenharmony_ci    }
2740a7ce71fSopenharmony_ci}
2750a7ce71fSopenharmony_ci
2760a7ce71fSopenharmony_cistatic int32_t OEMReadToken(char* token, uint32_t len)
2770a7ce71fSopenharmony_ci{
2780a7ce71fSopenharmony_ci    if (token == NULL || len == 0) {
2790a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2800a7ce71fSopenharmony_ci    }
2810a7ce71fSopenharmony_ci    char tokenWithFlagA[TOKEN_WITH_FLAG_SIZE] = {0};
2820a7ce71fSopenharmony_ci    char tokenWithFlagB[TOKEN_WITH_FLAG_SIZE] = {0};
2830a7ce71fSopenharmony_ci    int32_t retA = ReadTokenWithFlag(TOKEN_FILE_PATH, TOKEN_A_FILE_NAME, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE);
2840a7ce71fSopenharmony_ci    int32_t retB = ReadTokenWithFlag(TOKEN_FILE_PATH, TOKEN_B_FILE_NAME, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE);
2850a7ce71fSopenharmony_ci    if ((retA != 0) && (retB != 0)) {
2860a7ce71fSopenharmony_ci        // -2 means current is no token exist on the device
2870a7ce71fSopenharmony_ci        return HAL_TOKEN_UNPRESET;
2880a7ce71fSopenharmony_ci    } else if ((retA == 0) && (retB != 0)) {
2890a7ce71fSopenharmony_ci        // token area A has data, area B is NULL, return A;
2900a7ce71fSopenharmony_ci        return memcpy_s(token, len, tokenWithFlagA, len);
2910a7ce71fSopenharmony_ci    } else if ((retA != 0) && (retB == 0)) {
2920a7ce71fSopenharmony_ci        // token area B has data, area A is NULL, return B;
2930a7ce71fSopenharmony_ci        return memcpy_s(token, len, tokenWithFlagB, len);
2940a7ce71fSopenharmony_ci    } else {
2950a7ce71fSopenharmony_ci        // token area A and B both have data, return area which flag is larger than the other one.
2960a7ce71fSopenharmony_ci        uint32_t flagA = GetTokenFlag(tokenWithFlagA);
2970a7ce71fSopenharmony_ci        uint32_t flagB = GetTokenFlag(tokenWithFlagB);
2980a7ce71fSopenharmony_ci        if (flagA > flagB) {
2990a7ce71fSopenharmony_ci            return memcpy_s(token, len, tokenWithFlagA, len);
3000a7ce71fSopenharmony_ci        } else {
3010a7ce71fSopenharmony_ci            return memcpy_s(token, len, tokenWithFlagB, len);
3020a7ce71fSopenharmony_ci        }
3030a7ce71fSopenharmony_ci    }
3040a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
3050a7ce71fSopenharmony_ci}
3060a7ce71fSopenharmony_ci
3070a7ce71fSopenharmony_cistatic int32_t OEMWriteTokenANoToken(const char* token, uint32_t len, char* tokenWithFlagA)
3080a7ce71fSopenharmony_ci{
3090a7ce71fSopenharmony_ci    if (tokenWithFlagA == NULL) {
3100a7ce71fSopenharmony_ci        printf("[OEMWriteTokenANoToken]Invalid parameter.\n");
3110a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
3120a7ce71fSopenharmony_ci    }
3130a7ce71fSopenharmony_ci    uint8_t flag[TOKEN_FLAG_SIZE] = {0};
3140a7ce71fSopenharmony_ci    if ((memcpy_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
3150a7ce71fSopenharmony_ci        (memcpy_s(tokenWithFlagA + len, TOKEN_WITH_FLAG_SIZE - len, flag, TOKEN_FLAG_SIZE) != 0)) {
3160a7ce71fSopenharmony_ci        printf("[OEMWriteTokenANoToken]:Flash write token memcpy failed.\n");
3170a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
3180a7ce71fSopenharmony_ci    }
3190a7ce71fSopenharmony_ci    if (WriteTokenWithFlag(TOKEN_FILE_PATH, TOKEN_A_FILE_NAME, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE) != 0) {
3200a7ce71fSopenharmony_ci        printf("[OEMWriteTokenANoToken]:Flash write token area A failed.\n");
3210a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
3220a7ce71fSopenharmony_ci    }
3230a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
3240a7ce71fSopenharmony_ci}
3250a7ce71fSopenharmony_ci
3260a7ce71fSopenharmony_cistatic int32_t OEMWriteTokenB(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)
3270a7ce71fSopenharmony_ci{
3280a7ce71fSopenharmony_ci    if (tokenWithFlagA == NULL || tokenWithFlagB == NULL) {
3290a7ce71fSopenharmony_ci        printf("[OEMWriteTokenB]Invalid parameter.\n");
3300a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
3310a7ce71fSopenharmony_ci    }
3320a7ce71fSopenharmony_ci    uint32_t flagA = GetTokenFlag(tokenWithFlagA);
3330a7ce71fSopenharmony_ci    uint8_t flag[TOKEN_FLAG_SIZE] = {0};
3340a7ce71fSopenharmony_ci    SetTokenFlag(flag, (uint32_t)(flagA + 1));
3350a7ce71fSopenharmony_ci    (void)memset_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
3360a7ce71fSopenharmony_ci    if ((memcpy_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
3370a7ce71fSopenharmony_ci        (memcpy_s(tokenWithFlagB + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
3380a7ce71fSopenharmony_ci        printf("[OEMWriteTokenB]:Flash write token memcpy failed.\n");
3390a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
3400a7ce71fSopenharmony_ci    }
3410a7ce71fSopenharmony_ci    if (WriteTokenWithFlag(TOKEN_FILE_PATH, TOKEN_B_FILE_NAME, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE) != 0) {
3420a7ce71fSopenharmony_ci        printf("[OEMWriteTokenB]:Flash write token area B failed.\n");
3430a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
3440a7ce71fSopenharmony_ci    }
3450a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
3460a7ce71fSopenharmony_ci}
3470a7ce71fSopenharmony_ci
3480a7ce71fSopenharmony_cistatic int32_t OEMWriteTokenA(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)
3490a7ce71fSopenharmony_ci{
3500a7ce71fSopenharmony_ci    if (tokenWithFlagA == NULL || tokenWithFlagB == NULL) {
3510a7ce71fSopenharmony_ci        printf("[OEMWriteTokenA]Invalid parameter.\n");
3520a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
3530a7ce71fSopenharmony_ci    }
3540a7ce71fSopenharmony_ci    uint32_t flagB = GetTokenFlag(tokenWithFlagB);
3550a7ce71fSopenharmony_ci    uint8_t flag[TOKEN_FLAG_SIZE] = {0};
3560a7ce71fSopenharmony_ci    SetTokenFlag(flag, (uint32_t)(flagB + 1));
3570a7ce71fSopenharmony_ci    (void)memset_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
3580a7ce71fSopenharmony_ci    if ((memcpy_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
3590a7ce71fSopenharmony_ci        (memcpy_s(tokenWithFlagA + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
3600a7ce71fSopenharmony_ci        printf("[OEMWriteTokenA]:Flash write token memcpy failed.\n");
3610a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
3620a7ce71fSopenharmony_ci    }
3630a7ce71fSopenharmony_ci    if (WriteTokenWithFlag(TOKEN_FILE_PATH, TOKEN_A_FILE_NAME, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE) != 0) {
3640a7ce71fSopenharmony_ci        printf("[OEMWriteTokenA]:Flash write token area A failed.\n");
3650a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
3660a7ce71fSopenharmony_ci    }
3670a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
3680a7ce71fSopenharmony_ci}
3690a7ce71fSopenharmony_ci
3700a7ce71fSopenharmony_cistatic int32_t OEMWriteTokenSmaller(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)
3710a7ce71fSopenharmony_ci{
3720a7ce71fSopenharmony_ci    if (tokenWithFlagA == NULL || tokenWithFlagB == NULL) {
3730a7ce71fSopenharmony_ci        printf("[OEMWriteTokenSmaller]Invalid parameter.\n");
3740a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
3750a7ce71fSopenharmony_ci    }
3760a7ce71fSopenharmony_ci    uint32_t flagA = GetTokenFlag(tokenWithFlagA);
3770a7ce71fSopenharmony_ci    uint32_t flagB = GetTokenFlag(tokenWithFlagB);
3780a7ce71fSopenharmony_ci    if (flagA > flagB) {
3790a7ce71fSopenharmony_ci        uint8_t flag[TOKEN_FLAG_SIZE] = {0};
3800a7ce71fSopenharmony_ci        SetTokenFlag(flag, (uint32_t)(flagA + 1));
3810a7ce71fSopenharmony_ci
3820a7ce71fSopenharmony_ci        // area A's token is new, recover area B;
3830a7ce71fSopenharmony_ci        (void)memset_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
3840a7ce71fSopenharmony_ci        if ((memcpy_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
3850a7ce71fSopenharmony_ci            (memcpy_s(tokenWithFlagB + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
3860a7ce71fSopenharmony_ci            printf("[OEMWriteTokenSmaller]:Flash write tokenB memcpy failed.\n");
3870a7ce71fSopenharmony_ci            return HAL_TOKEN_ERR;
3880a7ce71fSopenharmony_ci        }
3890a7ce71fSopenharmony_ci        if (WriteTokenWithFlag(TOKEN_FILE_PATH, TOKEN_B_FILE_NAME, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE) != 0) {
3900a7ce71fSopenharmony_ci            printf("[OEMWriteTokenSmaller]:Flash write token area B failed.\n");
3910a7ce71fSopenharmony_ci            return HAL_TOKEN_ERR;
3920a7ce71fSopenharmony_ci        }
3930a7ce71fSopenharmony_ci        return HAL_TOKEN_OK;
3940a7ce71fSopenharmony_ci    } else {
3950a7ce71fSopenharmony_ci        uint8_t flag[TOKEN_FLAG_SIZE] = {0};
3960a7ce71fSopenharmony_ci        SetTokenFlag(flag, (uint32_t)(flagB + 1));
3970a7ce71fSopenharmony_ci
3980a7ce71fSopenharmony_ci        // area B's token is new, recover area A;
3990a7ce71fSopenharmony_ci        (void)memset_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
4000a7ce71fSopenharmony_ci        if ((memcpy_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
4010a7ce71fSopenharmony_ci            (memcpy_s(tokenWithFlagA + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
4020a7ce71fSopenharmony_ci            printf("[OEMWriteTokenSmaller]:Flash write tokenA memcpy failed.\n");
4030a7ce71fSopenharmony_ci            return HAL_TOKEN_ERR;
4040a7ce71fSopenharmony_ci        }
4050a7ce71fSopenharmony_ci        if (WriteTokenWithFlag(TOKEN_FILE_PATH, TOKEN_A_FILE_NAME, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE) != 0) {
4060a7ce71fSopenharmony_ci            printf("[OEMWriteTokenSmaller]:Flash write token area A failed.\n");
4070a7ce71fSopenharmony_ci            return HAL_TOKEN_ERR;
4080a7ce71fSopenharmony_ci        }
4090a7ce71fSopenharmony_ci        return HAL_TOKEN_OK;
4100a7ce71fSopenharmony_ci    }
4110a7ce71fSopenharmony_ci}
4120a7ce71fSopenharmony_ci/* *
4130a7ce71fSopenharmony_ci * @brief Write token value to the token A or B area on the flash, and this function is only for token read and write.
4140a7ce71fSopenharmony_ci *
4150a7ce71fSopenharmony_ci * @param token The input token data.
4160a7ce71fSopenharmony_ci * @param len The token's length.
4170a7ce71fSopenharmony_ci *
4180a7ce71fSopenharmony_ci * @returns    -1 if it fails, write token failed.
4190a7ce71fSopenharmony_ci * 0 if it succeeds and means write token to area A or area B's data.
4200a7ce71fSopenharmony_ci */
4210a7ce71fSopenharmony_cistatic int32_t OEMWriteToken(const char* token, uint32_t len)
4220a7ce71fSopenharmony_ci{
4230a7ce71fSopenharmony_ci    if ((token == NULL) || (len == 0)) {
4240a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
4250a7ce71fSopenharmony_ci    }
4260a7ce71fSopenharmony_ci    char tokenWithFlagA[TOKEN_WITH_FLAG_SIZE] = {0};
4270a7ce71fSopenharmony_ci    char tokenWithFlagB[TOKEN_WITH_FLAG_SIZE] = {0};
4280a7ce71fSopenharmony_ci    int32_t retA = ReadTokenWithFlag(TOKEN_FILE_PATH, TOKEN_A_FILE_NAME, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE);
4290a7ce71fSopenharmony_ci    int32_t retB = ReadTokenWithFlag(TOKEN_FILE_PATH, TOKEN_B_FILE_NAME, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE);
4300a7ce71fSopenharmony_ci    if ((retA != 0) && (retB != 0)) {
4310a7ce71fSopenharmony_ci        printf("[OEMWriteToken]:No token data on device.\n");
4320a7ce71fSopenharmony_ci        return OEMWriteTokenANoToken(token, len, tokenWithFlagA);
4330a7ce71fSopenharmony_ci    } else if ((retA == 0) && (retB != 0)) {
4340a7ce71fSopenharmony_ci        // token area A has data, area B is NULL, write token to B area;
4350a7ce71fSopenharmony_ci        return OEMWriteTokenB(token, len, tokenWithFlagA, tokenWithFlagB);
4360a7ce71fSopenharmony_ci    } else if ((retA != 0) && (retB == 0)) {
4370a7ce71fSopenharmony_ci        // write token to A area
4380a7ce71fSopenharmony_ci        return OEMWriteTokenA(token, len, tokenWithFlagA, tokenWithFlagB);
4390a7ce71fSopenharmony_ci    } else {
4400a7ce71fSopenharmony_ci        // write token to the area which flag is smaller than the other one.
4410a7ce71fSopenharmony_ci        return OEMWriteTokenSmaller(token, len, tokenWithFlagA, tokenWithFlagB);
4420a7ce71fSopenharmony_ci    }
4430a7ce71fSopenharmony_ci}
4440a7ce71fSopenharmony_ci
4450a7ce71fSopenharmony_ciint HalReadToken(char *token, unsigned int len)
4460a7ce71fSopenharmony_ci{
4470a7ce71fSopenharmony_ci    if (token == NULL) {
4480a7ce71fSopenharmony_ci        return EC_FAILURE;
4490a7ce71fSopenharmony_ci    }
4500a7ce71fSopenharmony_ci    return OEMReadToken(token, len);
4510a7ce71fSopenharmony_ci}
4520a7ce71fSopenharmony_ci
4530a7ce71fSopenharmony_ciint HalWriteToken(const char *token, unsigned int len)
4540a7ce71fSopenharmony_ci{
4550a7ce71fSopenharmony_ci    if (token == NULL) {
4560a7ce71fSopenharmony_ci        return EC_FAILURE;
4570a7ce71fSopenharmony_ci    }
4580a7ce71fSopenharmony_ci    return OEMWriteToken(token, len);
4590a7ce71fSopenharmony_ci}
4600a7ce71fSopenharmony_ci
4610a7ce71fSopenharmony_ciint HalGetAcKey(char *acKey, unsigned int len)
4620a7ce71fSopenharmony_ci{
4630a7ce71fSopenharmony_ci    if ((acKey == NULL) || (len == 0)) {
4640a7ce71fSopenharmony_ci        return EC_FAILURE;
4650a7ce71fSopenharmony_ci    }
4660a7ce71fSopenharmony_ci    const char manufacturekeyBuf[] = {
4670a7ce71fSopenharmony_ci        0x13, 0x42, 0x3F, 0x3F, 0x53, 0x3F, 0x72, 0x30, 0x3F, 0x3F, 0x1C, 0x3F, 0x2F, 0x3F, 0x2E, 0x42,
4680a7ce71fSopenharmony_ci        0x3F, 0x08, 0x3F, 0x57, 0x3F, 0x10, 0x3F, 0x3F, 0x29, 0x17, 0x52, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
4690a7ce71fSopenharmony_ci        0x57, 0x16, 0x3F, 0x7D, 0x4A, 0x0F, 0x3F, 0x3F, 0x3F, 0x30, 0x0C, 0x3F, 0x3F, 0x4C, 0x3F, 0x47
4700a7ce71fSopenharmony_ci    };
4710a7ce71fSopenharmony_ci    uint32_t manufacturekeyBufLen = sizeof(manufacturekeyBuf);
4720a7ce71fSopenharmony_ci    if (len < manufacturekeyBufLen) {
4730a7ce71fSopenharmony_ci        return EC_FAILURE;
4740a7ce71fSopenharmony_ci    }
4750a7ce71fSopenharmony_ci
4760a7ce71fSopenharmony_ci    int ret = memcpy_s(acKey, len, manufacturekeyBuf, manufacturekeyBufLen);
4770a7ce71fSopenharmony_ci    return ret;
4780a7ce71fSopenharmony_ci}
4790a7ce71fSopenharmony_ci
4800a7ce71fSopenharmony_ciint HalGetProdId(char *productId, unsigned int len)
4810a7ce71fSopenharmony_ci{
4820a7ce71fSopenharmony_ci    if ((productId == NULL) || (len == 0)) {
4830a7ce71fSopenharmony_ci        return EC_FAILURE;
4840a7ce71fSopenharmony_ci    }
4850a7ce71fSopenharmony_ci    const char productIdBuf[] = "OH00000D";
4860a7ce71fSopenharmony_ci    uint32_t productIdLen = strlen(productIdBuf);
4870a7ce71fSopenharmony_ci    if (len < productIdLen) {
4880a7ce71fSopenharmony_ci        return EC_FAILURE;
4890a7ce71fSopenharmony_ci    }
4900a7ce71fSopenharmony_ci
4910a7ce71fSopenharmony_ci    int ret = memcpy_s(productId, len, productIdBuf, productIdLen);
4920a7ce71fSopenharmony_ci    return ret;
4930a7ce71fSopenharmony_ci}
4940a7ce71fSopenharmony_ci
4950a7ce71fSopenharmony_ciint HalGetProdKey(char *productKey, unsigned int len)
4960a7ce71fSopenharmony_ci{
4970a7ce71fSopenharmony_ci    if ((productKey == NULL) || (len == 0)) {
4980a7ce71fSopenharmony_ci        return EC_FAILURE;
4990a7ce71fSopenharmony_ci    }
5000a7ce71fSopenharmony_ci    const char productKeyBuf[] = "test";
5010a7ce71fSopenharmony_ci    uint32_t productKeyLen = sizeof(productKeyBuf);
5020a7ce71fSopenharmony_ci    if (len < productKeyLen) {
5030a7ce71fSopenharmony_ci        return EC_FAILURE;
5040a7ce71fSopenharmony_ci    }
5050a7ce71fSopenharmony_ci
5060a7ce71fSopenharmony_ci    int ret = memcpy_s(productKey, len, productKeyBuf, productKeyLen);
5070a7ce71fSopenharmony_ci    return ret;
5080a7ce71fSopenharmony_ci}