Project import generated by Copybara.
GitOrigin-RevId: abbc95b6c8806446e86dc701509e6afbda80f8e3
diff --git a/cmd/amlogic/ini/UnifyKey.c b/cmd/amlogic/ini/UnifyKey.c
new file mode 100644
index 0000000..b953672
--- /dev/null
+++ b/cmd/amlogic/ini/UnifyKey.c
@@ -0,0 +1,482 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#include "ini_config.h"
+
+#define LOG_TAG "UnifyKey"
+#define LOG_NDEBUG 0
+
+#include "ini_log.h"
+#include "UnifyKey.h"
+#include "ini_size_define.h"
+
+#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_no_header(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 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_no_header(const char *key_name, unsigned char data_buf[], int rd_size) {
+ int ret = 0, key_len = 0;
+
+ 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;
+ }
+
+ ret = key_unify_read(key_name, data_buf, key_len);
+ if (ret) {
+ ALOGE("%s, %s unify read error\n",__FUNCTION__, key_name);
+ return -1;
+ }
+
+ 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