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 "hi_flash.h"
220a7ce71fSopenharmony_ci#include "ohos_errno.h"
230a7ce71fSopenharmony_ci#include "ohos_types.h"
240a7ce71fSopenharmony_ci#include "hal_token.h"
250a7ce71fSopenharmony_ci
260a7ce71fSopenharmony_ci#define BITS_PER_BYTE 8
270a7ce71fSopenharmony_ci// sector size is 4096 Bytes
280a7ce71fSopenharmony_ci#define SECTOR_ALIGN_BYTES 4096
290a7ce71fSopenharmony_ci#define TOKEN_SIZE 151
300a7ce71fSopenharmony_ci
310a7ce71fSopenharmony_ci// using 256 Bytes to erase each token aera
320a7ce71fSopenharmony_ci#define MAX_TOKEN_AREA_SIZE 256
330a7ce71fSopenharmony_ci
340a7ce71fSopenharmony_ci// 4 Bytes for token flag
350a7ce71fSopenharmony_ci// if token's both area are available, when read token, always return area which flag is bigger;
360a7ce71fSopenharmony_ci// and recover area which flag is small while write token.
370a7ce71fSopenharmony_ci#define TOKEN_FLAG_SIZE 4
380a7ce71fSopenharmony_ci#define TOKEN_WITH_FLAG_SIZE (TOKEN_SIZE + TOKEN_FLAG_SIZE)
390a7ce71fSopenharmony_ci
400a7ce71fSopenharmony_ci#define TOKEN_ADDR 0x001F0000        // 实际的toekn地址
410a7ce71fSopenharmony_ci
420a7ce71fSopenharmony_ci#define TOKEN_A_ADDR TOKEN_ADDR
430a7ce71fSopenharmony_ci
440a7ce71fSopenharmony_ci#define TOKEN_B_ADDR (TOKEN_A_ADDR + SECTOR_ALIGN_BYTES)
450a7ce71fSopenharmony_ci
460a7ce71fSopenharmony_ci#define TOKEN_DEBUG 1
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_ci#define FLASH_OPERAT_LEN 4
530a7ce71fSopenharmony_ci#define MALLOC_PARA 350
540a7ce71fSopenharmony_ci// 4 Bytes for token magic number, if data not in {1,2,3,4} order means the token area is not initialled.
550a7ce71fSopenharmony_ci// if token area is initialled, the token magic number's next Byte data is token actual value.
560a7ce71fSopenharmony_cistatic const char g_tokenMagicNum[] = {1, 2, 3, 4};
570a7ce71fSopenharmony_ci#define TOKEN_MAGIC_NUM_SIZE (sizeof(g_tokenMagicNum) / sizeof(g_tokenMagicNum[0]))
580a7ce71fSopenharmony_ci
590a7ce71fSopenharmony_ci#if TOKEN_DEBUG
600a7ce71fSopenharmony_ci#define TOKEN_LOG(...) printf(__VA_ARGS__)
610a7ce71fSopenharmony_ci#else
620a7ce71fSopenharmony_ci#define TOKEN_LOG(...)
630a7ce71fSopenharmony_ci#endif
640a7ce71fSopenharmony_ci
650a7ce71fSopenharmony_ci
660a7ce71fSopenharmony_cistatic int32_t flashRead(uint32_t addr, uint32_t size, uint8_t *buffer)
670a7ce71fSopenharmony_ci{
680a7ce71fSopenharmony_ci    uint32_t len = 0;
690a7ce71fSopenharmony_ci    if ((size % FLASH_OPERAT_LEN) != 0) {
700a7ce71fSopenharmony_ci        len = size / FLASH_OPERAT_LEN * FLASH_OPERAT_LEN + FLASH_OPERAT_LEN;
710a7ce71fSopenharmony_ci    } else {
720a7ce71fSopenharmony_ci        len = size;
730a7ce71fSopenharmony_ci    }
740a7ce71fSopenharmony_ci    return hi_flash_read(addr, len, buffer);
750a7ce71fSopenharmony_ci}
760a7ce71fSopenharmony_ci
770a7ce71fSopenharmony_cistatic int32_t flashWrite(uint32_t addr, uint32_t size, uint8_t *buffer)
780a7ce71fSopenharmony_ci{
790a7ce71fSopenharmony_ci    uint32_t len = 0;
800a7ce71fSopenharmony_ci    if ((size % FLASH_OPERAT_LEN) != 0) {
810a7ce71fSopenharmony_ci        len = size / FLASH_OPERAT_LEN * FLASH_OPERAT_LEN + FLASH_OPERAT_LEN;
820a7ce71fSopenharmony_ci    } else {
830a7ce71fSopenharmony_ci        len = size;
840a7ce71fSopenharmony_ci    }
850a7ce71fSopenharmony_ci    return hi_flash_write(addr, len, buffer, 0);
860a7ce71fSopenharmony_ci}
870a7ce71fSopenharmony_ci
880a7ce71fSopenharmony_cistatic int32_t flashErase(uint32_t start_addr)
890a7ce71fSopenharmony_ci{
900a7ce71fSopenharmony_ci    return hi_flash_erase(start_addr, SECTOR_ALIGN_BYTES);
910a7ce71fSopenharmony_ci}
920a7ce71fSopenharmony_ci
930a7ce71fSopenharmony_cistatic int32_t FlashWriteTokenRawData(uint32_t start, const char* tokenRawData, uint32_t len)
940a7ce71fSopenharmony_ci{
950a7ce71fSopenharmony_ci    if (start % SECTOR_ALIGN_BYTES != 0) {
960a7ce71fSopenharmony_ci        printf("[FlashWriteTokenRawData]:Unsupport address not align yet, may cause data overlap error.\n");
970a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
980a7ce71fSopenharmony_ci    }
990a7ce71fSopenharmony_ci    if (tokenRawData == NULL || len <= 0) {
1000a7ce71fSopenharmony_ci        printf("[FlashWriteTokenRawData]:Invalid parameter.\n");
1010a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1020a7ce71fSopenharmony_ci    }
1030a7ce71fSopenharmony_ci    if (flashErase(start) != 0) {
1040a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1050a7ce71fSopenharmony_ci    }
1060a7ce71fSopenharmony_ci    return flashWrite(start, len, tokenRawData);
1070a7ce71fSopenharmony_ci}
1080a7ce71fSopenharmony_ci
1090a7ce71fSopenharmony_cistatic int32_t FlashReadTokenRawData(uint32_t start, char* tokenRawData, uint32_t len)
1100a7ce71fSopenharmony_ci{
1110a7ce71fSopenharmony_ci    if (start % SECTOR_ALIGN_BYTES != 0) {
1120a7ce71fSopenharmony_ci        printf("[FlashReadTokenRawData]:Unsupport start address not align yet, may cause data overlap error.\n");
1130a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1140a7ce71fSopenharmony_ci    }
1150a7ce71fSopenharmony_ci    if (tokenRawData == NULL || len <= 0) {
1160a7ce71fSopenharmony_ci        printf("[FlashReadTokenRawData]:Invalid parameter.\n");
1170a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1180a7ce71fSopenharmony_ci    }
1190a7ce71fSopenharmony_ci    return flashRead(start, len, tokenRawData);
1200a7ce71fSopenharmony_ci}
1210a7ce71fSopenharmony_ci
1220a7ce71fSopenharmony_cistatic int32_t ReadTokenWithFlag(uint32_t start, char* result, uint32_t len)
1230a7ce71fSopenharmony_ci{
1240a7ce71fSopenharmony_ci    const uint32_t buffLen = TOKEN_MAGIC_NUM_SIZE + TOKEN_WITH_FLAG_SIZE + 1;
1250a7ce71fSopenharmony_ci    if (len < TOKEN_WITH_FLAG_SIZE) {
1260a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1270a7ce71fSopenharmony_ci    }
1280a7ce71fSopenharmony_ci    char *buf = hi_malloc(MALLOC_PARA, buffLen);
1290a7ce71fSopenharmony_ci    if (buf == NULL) {
1300a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1310a7ce71fSopenharmony_ci    }
1320a7ce71fSopenharmony_ci
1330a7ce71fSopenharmony_ci    (void)memset_s(buf, buffLen, 0, buffLen);
1340a7ce71fSopenharmony_ci    if (FlashReadTokenRawData(start, buf, buffLen) != 0) {
1350a7ce71fSopenharmony_ci        printf("[ReadTokenWithFlag]:Read flash token area failed.\n");
1360a7ce71fSopenharmony_ci        hi_free(MALLOC_PARA, buf);
1370a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1380a7ce71fSopenharmony_ci    }
1390a7ce71fSopenharmony_ci
1400a7ce71fSopenharmony_ci    int32_t tokenValid = 1;
1410a7ce71fSopenharmony_ci    // check is initialed or not
1420a7ce71fSopenharmony_ci    for (uint32_t i = 0; i < TOKEN_MAGIC_NUM_SIZE; i++) {
1430a7ce71fSopenharmony_ci        if (buf[i] != g_tokenMagicNum[i]) {
1440a7ce71fSopenharmony_ci            tokenValid = 0;
1450a7ce71fSopenharmony_ci            break;
1460a7ce71fSopenharmony_ci        }
1470a7ce71fSopenharmony_ci    }
1480a7ce71fSopenharmony_ci    // token area is invalid
1490a7ce71fSopenharmony_ci    if (tokenValid == 0) {
1500a7ce71fSopenharmony_ci        printf("[ReadTokenWithFlag]:The token area is invalid.\n");
1510a7ce71fSopenharmony_ci        hi_free(MALLOC_PARA, buf);
1520a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1530a7ce71fSopenharmony_ci    }
1540a7ce71fSopenharmony_ci    if (memcpy_s(result, TOKEN_WITH_FLAG_SIZE, buf + TOKEN_MAGIC_NUM_SIZE, TOKEN_WITH_FLAG_SIZE) != 0) {
1550a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1560a7ce71fSopenharmony_ci    }
1570a7ce71fSopenharmony_ci    hi_free(MALLOC_PARA, buf);
1580a7ce71fSopenharmony_ci    printf("[ReadTokenWithFlag]:Read token success!\n");
1590a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
1600a7ce71fSopenharmony_ci}
1610a7ce71fSopenharmony_ci
1620a7ce71fSopenharmony_cistatic int32_t WriteTokenWithFlag(uint32_t start, const char* tokenWithFlag, uint32_t len)
1630a7ce71fSopenharmony_ci{
1640a7ce71fSopenharmony_ci    const uint32_t buffLen = TOKEN_MAGIC_NUM_SIZE + TOKEN_WITH_FLAG_SIZE + 1;
1650a7ce71fSopenharmony_ci    char buf[buffLen];
1660a7ce71fSopenharmony_ci    (void)memset_s(buf, buffLen, 0, buffLen);
1670a7ce71fSopenharmony_ci    for (uint32_t i = 0; i < TOKEN_MAGIC_NUM_SIZE; i++) {
1680a7ce71fSopenharmony_ci        buf[i] = g_tokenMagicNum[i];
1690a7ce71fSopenharmony_ci    }
1700a7ce71fSopenharmony_ci    if (memcpy_s(buf + TOKEN_MAGIC_NUM_SIZE, TOKEN_WITH_FLAG_SIZE, tokenWithFlag, TOKEN_WITH_FLAG_SIZE) != 0) {
1710a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1720a7ce71fSopenharmony_ci    }
1730a7ce71fSopenharmony_ci    if (FlashWriteTokenRawData(start, buf, buffLen) != 0) {
1740a7ce71fSopenharmony_ci        printf("[WriteTokenWithFlag]: Write flash token area failed.\n");
1750a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
1760a7ce71fSopenharmony_ci    }
1770a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
1780a7ce71fSopenharmony_ci}
1790a7ce71fSopenharmony_ci
1800a7ce71fSopenharmony_cistatic uint32_t GetTokenFlag(const char tokenWithFlag[])
1810a7ce71fSopenharmony_ci{
1820a7ce71fSopenharmony_ci    uint32_t result = 0;
1830a7ce71fSopenharmony_ci    for (uint32_t i = 0; i < TOKEN_FLAG_SIZE; i++) {
1840a7ce71fSopenharmony_ci        result |= ((uint8_t)tokenWithFlag[TOKEN_SIZE + i]) << ((TOKEN_FLAG_SIZE - 1 - i) * BITS_PER_BYTE);
1850a7ce71fSopenharmony_ci    }
1860a7ce71fSopenharmony_ci    return result;
1870a7ce71fSopenharmony_ci}
1880a7ce71fSopenharmony_ci
1890a7ce71fSopenharmony_cistatic void SetTokenFlag(uint8_t flag[], uint32_t value)
1900a7ce71fSopenharmony_ci{
1910a7ce71fSopenharmony_ci    for (uint32_t i = 0; i < TOKEN_FLAG_SIZE; i++) {
1920a7ce71fSopenharmony_ci        flag[i] = (value >> (BITS_PER_BYTE * (TOKEN_FLAG_SIZE - 1 - i))) & 0xFF;
1930a7ce71fSopenharmony_ci    }
1940a7ce71fSopenharmony_ci}
1950a7ce71fSopenharmony_ci
1960a7ce71fSopenharmony_ci/* *
1970a7ce71fSopenharmony_ci * @brief Read token value from the flash token A or B area, and this function is only for token read and write.
1980a7ce71fSopenharmony_ci *
1990a7ce71fSopenharmony_ci * @param token The data buffer malloced by caller.
2000a7ce71fSopenharmony_ci * @param len The data buffer length.
2010a7ce71fSopenharmony_ci *
2020a7ce71fSopenharmony_ci * @returns -1 if it fails, the actual data is unknown.
2030a7ce71fSopenharmony_ci *          0 if it succeeds and means read token from area A or area B's data.
2040a7ce71fSopenharmony_ci *          -2 if it succeeds and means current is no token exist on the device.
2050a7ce71fSopenharmony_ci */
2060a7ce71fSopenharmony_cistatic int32_t OEMReadToken(char* token, uint32_t len)
2070a7ce71fSopenharmony_ci{
2080a7ce71fSopenharmony_ci    if (token == NULL || len == 0) {
2090a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2100a7ce71fSopenharmony_ci    }
2110a7ce71fSopenharmony_ci    char tokenWithFlagA[TOKEN_WITH_FLAG_SIZE] = {0};
2120a7ce71fSopenharmony_ci    char tokenWithFlagB[TOKEN_WITH_FLAG_SIZE] = {0};
2130a7ce71fSopenharmony_ci    int32_t retA = ReadTokenWithFlag(TOKEN_A_ADDR, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE);
2140a7ce71fSopenharmony_ci    int32_t retB = ReadTokenWithFlag(TOKEN_B_ADDR, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE);
2150a7ce71fSopenharmony_ci    if ((retA != 0) && (retB != 0)) {
2160a7ce71fSopenharmony_ci        printf("[OEMReadToken]:No token.\n");
2170a7ce71fSopenharmony_ci        return HAL_TOKEN_UNPRESET;
2180a7ce71fSopenharmony_ci    } else if ((retA == 0) && (retB != 0)) {
2190a7ce71fSopenharmony_ci        // token area A has data, area B is NULL, return A;
2200a7ce71fSopenharmony_ci        return memcpy_s(token, len, tokenWithFlagA, len);
2210a7ce71fSopenharmony_ci    } else if ((retA != 0) && (retB == 0)) {
2220a7ce71fSopenharmony_ci        // token area B has data, area A is NULL, return B;
2230a7ce71fSopenharmony_ci        return memcpy_s(token, len, tokenWithFlagB, len);
2240a7ce71fSopenharmony_ci    } else {
2250a7ce71fSopenharmony_ci        // token area A and B both have data, return area which flag is larger than the other one.
2260a7ce71fSopenharmony_ci        uint32_t flagA = GetTokenFlag(tokenWithFlagA);
2270a7ce71fSopenharmony_ci        uint32_t flagB = GetTokenFlag(tokenWithFlagB);
2280a7ce71fSopenharmony_ci        if (flagA > flagB) {
2290a7ce71fSopenharmony_ci            return memcpy_s(token, len, tokenWithFlagA, len);
2300a7ce71fSopenharmony_ci        } else {
2310a7ce71fSopenharmony_ci            return memcpy_s(token, len, tokenWithFlagB, len);
2320a7ce71fSopenharmony_ci        }
2330a7ce71fSopenharmony_ci    }
2340a7ce71fSopenharmony_ci}
2350a7ce71fSopenharmony_ci
2360a7ce71fSopenharmony_cistatic int32_t OEMWriteTokenANoToken(const char* token, uint32_t len, char* tokenWithFlagA)
2370a7ce71fSopenharmony_ci{
2380a7ce71fSopenharmony_ci    if (tokenWithFlagA == NULL) {
2390a7ce71fSopenharmony_ci        printf("[OEMWriteTokenANoToken]Invalid parameter.\n");
2400a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2410a7ce71fSopenharmony_ci    }
2420a7ce71fSopenharmony_ci    uint8_t flag[TOKEN_FLAG_SIZE] = {0};
2430a7ce71fSopenharmony_ci    if ((memcpy_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
2440a7ce71fSopenharmony_ci        (memcpy_s(tokenWithFlagA + len, TOKEN_WITH_FLAG_SIZE - len, flag, TOKEN_FLAG_SIZE) != 0)) {
2450a7ce71fSopenharmony_ci        printf("[OEMWriteTokenANoToken]:Flash write token memcpy failed.\n");
2460a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2470a7ce71fSopenharmony_ci    }
2480a7ce71fSopenharmony_ci    if (WriteTokenWithFlag(TOKEN_A_ADDR, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE) != 0) {
2490a7ce71fSopenharmony_ci        printf("[OEMWriteTokenANoToken]:Flash write token area A failed.\n");
2500a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2510a7ce71fSopenharmony_ci    }
2520a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
2530a7ce71fSopenharmony_ci}
2540a7ce71fSopenharmony_ci
2550a7ce71fSopenharmony_cistatic int32_t OEMWriteTokenB(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)
2560a7ce71fSopenharmony_ci{
2570a7ce71fSopenharmony_ci    if (tokenWithFlagA == NULL || tokenWithFlagB == NULL) {
2580a7ce71fSopenharmony_ci        printf("[OEMWriteTokenB]Invalid parameter.\n");
2590a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2600a7ce71fSopenharmony_ci    }
2610a7ce71fSopenharmony_ci    uint32_t flagA = GetTokenFlag(tokenWithFlagA);
2620a7ce71fSopenharmony_ci    uint8_t flag[TOKEN_FLAG_SIZE] = {0};
2630a7ce71fSopenharmony_ci    SetTokenFlag(flag, (uint32_t)(flagA + 1));
2640a7ce71fSopenharmony_ci    (void)memset_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
2650a7ce71fSopenharmony_ci    if ((memcpy_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
2660a7ce71fSopenharmony_ci        (memcpy_s(tokenWithFlagB + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
2670a7ce71fSopenharmony_ci        printf("[OEMWriteTokenB]:Flash write token memcpy failed.\n");
2680a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2690a7ce71fSopenharmony_ci    }
2700a7ce71fSopenharmony_ci    if (WriteTokenWithFlag(TOKEN_B_ADDR, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE) != 0) {
2710a7ce71fSopenharmony_ci        printf("[OEMWriteTokenB]:Flash write token area B failed.\n");
2720a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2730a7ce71fSopenharmony_ci    }
2740a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
2750a7ce71fSopenharmony_ci}
2760a7ce71fSopenharmony_ci
2770a7ce71fSopenharmony_cistatic int32_t OEMWriteTokenA(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)
2780a7ce71fSopenharmony_ci{
2790a7ce71fSopenharmony_ci    if (tokenWithFlagA == NULL || tokenWithFlagB == NULL) {
2800a7ce71fSopenharmony_ci        printf("[OEMWriteTokenA]Invalid parameter.\n");
2810a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2820a7ce71fSopenharmony_ci    }
2830a7ce71fSopenharmony_ci    uint32_t flagB = GetTokenFlag(tokenWithFlagB);
2840a7ce71fSopenharmony_ci    uint8_t flag[TOKEN_FLAG_SIZE] = {0};
2850a7ce71fSopenharmony_ci    SetTokenFlag(flag, (uint32_t)(flagB + 1));
2860a7ce71fSopenharmony_ci    (void)memset_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
2870a7ce71fSopenharmony_ci    if ((memcpy_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
2880a7ce71fSopenharmony_ci        (memcpy_s(tokenWithFlagA + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
2890a7ce71fSopenharmony_ci        printf("[OEMWriteTokenA]:Flash write token memcpy failed.\n");
2900a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2910a7ce71fSopenharmony_ci    }
2920a7ce71fSopenharmony_ci    if (WriteTokenWithFlag(TOKEN_A_ADDR, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE) != 0) {
2930a7ce71fSopenharmony_ci        printf("[OEMWriteTokenA]:Flash write token area A failed.\n");
2940a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
2950a7ce71fSopenharmony_ci    }
2960a7ce71fSopenharmony_ci    return HAL_TOKEN_OK;
2970a7ce71fSopenharmony_ci}
2980a7ce71fSopenharmony_ci
2990a7ce71fSopenharmony_cistatic int32_t OEMWriteTokenSmaller(const char* token, uint32_t len, char* tokenWithFlagA, char* tokenWithFlagB)
3000a7ce71fSopenharmony_ci{
3010a7ce71fSopenharmony_ci    if (tokenWithFlagA == NULL || tokenWithFlagB == NULL) {
3020a7ce71fSopenharmony_ci        printf("[OEMWriteTokenSmaller]Invalid parameter.\n");
3030a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
3040a7ce71fSopenharmony_ci    }
3050a7ce71fSopenharmony_ci    uint32_t flagA = GetTokenFlag(tokenWithFlagA);
3060a7ce71fSopenharmony_ci    uint32_t flagB = GetTokenFlag(tokenWithFlagB);
3070a7ce71fSopenharmony_ci    if (flagA > flagB) {
3080a7ce71fSopenharmony_ci        uint8_t flag[TOKEN_FLAG_SIZE] = {0};
3090a7ce71fSopenharmony_ci        SetTokenFlag(flag, (uint32_t)(flagA + 1));
3100a7ce71fSopenharmony_ci
3110a7ce71fSopenharmony_ci        // area A's token is new, recover area B;
3120a7ce71fSopenharmony_ci        (void)memset_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
3130a7ce71fSopenharmony_ci        if ((memcpy_s(tokenWithFlagB, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
3140a7ce71fSopenharmony_ci            (memcpy_s(tokenWithFlagB + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
3150a7ce71fSopenharmony_ci            printf("[OEMWriteTokenSmaller]:Flash write tokenB memcpy failed.\n");
3160a7ce71fSopenharmony_ci            return HAL_TOKEN_ERR;
3170a7ce71fSopenharmony_ci        }
3180a7ce71fSopenharmony_ci        if (WriteTokenWithFlag(TOKEN_B_ADDR, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE) != 0) {
3190a7ce71fSopenharmony_ci            printf("[OEMWriteTokenSmaller]:Flash write token area B failed.\n");
3200a7ce71fSopenharmony_ci            return HAL_TOKEN_ERR;
3210a7ce71fSopenharmony_ci        }
3220a7ce71fSopenharmony_ci        return HAL_TOKEN_OK;
3230a7ce71fSopenharmony_ci    } else {
3240a7ce71fSopenharmony_ci        uint8_t flag[TOKEN_FLAG_SIZE] = {0};
3250a7ce71fSopenharmony_ci        SetTokenFlag(flag, (uint32_t)(flagB + 1));
3260a7ce71fSopenharmony_ci
3270a7ce71fSopenharmony_ci        // area B's token is new, recover area A;
3280a7ce71fSopenharmony_ci        (void)memset_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, 0, TOKEN_WITH_FLAG_SIZE);
3290a7ce71fSopenharmony_ci        if ((memcpy_s(tokenWithFlagA, TOKEN_WITH_FLAG_SIZE, token, len) != 0) ||
3300a7ce71fSopenharmony_ci            (memcpy_s(tokenWithFlagA + len, TOKEN_WITH_FLAG_SIZE, flag, TOKEN_FLAG_SIZE) != 0)) {
3310a7ce71fSopenharmony_ci            printf("[OEMWriteTokenSmaller]:Flash write tokenA memcpy failed.\n");
3320a7ce71fSopenharmony_ci            return HAL_TOKEN_ERR;
3330a7ce71fSopenharmony_ci        }
3340a7ce71fSopenharmony_ci        if (WriteTokenWithFlag(TOKEN_A_ADDR, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE) != 0) {
3350a7ce71fSopenharmony_ci            printf("[OEMWriteTokenSmaller]:Flash write token area A failed.\n");
3360a7ce71fSopenharmony_ci            return HAL_TOKEN_ERR;
3370a7ce71fSopenharmony_ci        }
3380a7ce71fSopenharmony_ci        return HAL_TOKEN_OK;
3390a7ce71fSopenharmony_ci    }
3400a7ce71fSopenharmony_ci}
3410a7ce71fSopenharmony_ci
3420a7ce71fSopenharmony_ci/* *
3430a7ce71fSopenharmony_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.
3440a7ce71fSopenharmony_ci *
3450a7ce71fSopenharmony_ci * @param token The input token data.
3460a7ce71fSopenharmony_ci * @param len The token's length.
3470a7ce71fSopenharmony_ci *
3480a7ce71fSopenharmony_ci * @returns -1 if it fails, write token failed.
3490a7ce71fSopenharmony_ci *          0 if it succeeds and means write token to area A or area B's data.
3500a7ce71fSopenharmony_ci */
3510a7ce71fSopenharmony_cistatic int32_t OEMWriteToken(const char* token, uint32_t len)
3520a7ce71fSopenharmony_ci{
3530a7ce71fSopenharmony_ci    if ((token == NULL) || (len == 0)) {
3540a7ce71fSopenharmony_ci        return HAL_TOKEN_ERR;
3550a7ce71fSopenharmony_ci    }
3560a7ce71fSopenharmony_ci    char tokenWithFlagA[TOKEN_WITH_FLAG_SIZE] = {0};
3570a7ce71fSopenharmony_ci    char tokenWithFlagB[TOKEN_WITH_FLAG_SIZE] = {0};
3580a7ce71fSopenharmony_ci    int32_t retA = ReadTokenWithFlag(TOKEN_A_ADDR, tokenWithFlagA, TOKEN_WITH_FLAG_SIZE);
3590a7ce71fSopenharmony_ci    int32_t retB = ReadTokenWithFlag(TOKEN_B_ADDR, tokenWithFlagB, TOKEN_WITH_FLAG_SIZE);
3600a7ce71fSopenharmony_ci    if ((retA != 0) && (retB != 0)) {
3610a7ce71fSopenharmony_ci        printf("[OEMWriteToken]:No token data on device.\n");
3620a7ce71fSopenharmony_ci        return OEMWriteTokenANoToken(token, len, tokenWithFlagA);
3630a7ce71fSopenharmony_ci    } else if ((retA == 0) && (retB != 0)) {
3640a7ce71fSopenharmony_ci        // token area A has data, area B is NULL, write token to B area;
3650a7ce71fSopenharmony_ci        return OEMWriteTokenB(token, len, tokenWithFlagA, tokenWithFlagB);
3660a7ce71fSopenharmony_ci    } else if ((retA != 0) && (retB == 0)) {
3670a7ce71fSopenharmony_ci        // write token to A area
3680a7ce71fSopenharmony_ci        return OEMWriteTokenA(token, len, tokenWithFlagA, tokenWithFlagB);
3690a7ce71fSopenharmony_ci    } else {
3700a7ce71fSopenharmony_ci        // write token to the area which flag is smaller than the other one.
3710a7ce71fSopenharmony_ci        return OEMWriteTokenSmaller(token, len, tokenWithFlagA, tokenWithFlagB);
3720a7ce71fSopenharmony_ci    }
3730a7ce71fSopenharmony_ci}
3740a7ce71fSopenharmony_ci
3750a7ce71fSopenharmony_ciint HalReadToken(char *token, unsigned int len)
3760a7ce71fSopenharmony_ci{
3770a7ce71fSopenharmony_ci    if (token == NULL) {
3780a7ce71fSopenharmony_ci        return EC_FAILURE;
3790a7ce71fSopenharmony_ci    }
3800a7ce71fSopenharmony_ci    return OEMReadToken(token, len);
3810a7ce71fSopenharmony_ci}
3820a7ce71fSopenharmony_ci
3830a7ce71fSopenharmony_ciint HalWriteToken(const char *token, unsigned int len)
3840a7ce71fSopenharmony_ci{
3850a7ce71fSopenharmony_ci    if (token == NULL) {
3860a7ce71fSopenharmony_ci        return EC_FAILURE;
3870a7ce71fSopenharmony_ci    }
3880a7ce71fSopenharmony_ci    return OEMWriteToken(token, len);
3890a7ce71fSopenharmony_ci}
3900a7ce71fSopenharmony_ci
3910a7ce71fSopenharmony_ciint HalGetAcKey(char *acKey, unsigned int len)
3920a7ce71fSopenharmony_ci{
3930a7ce71fSopenharmony_ci    if ((acKey == NULL) || (len == 0)) {
3940a7ce71fSopenharmony_ci        return EC_FAILURE;
3950a7ce71fSopenharmony_ci    }
3960a7ce71fSopenharmony_ci    const char manufacturekeyBuf[] = {
3970a7ce71fSopenharmony_ci        0x13, 0x42, 0x3F, 0x3F, 0x53, 0x3F, 0x72, 0x30, 0x3F, 0x3F, 0x1C, 0x3F, 0x2F, 0x3F, 0x2E, 0x42,
3980a7ce71fSopenharmony_ci        0x3F, 0x08, 0x3F, 0x57, 0x3F, 0x10, 0x3F, 0x3F, 0x29, 0x17, 0x52, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
3990a7ce71fSopenharmony_ci        0x57, 0x16, 0x3F, 0x7D, 0x4A, 0x0F, 0x3F, 0x3F, 0x3F, 0x30, 0x0C, 0x3F, 0x3F, 0x4C, 0x3F, 0x47
4000a7ce71fSopenharmony_ci    };
4010a7ce71fSopenharmony_ci    uint32_t manufacturekeyBufLen = sizeof(manufacturekeyBuf);
4020a7ce71fSopenharmony_ci    if (len < manufacturekeyBufLen) {
4030a7ce71fSopenharmony_ci        return EC_FAILURE;
4040a7ce71fSopenharmony_ci    }
4050a7ce71fSopenharmony_ci
4060a7ce71fSopenharmony_ci    int ret = memcpy_s(acKey, len, manufacturekeyBuf, manufacturekeyBufLen);
4070a7ce71fSopenharmony_ci    return ret;
4080a7ce71fSopenharmony_ci}
4090a7ce71fSopenharmony_ci
4100a7ce71fSopenharmony_ciint HalGetProdId(char *productId, unsigned int len)
4110a7ce71fSopenharmony_ci{
4120a7ce71fSopenharmony_ci    if ((productId == NULL) || (len == 0)) {
4130a7ce71fSopenharmony_ci        return EC_FAILURE;
4140a7ce71fSopenharmony_ci    }
4150a7ce71fSopenharmony_ci    const char productIdBuf[] = "OH00004O";
4160a7ce71fSopenharmony_ci    uint32_t productIdLen = strlen(productIdBuf);
4170a7ce71fSopenharmony_ci    if (len < productIdLen) {
4180a7ce71fSopenharmony_ci        return EC_FAILURE;
4190a7ce71fSopenharmony_ci    }
4200a7ce71fSopenharmony_ci
4210a7ce71fSopenharmony_ci    int ret = memcpy_s(productId, len, productIdBuf, productIdLen);
4220a7ce71fSopenharmony_ci    return ret;
4230a7ce71fSopenharmony_ci}
4240a7ce71fSopenharmony_ci
4250a7ce71fSopenharmony_ciint HalGetProdKey(char *productKey, unsigned int len)
4260a7ce71fSopenharmony_ci{
4270a7ce71fSopenharmony_ci    if ((productKey == NULL) || (len == 0)) {
4280a7ce71fSopenharmony_ci        return EC_FAILURE;
4290a7ce71fSopenharmony_ci    }
4300a7ce71fSopenharmony_ci    const char productKeyBuf[] = "test";
4310a7ce71fSopenharmony_ci    uint32_t productKeyLen = sizeof(productKeyBuf);
4320a7ce71fSopenharmony_ci    if (len < productKeyLen) {
4330a7ce71fSopenharmony_ci        return EC_FAILURE;
4340a7ce71fSopenharmony_ci    }
4350a7ce71fSopenharmony_ci
4360a7ce71fSopenharmony_ci    int ret = memcpy_s(productKey, len, productKeyBuf, productKeyLen);
4370a7ce71fSopenharmony_ci    return ret;
4380a7ce71fSopenharmony_ci}
4390a7ce71fSopenharmony_ci
440