probackup硬件加密添加hmac校验

This commit is contained in:
耶梦加得
2024-09-03 18:49:29 +08:00
parent 0bf4146012
commit 83edb6418e
6 changed files with 110 additions and 32 deletions

View File

@ -2915,6 +2915,7 @@ static void compress_encrypt_directory()
int ret = 0;
bool res = false;
uint key_len = 0;
uint hmac_len = MAX_HMAC_LEN;
uint enc_buffer_len = 0;
uint out_buffer_len = 0;
long int backup_tar_pos = 0;
@ -2923,6 +2924,7 @@ static void compress_encrypt_directory()
char sys_cmd[MAXPGPATH] = {0};
char tar_file[MAXPGPATH] = {0};
char enc_file[MAXPGPATH] = {0};
unsigned char hmac_buffer[MAX_HMAC_LEN + 1] = {0};
unsigned char enc_buffer[MAX_ENCRYPT_LEN + 1] = {0};
unsigned char out_buffer[MAX_ENCRYPT_LEN + 1] = {0};
char errmsg[MAX_ERRMSG_LEN] = {0};
@ -2969,25 +2971,43 @@ static void compress_encrypt_directory()
ret = crypto_create_symm_key_use(crypto_module_session, (ModuleSymmKeyAlgo)algo, (unsigned char*)key, (size_t*)&key_len);
if (ret != 1) {
crypto_get_errmsg_use(NULL, errmsg);
clearCrypto(crypto_module_session, crypto_module_keyctx);
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, "crypto module gen key error, errmsg:%s\n", errmsg);
}
} else {
key = SEC_decodeBase64(encrypt_key, &key_len);
if (NULL == key) {
clearCrypto(crypto_module_session, crypto_module_keyctx);
elog(ERROR, "crypto module decode key error, please check --with-key.");
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, "crypto module decode key error, please check --with-key.\n");
}
}
encrypt_key = SEC_encodeBase64(key, (GS_UINT32)key_len);
if (NULL == encrypt_key) {
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, "crypto module encode key error.\n");
}
elog(INFO, "crypto module encrypt with key: %s , salt: %s \n", encrypt_key, encrypt_salt);
ret = crypto_ctx_init_use(crypto_module_session, &crypto_module_keyctx, (ModuleSymmKeyAlgo)algo, 1, (unsigned char*)key, key_len);
if (ret != 1)
{
crypto_get_errmsg_use(NULL, errmsg);
clearCrypto(crypto_module_session, crypto_module_keyctx);
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, "crypto keyctx init error, errmsg:%s\n", errmsg);
}
algo = getHmacType((ModuleSymmKeyAlgo)algo);
ret = crypto_hmac_init_use(crypto_module_session, &crypto_hmac_keyctx, (ModuleSymmKeyAlgo)algo, (unsigned char*)key, key_len);
if (ret != 1)
{
crypto_get_errmsg_use(NULL, errmsg);
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, "crypto hmac keyctx init error, errmsg:%s\n", errmsg);
}
fseek(backup_tar_fd,0,SEEK_END);
backup_tar_length = ftell(backup_tar_fd);
fseek(backup_tar_fd,0,SEEK_SET);
@ -3011,25 +3031,35 @@ static void compress_encrypt_directory()
ret = memset_s(out_buffer, MAX_ENCRYPT_LEN + 1, '\0', MAX_ENCRYPT_LEN + 1);
securec_check(ret, "\0", "\0");
ret = memset_s(hmac_buffer, MAX_HMAC_LEN + 1, '\0', MAX_HMAC_LEN + 1);
securec_check(ret, "\0", "\0");
ret = crypto_hmac_use(crypto_hmac_keyctx, (unsigned char*)enc_buffer, enc_buffer_len, hmac_buffer, (size_t*)&hmac_len);
if (ret != 1) {
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, ("failed to calculate hmac\n"));
}
ret = crypto_encrypt_decrypt_use(crypto_module_keyctx, 1, (unsigned char*)enc_buffer, enc_buffer_len,
(unsigned char*)encrypt_salt, MAX_IV_LEN, out_buffer, (size_t*)&out_buffer_len, NULL);
if (ret != 1) {
clearCrypto(crypto_module_session, crypto_module_keyctx);
elog(ERROR, ("failed to encrypt backup file"));
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, ("failed to encrypt backup file\n"));
}
fwrite(out_buffer, 1, out_buffer_len, enc_backup_fd);
fwrite(hmac_buffer, 1, hmac_len, enc_backup_fd);
}
fclose(backup_tar_fd);
fclose(enc_backup_fd);
clearCrypto(crypto_module_session, crypto_module_keyctx);
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
rc = sprintf_s(sys_cmd, MAXPGPATH, "rm %s %s.tar -rf", current.root_dir, current.root_dir);
securec_check_ss_c(rc, "\0", "\0");
if (!is_valid_cmd(sys_cmd)) {
elog(ERROR, "cmd is rejected");
elog(ERROR, "cmd is rejected\n");
}
system(sys_cmd);
enc_flag = true;

