/*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
* *
This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* *
This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* *
You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* *
Description:
*/


#include "ini_config.h"

#define LOG_TAG "UnifyKey"
#define LOG_NDEBUG 0

#include "ini_log.h"

#include "UnifyKey.h"

#define CC_ONE_SECTION_SIZE                      (0x1000)

#if (defined (CC_INI_IO_USE_UNIFY_KEY))

#if (!defined (CC_INI_IO_UKEY_USE_OTHER_MODULE))

#if (defined(CC_COMPILE_IN_PC) || defined(CC_COMPILE_IN_ANDROID))

#if (defined CC_COMPILE_IN_PC)

#define CS_KEY_DATA_LIST_DEV_PATH                   "sys/class/unifykeys/list"
#define CS_KEY_DATA_NAME_DEV_PATH                   "sys/class/unifykeys/name"

static char gDevPath[256] = {0};
static int GetDevPath(char path_buf[]) {
    int tmp_len = 0;
    FILE *dev_fp = NULL;

    strcpy(path_buf, "sys/class/unifykeys/");
    dev_fp = fopen(CS_KEY_DATA_NAME_DEV_PATH, "r");
    if (dev_fp == NULL) {
        ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
                CS_KEY_DATA_NAME_DEV_PATH, strerror(errno));
        return -1;
    }

    tmp_len = strlen(path_buf);
    fscanf(dev_fp, "%s", path_buf + tmp_len);

    fclose(dev_fp);
    dev_fp = NULL;

    return 0;
}

static const char *GetKeyDataWriteDevPath() {
    memset((void *)gDevPath, 0, 256);
    GetDevPath(gDevPath);
    return gDevPath;
}

static const char *GetKeyDataReadDevPath() {
    memset((void *)gDevPath, 0, 256);
    GetDevPath(gDevPath);
    return gDevPath;
}

#else

#define CS_KEY_DATA_LIST_DEV_PATH                   "/sys/class/unifykeys/list"
#define CS_KEY_DATA_NAME_DEV_PATH                   "/sys/class/unifykeys/name"

static const char *GetKeyDataWriteDevPath() {
    return "/sys/class/unifykeys/write";
}

static const char *GetKeyDataReadDevPath() {
    return "/sys/class/unifykeys/read";
}

#endif //CC_COMPILE_IN_PC

static int checkKeyNameInList(const char *key_name) {
    FILE *dev_fp = NULL;
    char *tmp_ptr = NULL;
    char lineStr[1024];

    dev_fp = fopen(CS_KEY_DATA_LIST_DEV_PATH, "r");
    if (dev_fp == NULL) {
        ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
                CS_KEY_DATA_LIST_DEV_PATH, strerror(errno));
        return -1;
    }

    while (fgets(lineStr, 1024, dev_fp) != NULL) {
        tmp_ptr = strstr(lineStr, key_name);
        if (tmp_ptr != NULL) {
            break;
        }

        tmp_ptr = NULL;
    }

    fclose(dev_fp);
    dev_fp = NULL;

    if (tmp_ptr == NULL) {
        return -1;
    }

    return 0;
}

int readUKeyData(const char *key_name, unsigned char data_buf[], int rd_size) {
    int rd_cnt = 0;
    FILE *dev_fp = NULL;

    if (checkKeyNameInList(key_name) < 0) {
        ALOGE("%s, key \"%s\" isn't exist in unifykeys list\n", __FUNCTION__, key_name);
        return -1;
    }

    dev_fp = fopen(CS_KEY_DATA_NAME_DEV_PATH, "w");
    if (dev_fp == NULL) {
        ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
                CS_KEY_DATA_NAME_DEV_PATH, strerror(errno));
        return -1;
    }

    fprintf(dev_fp, "%s", key_name);

    fclose(dev_fp);
    dev_fp = NULL;

    int mode = 1;

    if (mode == 0) {
        dev_fp = fopen(GetKeyDataReadDevPath(), "r");
        if (dev_fp == NULL) {
            ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
                    GetKeyDataReadDevPath(), strerror(errno));
            return -1;
        }

        fscanf(dev_fp, "%s", data_buf);
        rd_cnt = strlen((char *) data_buf);
    } else {
        dev_fp = fopen(GetKeyDataReadDevPath(), "rb");
        if (dev_fp == NULL) {
            ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
                    GetKeyDataReadDevPath(), strerror(errno));
            return -1;
        }

        rd_cnt = fread(data_buf, 1, CC_ONE_SECTION_SIZE, dev_fp);
    }

    fclose(dev_fp);
    dev_fp = NULL;

    return rd_cnt;
}

