security_huks模块下hks_file.c代码评注

理解Huks框架下的文件操作:hks_file.c解析
本文深入剖析了security_huks模块中的hks_file.c,涉及文件系统操作的关键函数,如文件注册回调、读取、写入、获取文件大小、初始化数据和安全删除。hks_file_callbacks结构体用于定义文件操作回调,hks_init_buf_data函数负责缓冲区初始化。此外,还详细介绍了hks_file_register_callbacks、hks_file_read、hks_file_write、hks_file_size等函数的实现和用途。通过对这些核心功能的解析,读者能更好地理解Huks框架下文件操作的实现细节。

本篇综述

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

<think>嗯,用户遇到了找不到模块@ohos.security.hash的问题,这需要我帮忙解决。首先,我得回想一下鸿蒙开发的模块结构。根据用户提供的引用资料,特别是引用[2]和引用[3],鸿蒙的安全模块主要是通过@ohos.security.huks来管理密钥和加密操作的。可能用户提到的hash模块其实是集成在HUKS中的,而不是单独的模块。 接下来,我需要确认是否存在@ohos.security.hash这个官方模块。查阅鸿蒙的官方文档,发现确实没有这个模块,而是哈希功能被包含在HUKS里。用户可能在文档或示例中看到过类似名称,导致混淆了模块名称。 然后,用户可能导入了错误的模块名,应该改用@ohos.security.huks。需要指导用户检查代码中的import语句,替换为正确的模块。同时,确保系统能力SystemCapability.Security.Huks已正确配置,这在引用[2]中提到过。 另外,用户可能需要使用HuksParam来指定摘要算法,比如SHA256。需要提供示例代码,展示如何正确调用HUKS的接口进行哈希操作,并处理可能的错误。 最后,提醒用户检查SDK版本和依赖,确保一切更新到最新,避免兼容性问题。如果问题依然存在,建议用户查阅官方资源或社区寻求帮助。总结下来,核心问题在于模块名称的错误,替换成HUKS并正确使用其API应该能解决问题。</think>### 如何解决 `@ohos.security.hash` 模块未找到的问题? #### 问题分析 根据你提供的引用信息,鸿蒙系统的安全模块中并未直接提供名为 `@ohos.security.hash` 的独立模块。鸿蒙的安全功能主要通过 `@ohos.security.huks`(通用密钥库系统)实现,包括哈希算法、加密解密等操作[^2][^3]。 #### 解决步骤 1. **确认模块名称的正确性** - 官方文档中,哈希算法功能通过 `@ohos.security.huks` 提供,而非单独的 `@ohos.security.hash`。需检查代码中是否错误引用了模块名称。 2. **使用 `@ohos.security.huks` 实现哈希功能** - 哈希算法(如 SHA1、SHA256)在 `huks` 模块中被定义为摘要算法。例如,`HUKS_DIGEST_SHA256` 表示使用 SHA256 算法。 - **示例代码**: ```typescript import huks from '@ohos.security.huks'; // 定义哈希参数 let options = { properties: [ { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_RSA }, { tag: huks.HuksTag.HUKS_TAG_DIGEST, value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 } ] }; // 调用哈希功能 async function hashData(data: Uint8Array) { try { const hashResult = await huks.initSession('default_key', options); console.info('Hash result:', hashResult); } catch (error) { console.error('Hash failed:', error); } } ``` 3. **检查系统能力配置** - 在 `module.json5` 文件中,确保已声明系统能力 `SystemCapability.Security.Huks`[^2]: ```json { "module": { "requestPermissions": [ { "name": "SystemCapability.Security.Huks" } ] } } ``` 4. **确认 SDK 版本与依赖** - 若开发环境版本过旧,可能导致模块缺失。建议更新 DevEco Studio 至最新版本,并同步鸿蒙 SDK。 #### 相关问题 1. **鸿蒙中如何实现数据加密与解密?** - 通过 `@ohos.security.huks` 提供密钥管理和加密接口,支持 AES、RSA 等算法。 2. **如何选择适合的摘要算法?** - 根据安全需求选择,例如 SHA256 平衡性能与安全性,SHA512 适用于更高安全场景[^1]。 3. **鸿蒙安全模块代码结构如何分析?** - 可参考 `security_huks` 的框架层次,其核心逻辑在 `.c` 和 `.cpp` 文件中实现,结合单元测试验证功能。 #### 总结 问题根源在于模块名称引用错误,正确使用 `@ohos.security.huks` 并配置对应参数即可实现哈希功能。若仍存在问题,建议查阅官方文档或社区资源进一步验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值