View File

@ -2884,13 +2884,16 @@ static void uncompress_decrypt_directory(const char *instance_name_str)
DIR *data_dir = NULL;
struct dirent *data_ent = NULL;
uint key_len = 0;
uint hmac_len = MAX_HMAC_LEN;
uint key_idx_uint = 0;
uint dec_buffer_len = 0;
uint out_buffer_len = MAX_CRYPTO_MODULE_LEN;
long int enc_file_pos = 0;
long int enc_file_len = 0;
char sys_cmd[MAXPGPATH] = {0};
char* key = NULL;
char* key = NULL;
unsigned char hmac_read_buffer[MAX_HMAC_LEN +1] = {0};
unsigned char hmac_cal_buffer[MAX_HMAC_LEN +1] = {0};
unsigned char dec_buffer[MAX_CRYPTO_MODULE_LEN + 1] = {0};
unsigned char out_buffer[MAX_CRYPTO_MODULE_LEN + 1] = {0};
char enc_backup_file[MAXPGPATH] = {0};
@ -2912,22 +2915,29 @@ static void uncompress_decrypt_directory(const char *instance_name_str)
rc = crypto_create_symm_key_use(crypto_module_session, (ModuleSymmKeyAlgo)algo, (unsigned char*)key, (size_t*)&key_len);
if (rc != 1) {
crypto_get_errmsg_use(NULL, errmsg);
clearCrypto(crypto_module_session, crypto_module_keyctx);
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, "crypto module gen key error, errmsg:%s\n", errmsg);
}
} else {
key = SEC_decodeBase64(encrypt_key, &key_len);
if (NULL == key) {
clearCrypto(crypto_module_session, crypto_module_keyctx);
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, "crypto module decode key error, please check --with-key.");
}
}
rc = crypto_ctx_init_use(crypto_module_session, &crypto_module_keyctx, (ModuleSymmKeyAlgo)algo, 0, (unsigned char*)key, key_len);
if (rc != 1)
{
if (rc != 1) {
crypto_get_errmsg_use(NULL, errmsg);
clearCrypto(crypto_module_session, crypto_module_keyctx);
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, "crypto keyctx init error, errmsg:%s\n", errmsg);
}
algo = getHmacType((ModuleSymmKeyAlgo)algo);
rc = crypto_hmac_init_use(crypto_module_session, &crypto_hmac_keyctx, (ModuleSymmKeyAlgo)algo, (unsigned char*)key, key_len);
if (rc != 1) {
crypto_get_errmsg_use(NULL, errmsg);
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, "crypto keyctx init error, errmsg:%s\n", errmsg);
}
@ -2949,7 +2959,7 @@ static void uncompress_decrypt_directory(const char *instance_name_str)
FILE* enc_backup_fd = fopen(enc_backup_file,"rb");
if(NULL == enc_backup_fd) {
clearCrypto(crypto_module_session, crypto_module_keyctx);
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, ("failed to create or open encrypt backup file."));
return;
}
@ -2968,17 +2978,18 @@ static void uncompress_decrypt_directory(const char *instance_name_str)
while(enc_file_pos < enc_file_len)
{
if(enc_file_pos + MAX_CRYPTO_MODULE_LEN < enc_file_len) {
memset_s(dec_buffer, MAX_CRYPTO_MODULE_LEN, 0, MAX_CRYPTO_MODULE_LEN);
memset_s(out_buffer, MAX_CRYPTO_MODULE_LEN, 0, MAX_CRYPTO_MODULE_LEN);
memset_s(dec_buffer, MAX_CRYPTO_MODULE_LEN, 0, MAX_CRYPTO_MODULE_LEN);
memset_s(out_buffer, MAX_CRYPTO_MODULE_LEN, 0, MAX_CRYPTO_MODULE_LEN);
if(enc_file_pos + MAX_CRYPTO_MODULE_LEN + MAX_HMAC_LEN < enc_file_len) {
fread(dec_buffer, 1, MAX_CRYPTO_MODULE_LEN, enc_backup_fd);
fread(hmac_read_buffer, 1, MAX_HMAC_LEN, enc_backup_fd);
dec_buffer_len = MAX_CRYPTO_MODULE_LEN;
enc_file_pos += MAX_CRYPTO_MODULE_LEN;
enc_file_pos += (MAX_CRYPTO_MODULE_LEN + MAX_HMAC_LEN);
} else {
memset_s(dec_buffer, MAX_CRYPTO_MODULE_LEN, 0, MAX_CRYPTO_MODULE_LEN);
memset_s(out_buffer, MAX_CRYPTO_MODULE_LEN, 0, MAX_CRYPTO_MODULE_LEN);
fread(dec_buffer, 1, enc_file_len - enc_file_pos, enc_backup_fd);
dec_buffer_len = enc_file_len - enc_file_pos;
fread(dec_buffer, 1, enc_file_len - (enc_file_pos + MAX_HMAC_LEN), enc_backup_fd);
fread(hmac_read_buffer, 1, MAX_HMAC_LEN, enc_backup_fd);
dec_buffer_len = enc_file_len - (enc_file_pos + MAX_HMAC_LEN);
enc_file_pos = enc_file_len;
}
@ -2986,16 +2997,27 @@ static void uncompress_decrypt_directory(const char *instance_name_str)
(unsigned char*)encrypt_salt, MAX_IV_LEN, (unsigned char*)out_buffer, (size_t*)&out_buffer_len, NULL);
if(rc != 1) {
crypto_get_errmsg_use(NULL, errmsg);
clearCrypto(crypto_module_session, crypto_module_keyctx);
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, ("failed to decrypt enc_backup_file, errmsg: %s"), errmsg);
}
rc = crypto_hmac_use(crypto_hmac_keyctx, (unsigned char*)out_buffer, out_buffer_len, hmac_cal_buffer, (size_t*)&hmac_len);
if(rc != 1) {
crypto_get_errmsg_use(NULL, errmsg);
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
elog(ERROR, ("failed to calculate hmac, errmsg: %s"), errmsg);
}
if (strncmp((char*)hmac_cal_buffer, (char*)hmac_read_buffer, (size_t)hmac_len) != 0) {
elog(ERROR, ("hmac verify failed\n"));
}
fwrite(out_buffer, 1, out_buffer_len, dec_file_fd);
}
fclose(dec_file_fd);
fclose(enc_backup_fd);
clearCrypto(crypto_module_session, crypto_module_keyctx);
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
rc = sprintf_s(sys_cmd, MAXPGPATH, "tar -xPf %s/%s.tar", backup_instance_path, data_ent->d_name);

