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

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

本篇主要讲述hks_access_aead_encrypt函数之后的部分内容。

各模块详解

hks的aead加密

其中函数hks_aead_encrypt调用了函数hks_aead_encrypt_ree,且函数hks_aead_encrypt_ree在检查过密钥、密钥参数、明文、带标记的密文等相关信息后是通过调用hks_access_aead_encrypt函数实现的。
hks的aead解密部分的代码理解同hks的aead加密,代码部分省略。

//hks的aead加密
static int32_t hks_aead_encrypt_ree(const struct hks_blob *key,
    const struct hks_key_param *key_param,          //密匙参数
    const struct hks_crypt_param *crypt_param,      //加密参数
    const struct hks_blob *plain_text,              //明文
    struct hks_blob *cipher_text_with_tag)          //带标记的密文
{
    hks_if_true_return_error(((key_param->key_type != HKS_KEY_TYPE_AES) ||  //检查密匙参数的类型是否为AES加密类型
        (key_param->key_mode != HKS_ALG_GCM) ||                             //检查密匙参数的模式是否为GCM加密模式
        (key_param->key_pad != HKS_PADDING_NONE) ||                         //检查密匙是否存在padding补位
        ((key_param->key_usage & HKS_KEY_USAGE_ENCRYPT) == 0)), HKS_ERROR_NOT_SUPPORTED);//检查密匙应用是否加密

    //检查密匙的长度有没有超过最大长度
    hks_if_true_return_error(((key_param->key_len != HKS_MAX_KEY_LEN_128) &&
        (key_param->key_len != HKS_MAX_KEY_LEN_192) &&
        (key_param->key_len != HKS_MAX_KEY_LEN_256)), HKS_ERROR_NOT_SUPPORTED);

    //检查密匙的类型与大小是否满足HKS_ERROR_INVALID_KEY_INFO
    hks_if_true_return_error(((key->type != HKS_BLOB_TYPE_KEY) || (key->data == NULL) ||
        (key->size != (key_param->key_len / HKS_BITS_PER_BYTES))), HKS_ERROR_INVALID_KEY_INFO);

    //检查加密参数信息的内容、大小以及明文的内容和大小是否满足HKS_ERROR_INVALID_ARGUMENT
    hks_if_true_return_error(((crypt_param->nonce.data == NULL) ||
        (crypt_param->nonce.size < HKS_AES_GCM_MIN_IV_LENGTH) ||
        (crypt_param->aad.data == NULL) ||
        (crypt_param->aad.size == 0) ||
        (plain_text->data == NULL) || (plain_text->size == 0)), HKS_ERROR_INVALID_ARGUMENT);

    //检查带标记的密文信息内容和大小是否满足HKS_ERROR_INVALID_ARGUMENT
    hks_if_true_return_error(((cipher_text_with_tag == NULL) ||
        (cipher_text_with_tag->data == NULL) ||
        (cipher_text_with_tag->size < (plain_text->size + HKS_SALT_MAX_SIZE))),
        HKS_ERROR_INVALID_ARGUMENT);

    //如果上述条件都成立则执行hks_access_aead_encrypt函数
    return hks_access_aead_encrypt(key, key_param, crypt_param, plain_text, cipher_text_with_tag);
}

//AEAD算法下的加密函数,先对传入参数进行检查,再调用了hks_aead_encrypt_ree,*****相当于把hks_aead_encrypt_ree做了一个封装*****
HKS_DLL_API_PUBLIC int32_t hks_aead_encrypt(const struct hks_blob *key,
    const struct hks_key_param *key_param,
    const struct hks_crypt_param *crypt_param,
    const struct hks_blob *plain_text,
    struct hks_blob *cipher_text_with_tag)
{
    //检查密匙、密匙参数、加密参数、明文、带标记的密文信息是否为空
    hks_if_true_return_error(((key == NULL) || (key_param == NULL) ||
        (crypt_param == NULL || (plain_text == NULL) ||
        (cipher_text_with_tag == NULL))), HKS_ERROR_NULL_POINTER);
    return hks_aead_encrypt_ree(key, key_param, crypt_param, plain_text, cipher_text_with_tag);
}

hks的密钥派生和密钥许可协议

hks的密钥派生函数:hks_key_derivation需要传入参数的有:
derived_key 派生密钥
hks_key_param hks密钥参数
kdf_key kdf密钥

hks密钥许可协议函数:hks_key_agreement需要传入参数的有:
agreed_key 许可密钥
private_key_param 私有密钥参数
agreement_alg alg协议
private_key 私有密钥
peer_public_key 对等公有密钥

//hks密匙派生
HKS_DLL_API_PUBLIC int32_t hks_key_derivation(struct hks_blob *derived_key,
    const struct hks_key_param *key_param, const struct hks_blob *kdf_key,
    const struct hks_blob *salt, const struct hks_blob *label)
{
    hks_if_true_return_error(((derived_key == NULL) ||
        (key_param == NULL) || (kdf_key == NULL) ||
        (salt == NULL) || (label == NULL)),
        HKS_ERROR_NULL_POINTER);
    //执行获取密匙派生信息对应的函数
    return hks_access_key_derivation(derived_key, kdf_key, salt, label,
        key_param);
}

