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加密
-
定义
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)是为其密文提供保密性和完整性的加密方案。它们还支持为未加密的相关数据提供完整性。
-
进一步解释
Authenticated Encryption with Associated Data (AEAD) 是一种同时具备保密性,完整性和可认证性的加密形式。AEAD 产生的原因很简单,单纯的对称加密算法,其解密步骤是无法确认密钥是否正确的。也就是说,加密后的数据可以用任何密钥执行解密运算,得到一组疑似原始数据,而不知道密钥是否是正确的,也不知道解密出来的原始数据是否正确。
因此,需要在单纯的加密算法之上,加上一层验证手段,来确认解密步骤是否正确。
-
实现步骤
通过密钥key对消息加密,通过增加随机数来保证隐私;
计算一个认证标签,通过该认证标签可保证一条消息中加密和未加密的部分均未被篡改。 -
AEAD加密算法分类:
其中GCM为AEAD加密算法中的典型,GCM算法的流程图如下:
其中依次用到的GHASH和GCTR的流程图如下:
服务类调用原函数参考
-
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); }
-
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); }
-
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; }
本篇结束,感谢您的阅读与点赞!