security_huks模块下hks_client.c代码评注(上)

OpenHarmony 同时被 2 个专栏收录
32 篇文章 0 订阅
19 篇文章 0 订阅

hks_client.c总述

hks_client.c是基于用户的hks安全模块的函数集成,其中囊括了hw_keystore_sdk当中主要文件夹common和soft_service当中的大部分功能模块。它将具体的功能封装成函数,在一些传入参数判空检查、格式大小检查的基础上再进一步调用核心模块,不仅提高了函数执行的效率,还提高了代码的鲁棒性和可读性,这样的代码思路值得我们学习。下面,就让我们深入hks_client.c的内容,一起来探索吧。
本篇的下篇部分详见:security_huks模块下hks_client.c代码评注(下)

代码关键部分模块框架

hks_client.c
├── include
│   └── "hks_client.h"
│   └── "hks_access.h"
│   └── "soft_service/hks_service.h"
│   └── "hks_types.h"
│   └── "common/hks_common.h"                           
├── functions                        
│   └── hks_client.h
│   		└── hks_get_sdk_version                
│   └── hks_access.c
│   		└── hks_access_generate_key
│   		└── hks_access_generate_key_ex
│   		└── hks_access_import_key
│   		└── hks_access_export_key
│   		└── hks_access_delete_key
│   		└── hks_access_get_key_param
│   		└── hks_access_is_key_exist
│   		└── hks_access_sign
│   		└── hks_access_verify
│   		└── hks_access_aead_encrypt
│   		└── hks_access_aead_decrypt
│   		└── hks_access_key_derivation
│   		└── hks_access_key_agreement
│   		└── hks_access_get_random
│   		└── hks_access_hmac
│   		└── hks_access_hash
│   		└── hks_access_bn_exp_mod
│   		└── hks_access_get_pub_key_alias_list
│   		└── hks_access_init
│   		└── hks_access_destroy
│   		└── hks_access_refresh_key_info                  
│   └── hks_service.c
│   		└── hks_service_register_file_callbacks
│   		└── hks_service_register_get_hardware_udid_callback
│   └── hks_log_utils.c
│   		└── hks_register_log

各模块详解

导入库函数与预编译

该模块包括了所需要的用到的头文件,其中#include "hks_access.h"尤为重要,本篇中大量的函数的调用都在 "hks_access.h"中有声明,且函数原型在 "hks_access.c"中。

#include "hks_client.h"
#include "securec.h"

#include "common/hks_common.h"
#include "common/hks_log_utils.h"
#include "hks_errno.h"
#include "hks_file_api.h"
#include "hks_hardware_api.h"
#include "hks_types.h"
#include "soft_service/hks_service.h"

#include "hks_access.h"

/* AES-GCM encrypt IV minimum size,96bit=12bytes */
//AES-GCM加密IV最小尺寸,96bit=12字节
#define HKS_AES_GCM_MIN_IV_LENGTH 12

获取版本号

需要注意的是:#define HKS_SDK_VERSION “1.0.0.10” 初始版本号为1.0.0.10,因此后序版本号都是在此基础上的拓展。代码如下:

//获取sdk版本号
void hks_get_sdk_version(struct hks_blob *sdk_version)
{
    if (sdk_version == NULL)
        return;
    //#define HKS_SDK_VERSION "1.0.0.10"
    const size_t version_len = strlen(HKS_SDK_VERSION);
    if ((sdk_version->data != NULL) && (sdk_version->size > version_len)) {
        //将版本号写入data数组中
        if (memcpy_s(sdk_version->data, sdk_version->size, HKS_SDK_VERSION, version_len) != EOK) {
            log_error("memcpy_s fail");
            return;
        }
        sdk_version->data[version_len] = '\0';//末位标记
        sdk_version->size = (uint32_t)version_len + 1;
    }
}

密钥相关函数集(上)

