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文件中的关键函数,在安全服务下有关于文件操作这一块的内容相信还是清晰易懂的。欢迎大家的阅读与点赞!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值