1e656c62eSopenharmony_ci/* 2e656c62eSopenharmony_ci * Copyright (C) 2023 Huawei Technologies Co., Ltd. 3e656c62eSopenharmony_ci * Licensed under the Mulan PSL v2. 4e656c62eSopenharmony_ci * You can use this software according to the terms and conditions of the Mulan PSL v2. 5e656c62eSopenharmony_ci * You may obtain a copy of Mulan PSL v2 at: 6e656c62eSopenharmony_ci * http://license.coscl.org.cn/MulanPSL2 7e656c62eSopenharmony_ci * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR 8e656c62eSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR 9e656c62eSopenharmony_ci * PURPOSE. 10e656c62eSopenharmony_ci * See the Mulan PSL v2 for more details. 11e656c62eSopenharmony_ci */ 12e656c62eSopenharmony_ci 13e656c62eSopenharmony_ci#include "tcu_authentication.h" 14e656c62eSopenharmony_ci#include <unistd.h> 15e656c62eSopenharmony_ci#include <errno.h> /* for errno */ 16e656c62eSopenharmony_ci#include <fcntl.h> 17e656c62eSopenharmony_ci#include <sys/types.h> /* for open close */ 18e656c62eSopenharmony_ci#include <sys/ioctl.h> /* for ioctl */ 19e656c62eSopenharmony_ci#include <sys/stat.h> /* for stat */ 20e656c62eSopenharmony_ci#include <linux/limits.h> 21e656c62eSopenharmony_ci#include "securec.h" 22e656c62eSopenharmony_ci#include "tee_log.h" 23e656c62eSopenharmony_ci#include "tc_ns_client.h" 24e656c62eSopenharmony_ci#include "tee_client_type.h" 25e656c62eSopenharmony_ci 26e656c62eSopenharmony_ci#ifdef LOG_TAG 27e656c62eSopenharmony_ci#undef LOG_TAG 28e656c62eSopenharmony_ci#endif 29e656c62eSopenharmony_ci#define LOG_TAG "tcu_authentication" 30e656c62eSopenharmony_ci#define HASH_FILE_MAX_SIZE (16 * 1024) 31e656c62eSopenharmony_ci#define ERR_SIZE (-1) 32e656c62eSopenharmony_ci#define XML_HEADER 4 33e656c62eSopenharmony_ci#define MAX_HASHFILE_PATHLEN 256 34e656c62eSopenharmony_ci 35e656c62eSopenharmony_cistatic const char *g_vendorCaHashFileList[] = { 36e656c62eSopenharmony_ci "/vendor/etc/native_packages.xml", 37e656c62eSopenharmony_ci "/vendor/root/res/native_packages.xml", 38e656c62eSopenharmony_ci}; 39e656c62eSopenharmony_ci 40e656c62eSopenharmony_cistatic const char *g_systemCaHashFileList[] = { 41e656c62eSopenharmony_ci "/system/etc/native_packages.xml", 42e656c62eSopenharmony_ci}; 43e656c62eSopenharmony_ci 44e656c62eSopenharmony_cistatic const char **GetCaHashFileList(uint8_t *num, uint8_t hash_type) 45e656c62eSopenharmony_ci{ 46e656c62eSopenharmony_ci if (num == NULL) { 47e656c62eSopenharmony_ci tloge("input parameter error\n"); 48e656c62eSopenharmony_ci return NULL; 49e656c62eSopenharmony_ci } 50e656c62eSopenharmony_ci 51e656c62eSopenharmony_ci if (hash_type == HASH_TYPE_SYSTEM) { 52e656c62eSopenharmony_ci *num = sizeof(g_systemCaHashFileList) / sizeof(intptr_t); 53e656c62eSopenharmony_ci return g_systemCaHashFileList; 54e656c62eSopenharmony_ci } else { 55e656c62eSopenharmony_ci *num = sizeof(g_vendorCaHashFileList) / sizeof(intptr_t); 56e656c62eSopenharmony_ci return g_vendorCaHashFileList; 57e656c62eSopenharmony_ci } 58e656c62eSopenharmony_ci} 59e656c62eSopenharmony_ci 60e656c62eSopenharmony_cistatic int IsNotValidFname(const char *path) 61e656c62eSopenharmony_ci{ 62e656c62eSopenharmony_ci if (path == NULL) { 63e656c62eSopenharmony_ci tloge("filename is invalid ...\n"); 64e656c62eSopenharmony_ci return 1; 65e656c62eSopenharmony_ci } 66e656c62eSopenharmony_ci 67e656c62eSopenharmony_ci /* filter the .. dir in the pname: */ 68e656c62eSopenharmony_ci if (strstr(path, "..") != NULL) { 69e656c62eSopenharmony_ci tloge("filename should not include .. dir\n"); 70e656c62eSopenharmony_ci return 1; 71e656c62eSopenharmony_ci } 72e656c62eSopenharmony_ci 73e656c62eSopenharmony_ci return 0; 74e656c62eSopenharmony_ci} 75e656c62eSopenharmony_ci 76e656c62eSopenharmony_cistatic int GetFileSize(const char *path, int *realSize) 77e656c62eSopenharmony_ci{ 78e656c62eSopenharmony_ci FILE *fp = NULL; 79e656c62eSopenharmony_ci int ret; 80e656c62eSopenharmony_ci int fileSize = -1; 81e656c62eSopenharmony_ci int xmlHeader = 0; 82e656c62eSopenharmony_ci char realPath[PATH_MAX + 1] = { 0 }; 83e656c62eSopenharmony_ci 84e656c62eSopenharmony_ci bool paramInvlid = ((path == NULL) || (IsNotValidFname(path) != 0) || (strlen(path) > PATH_MAX) || 85e656c62eSopenharmony_ci (realpath(path, realPath) == NULL)); 86e656c62eSopenharmony_ci if (paramInvlid) { 87e656c62eSopenharmony_ci return fileSize; 88e656c62eSopenharmony_ci } 89e656c62eSopenharmony_ci 90e656c62eSopenharmony_ci fp = fopen(realPath, "r"); 91e656c62eSopenharmony_ci if (fp == NULL) { 92e656c62eSopenharmony_ci return fileSize; 93e656c62eSopenharmony_ci } 94e656c62eSopenharmony_ci 95e656c62eSopenharmony_ci ret = fseek(fp, 0L, SEEK_END); 96e656c62eSopenharmony_ci if (ret < 0) { 97e656c62eSopenharmony_ci fclose(fp); 98e656c62eSopenharmony_ci fp = NULL; 99e656c62eSopenharmony_ci return fileSize; 100e656c62eSopenharmony_ci } 101e656c62eSopenharmony_ci 102e656c62eSopenharmony_ci fileSize = (int)ftell(fp); 103e656c62eSopenharmony_ci 104e656c62eSopenharmony_ci ret = fseek(fp, 0L, SEEK_SET); 105e656c62eSopenharmony_ci if (ret < 0 || fileSize < XML_HEADER) { 106e656c62eSopenharmony_ci fclose(fp); 107e656c62eSopenharmony_ci fp = NULL; 108e656c62eSopenharmony_ci return ERR_SIZE; 109e656c62eSopenharmony_ci } 110e656c62eSopenharmony_ci int len = (int)fread(&xmlHeader, 1, sizeof(int), fp); 111e656c62eSopenharmony_ci if (len != sizeof(int) || xmlHeader < fileSize) { 112e656c62eSopenharmony_ci tloge("size read is invalid\n"); 113e656c62eSopenharmony_ci fclose(fp); 114e656c62eSopenharmony_ci fp = NULL; 115e656c62eSopenharmony_ci return ERR_SIZE; 116e656c62eSopenharmony_ci } 117e656c62eSopenharmony_ci 118e656c62eSopenharmony_ci (void)fclose(fp); 119e656c62eSopenharmony_ci fp = NULL; 120e656c62eSopenharmony_ci *realSize = fileSize; 121e656c62eSopenharmony_ci return xmlHeader; 122e656c62eSopenharmony_ci} 123e656c62eSopenharmony_ci 124e656c62eSopenharmony_cistatic int GetFileInfo(int bufLen, uint8_t *buffer, const char *path) 125e656c62eSopenharmony_ci{ 126e656c62eSopenharmony_ci FILE *fp = NULL; 127e656c62eSopenharmony_ci int fileSize; 128e656c62eSopenharmony_ci char realPath[PATH_MAX + 1] = { 0 }; 129e656c62eSopenharmony_ci 130e656c62eSopenharmony_ci bool paramInvlid = ((buffer == NULL) || (path == NULL) || (IsNotValidFname(path) != 0) || 131e656c62eSopenharmony_ci (strlen(path) > PATH_MAX) || (realpath(path, realPath) == NULL) || 132e656c62eSopenharmony_ci (bufLen == 0)); 133e656c62eSopenharmony_ci if (paramInvlid) { 134e656c62eSopenharmony_ci return -1; 135e656c62eSopenharmony_ci } 136e656c62eSopenharmony_ci 137e656c62eSopenharmony_ci fp = fopen(realPath, "rb"); 138e656c62eSopenharmony_ci if (fp == NULL) { 139e656c62eSopenharmony_ci tloge("open file failed\n"); 140e656c62eSopenharmony_ci return -1; 141e656c62eSopenharmony_ci } 142e656c62eSopenharmony_ci 143e656c62eSopenharmony_ci fileSize = (int)fread(buffer, sizeof(char), (unsigned int)bufLen, fp); 144e656c62eSopenharmony_ci if (fileSize != bufLen) { 145e656c62eSopenharmony_ci tloge("read file read number:%d\n", fileSize); 146e656c62eSopenharmony_ci fclose(fp); 147e656c62eSopenharmony_ci fp = NULL; 148e656c62eSopenharmony_ci return -1; 149e656c62eSopenharmony_ci } 150e656c62eSopenharmony_ci 151e656c62eSopenharmony_ci (void)fclose(fp); 152e656c62eSopenharmony_ci fp = NULL; 153e656c62eSopenharmony_ci return 0; 154e656c62eSopenharmony_ci} 155e656c62eSopenharmony_ci 156e656c62eSopenharmony_cistatic uint8_t *InitTempBuf(int bufLen) 157e656c62eSopenharmony_ci{ 158e656c62eSopenharmony_ci errno_t ret; 159e656c62eSopenharmony_ci uint8_t *buffer = NULL; 160e656c62eSopenharmony_ci 161e656c62eSopenharmony_ci bool variablesCheck = ((bufLen <= 0) || (bufLen > HASH_FILE_MAX_SIZE)); 162e656c62eSopenharmony_ci if (variablesCheck) { 163e656c62eSopenharmony_ci tloge("wrong buflen\n"); 164e656c62eSopenharmony_ci return buffer; 165e656c62eSopenharmony_ci } 166e656c62eSopenharmony_ci 167e656c62eSopenharmony_ci buffer = (uint8_t *)malloc((unsigned int)bufLen); 168e656c62eSopenharmony_ci if (buffer == NULL) { 169e656c62eSopenharmony_ci tloge("malloc failed!\n"); 170e656c62eSopenharmony_ci return buffer; 171e656c62eSopenharmony_ci } 172e656c62eSopenharmony_ci 173e656c62eSopenharmony_ci ret = memset_s(buffer, (unsigned int)bufLen, 0, (unsigned int)bufLen); 174e656c62eSopenharmony_ci if (ret != EOK) { 175e656c62eSopenharmony_ci tloge("memset failed!\n"); 176e656c62eSopenharmony_ci free(buffer); 177e656c62eSopenharmony_ci buffer = NULL; 178e656c62eSopenharmony_ci return buffer; 179e656c62eSopenharmony_ci } 180e656c62eSopenharmony_ci 181e656c62eSopenharmony_ci return buffer; 182e656c62eSopenharmony_ci} 183e656c62eSopenharmony_ci 184e656c62eSopenharmony_cistatic uint8_t *ReadXmlFile(const char *xmlFile) 185e656c62eSopenharmony_ci{ 186e656c62eSopenharmony_ci int ret; 187e656c62eSopenharmony_ci int bufLen; 188e656c62eSopenharmony_ci uint8_t *buffer = NULL; 189e656c62eSopenharmony_ci int realSize = 0; 190e656c62eSopenharmony_ci 191e656c62eSopenharmony_ci bufLen = GetFileSize(xmlFile, &realSize); 192e656c62eSopenharmony_ci buffer = InitTempBuf(bufLen); 193e656c62eSopenharmony_ci if (buffer == NULL) { 194e656c62eSopenharmony_ci tloge("init temp buffer failed\n"); 195e656c62eSopenharmony_ci return buffer; 196e656c62eSopenharmony_ci } 197e656c62eSopenharmony_ci 198e656c62eSopenharmony_ci ret = GetFileInfo(realSize, buffer, xmlFile); 199e656c62eSopenharmony_ci if (ret != 0) { 200e656c62eSopenharmony_ci tloge("get xml file info failed\n"); 201e656c62eSopenharmony_ci free(buffer); 202e656c62eSopenharmony_ci buffer = NULL; 203e656c62eSopenharmony_ci return buffer; 204e656c62eSopenharmony_ci } 205e656c62eSopenharmony_ci 206e656c62eSopenharmony_ci return buffer; 207e656c62eSopenharmony_ci} 208e656c62eSopenharmony_ci 209e656c62eSopenharmony_cistatic int TeeSetNativeCaHash(const char *xmlFlie) 210e656c62eSopenharmony_ci{ 211e656c62eSopenharmony_ci int ret; 212e656c62eSopenharmony_ci int fd = -1; 213e656c62eSopenharmony_ci uint8_t *buffer = NULL; 214e656c62eSopenharmony_ci 215e656c62eSopenharmony_ci buffer = ReadXmlFile(xmlFlie); 216e656c62eSopenharmony_ci if (buffer == NULL) { 217e656c62eSopenharmony_ci tloge("read xml file failed\n"); 218e656c62eSopenharmony_ci return fd; 219e656c62eSopenharmony_ci } 220e656c62eSopenharmony_ci 221e656c62eSopenharmony_ci fd = open(TC_PRIVATE_DEV_NAME, O_RDWR); 222e656c62eSopenharmony_ci if (fd < 0) { 223e656c62eSopenharmony_ci tloge("Failed to open dev node: %d\n", errno); 224e656c62eSopenharmony_ci free(buffer); 225e656c62eSopenharmony_ci buffer = NULL; 226e656c62eSopenharmony_ci return -1; 227e656c62eSopenharmony_ci } 228e656c62eSopenharmony_ci ret = ioctl(fd, (int)(TC_NS_CLIENT_IOCTL_SET_NATIVE_IDENTITY), buffer); 229e656c62eSopenharmony_ci if (ret != 0) { 230e656c62eSopenharmony_ci tloge("ioctl fail %d\n", ret); 231e656c62eSopenharmony_ci } 232e656c62eSopenharmony_ci 233e656c62eSopenharmony_ci free(buffer); 234e656c62eSopenharmony_ci buffer = NULL; 235e656c62eSopenharmony_ci close(fd); 236e656c62eSopenharmony_ci fd = -1; 237e656c62eSopenharmony_ci return ret; 238e656c62eSopenharmony_ci} 239e656c62eSopenharmony_ci 240e656c62eSopenharmony_cistatic bool IsFileExist(const char *name) 241e656c62eSopenharmony_ci{ 242e656c62eSopenharmony_ci struct stat statbuf; 243e656c62eSopenharmony_ci 244e656c62eSopenharmony_ci if (name == NULL) { 245e656c62eSopenharmony_ci return false; 246e656c62eSopenharmony_ci } 247e656c62eSopenharmony_ci if (stat(name, &statbuf) != 0) { 248e656c62eSopenharmony_ci if (errno == ENOENT) { /* file not exist */ 249e656c62eSopenharmony_ci tlogi("file not exist: %s\n", name); 250e656c62eSopenharmony_ci return false; 251e656c62eSopenharmony_ci } 252e656c62eSopenharmony_ci return true; 253e656c62eSopenharmony_ci } 254e656c62eSopenharmony_ci 255e656c62eSopenharmony_ci return true; 256e656c62eSopenharmony_ci} 257e656c62eSopenharmony_ci 258e656c62eSopenharmony_ciint TcuAuthentication(uint8_t hash_type) 259e656c62eSopenharmony_ci{ 260e656c62eSopenharmony_ci uint8_t listLen; 261e656c62eSopenharmony_ci const char **hashFileList = GetCaHashFileList(&listLen, hash_type); 262e656c62eSopenharmony_ci if (hashFileList == NULL) { 263e656c62eSopenharmony_ci tloge("get hashFileList failed\n"); 264e656c62eSopenharmony_ci return -1; 265e656c62eSopenharmony_ci } 266e656c62eSopenharmony_ci if (listLen == 0) { 267e656c62eSopenharmony_ci tloge("list num is 0, please set hashfile\n"); 268e656c62eSopenharmony_ci return -1; 269e656c62eSopenharmony_ci } 270e656c62eSopenharmony_ci static int gHashXmlSetted; 271e656c62eSopenharmony_ci uint8_t count = 0; 272e656c62eSopenharmony_ci if (gHashXmlSetted == 0) { 273e656c62eSopenharmony_ci for (uint8_t index = 0; index < listLen; index++) { 274e656c62eSopenharmony_ci if (hashFileList[index] == NULL) { 275e656c62eSopenharmony_ci tloge("get hashFile failed, index is %d\n", index); 276e656c62eSopenharmony_ci continue; 277e656c62eSopenharmony_ci } 278e656c62eSopenharmony_ci if (!IsFileExist(hashFileList[index])) { 279e656c62eSopenharmony_ci continue; 280e656c62eSopenharmony_ci } 281e656c62eSopenharmony_ci 282e656c62eSopenharmony_ci int setRet = TeeSetNativeCaHash(hashFileList[index]); 283e656c62eSopenharmony_ci if (setRet != 0) { 284e656c62eSopenharmony_ci tloge("hashfile read failed, index is %d\n", index); 285e656c62eSopenharmony_ci continue; 286e656c62eSopenharmony_ci } 287e656c62eSopenharmony_ci count++; 288e656c62eSopenharmony_ci } 289e656c62eSopenharmony_ci } 290e656c62eSopenharmony_ci 291e656c62eSopenharmony_ci if (count == listLen) { 292e656c62eSopenharmony_ci gHashXmlSetted = 1; 293e656c62eSopenharmony_ci return 0; 294e656c62eSopenharmony_ci } 295e656c62eSopenharmony_ci 296e656c62eSopenharmony_ci return -1; 297e656c62eSopenharmony_ci}