这里包括了密钥的生成、公有密钥的导入导出、密钥的删除、获取密钥详细信息、判断密钥是否存在、hks非对称性标记与检验一系列函数。
需要注意的是:

  1. HKS_DLL_API_PUBLIC 在hks_types.h中有定义,
    定义如下:#define HKS_DLL_API_PUBLIC __declspec(dllimport),
    详细意义见知识提点:DLL编程的导入导出部分。

  2. 函数:hks_if_true_return_error
    它的作用在于检查各参数信息是否合规

    /*
     * warning: this macro function only can be used in the beginnig of
     * each function
     * do not use it after malloc, alloc etc. you can use goto statement instead
     */
    #define hks_if_true_return_error(s, err) \
        if ((s) == HKS_BOOL_TRUE) { \
            log_error("%s %d return status: %d.\n", __func__, __LINE__, (err)); return err; }
    
  3. HKS_status_OK
    对于当前接口,如果status为HKS status OK表示key存在,others表示key不存在或出现错误

系列代码及注解如下:

//#define HKS_DLL_API_PUBLIC __declspec(dllimport)
//生成密匙
HKS_DLL_API_PUBLIC int32_t hks_generate_key(const struct hks_blob *key_alias,
    const struct hks_key_param *key_param)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    HKS_TRACE_IN;
    //检查上级状态:用户id与别名是否为success
    hks_if_status_error_return(hks_is_valid_auth_id(key_param));
    hks_if_status_error_return(hks_is_valid_alias(key_alias));

    //检查密匙参数类型信息
    if (key_param->key_type != HKS_KEY_TYPE_EDDSA_KEYPAIR_ED25519)
        return HKS_ERROR_NOT_SUPPORTED;
    //执行生成秘钥函数,返回生成密匙的key_alias和key_param信息
    return hks_access_generate_key(key_alias, key_param);
#endif
}

//生成非对称密匙
HKS_DLL_API_PUBLIC int32_t hks_generate_asymmetric_key(
    const struct hks_key_param *key_param, struct hks_blob *pri_key,
    struct hks_blob *pub_key)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    HKS_TRACE_IN;
    hks_if_true_return_error((key_param == NULL), HKS_ERROR_NULL_POINTER);
    //检查密匙参数类型信息
    if (key_param->key_type != HKS_KEY_TYPE_ECC_KEYPAIR_CURVE25519)
        return HKS_ERROR_NOT_SUPPORTED;
    //检查密匙参数模式信息
    if (key_param->key_mode != hks_alg_ecdh(HKS_ALG_SELECT_RAW))
        return HKS_ERROR_NOT_SUPPORTED;
    //检查密钥参数验证模式 私有密匙与公有密匙是否为空
    if ((pri_key == NULL) || (pri_key->data == NULL) || (pub_key == NULL) ||
        (pub_key->data == NULL))
        return HKS_ERROR_NULL_POINTER;
    //执行生成密匙对对应函数
    return hks_access_generate_key_ex(key_param, pri_key, pub_key);
#endif
}

//hks导入公有密匙
HKS_DLL_API_PUBLIC int32_t hks_import_public_key(
    const struct hks_blob *key_alias,
    const struct hks_key_param *key_param, const struct hks_blob *key)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    HKS_TRACE_IN;
    hks_if_status_error_return(hks_is_valid_auth_id(key_param));
    int32_t status = hks_is_valid_alias(key_alias);

    //判断hks_is_valid_alias的状态是否正常
    if (status != HKS_STATUS_OK)
        return status;

    //检查密匙参数类型信息
    if (key_param->key_type != HKS_KEY_TYPE_EDDSA_PUBLIC_KEY_ED25519)
        return HKS_ERROR_NOT_SUPPORTED;
    hks_if_true_return_error((key == NULL), HKS_ERROR_NULL_POINTER);
    //检查密匙内容以及大小是否合规
    if ((key->data == NULL) || (key->size != CRYPTO_PUBLIC_KEY_BYTES))
        return HKS_ERROR_INVALID_PUBLIC_KEY;

    //执行hks存取导入密匙信息对应函数
    return hks_access_import_key(key_alias, key_param, key);