//hks密匙许可协议
//需要传入许可密匙:agreed_key、私有密匙参数:private_key_param、alg协议:agreement_alg、私有密匙:private_key、对等公有密匙:peer_public_key
HKS_DLL_API_PUBLIC int32_t hks_key_agreement(struct hks_blob *agreed_key,
    const struct hks_key_param *private_key_param,
    const uint32_t agreement_alg, const struct hks_blob *private_key,
    const struct hks_blob *peer_public_key)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    //检查传入参数是否为空
    hks_if_true_return_error(((agreed_key == NULL) ||
        (private_key_param == NULL) || (private_key == NULL) ||
        (peer_public_key == NULL)), HKS_ERROR_NULL_POINTER);

    if ((agreed_key == NULL) || (agreed_key->data == NULL))
        return HKS_ERROR_NULL_POINTER;

    //检查许可密匙大小是否符合HKS_KEY_BYTES_CURVE25519
    if (agreed_key->size < HKS_KEY_BYTES_CURVE25519)
        return HKS_ERROR_INVALID_KEY_INFO;

    //检查密匙是否使用了特定加密方法HKS_KEY_TYPE_ECC_KEYPAIR_CURVE25519、密匙应用与模式是否合规
    if ((private_key_param->key_type !=
        HKS_KEY_TYPE_ECC_KEYPAIR_CURVE25519) ||
        (private_key_param->key_usage != HKS_KEY_USAGE_DERIVE) ||
        (private_key_param->key_mode != hks_alg_ecdh(HKS_ALG_ECDH_RAW)) ||
        (agreement_alg != hks_alg_ecdh(HKS_ALG_ECDH_RAW)))
        return HKS_ERROR_NOT_SUPPORTED;

    //检查私有密匙和对等公有密匙的数据和大小是否合规
    if ((private_key->data == NULL) ||
        (private_key->size != HKS_KEY_BYTES_CURVE25519))
        return HKS_ERROR_INVALID_PRIVATE_KEY;

    if ((peer_public_key->data == NULL) ||
        (peer_public_key->size != HKS_KEY_BYTES_CURVE25519))
        return HKS_ERROR_INVALID_PUBLIC_KEY;
    //执行获取密匙协议相对应的函数
    return hks_access_key_agreement(agreed_key,
        private_key_param, private_key, peer_public_key, agreement_alg);
#endif
}

hash运算相关函数集

该部分包括以下函数:
hks_generate_random
hks_hmac
hks_hash
hks_if_true_return_error
hks_bn_exp_mod
具体执行功能都是调用了hks_access.c中的对应功能函数。


//hks生成随机数
HKS_DLL_API_PUBLIC int32_t hks_generate_random(struct hks_blob *random)
{
    hks_if_true_return_error(((random == NULL) || (random->data == NULL)),
        HKS_ERROR_NULL_POINTER);
    hks_if_true_return_error((random->size > HKS_RANDOM_MAX_LEN),
        HKS_ERROR_INVALID_ARGUMENT);
    //调用hks_access_get_random函数
    return hks_access_get_random(random);
}

//hks获取哈希运算验证码
HKS_DLL_API_PUBLIC int32_t hks_hmac(const struct hks_blob *key,
    const uint32_t alg, const struct hks_blob *src_data,
    struct hks_blob *output)
{
    hks_if_true_return_error(((key == NULL) || (src_data == NULL) ||
        (output == NULL)), HKS_ERROR_NULL_POINTER);
    //调用hks_access_hmac函数
    return hks_access_hmac(key, alg, src_data, output);
}

//hks哈希算法
HKS_DLL_API_PUBLIC int32_t hks_hash(const uint32_t alg,
    const struct hks_blob *src_data, struct hks_blob *hash)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    hks_if_true_return_error(((src_data == NULL) || (hash == NULL)),
        HKS_ERROR_NULL_POINTER);
    //调用hks_access_hash函数
    return hks_access_hash(alg, src_data, hash);
#endif
}

//hks大整数模幂运算
HKS_DLL_API_PUBLIC int32_t hks_bn_exp_mod(struct hks_blob *x,
    const struct hks_blob *a, const struct hks_blob *e,
    const struct hks_blob *n)
{
    hks_if_true_return_error(((x == NULL) || (a == NULL) || (e == NULL) ||
        (n == NULL)), HKS_ERROR_NULL_POINTER);
    //调用hks_access_bn_exp_mod函数
    return hks_access_bn_exp_mod(x, a, e, n);
}

服务类函数集

该部分包括以下函数:
hks_register_file_callbacks
hks_register_get_hardware_udid_callback
hks_register_log_interface
能够实现注册文件回调、注册日志界面等功能

//hks注册文件回调
HKS_DLL_API_PUBLIC int32_t hks_register_file_callbacks(
    struct hks_file_callbacks *callbacks)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_SUCCESS;