int writeUKeyData(const char *key_name, unsigned char data_buf[], int wr_size) {
    int wr_cnt = 0;
    int dev_fd = -1;
    FILE *dev_fp = NULL;

    if (checkKeyNameInList(key_name) < 0) {
        ALOGE("%s, key \"%s\" isn't exist in unifykeys list\n", __FUNCTION__, key_name);
        return -1;
    }

    dev_fp = fopen(CS_KEY_DATA_NAME_DEV_PATH, "w");
    if (dev_fp == NULL) {
        ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
                CS_KEY_DATA_NAME_DEV_PATH, strerror(errno));
        return -1;
    }

    fprintf(dev_fp, "%s", key_name);

    fclose(dev_fp);
    dev_fp = NULL;

    dev_fd = open(GetKeyDataWriteDevPath(), O_WRONLY | O_SYNC | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);

    if (dev_fd < 0) {
        ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
                GetKeyDataWriteDevPath(), strerror(errno));
        return -1;
    }

    wr_cnt = write(dev_fd, data_buf, wr_size);

    fsync(dev_fd);

    close(dev_fd);
    dev_fd = -1;

    return wr_cnt;
}

#elif (defined CC_COMPILE_IN_UBOOT)

#include "model.h"

#define CC_UKEY_RETRY_CNT_MAX   (5)

static int checkUnifyKey(const char *key_name) {
    int ret = 0, key_exist = 0, isSecure = 0;
    unsigned int key_len = 0;
    ssize_t key_size = 0;

    // start check the key is exist?
    ret = key_unify_query_exist(key_name, &key_exist);
    if (ret) {
        ALOGE("%s, %s query exist error.\n",__FUNCTION__, key_name);
        return -1;
    }
    if (key_exist == 0) {
        ALOGE("%s, %s is not exist.\n",__FUNCTION__, key_name);
        return -1;
    }
    // end check the key is exist?

    // start check the key is secure?
    ret = key_unify_query_secure(key_name, &isSecure);
    if (ret) {
        ALOGE("%s, %s query secure error\n",__FUNCTION__, key_name);
        return -1;
    }
    if (isSecure) {
        ALOGE("%s, %s is secure key\n",__FUNCTION__, key_name);
        return -1;
    }
    // end check the key is secure?

    // start read and check data integrity
    ret = key_unify_query_size(key_name, &key_size);
    if (ret) {
        ALOGE("%s, %s query size error\n",__FUNCTION__, key_name);
        return -1;
    }
    //ALOGD("%s, %s size: %d\n",__FUNCTION__, key_name, (int)key_size);

    key_len = (int)key_size;
    //ALOGD("%s, %s size: %d\n",__FUNCTION__, key_name, key_len);

    return key_len;
}

