[CP] support load the soft module to encrypt data

This commit is contained in:
obdev
2023-02-10 08:11:16 +00:00
committed by ob-robot
parent 6525b0514a
commit 63440bd16e
7 changed files with 182 additions and 2 deletions

View File

@ -87,6 +87,7 @@ int ObServerReloadConfig::operator()()
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
int real_ret = ret; int real_ret = ret;
if (!gctx_.is_inited()) { if (!gctx_.is_inited()) {
real_ret = ret = OB_INNER_STAT_ERROR; real_ret = ret = OB_INNER_STAT_ERROR;
LOG_WARN("gctx not init", "gctx inited", gctx_.is_inited(), K(ret)); LOG_WARN("gctx not init", "gctx inited", gctx_.is_inited(), K(ret));
@ -124,6 +125,10 @@ int ObServerReloadConfig::operator()()
real_ret = ret; real_ret = ret;
LOG_WARN("reload config for ratelimit manager fail", K(ret)); LOG_WARN("reload config for ratelimit manager fail", K(ret));
} }
if (OB_FAIL(ObTdeEncryptEngineLoader::get_instance().reload_config())) {
real_ret = ret;
LOG_WARN("reload config for tde encrypt engine fail", K(ret));
}
} }
{ {
GMEMCONF.reload_config(GCONF); GMEMCONF.reload_config(GCONF);

View File

@ -86,6 +86,8 @@ int ObConfigManager::reload_config()
LOG_WARN("reload config for ratelimit manager fail", K(ret)); LOG_WARN("reload config for ratelimit manager fail", K(ret));
} else if (OB_FAIL(OBSERVER.get_net_frame().reload_mysql_login_thread_config())) { } else if (OB_FAIL(OBSERVER.get_net_frame().reload_mysql_login_thread_config())) {
LOG_WARN("reload config for mysql login thread count failed", K(ret)); LOG_WARN("reload config for mysql login thread count failed", K(ret));
} else if (OB_FAIL(ObTdeEncryptEngineLoader::get_instance().reload_config())) {
LOG_WARN("reload config for tde encrypt engine fail", K(ret));
} }
return ret; return ret;
} }

View File

