security_huks模块下hks_service.c代码评注(一)
本篇概述
由security_huks模块下hks_service部分代码框架,我们可将华为密钥存储hks的服务部分分成:密钥服务、算法服务、管理服务和检验服务这几个模块,本篇主要讲述有关密钥服务的部分代码注释。
本篇框架
hks_service.c
├── include & define
├── generate_key_service
│ └── hks_service_generate_key
│ └── hks_service_generate_asymmetric_key
├── aead_方案
│ └── hks_service_aead_encrypt
│ └── hks_service_aead_encrypt_ex
│ └── hks_service_aead_decrypt
│ └── hks_service_aead_decrypt_ex
准备工作
添加包依赖
本部分要特别注意增加mbedtls相关接口源码库,其中的hkdf、ecdh、config、ctr_drbg、md等库函数的连接都十分紧密,例如:ecdh.h的文件参考
相关联系的细节如下:
头文件部分代码如下:
#include "hks_service.h"
#ifndef _CUT_AUTHENTICATE_
#include <ec_local.h>
#endif
#include <mbedtls/ctr_drbg.h> //使能随机数模块
#include <mbedtls/ecdh.h>
#include <mbedtls/entropy.h> //使能熵源模块
#include <mbedtls/platform.h>
#include <mbedtls/sha1.h> //使能SHA系列算法
#include "securec.h"
//本地系统函数的调用
#include "common/hks_bn.h"
#include "common/hks_common.h"
#include "common/hks_log_utils.h"
#include "common/hks_mem.h"
#include "hks_errno.h"
#include "hks_rkc.h"
定义静态量
定义的静态变量主要跟加密解密算法、相关检查核实量有关,主要代码部分如下:
#define HKS_BN_MOD_SHIFT_DEC 4 /* bn mod Dec bit shift */ //大数模10位移
#define HKS_BN_MOD_SHIFT_HEX 16 /* bn mod Hex bit shift */ //大数模16位移
#ifndef _CUT_AUTHENTICATE_
//声明静态变量:hks生成x25519密钥服务
static int32_t hks_service_generate_x25519_key(struct hks_blob *pri_key,
struct hks_blob *pub_key);
#endif
//hks——hmac服务
static int32_t hks_service_hmac(const struct hks_blob *key, uint32_t alg,
const struct hks_blob *src_data, struct hks_blob *output);
//hks大数模幂运算检查服务
static int32_t hks_service_bn_exp_mod_check(struct hks_blob *x,
const struct hks_blob *a, const struct hks_blob *e, const struct hks_blob *n);
//hks——aead加密算法服务
static int32_t hks_service_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——aead解密算法服务
static int32_t hks_service_aead_decrypt(const struct hks_blob *key,
const struct hks_key_param *key_param,
const struct hks_crypt_param *crypt_param,
const struct hks_blob *cipher_text_with_tag,
struct hks_blob *plain_text);
#ifndef _CUT_AUTHENTICATE_
//声明mbedtls中的hash加密组件
static int32_t hks_mbedtls_hash(uint32_t alg, const unsigned char *input,
size_t ilen, unsigned char *output);
//非对称核实初始化服务
static int32_t hks_service_asymmetric_verify_init(
const struct hks_blob *key_alias, struct hks_key_param *param,
struct hks_blob *public_key, struct hks_storage_key_info *key_info);
//使用别名核实的服务
static int32_t hks_service_verify_with_alias(const struct hks_blob *key_alias,
struct hks_blob *public_key,
struct hks_key_param *param, struct hks_storage_key_info *key_info);
核心函数定义
1. hks_service_generate_key
函数功能:生成密钥服务
其中,生成过程主要是通过调用接口函数ED25519_public_from_private来实现由公有密钥到私有的密钥的转化过程。详细代码如下:
//函数功能:生成密钥服务
//传参:密钥别名、密钥参数
int32_t hks_service_generate_key(const struct hks_blob *key_alias,
const struct hks_key_param *key_param)
{
//首先判断密钥别名以及密钥参数是否为空
hks_if_true_return_error(((key_alias == NULL) || (key_param == NULL)), HKS_ERROR_NULL_POINTER);
//此处调用hks_stroage.c中判断密钥是否能被存储
if (hks_is_key_can_store(key_alias,
HKS_LOCAL_STORAGE_KEY_MAX_NUM) != HKS_BOOL_TRUE)
return HKS_ERROR_INSUFFICIENT_STORAGE;
//声明密钥存储信息
struct hks_storage_key_info key_info;
//将key_info初始化为0
(void)memset_s(&key_info, sizeof(key_info), 0, sizeof(key_info));
//对key_info中的参数进行赋值
key_info.param = (struct hks_key_param *)key_param;
struct hks_blob private_key;
struct hks_blob pub_key = HKS_BLOB_DEFAULT_VALUE;
size_t private_key_len = CRYPTO_SECRET_KEY_BYTES;
size_t pub_key_len = CRYPTO_PUBLIC_KEY_BYTES;
//blob初始化,即初始化私有密钥
int32_t status = hks_blob_init(&private_key, sizeof(uint8_t),
private_key_len, HKS_BLOB_TYPE_KEY);
//判断初始化状态是否成功
hks_if_status_error_return(status);
//将status重新初始化存储公钥
status = hks_blob_init(&pub_key, sizeof(uint8_t), pub_key_len, HKS_BLOB_TYPE_KEY);
hks_if_status_error_goto_error(status, exit);
//检查密钥参数的类型,如果密钥参数类型不是经过ed25519算法配对,则返回非法状态
if (key_param->key_type != HKS_KEY_TYPE_EDDSA_KEYPAIR_ED25519) {
status = HKS_ERROR_INVALID_ARGUMENT;
goto exit;
}
//创建临时密钥存储结构体
struct hks_blob tmp;
//写入私有密钥数据、密钥大小、密钥本体使用随机函数赋予
tmp.data = private_key.data;
tmp.size = CRYPTO_PUBLIC_KEY_BYTES;
hks_service_get_random(&tmp);
//利用ed25519曲线拟合将私有密钥转换为共有变量
ED25519_public_from_private(pub_key.data, private_key.data);
//将公钥数据内容太复制到私钥数据位置处
(void)memcpy_s(private_key.data + CRYPTO_PUBLIC_KEY_BYTES,
CRYPTO_PUBLIC_KEY_BYTES, pub_key.data, CRYPTO_PUBLIC_KEY_BYTES);
//对key_info赋值
key_info.private_key = &private_key;
key_info.public_key = &pub_key;
//根据输入的密钥别名的类型,进行加密和密封密钥
if (key_alias->type == HKS_BLOB_TYPE_ALIAS)
status = hks_storage_write_key_info(key_alias, &key_info);
else
status = HKS_STATUS_OK;
//在退出该函数是要销毁内存以保证密钥的安全性
exit:
hks_blob_destroy(&pub_key);
hks_blob_destroy(&private_key);
hks_check_return_code(status, &status);
return status;
}
2. hks_service_generate_x25519_key
函数功能:使用x25519算法生成密钥
需要注意的接口函数有:
- 加载椭圆曲线 mbedtls_ecp_group_load()
Brief introduction:
This function sets up an ECP group context from a standardized set of domain parameters.
这个函数从一组标准化的域参数设置一个ECP组上下文
Note:
The index should be a value of the NamedCurve enum, as defined in <em>RFC-4492: Elliptic Curve Cryptography
椭圆曲线密码体制:
(ECC) Cipher Suites for Transport Layer Security (TLS)</em>, usually in the form of an \c MBEDTLS_ECP_DP_XXX macro.
\param grp The group context to setup. This must be initialized.
\param id The identifier of the domain parameter set to load.
\return \c 0 on success.
\return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p id doesn't correspond to a known group.
\return Another negative error code on other kinds of failure.
- 生成公开ECDH协议 mbedtls_ecdh_gen_public()
\brief This function generates an ECDH keypair on an elliptic curve.
这个函数在椭圆曲线上生成一个ECDH(密钥交换协议)键对
This function performs the first of two core computations implemented during the ECDH key exchange. The second core computation is performed by mbedtls_ecdh_compute_shared().
这个函数执行在ECDH密钥交换期间实现的两个核心计算中的第一个。第二个核心计算由mbedtls_ecdh_compute_shared()执行。
\see ecp.h
\param grp The ECP group to use. This must be initialized and have domain parameters loaded, for example through mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
\param d The destination MPI (private key). This must be initialized.
\param Q The destination point (public key). This must be initialized.
\param f_rng The RNG function to use. This must not be \c NULL.
\param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL in case \p f_rng doesn't need a context argument.
\return \c 0 on success.
\return Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code on failure.
该部分主要使用的是mbedtls接口函数实现了算法x25519的密钥生成工作,需要特别强调的是接口函数功能性应用的学习和调试,函数详情请参考:mbedtls Directory Reference
//函数功能:使用x25519算法生成密钥
static int32_t hks_service_generate_x25519_key(struct hks_blob *pri_key,
struct hks_blob *pub_key)
{
//定义一个pers数组
const char pers[] = "ecdh";
mbedtls_ecdh_context ctx_cli;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ecdh_init(&ctx_cli); //初始化密钥协商语境(结构体)
mbedtls_ctr_drbg_init(&ctr_drbg); //初始化随机数语境(结构体)
//初始化随机数生成器
/* Initialize random number generation */
mbedtls_entropy_context entropy; //保存熵配置
//初始化熵结构体
mbedtls_entropy_init(&entropy);
/* mbedtls_entropy_add_source(&entropy, entropy_source, NULL,
MBEDTLS_ENTROPY_MAX_GATHER,//熵源可用阈值,随机数达到阈值时熵源才被使用
MBEDTLS_ENTROPY_SOURCE_STRONG);//强熵源,一般是硬件真随机数生成器
//添加熵源接口,设置熵源属性*/
//根据个性化字符串更新随机种子
int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
&entropy, (const unsigned char *)pers, sizeof(pers));
hks_if_status_error_goto_error(ret, exit);
//客户端:初始化语境(context)并生成密钥
/* Client: inialize context and generate keypair */
//mbedtls_ecp_group_load()载入椭圆曲线CURVE25519
ret = mbedtls_ecp_group_load(&ctx_cli.grp, MBEDTLS_ECP_DP_CURVE25519);
hks_if_status_error_goto_error(ret, exit);
//生成公开ECDH协议
ret = mbedtls_ecdh_gen_public(&ctx_cli.grp, &ctx_cli.d, &ctx_cli.Q,
mbedtls_ctr_drbg_random, &ctr_drbg);
hks_if_status_error_goto_error(ret, exit);
//将私有密钥数据写入mbedtls_ecdh_context定义的ecdh语境当中
ret = mbedtls_mpi_write_binary(&ctx_cli.d, pri_key->data, CRYPTO_PUBLIC_KEY_BYTES);
hks_if_status_error_goto_error(ret, exit);
//将公有密钥数据写入mbedtls_ecdh_context定义的ecdh语境当中
ret = mbedtls_mpi_write_binary(&ctx_cli.Q.X, pub_key->data, CRYPTO_PUBLIC_KEY_BYTES);
hks_if_status_error_goto_error(ret, exit);
//将公有密钥数据倒序存放
hks_endian_swap(pub_key->data, CRYPTO_PUBLIC_KEY_BYTES);
hks_if_status_error_goto_error(ret, exit);
ret = HKS_SUCCESS;
pri_key->size = CRYPTO_PUBLIC_KEY_BYTES;
pub_key->size = CRYPTO_PUBLIC_KEY_BYTES;
//退出返回:密钥协商语境释放、初始化随机数空间释放、初始化熵的释放
exit:
mbedtls_ecdh_free(&ctx_cli);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
int32_t status = (int32_t)ret;
//hks检查返回值
hks_check_return_code(status, &status);
return status;
}
3. hks_service_generate_asymmetric_key
函数功能:生成非对称密钥
该函数的功能主要通过调用函数hks_service_generate_x25519_key()实现,不同之处在于函数增加了对密钥参数密钥对的检查与判别工作,因此我们关注的终点仍然应该在密钥生成协议与ECC曲线算法上。具体代码如下:
//函数功能:生成非对称密钥
int32_t hks_service_generate_asymmetric_key(
const struct hks_key_param *key_param, struct hks_blob *pri_key,
struct hks_blob *pub_key)
{
//判断传入密钥参数、私有及公有密钥是否为空,数据内容和大小是否合规,不满足条件则报错
hks_if_true_return_error((key_param == NULL), HKS_ERROR_NULL_POINTER);
hks_if_true_return_error((pri_key == NULL) || (pub_key == NULL), HKS_ERROR_NULL_POINTER);
hks_if_true_return_error((pri_key->data == NULL) || (pub_key->data == NULL), HKS_ERROR_NULL_POINTER);
hks_if_true_return_error((pri_key->size < CRYPTO_PUBLIC_KEY_BYTES) ||
(pub_key->size < CRYPTO_PUBLIC_KEY_BYTES), HKS_ERROR_INVALID_ARGUMENT);
int32_t status;
//判断密钥参数结构体重的密钥类型是否由ECC曲线25519生成
if (key_param->key_type == hks_key_type_ecc_key_pair(
HKS_ECC_CURVE_CURVE25519))
//利用密钥生成函数hks_service_generate_x25519_key生成密钥
status = hks_service_generate_x25519_key(pri_key, pub_key);
else
status = HKS_ERROR_NOT_SUPPORTED;
//利用返回状态检查函数进行校验
hks_check_return_code(status, &status);
return status;
}
4. aead加密方案
4.1 hks_service_aead_encrypt
函数功能:aead加密服务
传入参数:密钥、密钥参数、加密参数、明文、带标志的密文
aead加密服务的关键部分在于调用了hks_common.c接口函数的封装部分:hks_mbedtls_aead_encrypt,主要实现功能的接口为:mbedtls_gcm_crypt_and_tag,我们把hks_mbedtls_aead_encrypt展示在下方:
int32_t hks_mbedtls_aead_encrypt(const struct hks_blob *key,
const struct hks_key_param *key_param, struct hks_aead_data *aead_data,
size_t *ciphertext_output_length)
{
//检查mbedtls_aead参数
int32_t status = check_mbedtls_aead_args(key, key_param, aead_data, ciphertext_output_length);
if (status != HKS_SUCCESS)
return status;
//定义aead算法操作结构体
struct hks_aead_operation operation;
*ciphertext_output_length = 0;
//设置aead(类似初始化)
status = hks_aead_setup(key, key_param, &operation);
if (status != HKS_SUCCESS)
return status;
/* For all supported modes, the tag is at the end of the ciphertext. */
//对于所有的模式,tag标记都放在密文的末尾
if (aead_data->ciphertext_length < (aead_data->plaintext_length + operation.tag_length)) {
status = HKS_ERROR_BUFFER_TOO_SMALL;
goto exit;
}
uint8_t *tag = aead_data->ciphertext + aead_data->plaintext_length;
//关键部分:操作核心算法:HKS_ALG_GCM,调用mbedtls_gcm_crypt_and_tag接口来实现aead加密
if (operation.core_alg == HKS_ALG_GCM)/*https://tls.mbed.org/api/gcm_8h.html*/
status = mbedtls_gcm_crypt_and_tag(&operation.gcm, MBEDTLS_GCM_ENCRYPT,
aead_data->plaintext_length, aead_data->nonce, aead_data->nonce_length, aead_data->additional_data,
aead_data->additional_data_length, aead_data->plaintext, aead_data->ciphertext, operation.tag_length, tag);
else
status = HKS_ERROR_NOT_SUPPORTED;
//返回系统转态、释放空间
if (status != 0 && aead_data->ciphertext_length != 0)
(void)memset_s(aead_data->ciphertext, aead_data->ciphertext_length, 0, aead_data->ciphertext_length);
exit:
mbedtls_gcm_free(&(operation.gcm));
if (status == HKS_SUCCESS) {
if (aead_data->plaintext_length > SIZE_MAX - operation.tag_length)
return HKS_ERROR_BAD_STATE;
*ciphertext_output_length = aead_data->plaintext_length + operation.tag_length;
}
return mbedtls_to_hks_error(status);
}
进行aead加密的功能接口为:mbedtls_gcm_crypt_and_tag
,接口函数具体情况如下:int mbedtls_gcm_crypt_and_tag ( mbedtls_gcm_context * ctx, int mode, size_t length, const unsigned char * iv, size_t iv_len, const unsigned char * add, size_t add_len, const unsigned char * input, unsigned char * output, size_t tag_len, unsigned char * tag )
Note:
For encryption, the output buffer can be the same as the input buffer. For decryption, the output buffer cannot be the same as input buffer. If the buffers overlap, the output buffer must trail at least 8 Bytes behind the input buffer.
Warning:
When this function performs a decryption, it outputs the authentication tag and does not verify that the data is authentic. You should use this function to perform encryption only. For decryption, use mbedtls_gcm_auth_decrypt() instead.
详细参数解释如下图:
函数hks_service_aead_encrypt()的代码及标注如下:
//aead加密服务 传入参数:密钥、密钥参数、加密参数、明文、带标志的密文
static int32_t hks_service_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)
{
//初始化加密长度和状态
size_t encrypt_length = 0;
int32_t status = 0;
struct hks_aead_data aead_data;
// 声明结构体变量:aead_data
/*struct hks_aead_data {
uint8_t *nonce;
size_t nonce_length;
uint8_t *additional_data;
size_t additional_data_length;
uint8_t *ciphertext;
size_t ciphertext_length;
uint8_t *plaintext;
size_t plaintext_length;
};*/
//对上述结构体变量进行赋值
aead_data.nonce = crypt_param->nonce.data;
aead_data.nonce_length = crypt_param->nonce.size;
aead_data.additional_data = crypt_param->aad.data;
aead_data.additional_data_length = crypt_param->aad.size;
aead_data.ciphertext = cipher_text_with_tag->data;
aead_data.ciphertext_length = cipher_text_with_tag->size;
aead_data.plaintext = plain_text->data;
aead_data.plaintext_length = plain_text->size;
//调用mbedtls接口函数,使用aead加密方法对密钥进行加密
int32_t encrypt_status = hks_mbedtls_aead_encrypt(key, key_param,
&aead_data, &encrypt_length);
/*https://tls.mbed.org/api/gcm_8h.html*/
//检查返回结果
hks_check_return_code(encrypt_status, &status);
if (status != HKS_STATUS_OK)
return status;
//检查加密长度,如果小于最大存储单元则需要将加密标记tag加在密钥尾部,将密钥长度写入带标记密文中
if (encrypt_length < UINT32_MAX) {
cipher_text_with_tag->size = (uint32_t)encrypt_length;
status = HKS_STATUS_OK;
} else {
status = HKS_ERROR_DATA_CORRUPT;
}
//检查返回值
hks_check_return_code(status, &status);
return status;
}
4.2 hks_service_aead_encrypt_ex
函数功能:aead加密方案
传入参数:密钥、密钥参数、加密参数、明文、带标志的密文
该部分是对hks_service_aead_encrypt的一个封装,其中增加了相关参数的校验工作,具体代码如下:
//函数功能:aead加密方案,传入参数:密钥、密钥参数、加密参数、明文、带标志的密文
int32_t hks_service_aead_encrypt_ex(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);
hks_if_true_return_error((key_param->key_mode != HKS_ALG_GCM), 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);
//调用aead加密算法对密钥进行加密
return hks_service_aead_encrypt(key, key_param, crypt_param,
plain_text, cipher_text_with_tag);
}
5. aead解密方案
5.1 hks_service_aead_decrypt
函数功能:aead解密服务
传入参数:密钥、密钥参数、加密参数、明文、带标志的密文
aead解密服务的主要解密操作都是通过common.c的封装函数hks_mbedtls_aead_decrypt执行的,与加密方案类似,封装函数在进行参数检查与初始化后调用了mbedtls接口mbedtls_gcm_auth_decrypt,需要注意的一点不同是,在使用密文解密的过程当中,密文的末尾为tag标记,因此需要定位标记后才能进行解密操作。封装函数hks_mbedtls_aead_decrypt展示如下:
int32_t hks_mbedtls_aead_decrypt(const struct hks_blob *key,
const struct hks_key_param *key_param,
struct hks_aead_data *aead_data, size_t *plaintext_output_length)
{
//检查aead算法参数
int32_t status = check_mbedtls_aead_args(key, key_param, aead_data, plaintext_output_length);
if (status != HKS_SUCCESS)
return status;
//定义aead相关操作结构体
struct hks_aead_operation operation;
const uint8_t *tag = NULL;
//初始化明文输出长度
*plaintext_output_length = 0;
//设置aead参数(初始化)
status = hks_aead_setup(key, key_param, &operation);
if (status != HKS_SUCCESS)
return status;
//由于密文的末尾为tag标记,因此需要定位标记后才能进行解密操作
if (operation.core_alg == HKS_ALG_GCM) {
status = hks_aead_unpadded_locate_tag(operation.tag_length,
aead_data->ciphertext, aead_data->ciphertext_length, aead_data->plaintext_length, &tag);
if (status != HKS_SUCCESS)
goto exit;
//调用接口函数mbedtls_gcm_auth_decrypt进行解密操作
/* length had been checked in hks_aead_unpadded_locate_tag */
status = mbedtls_gcm_auth_decrypt(&operation.gcm, aead_data->ciphertext_length - operation.tag_length,
aead_data->nonce, aead_data->nonce_length, aead_data->additional_data,
aead_data->additional_data_length, tag, operation.tag_length, aead_data->ciphertext,
aead_data->plaintext);
} else {
status = HKS_ERROR_NOT_SUPPORTED;
goto exit;
}
//置零明文并释放空间
if (status != HKS_SUCCESS && aead_data->plaintext_length != 0)
(void)memset_s(aead_data->plaintext, aead_data->plaintext_length, 0, aead_data->plaintext_length);
exit:
mbedtls_gcm_free(&(operation.gcm));
if (status == HKS_SUCCESS)
*plaintext_output_length =
aead_data->ciphertext_length - operation.tag_length;
return mbedtls_to_hks_error(status);
}
aead解密服务函数hks_service_aead_decrypt代码如下:
//aead解密服务 传入参数:密钥、密钥参数、加密参数、明文、带标志的密文
static int32_t hks_service_aead_decrypt(const struct hks_blob *key,
const struct hks_key_param *key_param,
const struct hks_crypt_param *crypt_param,
const struct hks_blob *cipher_text_with_tag,
struct hks_blob *plain_text)
{
//初始化明文长度并定义hks_aead_data结构体变量
size_t plain_text_length = 0;
struct hks_aead_data aead_data;
//hks_aead_data结构体变量赋值
aead_data.nonce = crypt_param->nonce.data;
aead_data.nonce_length = crypt_param->nonce.size;
aead_data.additional_data = crypt_param->aad.data;
aead_data.additional_data_length = crypt_param->aad.size;
aead_data.ciphertext = cipher_text_with_tag->data;
aead_data.ciphertext_length = cipher_text_with_tag->size;
aead_data.plaintext = plain_text->data;
aead_data.plaintext_length = plain_text->size;
//调用接口函数mbedtls中aead算法的解密部分,主要接口为mbedtls_gcm_auth_decrypt
int32_t decrypt_status = hks_mbedtls_aead_decrypt(key, key_param,
&aead_data, &plain_text_length);
int32_t status = 0;
//检查返回值
hks_check_return_code(decrypt_status, &status);
if (status != HKS_STATUS_OK)
return status;
//将写入明文大小
if (plain_text_length < UINT32_MAX) {
plain_text->size = (uint32_t)plain_text_length;
status = HKS_STATUS_OK;
} else {
status = HKS_ERROR_DATA_CORRUPT;
}
//在此检查返回状态
hks_check_return_code(status, &status);
return status;
}
5.2 hks_service_aead_decrypt_ex
aead解密方案与加密方案的思想类似,都是在参数检查的基础上调用解密服务函数hks_service_aead_decrypt实现的,它的代码如下:
//函数功能:aead解密方案
int32_t hks_service_aead_decrypt_ex(const struct hks_blob *key,
const struct hks_key_param *key_param,
const struct hks_crypt_param *crypt_param,
const struct hks_blob *cipher_text_with_tag,
struct hks_blob *plain_text)
{
//进行输入参数的格式化检查
hks_if_true_return_error(((key == NULL) || (key_param == NULL) || (crypt_param == NULL) ||
(cipher_text_with_tag == NULL) || (plain_text == NULL)), HKS_ERROR_NULL_POINTER);
hks_if_true_return_error((key_param->key_mode != HKS_ALG_GCM), 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_if_true_return_error((plain_text == NULL), HKS_ERROR_NULL_POINTER);
//调用aead算法解密服务对密钥进行解密
return hks_service_aead_decrypt(key, key_param, crypt_param,
cipher_text_with_tag, plain_text);
}
本篇小结
本篇具体介绍了密钥的生成和加密解密算法,其中我们可以发现,核心算法都由ARM提供的mbedtls库实现,真正根算法有关的内容相当少,因此在理清整体代码结构的基础上,我们能够在对各部分的功能有一个初步认识的基础上看懂代码。