539 lines
14 KiB
C++
Executable File
539 lines
14 KiB
C++
Executable File
#include "common_cipher.h"
|
|
#include "common_err.h"
|
|
#include "common_utils.h"
|
|
#include "common_internal_interfaces.h"
|
|
|
|
/** 初始化密码模块
|
|
*
|
|
* @param[in]
|
|
* load_info 密码模块相关信息(硬件设备口令,硬件设备、硬件库路径等),通过kv方式传入
|
|
*
|
|
* @param[out]
|
|
* supported_feature 返回当前密码模块支持的加密方式,参考上述结构体
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
* 示例:
|
|
* 用户设置GUC参数crypto_module_info = 'enable_crypto_module=on,module_third_msg=aaa'
|
|
* 传入接口时load_info = 'aaa'
|
|
*/
|
|
int crypto_module_init(char *load_info, SupportedFeature *supported_feature)
|
|
{
|
|
int ret = CRYPT_MOD_OK;
|
|
|
|
ModuleParams moduleparams;
|
|
|
|
memset(&moduleparams, 0x0, sizeof(ModuleParams));
|
|
|
|
/* 1.解析load_info获取加载密码模块的参数*/
|
|
ret = parse_module_params(load_info, &moduleparams);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
goto err;
|
|
}
|
|
|
|
/* 2.根据密码模块类型填充supported_feature*/
|
|
ret = get_supported_feature(moduleparams.moduletype, supported_feature);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
|
|
goto err;
|
|
}
|
|
|
|
/* 3.dlopen打开密码模块驱动库,并加载接口函数*/
|
|
ret = load_module_driver(moduleparams);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
goto err;
|
|
}
|
|
|
|
/* 4.打开设备*/
|
|
ret = internal_open_device(moduleparams.cfgfilepath);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
goto err;
|
|
}
|
|
|
|
return CRYPT_MOD_OK;
|
|
err:
|
|
/*可能已经打开/加载,尝试释放*/
|
|
(void)internal_close_device();
|
|
(void)unload_module_driver();
|
|
set_thread_errno(ret);
|
|
return ret;
|
|
|
|
}
|
|
|
|
/** 会话中连接密码模块
|
|
*
|
|
* @param[in]
|
|
* key_info 密码相关信息(用户口令等信息),通过kv方式传入
|
|
*
|
|
* @param[out]
|
|
* sess 会话信息
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
* 示例:
|
|
* 用户设置GUC参数tde_key_info = 'keyType=third_kms, keyThirdMsg =bbb'
|
|
* 传入接口时key_info = 'bbb'
|
|
*/
|
|
int crypto_module_sess_init(char *key_info, void **sess)
|
|
{
|
|
int ret = CRYPT_MOD_OK;
|
|
|
|
ret = internal_open_session(sess);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
set_thread_errno(ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/** 会话中断开连接密码模块
|
|
*
|
|
* @param[in]
|
|
* sess 会话信息
|
|
*
|
|
* @param[out]
|
|
*
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
*/
|
|
void crypto_module_sess_exit(void *sess)
|
|
{
|
|
int ret = CRYPT_MOD_OK;
|
|
|
|
ret = internal_close_session(sess);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
set_thread_errno(ret);
|
|
}
|
|
|
|
}
|
|
|
|
/** 创建密钥
|
|
*
|
|
* @param[in]
|
|
* sess 会话信息
|
|
* algo 密钥使用场景的算法
|
|
*
|
|
* @param[out]
|
|
* key_id 返回生成密钥/密钥ID/密钥密文
|
|
* key_id_size 返回生成内容长度
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
*/
|
|
int crypto_create_symm_key(void *sess, ModuleSymmKeyAlgo algo, unsigned char *key_id, size_t *key_id_size)
|
|
{
|
|
int ret = CRYPT_MOD_OK;
|
|
|
|
ret = internal_generate_symm_key(sess, algo, key_id, (unsigned int*)key_id_size);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
set_thread_errno(ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/** 密钥上下文初始化,后续进行加解密可直接使用上下文
|
|
*
|
|
* @param[in]
|
|
* sess 会话信息
|
|
* algo 加密算法
|
|
* enc 加密1、解密0
|
|
* key_id 密码信息
|
|
* key_id_size 密码信息长度
|
|
* @param[out]
|
|
* ctx 返回使用密钥信息
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
*/
|
|
int crypto_ctx_init(void *sess, void **ctx, ModuleSymmKeyAlgo algo, int enc, unsigned char *key_id, size_t key_id_size)
|
|
{
|
|
InternalKeyCtx *keyctx = NULL;
|
|
int ret = CRYPT_MOD_OK;
|
|
|
|
if (sess == NULL) {
|
|
return CRYPTO_MOD_NOT_OPENSESSION_ERR;
|
|
}
|
|
|
|
if (enc != INTERNAL_DO_DEC && enc != INTERNAL_DO_ENC) {
|
|
return CRYPTO_MOD_INVALID_CRYPTO_TYPE_ERR;
|
|
}
|
|
|
|
if (key_id == NULL || key_id[0] == '\0' || key_id_size <= 0 || key_id_size > INTERNAL_MAX_KEY_LEN) {
|
|
return CRYPTO_MOD_INVALID_KEY_ERR;
|
|
}
|
|
|
|
keyctx = (InternalKeyCtx*)malloc(sizeof(InternalKeyCtx));
|
|
|
|
keyctx->session = sess;
|
|
|
|
ret = get_real_symm_algo_type(get_current_module_type(), algo, &(keyctx->algotype), &(keyctx->algomode));
|
|
if (ret != CRYPT_MOD_OK) {
|
|
free(keyctx);
|
|
return ret;
|
|
}
|
|
|
|
keyctx->enc = enc;
|
|
|
|
memset(keyctx->key, 0x0, sizeof(keyctx->key));
|
|
memcpy(keyctx->key, key_id, key_id_size);
|
|
keyctx->keysize = key_id_size;
|
|
|
|
*ctx = keyctx;
|
|
|
|
return CRYPT_MOD_OK;
|
|
}
|
|
|
|
/** 获取数据加解密后的数据长度
|
|
*
|
|
* @param[in]
|
|
* ctx 加解密上下文信息
|
|
* enc 加密1、解密0
|
|
* data_size 返回加解密结果长度
|
|
* @return 返回数据长度
|
|
*
|
|
*/
|
|
int crypto_result_size(void *ctx, int enc, size_t data_size)
|
|
{
|
|
if (ctx == NULL) {
|
|
return CRYPTO_MOD_INVALID_KEY_CTX_ERR;
|
|
}
|
|
|
|
if (enc == INTERNAL_DO_DEC) {
|
|
return data_size;
|
|
} else if (enc == INTERNAL_DO_ENC) {
|
|
return (data_size + INTERNAL_BLOCK_LEN);
|
|
} else
|
|
return CRYPTO_MOD_INVALID_CRYPTO_TYPE_ERR;
|
|
}
|
|
|
|
/** 密钥上下文清理
|
|
*
|
|
* @param[in]
|
|
* ctx 加解密上下文信息
|
|
* @param[out]
|
|
*
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
*/
|
|
void crypto_ctx_clean(void *ctx)
|
|
{
|
|
if (ctx) {
|
|
free(ctx);
|
|
ctx = NULL;
|
|
}
|
|
}
|
|
|
|
/** 执行加解密
|
|
*
|
|
* @param[in]
|
|
* ctx 加解密上下文信息
|
|
* enc 加密1、解密0
|
|
* data 原数据信息
|
|
* data_size 原数据长度
|
|
* iv iv信息
|
|
* iv_size iv信息长度
|
|
* tag GCM模式的校验值
|
|
* @param[out]
|
|
* result 返回结果信息
|
|
* result_size 返回结果信息长度
|
|
*
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
*/
|
|
int crypto_encrypt_decrypt(void *ctx, int enc, unsigned char *data, size_t data_size, unsigned char *iv, size_t iv_size, unsigned char *result, size_t *result_size, unsigned char *tag)
|
|
{
|
|
int ret = CRYPT_MOD_OK;
|
|
|
|
if ((enc == INTERNAL_DO_ENC && *result_size < (data_size + INTERNAL_BLOCK_LEN))
|
|
|| (enc == INTERNAL_DO_DEC && *result_size < data_size)) {
|
|
set_thread_errno(CRYPTO_MOD_NOT_ENOUGH_SPACE_ERR);
|
|
return CRYPTO_MOD_NOT_ENOUGH_SPACE_ERR;
|
|
}
|
|
|
|
if (enc == INTERNAL_DO_ENC) {
|
|
ret = internal_symm_encrypt(ctx, data, data_size, iv, iv_size, result, (unsigned int*)result_size, tag);
|
|
} else if (enc == INTERNAL_DO_DEC) {
|
|
ret = internal_symm_decrypt(ctx, data, data_size, iv, iv_size, result, (unsigned int*)result_size, tag);
|
|
}
|
|
|
|
if (ret != CRYPT_MOD_OK) {
|
|
set_thread_errno(ret);
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
/** 计算摘要
|
|
*
|
|
* @param[in]
|
|
* sess 会话信息
|
|
* algo 摘要算法
|
|
* data 原数据信息
|
|
* data_size 原数据长度
|
|
* @param[out]
|
|
* result 返回结果信息
|
|
* result_size 返回结果信息长度
|
|
*
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
*/
|
|
int crypto_digest(void *sess, ModuleDigestAlgo algo, unsigned char * data, size_t data_size,unsigned char *result, size_t *result_size)
|
|
{
|
|
int ret = CRYPT_MOD_OK;
|
|
|
|
ret = internal_digest(sess, algo, data, data_size, result, (unsigned int*)result_size);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
set_thread_errno(ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/** hmac初始化
|
|
*
|
|
* @param[in]
|
|
* sess 会话信息
|
|
* algo 摘要算法
|
|
* key_id 密码信息
|
|
* key_id_size 密码信息长度
|
|
* @param[out]
|
|
* ctx 返回密钥上下文
|
|
*
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
*/
|
|
int crypto_hmac_init(void *sess, void **ctx, ModuleSymmKeyAlgo algo, unsigned char *key_id, size_t key_id_size)
|
|
{
|
|
InternalKeyCtx *keyctx = NULL;
|
|
int ret = CRYPT_MOD_OK;
|
|
|
|
if (sess == NULL) {
|
|
return CRYPTO_MOD_NOT_OPENSESSION_ERR;
|
|
}
|
|
|
|
if (key_id == NULL || key_id[0] == '\0' || key_id_size <= 0 || key_id_size > INTERNAL_MAX_KEY_LEN) {
|
|
return CRYPTO_MOD_INVALID_KEY_ERR;
|
|
}
|
|
|
|
keyctx = (InternalKeyCtx*)malloc(sizeof(InternalKeyCtx));
|
|
|
|
|
|
keyctx->session = sess;
|
|
|
|
ret = get_real_symm_algo_type(get_current_module_type(), algo, &(keyctx->algotype), &(keyctx->algomode));
|
|
if (ret != CRYPT_MOD_OK) {
|
|
free(keyctx);
|
|
return ret;
|
|
}
|
|
|
|
memcpy(keyctx->key, key_id, key_id_size);
|
|
keyctx->keysize = key_id_size;
|
|
|
|
*ctx = keyctx;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/** hmac清理
|
|
*
|
|
* @param[in]
|
|
* ctx 密钥上下文信息
|
|
*
|
|
* @param[out]
|
|
*
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
*/
|
|
void crypto_hmac_clean(void *ctx)
|
|
{
|
|
if (ctx) {
|
|
free(ctx);
|
|
ctx = NULL;
|
|
}
|
|
}
|
|
|
|
/** 执行hmac计算
|
|
*
|
|
* @param[in]
|
|
* ctx 密钥上下文信息
|
|
* data 原数据信息
|
|
* data_size 原数据长度
|
|
* @param[out]
|
|
* result 返回结果信息
|
|
* result_size 返回结果信息长度
|
|
*
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
*/
|
|
int crypto_hmac(void *ctx, unsigned char * data, size_t data_size, unsigned char *result, size_t *result_size)
|
|
{
|
|
int ret = CRYPT_MOD_OK;
|
|
|
|
ret = internal_hmac(ctx, data, data_size, result, result_size);
|
|
if (ret != CRYPT_MOD_OK)
|
|
set_thread_errno(ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/** 生成随机数
|
|
*
|
|
* @param[in]
|
|
* sess 会话信息
|
|
* size 申请的随机信息长度
|
|
*
|
|
* @param[out]
|
|
* buffer 返回随机信息
|
|
*
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
*/
|
|
int crypto_gen_random(void *sess, char *buffer, size_t size)
|
|
{
|
|
int ret = CRYPT_MOD_OK;
|
|
|
|
ret = internal_generate_random(sess, buffer, size);
|
|
if (ret != CRYPT_MOD_OK)
|
|
set_thread_errno(ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
/** 执行确定性加解密
|
|
*
|
|
* @param[in]
|
|
* sess 会话信息
|
|
* enc 加密1、解密0
|
|
* data 原数据信息
|
|
* data_size 原数据长度
|
|
* key_id 密钥信息
|
|
* key_id_size 密钥信息长度
|
|
* @param[out]
|
|
* result 返回结果信息
|
|
* result_size 返回结果信息长度
|
|
*
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
*/
|
|
int crypto_deterministic_enc_dec(void *sess, int enc, unsigned char *data, unsigned char *key_id, size_t key_id_size, size_t data_size, unsigned char *result, size_t *result_size)
|
|
{
|
|
int ret = CRYPT_MOD_OK;
|
|
void *tmpkeyctx = NULL;
|
|
unsigned char tmpiv[INTERNAL_IV_LEN + 1] = {0};
|
|
|
|
ret = crypto_ctx_init(sess, &tmpkeyctx, MODULE_SM4_CBC, enc, key_id, key_id_size);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
set_thread_errno(ret);
|
|
return ret;
|
|
}
|
|
|
|
/*加密:对明文计算hmac作为iv,并将hmac放到密文串头;
|
|
*解密:从密文头获取iv和hmac,并对解密出的明文计算hmac进行校验*/
|
|
|
|
if (enc == INTERNAL_DO_ENC) {
|
|
void *tmphmacctx = NULL;
|
|
unsigned char tmphmac[INTERNAL_HMAC_LEN] = {0};
|
|
long unsigned int hmaclen = 0;
|
|
|
|
/*计算iv */
|
|
ret = crypto_hmac_init(sess, &tmphmacctx, MODULE_HMAC_SM3, key_id, key_id_size);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
set_thread_errno(ret);
|
|
crypto_ctx_clean(tmpkeyctx);
|
|
return ret;
|
|
}
|
|
|
|
ret = crypto_hmac(tmphmacctx, data, data_size, tmphmac, &hmaclen);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
set_thread_errno(ret);
|
|
crypto_ctx_clean(tmphmacctx);
|
|
crypto_ctx_clean(tmpkeyctx);
|
|
return ret;
|
|
}
|
|
|
|
memcpy(tmpiv, tmphmac, INTERNAL_IV_LEN);
|
|
|
|
/*把hmac放到密文头 */
|
|
memcpy(result, tmphmac, INTERNAL_HMAC_LEN);
|
|
|
|
crypto_hmac_clean(tmphmacctx);
|
|
|
|
|
|
ret = internal_symm_encrypt(tmpkeyctx, data, data_size, tmpiv, INTERNAL_IV_LEN, result + INTERNAL_HMAC_LEN, (unsigned int*)result_size, NULL);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
set_thread_errno(ret);
|
|
}
|
|
|
|
crypto_ctx_clean(tmpkeyctx);
|
|
|
|
*result_size += INTERNAL_HMAC_LEN;
|
|
|
|
return ret;
|
|
|
|
} else if (enc == INTERNAL_DO_DEC){
|
|
void *tmphmacctx = NULL;
|
|
unsigned char tmphmac[INTERNAL_HMAC_LEN] = {0};
|
|
long unsigned int hmaclen = 0;
|
|
unsigned char verifyhmac[INTERNAL_HMAC_LEN] = {0};
|
|
/*获取iv */
|
|
memcpy(tmpiv, data, INTERNAL_IV_LEN);
|
|
|
|
/*获取hmac*/
|
|
memcpy(verifyhmac, data, INTERNAL_HMAC_LEN);
|
|
|
|
ret = internal_symm_decrypt(tmpkeyctx, data + INTERNAL_HMAC_LEN, data_size - INTERNAL_HMAC_LEN, tmpiv, INTERNAL_IV_LEN, result, (unsigned int*)result_size, NULL);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
set_thread_errno(ret);
|
|
crypto_ctx_clean(tmpkeyctx);
|
|
return ret;
|
|
}
|
|
|
|
crypto_ctx_clean(tmpkeyctx);
|
|
|
|
/*计算明文hmac */
|
|
ret = crypto_hmac_init(sess, &tmphmacctx, MODULE_HMAC_SM3, key_id, key_id_size);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
set_thread_errno(ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = crypto_hmac(tmphmacctx, result, *result_size, tmphmac, &hmaclen);
|
|
if (ret != CRYPT_MOD_OK) {
|
|
set_thread_errno(ret);
|
|
crypto_ctx_clean(tmphmacctx);
|
|
return ret;
|
|
}
|
|
|
|
crypto_hmac_clean(tmphmacctx);
|
|
|
|
/*校验明文hmac值 */
|
|
if (strncmp((char*)tmphmac, (char*)verifyhmac, INTERNAL_HMAC_LEN)) {
|
|
set_thread_errno(CRYPTO_MOD_DETERMINISTIC_DEC_VERIFY_ERR);
|
|
return CRYPTO_MOD_DETERMINISTIC_DEC_VERIFY_ERR;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
/** 获取报错信息
|
|
*
|
|
* @param[in]
|
|
* sess 会话信息
|
|
* @param[out]
|
|
* errmsg 返回结果信息,最长256字节
|
|
*
|
|
* @return 成功返回CRYPT_MOD_OK,失败返回错误码
|
|
*
|
|
*/
|
|
int crypto_get_errmsg(void *sess, char *errmsg)
|
|
{
|
|
strcpy(errmsg, common_get_errmsg());
|
|
|
|
return CRYPT_MOD_OK;
|
|
}
|
|
|
|
|