@ -18,8 +18,10 @@
#include "ob_encryption_struct.h" #include "ob_encryption_struct.h"
#include "lib/alloc/alloc_assist.h" #include "lib/alloc/alloc_assist.h"
#include "share/ob_errno.h" #include "share/ob_errno.h"
#include "lib/atomic/atomic128.h"
#include "lib/string/ob_string.h" #include "lib/string/ob_string.h"
#include "lib/random/ob_random.h" #include "lib/random/ob_random.h"
#include "lib/utility/ob_macro_utils.h"
#include "observer/ob_server_struct.h" #include "observer/ob_server_struct.h"
#include "observer/omt/ob_tenant_config_mgr.h" #include "observer/omt/ob_tenant_config_mgr.h"
@ -149,6 +151,8 @@ int ObAesEncryption::aes_encrypt(const char *key, const int64_t &key_len, const
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
int64_t expect_buf_len = (data_len / OB_AES_BLOCK_SIZE + 1) * OB_AES_BLOCK_SIZE; int64_t expect_buf_len = (data_len / OB_AES_BLOCK_SIZE + 1) * OB_AES_BLOCK_SIZE;
bool need_iv = false; bool need_iv = false;
ENGINE *engine = NULL;
common::ObString err_reason;
if (OB_ISNULL(buf) || buf_len < expect_buf_len || key_len < 0 || if (OB_ISNULL(buf) || buf_len < expect_buf_len || key_len < 0 ||
ObAesOpMode::ob_invalid_mode == mode || ObAesOpMode::ob_invalid_mode == mode ||
(iv_len != 0 && iv_len != OB_AES_IV_SIZE) || (iv_len != 0 && iv_len != OB_AES_IV_SIZE) ||
@ -162,6 +166,12 @@ int ObAesEncryption::aes_encrypt(const char *key, const int64_t &key_len, const
int u_len=0, f_len=0; int u_len=0, f_len=0;
unsigned char rkey[OB_MAX_AES_KEY_LENGTH / 8]; unsigned char rkey[OB_MAX_AES_KEY_LENGTH / 8];
unsigned char *iv_encrypt = need_iv ? (unsigned char *)iv : NULL; unsigned char *iv_encrypt = need_iv ? (unsigned char *)iv : NULL;
engine = ObTdeEncryptEngineLoader::get_instance().get_tde_engine(mode);
if (NULL != engine) {
if (EXECUTE_COUNT_PER_SEC(1)) {
LOG_INFO("tde use engine to encrypt data", K(mode));
}
}
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if (OB_ISNULL(ctx)) { if (OB_ISNULL(ctx)) {
ret = OB_INVALID_ARGUMENT; ret = OB_INVALID_ARGUMENT;
@ -169,7 +179,7 @@ int ObAesEncryption::aes_encrypt(const char *key, const int64_t &key_len, const
} else if (FALSE_IT(EVP_CIPHER_CTX_init(ctx))) { } else if (FALSE_IT(EVP_CIPHER_CTX_init(ctx))) {
} else if (FALSE_IT(aes_create_key((const unsigned char *)key, (int)key_len, } else if (FALSE_IT(aes_create_key((const unsigned char *)key, (int)key_len,
(char *)rkey, mode))) { (char *)rkey, mode))) {
} else if (!EVP_EncryptInit(ctx, aes_evp_type(mode), rkey, iv_encrypt)) { } else if (!EVP_EncryptInit_ex(ctx, aes_evp_type(mode), engine, rkey, iv_encrypt)) {
ret = OB_ERR_AES_ENCRYPT; ret = OB_ERR_AES_ENCRYPT;
LOG_WARN("fail to init evp ctx in aes_encrypt", K(ret)); LOG_WARN("fail to init evp ctx in aes_encrypt", K(ret));
} else if (!EVP_CIPHER_CTX_set_padding(ctx, true)) { } else if (!EVP_CIPHER_CTX_set_padding(ctx, true)) {
@ -184,6 +194,10 @@ int ObAesEncryption::aes_encrypt(const char *key, const int64_t &key_len, const
} else { } else {
out_len = u_len + f_len; out_len = u_len + f_len;
} }
if (OB_FAIL(ret)) {
err_reason = common::ObString::make_string(ERR_reason_error_string(ERR_get_error()));
LOG_WARN("tde encrypt failed", K(err_reason));
}
if (OB_NOT_NULL(ctx)) { if (OB_NOT_NULL(ctx)) {
EVP_CIPHER_CTX_free(ctx); EVP_CIPHER_CTX_free(ctx);
} }
@ -197,6 +211,8 @@ int ObAesEncryption::aes_decrypt(const char *key, const int64_t &key_len, const
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
bool need_iv = false; bool need_iv = false;
ENGINE *engine = NULL;
common::ObString err_reason;
if (OB_ISNULL(buf) || key_len < 0 || buf_len < data_len || if (OB_ISNULL(buf) || key_len < 0 || buf_len < data_len ||
ObAesOpMode::ob_invalid_mode == mode || ObAesOpMode::ob_invalid_mode == mode ||
(iv_len != 0 && iv_len != OB_AES_IV_SIZE) || (iv_len != 0 && iv_len != OB_AES_IV_SIZE) ||
@ -210,6 +226,12 @@ int ObAesEncryption::aes_decrypt(const char *key, const int64_t &key_len, const
int u_len=0, f_len=0; int u_len=0, f_len=0;
unsigned char rkey[OB_MAX_AES_KEY_LENGTH / 8]; unsigned char rkey[OB_MAX_AES_KEY_LENGTH / 8];
unsigned char *iv_encrypt = need_iv ? (unsigned char *)iv : NULL; unsigned char *iv_encrypt = need_iv ? (unsigned char *)iv : NULL;
engine = ObTdeEncryptEngineLoader::get_instance().get_tde_engine(mode);
if (NULL != engine) {
if (EXECUTE_COUNT_PER_SEC(1)) {
LOG_INFO("tde use engine to decrypt data", K(mode));
}
}
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if (OB_ISNULL(ctx)) { if (OB_ISNULL(ctx)) {
ret = OB_INVALID_ARGUMENT; ret = OB_INVALID_ARGUMENT;
@ -217,7 +239,7 @@ int ObAesEncryption::aes_decrypt(const char *key, const int64_t &key_len, const
} else if (FALSE_IT(EVP_CIPHER_CTX_init(ctx))) { } else if (FALSE_IT(EVP_CIPHER_CTX_init(ctx))) {
} else if (FALSE_IT(aes_create_key((const unsigned char *)key, (int)key_len, } else if (FALSE_IT(aes_create_key((const unsigned char *)key, (int)key_len,
(char *)rkey, mode))) { (char *)rkey, mode))) {
} else if (!EVP_DecryptInit(ctx, aes_evp_type(mode), rkey, iv_encrypt)) { } else if (!EVP_DecryptInit_ex(ctx, aes_evp_type(mode), engine, rkey, iv_encrypt)) {
ret = OB_ERR_AES_DECRYPT; ret = OB_ERR_AES_DECRYPT;
LOG_WARN("fail to init evp ctx in aes_decrypt", K(ret)); LOG_WARN("fail to init evp ctx in aes_decrypt", K(ret));
} else if (!EVP_CIPHER_CTX_set_padding(ctx, true)) { } else if (!EVP_CIPHER_CTX_set_padding(ctx, true)) {
@ -232,6 +254,10 @@ int ObAesEncryption::aes_decrypt(const char *key, const int64_t &key_len, const
} else { } else {
out_len = u_len + f_len; out_len = u_len + f_len;
} }
if (OB_FAIL(ret)) {
err_reason = common::ObString::make_string(ERR_reason_error_string(ERR_get_error()));
LOG_WARN("tde decrypt failed", K(err_reason));
}
if (OB_NOT_NULL(ctx)) { if (OB_NOT_NULL(ctx)) {
EVP_CIPHER_CTX_free(ctx); EVP_CIPHER_CTX_free(ctx);
} }
@ -485,5 +511,118 @@ const EVP_MD* ObHashUtil::get_hash_evp_md(const ObHashAlgorithm algo)
} }
} }
void ObTdeEncryptEngineLoader::ssl_init()
{
OpenSSL_add_all_digests();
OpenSSL_add_all_ciphers();
OPENSSL_load_builtin_modules();
ENGINE_load_builtin_engines();
ERR_load_ERR_strings();
}
int ObTdeEncryptEngineLoader::load(const common::ObString& engine)
{
int ret = OB_SUCCESS;
common::ObString err_reason;
ObEncryptEngineType type = get_engine_type(engine);
if (OB_NONE_ENGINE == type) {
} else if (OB_INVALID_ENGINE == type) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("unsupport engine", K(engine));
} else {
if (NULL == tde_engine_[type]) {
tde_engine_[type] = ENGINE_by_id(engine.ptr());
if (NULL == tde_engine_[type]) {
ret = OB_INIT_FAIL;
err_reason = common::ObString::make_string(ERR_reason_error_string(ERR_get_error()));
LOG_WARN("load engine failed", K(engine), K(err_reason));
} else if (!ENGINE_init(tde_engine_[type])) {
ret = OB_INIT_FAIL;
err_reason = common::ObString::make_string(ERR_reason_error_string(ERR_get_error()));
LOG_WARN("Failed initialisation engine!", K(engine), K(err_reason));
ENGINE_free(tde_engine_[type]);
tde_engine_[type] = NULL;
} else {
LOG_INFO("tde install engine success", K(engine));
}
}
}
return ret;
}
void ObTdeEncryptEngineLoader::destroy()
{
for (int i = 0; i < OB_MAX_ENGINE; i++) {
if (NULL != tde_engine_[i]) {
ENGINE_finish(tde_engine_[i]);
ENGINE_free(tde_engine_[i]);
}
}
}
ENGINE* ObTdeEncryptEngineLoader::get_tde_engine(ObAesOpMode &mode) const
{
ObEncryptEngineType type = OB_INVALID_ENGINE;
switch(mode) {
case ob_sm4_mode:
case ob_sm4_cbc_mode:
type = OB_SM4_ENGINE;
break;
case ob_aes_128_ecb:
case ob_aes_128_cbc:
case ob_aes_128_cfb1:
case ob_aes_128_cfb8:
case ob_aes_128_cfb128:
case ob_aes_128_ofb:
case ob_aes_192_ecb:
case ob_aes_192_cbc:
case ob_aes_192_cfb1:
case ob_aes_192_cfb8:
case ob_aes_192_cfb128:
case ob_aes_192_ofb:
case ob_aes_256_ecb:
case ob_aes_256_cbc:
case ob_aes_256_cfb1:
case ob_aes_256_cfb8:
case ob_aes_256_cfb128:
case ob_aes_256_ofb:
type = OB_AES_ENGINE;
break;
case ob_invalid_mode:
case ob_max_mode:
type = OB_INVALID_ENGINE;
break;
}
return tde_engine_[type];
}
ObTdeEncryptEngineLoader &ObTdeEncryptEngineLoader::get_instance()
{
static ObTdeEncryptEngineLoader instance;
return instance;
}
ObTdeEncryptEngineLoader::ObEncryptEngineType ObTdeEncryptEngineLoader::get_engine_type(const common::ObString& engine)
{
ObEncryptEngineType type = OB_INVALID_ENGINE;
if (OB_NOT_NULL(strcasestr(engine.ptr(), "sm4"))) {
type = OB_SM4_ENGINE;
} else if (OB_NOT_NULL(strcasestr(engine.ptr(), "hy"))) {
type = OB_SM4_ENGINE;
} else if (OB_NOT_NULL(strcasestr(engine.ptr(), "aes"))) {
type = OB_AES_ENGINE;
} else if (0 == engine.case_compare("none")) {
type = OB_NONE_ENGINE;
}
return type;
}
int ObTdeEncryptEngineLoader::reload_config()
{
int ret = OB_SUCCESS;
common::ObString engine = GCONF._load_tde_encrypt_engine.get_value_string();
return load(engine);
}
}//end share }//end share
} //end oceanbase } //end oceanbase

View File

@ -171,6 +171,32 @@ private:
static const EVP_MD* get_hash_evp_md(const ObHashAlgorithm algo); static const EVP_MD* get_hash_evp_md(const ObHashAlgorithm algo);
}; };
class ObTdeEncryptEngineLoader {
public:
enum ObEncryptEngineType {
OB_NONE_ENGINE = 0,
OB_INVALID_ENGINE = 1,
OB_AES_ENGINE = 2,
OB_SM4_ENGINE = 3,
OB_MAX_ENGINE
};
static ObTdeEncryptEngineLoader &get_instance();
ObTdeEncryptEngineLoader() {
ssl_init();
MEMSET(tde_engine_, 0, sizeof(ENGINE*)*OB_MAX_ENGINE);
}
~ObTdeEncryptEngineLoader() { destroy(); }
void ssl_init();
void destroy();
int load(const common::ObString& engine);
ObEncryptEngineType get_engine_type(const common::ObString& engine);
ENGINE* get_tde_engine(ObAesOpMode &mode) const;
int reload_config();
private:
bool is_inited_;
ENGINE* tde_engine_[OB_MAX_ENGINE];
};
}//end share }//end share
} //end oceanbase } //end oceanbase
#endif #endif

View File

@ -1361,3 +1361,6 @@ DEF_BOOL(_enable_protocol_diagnose, OB_CLUSTER_PARAMETER, "True",
DEF_BOOL(_enable_transaction_internal_routing, OB_TENANT_PARAMETER, "True", DEF_BOOL(_enable_transaction_internal_routing, OB_TENANT_PARAMETER, "True",
"enable SQLs of transaction routed to any servers in the cluster on demand", "enable SQLs of transaction routed to any servers in the cluster on demand",
ObParameterAttr(Section::TRANS, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); ObParameterAttr(Section::TRANS, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
DEF_STR(_load_tde_encrypt_engine, OB_CLUSTER_PARAMETER, "NONE",
"load the engine that meet the security classification requirement to encrypt data. default NONE",
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));

View File

@ -2086,6 +2086,10 @@ int ObSetConfigResolver::check_param_valid(int64_t tenant_id ,
LOG_WARN("ERRSIM, fail to set ssl invite node", K(ret)); LOG_WARN("ERRSIM, fail to set ssl invite node", K(ret));
} }
#endif #endif
} else if (0 == name.case_compare("_load_tde_encrypt_engine")) {
if (OB_FAIL(share::ObTdeEncryptEngineLoader::get_instance().load(value))) {
LOG_WARN("load antsm-engine failed", K(ret));
}
} }
} }
return ret; return ret;

View File

@ -270,6 +270,7 @@ _ignore_system_memory_over_limit_error
_io_callback_thread_count _io_callback_thread_count
_large_query_io_percentage _large_query_io_percentage
_lcl_op_interval _lcl_op_interval
_load_tde_encrypt_engine
_max_elr_dependent_trx_count _max_elr_dependent_trx_count
_max_schema_slot_num _max_schema_slot_num
_migrate_block_verify_level _migrate_block_verify_level