View File

@ -14,9 +14,7 @@ typedef void (*crypto_module_sess_exit_type)(void *sess);
typedef int (*crypto_result_size_type)(void *ctx, int enc, size_t data_size);
typedef void (*crypto_ctx_clean_type)(void *ctx);
typedef int (*crypto_digest_type)(void *sess, ModuleDigestAlgo algo, unsigned char * data, size_t data_size,unsigned char *result, size_t *result_size);
typedef int (*crypto_hmac_init_type)(void *sess, void **ctx, ModuleSymmKeyAlgo algo, unsigned char *key_id, size_t key_id_size);
typedef void (*crypto_hmac_clean_type)(void *ctx);
typedef int (*crypto_hmac_type)(void *ctx, unsigned char * data, size_t data_size, unsigned char *result, size_t *result_size);
typedef int (*crypto_gen_random_type)(void *sess, char *buffer, size_t size);
typedef int (*crypto_deterministic_enc_dec_type)(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);
@ -32,9 +30,9 @@ static crypto_result_size_type crypto_result_size_use = NULL;
static crypto_ctx_clean_type crypto_ctx_clean_use = NULL;
crypto_encrypt_decrypt_type crypto_encrypt_decrypt_use = NULL;
static crypto_digest_type crypto_digest_use = NULL;
static crypto_hmac_init_type crypto_hmac_init_use = NULL;
crypto_hmac_init_type crypto_hmac_init_use = NULL;
static crypto_hmac_clean_type crypto_hmac_clean_use = NULL;
static crypto_hmac_type crypto_hmac_use = NULL;
crypto_hmac_type crypto_hmac_use = NULL;
static crypto_gen_random_type crypto_gen_random_use = NULL;
static crypto_deterministic_enc_dec_type crypto_deterministic_enc_dec_use = NULL;
crypto_get_errmsg_type crypto_get_errmsg_use = NULL;
@ -127,6 +125,17 @@ int transform_type(const char* type)
}
int getHmacType(ModuleSymmKeyAlgo algo)
{
if (algo >= MODULE_AES_128_CBC && algo <= MODULE_AES_256_GCM) {
return MODULE_HMAC_SHA256;
} else if (algo == MODULE_SM4_CBC || algo == MODULE_SM4_CTR) {
return MODULE_HMAC_SM3;
}
return MODULE_ALGO_MAX;
}
void initCryptoModule(char* crypto_module_params, const char* encrypt_mode)
{
int ret = 1;
@ -184,8 +193,17 @@ void releaseCryptoCtx(void* crypto_module_keyctx)
}
}
void clearCrypto(void* crypto_module_session, void* crypto_module_keyctx)
void releaseHmacCtx(void* crypto_hmac_keyctx)
{
if (libhandle && crypto_hmac_keyctx) {
crypto_hmac_clean_use(crypto_hmac_keyctx);
crypto_hmac_keyctx = NULL;
}
}
void clearCrypto(void* crypto_module_session, void* crypto_module_keyctx, void* crypto_hmac_keyctx)
{
releaseHmacCtx(crypto_hmac_keyctx);
releaseCryptoCtx(crypto_module_keyctx);
releaseCryptoSession(crypto_module_session);
unload_crypto_module();

View File

@ -19,6 +19,7 @@ extern "C" {
#define MAX_PROVIDER_NAME_LEN 128
#define MAX_ERRMSG_LEN 256
#define MAX_IV_LEN 16
#define MAX_HMAC_LEN 32
typedef enum {
MODULE_AES_128_CBC = 0,
@ -60,20 +61,25 @@ typedef int (*crypto_encrypt_decrypt_type)(void *ctx, int enc, unsigned char *da
typedef int (*crypto_create_symm_key_type)(void *sess, ModuleSymmKeyAlgo algo, unsigned char *key_id, size_t *key_id_size);
typedef int (*crypto_get_errmsg_type)(void *sess, char *errmsg);
typedef int (*crypto_ctx_init_type)(void *sess, void **ctx, ModuleSymmKeyAlgo algo, int enc, unsigned char *key_id, size_t key_id_size);
typedef int (*crypto_hmac_init_type)(void *sess, void **ctx, ModuleSymmKeyAlgo algo, unsigned char *key_id, size_t key_id_size);
typedef int (*crypto_hmac_type)(void *ctx, unsigned char * data, size_t data_size, unsigned char *result, size_t *result_size);
extern crypto_create_symm_key_type crypto_create_symm_key_use;
extern crypto_encrypt_decrypt_type crypto_encrypt_decrypt_use;
extern crypto_get_errmsg_type crypto_get_errmsg_use;
extern crypto_ctx_init_type crypto_ctx_init_use;
extern crypto_hmac_init_type crypto_hmac_init_use;
extern crypto_hmac_type crypto_hmac_use;
extern int transform_type(const char* type);
extern int getHmacType(ModuleSymmKeyAlgo algo);
extern bool load_crypto_module_lib();
extern void unload_crypto_module();
extern void initCryptoModule(char* crypto_module_params, const char* encrypt_mode);
extern void initCryptoSession(void** crypto_module_session);
extern void releaseCryptoSession(void* crypto_module_session);
extern void releaseCryptoCtx(void* crypto_module_keyctx);
extern void clearCrypto(void* crypto_module_session, void* crypto_module_keyctx);
extern void clearCrypto(void* crypto_module_session, void* crypto_module_keyctx, void* crypto_hmac_keyctx);
extern void CryptoModuleParamsCheck(bool gen_key, char* params, const char* module_encrypt_mode, const char* module_encrypt_key, const char* module_encrypt_salt);
#ifdef __cplusplus

View File

@ -160,6 +160,7 @@ char* encrypt_salt = NULL;
char* encrypt_dev_params = NULL;
void* crypto_module_session = NULL;
void* crypto_module_keyctx = NULL;
void* crypto_hmac_keyctx = NULL;
/* Mark whether encryption and decryption are performed */
/* only when encryption and decryption are actually performed will it be marked as true */
@ -640,7 +641,7 @@ static int do_actual_operate()
delete_backup_directory(instance_name);
on_cleanup();
release_logfile();
clearCrypto(crypto_module_session, crypto_module_keyctx);
clearCrypto(crypto_module_session, crypto_module_keyctx, crypto_hmac_keyctx);
return res;
}

View File

@ -88,6 +88,7 @@ extern char* encrypt_salt;
extern char* encrypt_dev_params;
extern void* crypto_module_session;
extern void* crypto_module_keyctx;
extern void* crypto_hmac_keyctx;
extern bool do_enc;
extern bool enc_flag;