security_huks模块下hks_file.c代码评注
本篇综述
hks_file.c是隶属于在soft_sevice目录下的,对文件系统操作函数定义的一个文件,其中包含了一下函数:文件注册回调、文件读取函数(字节上)、读取文件大小函数(存储上)、文件写入函数、文件数据初始化函数以及安全删除文件函数。
它的具体目录为: security_huks\frameworks\huks_lite\source\hw_keystore_sdk\soft_service\hks_file.h
下面就让我们开始本段代码的解读吧!
关键代码架构
hks_client.c
├── include
│ └── "hks_file.h"
│ └── "common/hks_common.h"
│ └── "hks_mem.h"
│ └── "hks_errno.h"
├── functions
│ └── hks_file_register_callbacks
│ └── hks_file_read
│ └── hks_file_write
│ └── hks_file_size
│ └── hks_file_init_data
│ └── hks_file_del_s
关键先导
在hks_file.c中,许多函数内都有调用security模块下的别的文件中的函数,本节会先列举一些重要的内容,方便后面对hks_file.c关键代码的解读。
1. 结构体 hks_file_callbacks
结构体 hks_file_callbacks的原始定义在"hks_file_api.h"中,其中具体存放(获取)的信息有三类,分别是:
- read 从文件或flash播放器中读取数据
- write 向文件或flash播放器中写入数据
- file_size 获得文件的大小
详细代码及注释如下:
struct hks_file_callbacks {
/*
* Read data from file or flash 从文件或flash播放器中读取数据
*
* filename: The path name of the file 文件的路径名
* offset: param reserved for future use 保留给将来使用的参数
* buf: The buffer used to store the content readed from the file 用来存储从文件中读取的内容的缓冲区
* len: The size count in buffer trying to read from the file 缓冲区中试图从文件中读取的大小计数
* return < 0 read error, return > 0 real read length,
* return == 0 secret key information does not exist in storage media
返回< 0读错误,返回> 0实际读长度,返回== 0密钥信息在存储介质中不存在
*/
int32_t (*read)(const char *file_name, uint32_t offset,
uint8_t *buf, uint32_t len);
/* 功能:将缓冲区buf下的内容写到名为file_name的地址下
* Write data into file or flash 向文件或flash播放器中写入数据
*
* filename: The path name of the file
* offset: param reserved for future use
* buf: The content which you want write into the file 你想要的写入文件的内容
* len: The size of the content 内容的大小
* return == 0 write ok, return < 0 other error 返回==0成功写入,返回<0其他错误
*/
int32_t (*write)(const char *file_name, uint32_t offset,
const uint8_t *buf, uint32_t len);
/*
* Get file size 获得文件的大小
*
* filename: The path name of the file
* return < 0 error, >= 0 The size of the file 返回<0其他错误,返回>=0则返回值代表文件大小
* flash can return a fixed value of 4096 flash可以返回一个固定值4096
*/
int32_t (*file_size)(const char *file_name);
};
2. 函数 hks_init_buf_data
该函数的作用是初始化缓冲区数据,初始化数据选择,可以是全0,全1或者随机。
传入的参数:data_type是数据类型,buf是存放数据的缓冲区,buf_len是预计初始化数据的长度。
返回值rc代表hks执行的状态,HKS_STATUS_OK表示成功执行。
具体代码如下:
/*
* initialize buffer data 初始化缓冲区数据
* parameter:
* data_type - [in] - data type
* buf - [out] - buffer
* buf_len - [in] - the length of buffer
* return value:
* success or error code
*/
//初始化数据选择,可以是全0,全1或者随机
//data_type是数据类型,buf是存放数据的缓冲区,buf_len是预计初始化数据的长度
int32_t hks_init_buf_data(uint8_t data_type, uint8_t *buf, uint32_t buf_len)
{
int32_t rc = hks_chk_init_buf_data_para(data_type, buf, buf_len);
if (rc != HKS_STATUS_OK)
return rc;
if (data_type == HKS_INIT_DATA_TYPE_ALL_ZERO) {
/* all zero */
(void)memset_s(buf, buf_len, 0, buf_len);
} else if (data_type == HKS_INIT_DATA_TYPE_ALL_ONE) {
/* all one */
(void)memset_s(buf, buf_len, 0xFF, buf_len);
} else {
/* random data */
rc = hks_gen_random(buf, buf_len);
}
return rc;
}
其中memset_s函数和hks_gen_random函数的意义是申请初始化缓冲区buf,将其中内容设置为选择的全零或全1或随机数,hks_gen_random的函数原型如下:
/*
* generate random number
* parameter:
* random - [out] - the buffer of random number.
* len - [in] - the length of random number.
* return value:
* success or error code
*/
int32_t hks_gen_random(uint8_t *random, uint32_t len)
{
if (random == NULL) {
log_error("invalid random");
return HKS_ERROR_NULL_POINTER;
}
if ((len == 0) || (len > HKS_RANDOM_MAX_LEN)) {
log_error("invalid len=%u", len);
return HKS_ERROR_INVALID_ARGUMENT;
}
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_context entropy;
(void)memset_s(&ctr_drbg, sizeof(ctr_drbg), 0, sizeof(ctr_drbg));
mbedtls_entropy_init(&entropy);
int ret = HKS_SUCCESS;
/* use the g_hks_random_seed_custom without string terminator */
int32_t rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
&entropy, g_hks_random_seed_custom,
sizeof(g_hks_random_seed_custom));
if (rc != HKS_STATUS_OK) {
log_error("ctr drbg seed fail,rc=%d", rc);
ret = HKS_ERROR_INTERNAL_UNKOWN;
goto exit;
}
rc = mbedtls_ctr_drbg_random(&ctr_drbg, random, len);
if (rc != HKS_STATUS_OK) {
log_error("ctr drbg random fail,rc=%d", rc);
ret = HKS_ERROR_INTERNAL_UNKOWN;
}
exit:
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
return ret;
}
3. 空间的申请与释放
空间的申请与释放是文件操作中不可缺少的一环,该部分的定义在hks_mem.h中都已预编译过了,代码如下:
/* redefine calloc & free, replace it for hilink */
#define HKS_MALLOC malloc
#define HKS_CALLOC calloc
#define HKS_FREE free
//已申请空间的释放
#define hks_free_ptr(p) { if ((p) != NULL) { HKS_FREE(p); (p) = NULL; }}
hks_file.c中关键函数
1. hks_file_register_callbacks
hks_file_register_callbacks函数的功能在hks文件注册回调,其中传入的参数就为导入的结构体hks_file_callbacks 指针变量callbacks,具体的代码注解如下:
//HKS文件注册回调
int32_t hks_file_register_callbacks(const struct hks_file_callbacks *callbacks)
{
hks_if_true_return_error((callbacks == NULL), HKS_ERROR_NULL_POINTER);
hks_if_true_return_error((callbacks->read == NULL ||
callbacks->write == NULL || callbacks->file_size == NULL),
HKS_ERROR_NULL_POINTER);
//重新生成一个g_file_callbacks文件,并把对应信息写入
g_file_callbacks.file_size = callbacks->file_size;
g_file_callbacks.read = callbacks->read;
g_file_callbacks.write = callbacks->write;
return HKS_STATUS_OK;
}
2. hks_file_read
hks_file_read函数的功能为hks文件读取字节大小,该函数的传入参数为:文件名,偏移量,缓冲区,缓冲区长度(大小),以及文件长度(大小),返回值为hks状态,并且在函数执行过程中文件真实长度存放如len指针中,具体的代码注解如下:
//hks文件读取函数(字节上),返回值为hks状态
//需要导入文件名,偏移量,缓冲区,缓冲区长度(大小),以及文件长度(大小)
int32_t hks_file_read(const char *file_name, uint32_t offset, uint8_t *buf,
uint32_t buf_len, int32_t *len)
{
//real_len中存放入去文件真实长度的信息
int32_t real_len;
//检查回调文件和传入参数是否为空
if ((g_file_callbacks.read == NULL) || (file_name == NULL) || (buf == NULL) || (len == NULL))
return HKS_ERROR_NULL_POINTER;
//real_len>0则把文件真实长度存放如len指针中
real_len = g_file_callbacks.read(file_name, offset, buf, buf_len);
if (real_len < 0)
return HKS_ERROR_READ_FILE_FAIL;
else
*len = real_len;
return HKS_STATUS_OK;
}
3. hks_file_write
hks_file_write函数的功能在于向文件写入信息,传入参数为文件名(地址)、文件偏移量、缓冲区地址,即将buf中存放的内容分写入file_name地址下,返回值为hks转态信息,具体的代码注解如下:
//hks文件写入函数,功能:把返回值也是hks状态
int32_t hks_file_write(const char *file_name, uint32_t offset, const uint8_t *buf,
uint32_t len)
{
//status中存放是否成功写入的信息
int32_t status;
if ((g_file_callbacks.write == NULL) || (file_name == NULL) || (buf == NULL))
return HKS_ERROR_NULL_POINTER;
//状态量status只可能是写入成功(0)或者不成功(非0)
status = g_file_callbacks.write(file_name, offset, buf, len);
if (status != 0)
return HKS_ERROR_WRITE_FILE_FAIL;
else
return HKS_STATUS_OK;
}
4. hks_file_size
hks_file_size函数的功能在于读取文件在存储上的大小,如果文件正常且内容不为空则把文件存储大小存放在file_size指针下,并且返回HKS_STATUS_OK,否则会返回hks转态错误的信息,具体的代码注解如下:
//hks读取文件大小函数(存储上)
int32_t hks_file_size(const char *file_name, uint32_t *size)
{
//file_size中存放所获得的文件大小
int file_size;
if ((g_file_callbacks.file_size == NULL) || (file_name == NULL) || (size == NULL))
return HKS_ERROR_NULL_POINTER;
//file_size>=0则将文件的大小存入size指针中
file_size = g_file_callbacks.file_size(file_name);
if (file_size < 0)
return HKS_ERROR_FILE_SIZE_FAIL;
*size = file_size;
return HKS_STATUS_OK;
}
5. hks_file_init_data
hks_file_init_data函数的功能在于文件数据初始化,传入参数为文件名、文件大小、数据类型。其中,开辟缓冲内存大小在一开始定义为1024个字节,即:#define HKS_FILE_IO_SIZE_MAX 1024
,详细的代码注解如下:
//hks文件数据初始化函数,传入参数:文件名、文件大小、数据类型
static int32_t hks_file_init_data(const char *file_name, uint32_t file_size,
uint8_t data_type)
{
//开辟存取文件的内存空间,大小为1024字节
uint8_t *file_buf = (uint8_t *)HKS_MALLOC(HKS_FILE_IO_SIZE_MAX);
//判断是否成功申请到空间
if (file_buf == NULL) {
log_error("malloc file buffer fail");
return HKS_ERROR_MALLOC_FAIL;
}
int32_t rc = 0; //当前文件大小
uint32_t offset = 0; //偏移量
uint32_t write_len; //写入长度
//按照IO块来写入文件,且每次写入大小不超过1024字节
while (offset < file_size) {
if ((offset + HKS_FILE_IO_SIZE_MAX) < file_size)
write_len = HKS_FILE_IO_SIZE_MAX;
else
write_len = file_size - offset;
//rc为初始化后(表示是否成功)的状态,初始化的内容写在file_buf中
rc = hks_init_buf_data(data_type, file_buf, write_len);
if (rc != HKS_STATUS_OK)
break;
//rc表示文件写入操作状态,把file_buf中初始化的内容写入file_name指针下
rc = hks_file_write(file_name, offset, file_buf, write_len);
if (rc != HKS_STATUS_OK)
break;
//设置文件的偏移量
offset += write_len;
}
//将创建的初始化文件缓冲区内存释放
hks_free_ptr(file_buf);
//返回值是最终文件内容初始化状态
return rc;
}
6. hks_file_del_s
hks_file_del_s函数的功能是安全删除文件,且将文件内容恢复成初始化后的状态,导入参数为文件名(文件存放地址),值得注意的是:设置初始化数据类型数组,可通过选择0, 1, 2分别代表其中初始化数据的类型,详细注解代码如下:
//安全删除文件函数,且将文件内容恢复成初始化后的状态。导入参数为文件名(文件存放地址)
void hks_file_del_s(const char *file_name)
{
//检查文件名是否存在或是否为空
if (file_name == NULL)
return;
//设置初始化数据类型数组,可通过选择0, 1, 2分别代表其中初始化数据的类型
uint8_t init_data_type[HKS_INIT_DATA_TYPE_NUM] = {
HKS_INIT_DATA_TYPE_ALL_ZERO,
HKS_INIT_DATA_TYPE_ALL_ONE,
HKS_INIT_DATA_TYPE_RANDOM
};
uint32_t file_size = 0;
int32_t rc = hks_file_size(file_name, &file_size);//读取文件的大小,文件大小存在file_size中
//如果文件状态不正确(无权限操作)或文件大小为0直接返回,即删除失败
if ((rc != HKS_STATUS_OK) || (file_size == 0))
return;
uint32_t i = 0;
//#define HKS_INIT_DATA_TYPE_NUM 3
// 文件清除数据类型的数量=3
for (; i < HKS_INIT_DATA_TYPE_NUM; ++i) {
rc = hks_file_init_data(file_name, file_size,
init_data_type[i]);
if (rc != HKS_STATUS_OK)
break;
}
return;
}
本篇小结
本篇文章主要分析了hks_file.c文件中的关键函数,在安全服务下有关于文件操作这一块的内容相信还是清晰易懂的。欢迎大家的阅读与点赞!