int readUKeyData(const char *key_name, unsigned char data_buf[], int rd_size) {
    int i = 0, ret = 0, key_len = 0, retry_cnt = 0, tmp_content_type = 0;
    unsigned int key_crc = 0, key_crc32 = 0, tmp_len = 0, tmp_crc = 0;
    struct all_info_header_s *pHeadPtr = NULL;

    key_len = checkUnifyKey(key_name);
    if (key_len < 0) {
        return -1;
    } else if (key_len == 0) {
        ALOGE("%s, %s size is zero\n",__FUNCTION__, key_name);
        return -1;
    } else if (key_len > rd_size) {
        ALOGE("%s, %s key len is larger than rd size.\n",__FUNCTION__, key_name);
        return -1;
    }

unifykey_read:
    ret = key_unify_read(key_name, data_buf, key_len);
    if (ret) {
        ALOGE("%s, %s unify read error\n",__FUNCTION__, key_name);
        return -1;
    }

    //judge unfikey data type, default is binary data
    tmp_content_type = 0;
    for (i = 0; i < 14; i++) {
        if (i < 8 || (i > 9 && i < 13)) {
            if (!isxdigit(data_buf[i])) {
                break;
            }
        } else if (i == 8 || i == 13) {
            if (data_buf[i] != ',') {
                break;
            }
        } else if (i == 9) {
            if (data_buf[i] != 'V' && data_buf[i] != 'v') {
                break;
            }
        }
    }

    if (i == 14) {
        tmp_content_type = 1;
    }

    tmp_crc = 0;
    tmp_len = 0;
    if (tmp_content_type == 0) {
        pHeadPtr = (struct all_info_header_s *)(data_buf);
        tmp_crc = pHeadPtr->crc32;
        tmp_len = pHeadPtr->data_len;
    } else {
        return key_len;
    }

    if (key_len != tmp_len) {
        ALOGE("%s, %s data_len %d is not match key_len %d\n",__FUNCTION__,
            key_name, tmp_len, key_len);
        if (retry_cnt < CC_UKEY_RETRY_CNT_MAX) {
            retry_cnt++;
            goto unifykey_read;
        } else {
            ALOGE("%s, %s load unifykey failed\n",__FUNCTION__, key_name);
            return -1;
        }
    }

    key_crc = crc32(0, &data_buf[4], (key_len - 4)); //except crc32
    key_crc32 = (unsigned int)key_crc;
    if (key_crc32 != tmp_crc) {
        ALOGE("%s, %s crc32 0x%08x is not match 0x%08x\n",__FUNCTION__,
            key_name, tmp_crc, key_crc32);
        if (retry_cnt < CC_UKEY_RETRY_CNT_MAX) {
            retry_cnt++;
            goto unifykey_read;
        } else {
            ALOGE("%s, %s load unifykey failed\n",__FUNCTION__, key_name);
            return -1;
        }
    }
    // end read and check data integrity

    return key_len;
}

int writeUKeyData(const char *key_name, unsigned char data_buf[], int wr_size) {
    // if the key is not burn data, the fucntion will return fail
    // now we disable the unifykey check function.
/*
    int key_len = 0;

    key_len = checkUnifyKey(key_name);
    if (key_len < 0) {
        return -1;
    }
*/
    if (key_unify_write(key_name, data_buf, wr_size) == 0) {
        return wr_size;
    }
    return -1;
}

#endif

#endif

#if (defined CC_UBOOT_RW_SIMULATE)

#include "ini_io.h"

unsigned int crc32(unsigned int crc, const unsigned char *ptr, int buf_len) {
    return CalCRC32(crc, ptr, buf_len);
}

static unsigned char gTempBuf[0x400000];

int key_unify_write(const char* keyname, const void* keydata, const unsigned datalen) {
    int tmp_ret = 0;

    tmp_ret = writeUKeyData(keyname, (unsigned char *)keydata, datalen);
    if (tmp_ret != datalen) {
        return -1;
    }
    return 0;
}

int key_unify_read(const char* keyname, void* keydata, const unsigned bufLen) {
    if (readUKeyData(keyname, (unsigned char *)keydata, CC_ONE_SECTION_SIZE) <= 0) {
        return -1;
    }

    return 0;
}

int key_unify_query_size(const char* keyname, ssize_t *keysize) {
    int rd_size = 0;

    rd_size = readUKeyData(keyname, gTempBuf, CC_ONE_SECTION_SIZE);
    if (rd_size > 0) {
        *keysize = rd_size;
        return 0;
    }

    return -1;
}

int key_unify_query_exist(const char* keyname, int *exist) {
    if (checkKeyNameInList(keyname) < 0) {
        ALOGE("%s, key \"%s\" isn't exist in unifykeys list\n", __FUNCTION__, keyname);
        *exist = 0;
        return -1;
    }

    *exist = 1;
    return 0;
}

int key_unify_query_secure(const char* keyname, int *isSecure) {
    *isSecure = 0;
    return 0;
}

#endif

#endif //CC_INI_IO_UKEY_USE_OTHER_MODULE