#endif
}

//hks导出公有密匙
HKS_DLL_API_PUBLIC int32_t hks_export_public_key(
    const struct hks_blob *key_alias, struct hks_blob *key)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    int32_t status = hks_is_valid_alias(key_alias);

    //判断hks_is_valid_alias的状态是否正常
    if (status != HKS_STATUS_OK)
        return status;
    if (key == NULL)
        return HKS_ERROR_NULL_POINTER;
    //检查密匙内容以及大小是否合规
    if ((key->data == NULL) || (key->size < CRYPTO_PUBLIC_KEY_BYTES))
        return HKS_ERROR_BUF_TOO_SMALL;
    //执行hks获得存取出口密匙的权限对应函数
    return hks_access_export_key(key_alias, key);
#endif
}

//hks删除密匙
HKS_DLL_API_PUBLIC int32_t hks_delete_key(const struct hks_blob *key_alias)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    /* to add log here track return value */
    //注意:要在这里添加日志跟踪返回值
    int32_t status = hks_is_valid_alias(key_alias);

    //判断hks_is_valid_alias的状态是否正常
    if (status != HKS_STATUS_OK)
        return status;
    //执行删除密匙信息对应的函数
    return hks_access_delete_key(key_alias);
#endif
}

//hks获取密匙参数信息
HKS_DLL_API_PUBLIC int32_t hks_get_key_param(const struct hks_blob *key_alias,
    struct hks_key_param *key_param)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    int32_t status = hks_is_valid_alias(key_alias);

    if (status != HKS_STATUS_OK)
        return status;
    if (key_param == NULL)
        return HKS_ERROR_NULL_POINTER;
    //执行hks获得密匙参数信息对应的函数
    return hks_access_get_key_param(key_alias, key_param);
#endif
}

/*
 * For current interface, if status is HKS_STATUS_OK
 * means key exist, others means key does not exist or error occurs
 */

//对于当前接口,如果status为HKS status OK表示key存在,others表示key不存在或出现错误

//hks判断密匙是否存在
HKS_DLL_API_PUBLIC int32_t hks_is_key_exist(const struct hks_blob *key_alias)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    int32_t status = hks_is_valid_alias(key_alias);

    //如果该密钥可用,判断是否存在并且返回状态值
    if (status != HKS_STATUS_OK)
        return status;
    status = hks_access_is_key_exist(key_alias);
    return status;
#endif
}

//hks非对称标记
HKS_DLL_API_PUBLIC int32_t hks_asymmetric_sign(
    const struct hks_blob *key_alias,
    const struct hks_key_param *key_param, const struct hks_blob *hash,
    struct hks_blob *signature)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    int32_t status = hks_is_valid_alias(key_alias);
    
    //检查key_alias的状态是否正常
    hks_if_status_error_return(status);
    //检查密匙参数、hash方法、签名是否为空
    hks_if_true_return_error(((key_param == NULL) || (hash == NULL) ||
        (signature == NULL)), HKS_ERROR_NULL_POINTER);
    //检查密匙参数类型、应用是否合规
    if ((key_param->key_type != HKS_KEY_TYPE_EDDSA_KEYPAIR_ED25519) ||
        ((key_param->key_usage & HKS_KEY_USAGE_SIGN) == 0))
        return HKS_ERROR_NOT_SUPPORTED;
    //检查hash规则内容与大小
    if ((hash->data == NULL) || (hash->size <= 0))
        return HKS_ERROR_INVALID_ARGUMENT;
    //检查签名内容与大小
    if ((signature->data == NULL) ||
        (signature->size < HKS_SIGNATURE_MIN_SIZE))
        return HKS_ERROR_BUFFER_TOO_SMALL;

    //执行hks存取签署信息对应函数
    return hks_access_sign(key_alias, key_param, hash, signature);
#endif
}