#else
    if (callbacks == NULL)
        return HKS_ERROR_NULL_POINTER;
    //调用hks_service_register_file_callbacks函数执行注册文件回调功能
    return hks_service_register_file_callbacks(callbacks);
#endif
}

//hks注册获取硬件udid回调,注:UDID(Unique Device Identifier)
HKS_DLL_API_PUBLIC int32_t hks_register_get_hardware_udid_callback(
    hks_get_hardware_udid_callback callback)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_SUCCESS;
#else
    //调用hks_service_register_get_hardware_udid_callback函数,HKS服务寄存器获取硬件udid回调
    return hks_service_register_get_hardware_udid_callback(callback);
#endif
}

//hks注册日志界面,传入日志组件参数信息
HKS_DLL_API_PUBLIC int32_t hks_register_log_interface(
    const struct hks_log_f_group *log)
{
    if (log == NULL)
        return HKS_ERROR_NULL_POINTER;
    //执行hks_register_log,将日志组件写入g_log_func中
    hks_register_log(log);
    return HKS_STATUS_OK;
}

其他函数

该部分包括以下函数:
hks_get_pub_key_alias_list
hks_init
hks_destroy
hks_refresh_key_info
具体函数内部调用的执行功能函数见hks_access.c。

//hks获取公有密钥别名列表
HKS_DLL_API_PUBLIC int32_t hks_get_pub_key_alias_list(
    struct hks_blob *key_alias_list, uint32_t *list_count)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_ERROR_NOT_SUPPORTED;
#else
    if ((key_alias_list == NULL) || (list_count == NULL))
        return HKS_ERROR_NULL_POINTER;

    //执行hks_access_get_pub_key_alias_list函数
    return hks_access_get_pub_key_alias_list(key_alias_list, list_count);
#endif
}

//hks初始化
HKS_DLL_API_PUBLIC int32_t hks_init(void)
{
#ifdef _CUT_AUTHENTICATE_
    log_debug("call hks init success.");
    return HKS_SUCCESS;
#else
    //执行hks权限初始化操作
    return hks_access_init();
#endif
}

//hks销毁(删除)
HKS_DLL_API_PUBLIC void hks_destroy(void)
{
#ifdef _CUT_AUTHENTICATE_
    return;
#else
    //执行函数hks_access_destroy
    hks_access_destroy();
#endif
}

//hks更新密匙信息
HKS_DLL_API_PUBLIC int32_t hks_refresh_key_info(void)
{
#ifdef _CUT_AUTHENTICATE_
    return HKS_SUCCESS;
#else
    //执行函数hks_access_refresh_key_info
    return hks_access_refresh_key_info();
#endif
}

知识提点

AEAD加密

  1. 定义
    Authenticated encryption with associated data (AEAD) are encryption schemes which provide both confidentiality and integrity for their ciphertext. They also support providing integrity for associated data which is not encrypted.

    带关联数据的身份验证加密(AEAD)是为其密文提供保密性和完整性的加密方案。它们还支持为未加密的相关数据提供完整性。

  2. 进一步解释
    Authenticated Encryption with Associated Data (AEAD) 是一种同时具备保密性,完整性和可认证性的加密形式。

    AEAD 产生的原因很简单,单纯的对称加密算法,其解密步骤是无法确认密钥是否正确的。也就是说,加密后的数据可以用任何密钥执行解密运算,得到一组疑似原始数据,而不知道密钥是否是正确的,也不知道解密出来的原始数据是否正确。

    因此,需要在单纯的加密算法之上,加上一层验证手段,来确认解密步骤是否正确。

  3. 实现步骤
    通过密钥key对消息加密,通过增加随机数来保证隐私;
    计算一个认证标签,通过该认证标签可保证一条消息中加密和未加密的部分均未被篡改。

  4. AEAD加密算法分类:
    在这里插入图片描述
    其中GCM为AEAD加密算法中的典型,GCM算法的流程图如下:
    在这里插入图片描述
    其中依次用到的GHASH和GCTR的流程图如下:
    在这里插入图片描述

服务类调用原函数参考

  1. hks_service_register_file_callbacks

    int32_t hks_service_register_file_callbacks(
        const struct hks_file_callbacks *callbacks)
    {
        if (callbacks == NULL)
            return HKS_ERROR_NULL_POINTER;
    
        return hks_file_register_callbacks(callbacks);
    }
    
  2. hks_service_register_get_hardware_udid_callback

    int32_t hks_service_register_get_hardware_udid_callback(
        hks_get_hardware_udid_callback callback)
    {
        return hks_reg_get_hardware_udid_callback(callback);
    }
    
  3. hks_register_log

    void hks_register_log(const struct hks_log_f_group *log)
    {
        if (log == NULL)
            return;
    
        if (log->log_info != NULL)
            g_log_func.log_info = log->log_info;
    
        if (log->log_warn != NULL)
            g_log_func.log_warn = log->log_warn;
    
        if (log->log_error != NULL)
            g_log_func.log_error = log->log_error;
    
        if (log->log_debug != NULL)
            g_log_func.log_debug = log->log_debug;
    }
    

本篇结束,感谢您的阅读与点赞!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值