//hks非对称性检验
HKS_DLL_API_PUBLIC int32_t hks_asymmetric_verify(const struct hks_blob *key,
    const struct hks_key_param *key_param, const struct hks_blob *hash,
    const struct hks_blob *signature)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    //先检查函数传入的参数是否有空值
    hks_if_true_return_error(((key == NULL) || (key_param == NULL) ||
        (hash == NULL) || (signature == NULL)), HKS_ERROR_NULL_POINTER);

    int32_t status;

    if (key->type == HKS_BLOB_TYPE_ALIAS) {
        status = hks_is_valid_alias(key);
        hks_if_status_error_return(status);
        //当密匙的类型为alias类型时候,检查密匙的可用性然后将检查结果状态值返回
    } else if (key->type == HKS_BLOB_TYPE_KEY) {
        //密匙参数中的密匙类型不为公匙ED25519则函数退出
        if (key_param->key_type != HKS_KEY_TYPE_EDDSA_PUBLIC_KEY_ED25519)
            return HKS_ERROR_NOT_SUPPORTED;
        if ((key->data == NULL) || (key->size != HKS_PUBLIC_BYTES_ED25519))
            return HKS_ERROR_INVALID_KEY_INFO;
        //检查密匙数据的合法性
    } else {
        return HKS_ERROR_INVALID_KEY_INFO;
    }

    //检查密匙参数中的usage属性
    if ((key_param->key_usage & HKS_KEY_USAGE_VERIFY) == 0)
        return HKS_ERROR_NOT_SUPPORTED;

    //检查hash方法的内容及大小
    if ((hash->data == NULL) || (hash->size <= 0))
        return HKS_ERROR_INVALID_ARGUMENT;

    //检查签名内容与大小
    if ((signature->data == NULL) || (signature->size < HKS_SIGNATURE_MIN_SIZE))
        return HKS_ERROR_INVALID_ARGUMENT;
    return hks_access_verify(key, hash, signature);
#endif
}

知识提点

DLL编程的导入导出

#ifdef _EXPORTING
#define API_DECLSPEC __declspec(dllexport)
#else
#define API_DECLSPEC __declspec(dllimport)
#endif

这个宏,是为了便于开发和使用自己写的dll库的。
用同样的 API_DECLSPEC 类型声明,在dll的.cpp文件里,添加

#define _EXPORTING

则 API_DECLSPEC 为输出库。
在调用dll方,无 #define _EXPORTING,则 API_DECLSPEC 为输入库。
这样,用于dll的.h文件,可以直接用于调用dll的项目中。

常用传参结构体类型

  1. hks_blob:主要用来定义密钥、密钥别名、hash算法、签名署名类型,如:

    const struct hks_blob *key_alias,
    const struct hks_key_param *key_param,
    const struct hks_blob *hash,
    struct hks_blob *signature
    

    它包含了密钥的类型,数据内容以及密钥的大小信息。

    struct hks_blob {
        uint8_t type;
        uint8_t *data;
        uint32_t size;
    };
    
  2. hks_key_param:主要用来定义密钥参数类型,其中包含了密钥使用的算法、密钥的应用、密钥使用的填充模式、密钥所属的组别模式以及密钥的域和角色等信息。

    struct hks_key_param {
        uint32_t key_type; /*使用算法类型*/
        uint32_t key_len;
        uint32_t key_usage; /* 密钥的应用方法*/
        uint32_t key_pad; /*密钥的填充模式*/
        uint32_t key_mode; /*密钥组模式*/
        uint32_t key_role; /*密钥角色*/
        uint16_t key_domain; /*密钥所属域*/
        struct hks_blob key_auth_id; /*密钥对应的用户id*/
    };
    

    3.hks_crypt_param:主要用来定义加密参数类型,代码如下:

    struct hks_crypt_param {
        struct hks_blob nonce; //没有值或iv向量
        struct hks_blob aad;
    };
    

上述常用传参结构体能在security_huks\interfaces\innerkits\huks_lite\hks_types.h中找到,此处提出的原因在于多数函数的形式参数类型定义都为以上几种,其余类型不再赘述。

下篇我们将继续介绍hks_client.c的剩余代码!

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值