add encryption (#1002)

* add encryption

* add doc

* add doc

* fix bug
This commit is contained in:
Thomas Young
2023-01-03 15:57:03 +08:00
committed by GitHub
parent 11ce2f42a7
commit ab49b41080
32 changed files with 1865 additions and 1 deletions

View File

@@ -64,6 +64,7 @@ option(ENABLE_LITE_BACKEND "Whether to enable paddle lite backend." OFF)
option(ENABLE_VISION "Whether to enable vision models usage." OFF)
option(ENABLE_TEXT "Whether to enable text models usage." OFF)
option(ENABLE_FLYCV "Whether to enable flycv to boost image preprocess." OFF)
option(ENABLE_ENCRYPTION "Whether to enable ENCRYPTION." OFF)
option(WITH_ASCEND "Whether to compile for Huawei Ascend deploy." OFF)
option(WITH_TIMVX "Whether to compile for TIMVX deploy." OFF)
option(WITH_KUNLUNXIN "Whether to compile for KunlunXin XPU deploy." OFF)
@@ -195,11 +196,13 @@ file(GLOB_RECURSE DEPLOY_OPENVINO_SRCS ${PROJECT_SOURCE_DIR}/${CSRCS_DIR_NAME}/f
file(GLOB_RECURSE DEPLOY_RKNPU2_SRCS ${PROJECT_SOURCE_DIR}/${CSRCS_DIR_NAME}/fastdeploy/backends/rknpu/rknpu2/*.cc)
file(GLOB_RECURSE DEPLOY_LITE_SRCS ${PROJECT_SOURCE_DIR}/${CSRCS_DIR_NAME}/fastdeploy/backends/lite/*.cc)
file(GLOB_RECURSE DEPLOY_VISION_SRCS ${PROJECT_SOURCE_DIR}/${CSRCS_DIR_NAME}/fastdeploy/vision/*.cc)
file(GLOB_RECURSE DEPLOY_ENCRYPTION_SRCS ${PROJECT_SOURCE_DIR}/${CSRCS_DIR_NAME}/fastdeploy/encryption/*.cc)
file(GLOB_RECURSE DEPLOY_PIPELINE_SRCS ${PROJECT_SOURCE_DIR}/${CSRCS_DIR_NAME}/fastdeploy/pipeline/*.cc)
file(GLOB_RECURSE DEPLOY_VISION_CUDA_SRCS ${PROJECT_SOURCE_DIR}/${CSRCS_DIR_NAME}/fastdeploy/vision/*.cu)
file(GLOB_RECURSE DEPLOY_TEXT_SRCS ${PROJECT_SOURCE_DIR}/${CSRCS_DIR_NAME}/fastdeploy/text/*.cc)
file(GLOB_RECURSE DEPLOY_PYBIND_SRCS ${PROJECT_SOURCE_DIR}/${CSRCS_DIR_NAME}/fastdeploy/pybind/*.cc ${PROJECT_SOURCE_DIR}/${CSRCS_DIR_NAME}/fastdeploy/*_pybind.cc)
list(REMOVE_ITEM ALL_DEPLOY_SRCS ${DEPLOY_ORT_SRCS} ${DEPLOY_PADDLE_SRCS} ${DEPLOY_POROS_SRCS} ${DEPLOY_TRT_SRCS} ${DEPLOY_OPENVINO_SRCS} ${DEPLOY_LITE_SRCS} ${DEPLOY_VISION_SRCS} ${DEPLOY_TEXT_SRCS} ${DEPLOY_PIPELINE_SRCS} ${DEPLOY_RKNPU2_SRCS})
list(REMOVE_ITEM ALL_DEPLOY_SRCS ${DEPLOY_ORT_SRCS} ${DEPLOY_PADDLE_SRCS} ${DEPLOY_POROS_SRCS} ${DEPLOY_TRT_SRCS} ${DEPLOY_OPENVINO_SRCS} ${DEPLOY_LITE_SRCS} ${DEPLOY_VISION_SRCS} ${DEPLOY_TEXT_SRCS} ${DEPLOY_PIPELINE_SRCS} ${DEPLOY_RKNPU2_SRCS} ${DEPLOY_ENCRYPTION_SRCS})
set(DEPEND_LIBS "")
@@ -441,6 +444,14 @@ if(ENABLE_TEXT)
include(${PROJECT_SOURCE_DIR}/cmake/fast_tokenizer.cmake)
endif()
if(ENABLE_ENCRYPTION)
add_definitions(-DENABLE_ENCRYPTION)
list(APPEND ALL_DEPLOY_SRCS ${DEPLOY_ENCRYPTION_SRCS})
include(${PROJECT_SOURCE_DIR}/cmake/gflags.cmake)
include(${PROJECT_SOURCE_DIR}/cmake/openssl.cmake)
list(APPEND DEPEND_LIBS ${OPENSSL_LIBRARIES})
endif()
if(ENABLE_PADDLE_FRONTEND)
add_definitions(-DENABLE_PADDLE_FRONTEND)
include(${PROJECT_SOURCE_DIR}/cmake/paddle2onnx.cmake)
@@ -653,6 +664,11 @@ if(BUILD_FASTDEPLOY_PYTHON)
list(REMOVE_ITEM DEPLOY_PYBIND_SRCS ${VISION_PYBIND_SRCS} ${PIPELINE_PYBIND_SRCS})
endif()
if(NOT ENABLE_ENCRYPTION)
file(GLOB_RECURSE ENCRYPTION_PYBIND_SRCS ${PROJECT_SOURCE_DIR}/${CSRCS_DIR_NAME}/fastdeploy/encryption/*_pybind.cc)
list(REMOVE_ITEM DEPLOY_PYBIND_SRCS ${ENCRYPTION_PYBIND_SRCS})
endif()
if (NOT ENABLE_TEXT)
file(GLOB_RECURSE TEXT_PYBIND_SRCS ${PROJECT_SOURCE_DIR}/${CSRCS_DIR_NAME}/fastdeploy/text/*_pybind.cc)
list(REMOVE_ITEM DEPLOY_PYBIND_SRCS ${TEXT_PYBIND_SRCS})

View File

@@ -13,6 +13,7 @@ set(ENABLE_PADDLE_FRONTEND @ENABLE_PADDLE_FRONTEND@)
set(ENABLE_VISION @ENABLE_VISION@)
set(ENABLE_FLYCV @ENABLE_FLYCV@)
set(ENABLE_TEXT @ENABLE_TEXT@)
set(ENABLE_ENCRYPTION @ENABLE_ENCRYPTION@)
set(BUILD_ON_JETSON @BUILD_ON_JETSON@)
set(PADDLEINFERENCE_VERSION @PADDLEINFERENCE_VERSION@)
set(OPENVINO_VERSION @OPENVINO_VERSION@)
@@ -287,6 +288,7 @@ endif()
message(STATUS " ENABLE_TRT_BACKEND : ${ENABLE_TRT_BACKEND}")
message(STATUS " ENABLE_VISION : ${ENABLE_VISION}")
message(STATUS " ENABLE_TEXT : ${ENABLE_TEXT}")
message(STATUS " ENABLE_ENCRYPTION : ${ENABLE_ENCRYPTION}")
if(WITH_GPU)
message(STATUS " CUDA_DIRECTORY : ${CUDA_DIRECTORY}")
endif()

50
cmake/openssl.cmake Executable file
View File

@@ -0,0 +1,50 @@
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
SET(OPENSSL_URL_PREFIX "https://bj.bcebos.com/paddlex/tools")
IF(CMAKE_SYSTEM_NAME MATCHES "Windows")
set(OPENSSL_FILENAME "windows_openssl-1.1.0k")
set(COMPRESSED_SUFFIX ".zip")
add_definitions(-DWIN32)
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(OPENSSL_FILENAME "openssl-1.1.0k")
set(COMPRESSED_SUFFIX ".tar.gz")
add_definitions(-DLINUX)
ENDIF()
set(OPENSSL_URL ${OPENSSL_URL_PREFIX}/${OPENSSL_FILENAME}${COMPRESSED_SUFFIX})
if(THIRD_PARTY_PATH)
SET(OPENSSL_INSTALL_DIR ${THIRD_PARTY_PATH})
SET(OPENSSL_ROOT_DIR ${THIRD_PARTY_PATH}/openssl-1.1.0k/install-${CMAKE_SYSTEM_PROCESSOR})
else()
SET(OPENSSL_INSTALL_DIR ${FASTDEPLOY_INSTALL_DIR}/installed_fastdeploy/cmake)
SET(OPENSSL_ROOT_DIR ${FASTDEPLOY_INSTALL_DIR}/installed_fastdeploy/cmake/openssl-1.1.0k/install-${CMAKE_SYSTEM_PROCESSOR})
endif()
download_and_decompress(${OPENSSL_URL} ${CMAKE_CURRENT_BINARY_DIR}/${OPENSSL_FILENAME}${COMPRESSED_SUFFIX} ${OPENSSL_INSTALL_DIR})
SET(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/include" CACHE PATH "openssl include directory." FORCE)
include_directories(${OPENSSL_INCLUDE_DIR})
IF(CMAKE_SYSTEM_NAME MATCHES "Windows")
set(OPENSSL_LIBRARIES
"${OPENSSL_ROOT_DIR}/lib/libssl_static.lib"
"${OPENSSL_ROOT_DIR}/lib/libcrypto_static.lib"
${GFLAGS_LIBRARIES}
shlwapi
CACHE FILEPATH "OPENSSL_LIBRARIES" FORCE)
ELSEIF (CMAKE_SYSTEM_NAME MATCHES "Linux")
set(OPENSSL_LIBRARIES
"${OPENSSL_ROOT_DIR}/lib/libssl.a"
"${OPENSSL_ROOT_DIR}/lib/libcrypto.a"
${GFLAGS_LIBRARIES}
-ldl -lpthread
CACHE FILEPATH "OPENSSL_LIBRARIES" FORCE)
ENDIF()

View File

@@ -60,6 +60,7 @@ function(fastdeploy_summary)
endif()
message(STATUS " ENABLE_VISION : ${ENABLE_VISION}")
message(STATUS " ENABLE_TEXT : ${ENABLE_TEXT}")
message(STATUS " ENABLE_ENCRYPTION : ${ENABLE_ENCRYPTION}")
message(STATUS " ENABLE_DEBUG : ${ENABLE_DEBUG}")
message(STATUS " ENABLE_VISION_VISUALIZE : ${ENABLE_VISION_VISUALIZE}")
if(ANDROID)

20
fastdeploy/encryption.h Executable file
View File

@@ -0,0 +1,20 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "fastdeploy/core/config.h"
#ifdef ENABLE_ENCRYPTION
#include "fastdeploy/encryption/include/decrypt.h"
#include "fastdeploy/encryption/include/encrypt.h"
#endif

View File

@@ -0,0 +1,30 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "fastdeploy/pybind/main.h"
namespace fastdeploy {
void BindEncryption(pybind11::module& m) {
m.def("encrypt", [](const std::string& input, const std::string& key) {
return Encrypt(input, key);
});
m.def("decrypt", [](const std::string& cipher, const std::string& key) {
return Decrypt(cipher, key);
});
m.def("generate_key", []() {
return GenerateRandomKey();
});
}
} // namespace fastdeploy

View File

@@ -0,0 +1,60 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdio.h>
#include <string>
#include "fastdeploy/utils/utils.h"
#ifndef PADDLE_MODEL_PROTECT_API_PADDLE_MODEL_DECRYPT_H
#define PADDLE_MODEL_PROTECT_API_PADDLE_MODEL_DECRYPT_H
namespace fastdeploy {
#ifdef __cplusplus
extern "C" {
#endif
/** \brief check stream is encrypted or not
*
* \param[in] cipher_stream The encrypted stream
* \return 0 if stream is encrypted.
*/
FASTDEPLOY_DECL int CheckStreamEncrypted(std::istream& cipher_stream);
/** \brief decrypt an encrypted stream
*
* \param[in] cipher_stream The encrypted stream
* \param[in] plain_stream The decrypted stream
* \param[in] key_base64 The key for decryption
* \return 0 if decrypt success.
*/
FASTDEPLOY_DECL int DecryptStream(std::istream& cipher_stream,
std::ostream& plain_stream,
const std::string& key_base64);
/** \brief decrypt an encrypted string
*
* \param[in] cipher The encrypted string
* \param[in] key The key for decryption
* \return The decrypted string
*/
FASTDEPLOY_DECL std::string Decrypt(const std::string& cipher,
const std::string& key);
#ifdef __cplusplus
}
#endif
} // namespace fastdeploy
#endif // PADDLE_MODEL_PROTECT_API_PADDLE_MODEL_DECRYPT_H

View File

@@ -0,0 +1,58 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <iostream>
#include <string>
#include "fastdeploy/utils/utils.h"
#ifndef PADDLE_MODEL_PROTECT_API_PADDLE_MODEL_ENCRYPT_H
#define PADDLE_MODEL_PROTECT_API_PADDLE_MODEL_ENCRYPT_H
namespace fastdeploy {
#ifdef __cplusplus
extern "C" {
#endif
/** \brief generate a random key(base64-32bytes) for an encrypted model
*
* \return std::string key
*/
FASTDEPLOY_DECL std::string GenerateRandomKey();
/** \brief encrypt a std::istream with key
*
* \param[in] keydata The key(base64-32bytes) for encryption
* \param[in] in_stream The plain stream
* \param[in] out_stream The ecrypted stream
* \return true if encrypt successed, otherwise false
*/
FASTDEPLOY_DECL int EncryptStream(const std::string &keydata,
std::istream& in_stream,
std::ostream& out_stream);
/** \brief encrypt a string with key
*
* \param[in] input The input string for encryption
* \param[in] key If not given by user, generate key automatically.
* \return std::vector<std::string> [encrypted string, key]
*/
FASTDEPLOY_DECL std::vector<std::string> Encrypt(const std::string& input,
const std::string& key = GenerateRandomKey());
#ifdef __cplusplus
}
#endif
} // namespace fastdeploy
#endif // PADDLE_MODEL_PROTECT_API_PADDLE_MODEL_ENCRYPT_H

View File

@@ -0,0 +1,43 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifndef DYGRAPH_DEPLOY_CPP_ENCRYPTION_INCLUDE_MODEL_CODE_H_
#define DYGRAPH_DEPLOY_CPP_ENCRYPTION_INCLUDE_MODEL_CODE_H_
namespace fastdeploy {
#ifdef __cplusplus
extern "C" {
#endif
enum {
CODE_OK = 0,
CODE_OPEN_FAILED = 100,
CODE_READ_FILE_PTR_IS_NULL = 101,
CODE_AES_GCM_ENCRYPT_FIALED = 102,
CODE_AES_GCM_DECRYPT_FIALED = 103,
CODE_KEY_NOT_MATCH = 104,
CODE_KEY_LENGTH_ABNORMAL = 105,
CODE_NOT_EXIST_DIR = 106,
CODE_FILES_EMPTY_WITH_DIR = 107,
CODE_MODEL_FILE_NOT_EXIST = 108,
CODE_PARAMS_FILE_NOT_EXIST = 109,
CODE_MODEL_YML_FILE_NOT_EXIST = 110,
CODE_MKDIR_FAILED = 111
};
#ifdef __cplusplus
}
#endif
} // namespace fastdeploy
#endif // DYGRAPH_DEPLOY_CPP_ENCRYPTION_INCLUDE_MODEL_CODE_H_

View File

@@ -0,0 +1,109 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include <iostream>
#include <string>
#include <fstream>
#include <memory>
#include <iterator>
#include <algorithm>
#include "fastdeploy/encryption/include/decrypt.h"
#include "fastdeploy/encryption/include/model_code.h"
#include "fastdeploy/encryption/util/include/crypto/aes_gcm.h"
#include "fastdeploy/encryption/util/include/crypto/base64.h"
#include "fastdeploy/encryption/util/include/io_utils.h"
#include "fastdeploy/encryption/util/include/log.h"
#include "fastdeploy/encryption/util/include/constant/constant_model.h"
#include "fastdeploy/encryption/util/include/system_utils.h"
namespace fastdeploy {
/**
* 0 - encrypted
* 1 - unencrypt
*/
int CheckStreamEncrypted(std::istream& cipher_stream) {
return util::SystemUtils::check_file_encrypted(cipher_stream);
}
int DecryptStream(std::istream& cipher_stream,
std::ostream& plain_stream,
const std::string& key_base64) {
int ret = CheckStreamEncrypted(cipher_stream);
if (ret != CODE_OK) {
LOGD("[M]check file encrypted failed, code: %d", ret);
return ret;
}
std::string key_str =
baidu::base::base64::base64_decode(key_base64.c_str());
int ret_check = util::SystemUtils::check_key_match(key_str, cipher_stream);
if (ret_check != CODE_OK) {
LOGD("[M]check key failed in decrypt_file, code: %d", ret_check);
return CODE_KEY_NOT_MATCH;
}
std::string aes_key = key_str.substr(0, AES_GCM_KEY_LENGTH);
std::string aes_iv = key_str.substr(16, AES_GCM_IV_LENGTH);
cipher_stream.seekg(0, std::ios::beg);
cipher_stream.seekg(0, std::ios::end);
int data_len = cipher_stream.tellg();
cipher_stream.seekg(0, std::ios::beg);
size_t pos = constant::MAGIC_NUMBER_LEN +
constant::VERSION_LEN + constant::TAG_LEN;
size_t cipher_len = data_len - pos;
std::unique_ptr<unsigned char[]> model_cipher(
new unsigned char[cipher_len]);
cipher_stream.seekg(pos); // skip header
cipher_stream.read(reinterpret_cast<char *>(model_cipher.get()),
cipher_len);
size_t plain_len = data_len - AES_GCM_TAG_LENGTH - pos;
std::unique_ptr<unsigned char[]> model_plain(new unsigned char[plain_len]);
int ret_decrypt_file = util::crypto::AesGcm::decrypt_aes_gcm(
model_cipher.get(),
cipher_len,
reinterpret_cast<const unsigned char*>(aes_key.c_str()),
reinterpret_cast<const unsigned char*>(aes_iv.c_str()),
model_plain.get(),
reinterpret_cast<int&>(plain_len));
if (ret_decrypt_file != CODE_OK) {
LOGD("[M]decrypt file failed, decrypt ret = %d", ret_decrypt_file);
return ret_decrypt_file;
}
plain_stream.write(reinterpret_cast<const char*>(model_plain.get()),
plain_len);
return CODE_OK;
}
std::string Decrypt(const std::string& cipher,
const std::string& key) {
std::string input = baidu::base::base64::base64_decode(cipher);
std::istringstream isst_cipher(input);
std::ostringstream osst_plain;
int ret = DecryptStream(isst_cipher, osst_plain, key);
if (ret != 0) {
FDERROR << ret << ", Failed decrypt " << std::endl;
return "";
}
return osst_plain.str();
}
} //namespace fastdeploy

View File

@@ -0,0 +1,104 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include "fastdeploy/encryption/include/model_code.h"
#include "fastdeploy/encryption/include/encrypt.h"
#include "fastdeploy/encryption/util/include/constant/constant_model.h"
#include "fastdeploy/encryption/util/include/crypto/aes_gcm.h"
#include "fastdeploy/encryption/util/include/crypto/sha256_utils.h"
#include "fastdeploy/encryption/util/include/crypto/base64.h"
#include "fastdeploy/encryption/util/include/system_utils.h"
#include "fastdeploy/encryption/util/include/io_utils.h"
#include "fastdeploy/encryption/util/include/log.h"
namespace fastdeploy {
std::string GenerateRandomKey() {
std::string tmp = util::SystemUtils::random_key_iv(AES_GCM_KEY_LENGTH);
// return util::crypto::Base64Utils::encode(tmp);
return baidu::base::base64::base64_encode(tmp);
}
int EncryptStream(std::istream& in_stream, std::ostream& out_stream,
const std::string &keydata) {
std::string key_str = baidu::base::base64::base64_decode(keydata);
if (key_str.length() != 32) {
return CODE_KEY_LENGTH_ABNORMAL;
}
in_stream.seekg(0, std::ios::beg);
in_stream.seekg(0, std::ios::end);
size_t plain_len = in_stream.tellg();
in_stream.seekg(0, std::ios::beg);
std::unique_ptr<unsigned char[]> plain(new unsigned char[plain_len]);
in_stream.read(reinterpret_cast<char *>(plain.get()), plain_len);
std::string aes_key = key_str.substr(0, AES_GCM_KEY_LENGTH);
std::string aes_iv = key_str.substr(16, AES_GCM_IV_LENGTH);
std::unique_ptr<unsigned char[]> cipher(
new unsigned char[plain_len + AES_GCM_TAG_LENGTH]);
size_t cipher_len = 0;
int ret_encrypt = util::crypto::AesGcm::encrypt_aes_gcm(
plain.get(),
plain_len,
reinterpret_cast<const unsigned char*>(aes_key.c_str()),
reinterpret_cast<const unsigned char*>(aes_iv.c_str()),
cipher.get(),
reinterpret_cast<int&>(cipher_len));
if (ret_encrypt != CODE_OK) {
LOGD("[M]aes encrypt ret code: %d", ret_encrypt);
return CODE_AES_GCM_ENCRYPT_FIALED;
}
std::string randstr = util::SystemUtils::random_str(constant::TAG_LEN);
std::string aes_key_iv(key_str);
std::string sha256_key_iv =
util::crypto::SHA256Utils::sha256_string(aes_key_iv);
for (int i = 0; i < 64; ++i) {
randstr[i] = sha256_key_iv[i];
}
size_t header_len = constant::MAGIC_NUMBER_LEN +
constant::VERSION_LEN + constant::TAG_LEN;
out_stream.write(constant::MAGIC_NUMBER.c_str(),
constant::MAGIC_NUMBER_LEN);
out_stream.write(constant::VERSION.c_str(), constant::VERSION_LEN);
out_stream.write(randstr.c_str(), constant::TAG_LEN);
out_stream.write(reinterpret_cast<char *>(cipher.get()), cipher_len);
return CODE_OK;
}
std::vector<std::string> Encrypt(const std::string& input,
const std::string& key) {
std::istringstream isst(input);
std::ostringstream osst;
int ret = EncryptStream(isst, osst, key);
if (ret != 0) {
FDERROR << ret << ", Failed encrypt " << std::endl;
return {"", ""};
}
return {baidu::base::base64::base64_encode(osst.str()), key};
}
} // namespace fastdeploy

View File

@@ -0,0 +1,30 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <string>
#ifndef PADDLE_MODEL_PROTECT_CONSTANT_CONSTANT_MODEL_H
#define PADDLE_MODEL_PROTECT_CONSTANT_CONSTANT_MODEL_H
namespace fastdeploy {
namespace constant {
const static std::string MAGIC_NUMBER = "PADDLE"; // NOLINT
const static std::string VERSION = "1"; // NOLINT
const static int MAGIC_NUMBER_LEN = 6; // NOLINT
const static int VERSION_LEN = 1; // NOLINT
const static int TAG_LEN = 128; // NOLINT
} // namespace constant
} // namespace fastdeploy
#endif // PADDLE_MODEL_PROTECT_CONSTANT_CONSTANT_MODEL_H

View File

@@ -0,0 +1,130 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifndef PADDLE_MODEL_PROTECT_UTIL_CRYPTO_AES_GCM_H
#define PADDLE_MODEL_PROTECT_UTIL_CRYPTO_AES_GCM_H
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <iostream>
#include <string>
#include "fastdeploy/encryption/util/include/crypto/basic.h"
namespace fastdeploy {
namespace util {
namespace crypto {
// aes key 32 byte for 256 bit
#define AES_GCM_KEY_LENGTH 32
// aes tag 16 byte for 128 bit
#define AES_GCM_TAG_LENGTH 16
// aes iv 12 byte for 96 bit
#define AES_GCM_IV_LENGTH 16
class AesGcm {
public:
/**
* \brief initial aes-gcm-256 context use key & iv
*
* \note initial aes-gcm-256 context use key & iv. gcm mode
* will generate a tag(16 byte), so the ciphertext's length
* should be longer 16 byte than plaintext.
*
*
* \param plaintext plain text to be encrypted(in)
* \param len plain text's length(in)
* \param key aes key (in)
* \param iv aes iv (in)
* \param ciphertext encrypted text(out)
* \param out_len encrypted length(out)
*
* \return return 0 if successful
* -1 EVP_CIPHER_CTX_new or aes_gcm_key error
* -2 EVP_EncryptUpdate error
* -3 EVP_EncryptFinal_ex error
* -4 EVP_CIPHER_CTX_ctrl error
*/
static int encrypt_aes_gcm(const unsigned char* plaintext, const int& len,
const unsigned char* key, const unsigned char* iv,
unsigned char* ciphertext,
int& out_len); // NOLINT
/**
* \brief encrypt using aes-gcm-256
*
* \note encrypt using aes-gcm-256
*
* \param ciphertext cipher text to be decrypted(in)
* \param len plain text's length(in)
* \param key aes key (in)
* \param iv aes iv (in)
* \param plaintext decrypted text(out)
* \param out_len decrypted length(out)
*
* \return return 0 if successful
* -1 EVP_CIPHER_CTX_new or aes_gcm_key error
* -2 EVP_DecryptUpdate error
* -3 EVP_CIPHER_CTX_ctrl error
* -4 EVP_DecryptFinal_ex error
*/
static int decrypt_aes_gcm(const unsigned char* ciphertext, const int& len,
const unsigned char* key, const unsigned char* iv,
unsigned char* plaintext, int& out_len); // NOLINT
private:
/**
* \brief initial aes-gcm-256 context use key & iv
*
* \note initial aes-gcm-256 context use key & iv
*
* \param key aes key (in)
* \param iv aes iv (in)
* \param e_ctx encryption context(out)
* \param d_ctx decryption context(out)
*
* \return return 0 if successful
* -1 EVP_xxcryptInit_ex error
* -2 EVP_CIPHER_CTX_ctrl error
* -3 EVP_xxcryptInit_ex error
*/
static int aes_gcm_key(const unsigned char* key, const unsigned char* iv,
EVP_CIPHER_CTX* e_ctx, EVP_CIPHER_CTX* d_ctx);
/**
* \brief initial aes-gcm-256 context use key & iv
*
* \note initial aes-gcm-256 context use key & iv
*
* \param key aes key (in)
* \param iv aes iv (in)
* \param e_ctx encryption context(out)
* \param d_ctx decryption context(out)
*
* \return return 0 if successful
* -1 EVP_xxcryptInit_ex error
* -2 EVP_CIPHER_CTX_ctrl error
* -3 EVP_xxcryptInit_ex error
* -4 invalid key length or iv length
* -5 hex_to_byte error
*/
static int aes_gcm_key(const std::string& key_hex, const std::string& iv_hex,
EVP_CIPHER_CTX* e_ctx, EVP_CIPHER_CTX* d_ctx);
};
} // namespace crypto
} // namespace util
} // namespace fastdeploy
#endif // PADDLE_MODEL_PROTECT_UTIL_CRYPTO_AES_GCM_H

View File

@@ -0,0 +1,33 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <vector>
#include <string>
#ifndef PADDLE_MODEL_PROTECT_UTIL_CRYPTO_BASE64_UTILS_H
#define PADDLE_MODEL_PROTECT_UTIL_CRYPTO_BASE64_UTILS_H
namespace fastdeploy {
namespace baidu {
namespace base {
namespace base64 {
std::string base64_encode(const std::string& input);
std::string base64_decode(const std::string& input);
} // namespace base64
} // namespace base
} // namespace baidu
} // namespace fastdeploy
#endif // PADDLE_MODEL_PROTECT_BASE64_UTILS_H

View File

@@ -0,0 +1,78 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifndef PADDLE_MODEL_PROTECT_UTIL_BASIC_H
#define PADDLE_MODEL_PROTECT_UTIL_BASIC_H
#include <iomanip>
#include <iostream>
#include <random>
#include <string>
#include <sstream>
namespace fastdeploy {
namespace util {
namespace crypto {
class Basic {
public:
/**
* \brief byte to hex
*
* \note byte to hex.
*
*
* \param in_byte byte array(in)
* \param len byte array length(in)
* \param out_hex the hex string(in)
*
*
* \return return 0 if successful
*/
static int byte_to_hex(const unsigned char* in_byte, int len,
std::string& out_hex); // NOLINT
/**
* \brief hex to byte
*
* \note hex to byte.
*
*
* \param in_hex the hex string(in)
* \param out_byte byte array(out)
*
* \return return 0 if successful
* -1 invalid in_hex
*/
static int hex_to_byte(const std::string& in_hex, unsigned char* out_byte);
/**
* \brief get random char for length
*
* \note get random char for length
*
*
* \param array to be random(out)
* \param len array length(in)
*
* \return return 0 if successful
* -1 invalid parameters
*/
static int random(unsigned char* random, int len);
};
} // namespace crypto
} // namespace util
} // namespace fastdeploy
#endif // PADDLE_MODEL_PROTECT_UTIL_BASIC_H

View File

@@ -0,0 +1,40 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <vector>
#include <string>
#ifndef PADDLE_MODEL_PROTECT_UTIL_CRYPTO_SHA256_UTILS_H
#define PADDLE_MODEL_PROTECT_UTIL_CRYPTO_SHA256_UTILS_H
namespace fastdeploy {
namespace util {
namespace crypto {
class SHA256Utils {
public:
static void sha256(const void* data, size_t len, unsigned char* md);
static std::vector<unsigned char> sha256(const void* data, size_t len);
static std::vector<unsigned char> sha256(
const std::vector<unsigned char>& data);
static std::string sha256_string(const void* data, size_t len);
static std::string sha256_string(const std::vector<unsigned char>& data);
static std::string sha256_string(const std::string& string);
static std::string sha256_file(const std::string& path);
};
} // namespace crypto
} // namespace util
} // namespace fastdeploy
#endif // PADDLE_MODEL_PROTECT_UTIL_CRYPTO_SHA256_UTILS_H

View File

@@ -0,0 +1,53 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <iostream>
#include <memory>
#include <vector>
#include <string>
#ifndef PADDLE_MODEL_PROTECT_IO_UTILS_H
#define PADDLE_MODEL_PROTECT_IO_UTILS_H
namespace fastdeploy {
namespace ioutil {
int read_file(const char* file_path, unsigned char** dataptr, size_t* sizeptr);
int read_with_pos_and_length(const char* file_path, unsigned char* dataptr,
size_t pos, size_t length);
int read_with_pos(const char* file_path, size_t pos, unsigned char** dataptr,
size_t* sizeptr);
int write_file(const char* file_path, const unsigned char* dataptr,
size_t sizeptr);
int append_file(const char* file_path, const unsigned char* data, size_t len);
size_t read_file_size(const char* file_path);
int read_file_to_file(const char* src_path, const char* dst_path);
int dir_exist_or_mkdir(const char* dir);
/**
* @return files.size()
*/
int read_dir_files(const char* dir_path,
std::vector<std::string>& files); // NOLINT
} // namespace ioutil
} // namespace fastdeploy
#endif // PADDLE_MODEL_PROTECT_IO_UTILS_H

View File

@@ -0,0 +1,24 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifndef PADDLE_MODEL_PROTECT_UTIL_LOG_H
#define PADDLE_MODEL_PROTECT_UTIL_LOG_H
#include <stdio.h>
namespace fastdeploy {
#define LOGD(fmt, ...) \
printf("{%s:%u}:" fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
} // namespace fastdeploy
#endif // PADDLE_MODEL_PROTECT_UTIL_LOG_H

View File

@@ -0,0 +1,42 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <string>
#include <vector>
#ifndef PADDLE_MODEL_PROTECT_SYSTEM_UTIL_H
#define PADDLE_MODEL_PROTECT_SYSTEM_UTIL_H
namespace fastdeploy {
namespace util {
class SystemUtils {
public:
static std::string random_key_iv(int len);
static std::string random_str(int len);
static int check_key_match(const char* key, const char* filepath);
static int check_key_match(const std::string& key,
std::istream& cipher_stream);
static int check_file_encrypted(const char* filepath);
static int check_file_encrypted(std::istream& cipher_stream);
static int check_pattern_exist(const std::vector<std::string>& vecs,
const std::string& pattern);
private:
inline static int intN(int n);
};
} // namespace util
} // namespace fastdeploy
#endif // PADDLE_MODEL_PROTECT_SYSTEM_UTIL_H

View File

@@ -0,0 +1,193 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <iostream>
#include "fastdeploy/encryption/util/include/crypto/aes_gcm.h"
namespace fastdeploy {
namespace util {
namespace crypto {
int AesGcm::aes_gcm_key(const unsigned char* key, const unsigned char* iv,
EVP_CIPHER_CTX* e_ctx, EVP_CIPHER_CTX* d_ctx) {
int ret = 0;
if (e_ctx != NULL) {
ret = EVP_EncryptInit_ex(e_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
if (ret != 1) {
return -1;
}
ret = EVP_CIPHER_CTX_ctrl(e_ctx, EVP_CTRL_GCM_SET_IVLEN, AES_GCM_IV_LENGTH,
NULL);
if (ret != 1) {
return -2;
}
ret = EVP_EncryptInit_ex(e_ctx, NULL, NULL, key, iv);
if (ret != 1) {
return -3;
}
}
// initial decrypt ctx
if (d_ctx != NULL) {
ret = EVP_DecryptInit_ex(d_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
if (!ret) {
return -1;
}
ret = EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_IVLEN, AES_GCM_IV_LENGTH,
NULL);
if (!ret) {
return -2;
}
ret = EVP_DecryptInit_ex(d_ctx, NULL, NULL, key, iv);
if (!ret) {
return -3;
}
}
return 0;
}
int AesGcm::aes_gcm_key(const std::string& key_hex, const std::string& iv_hex,
EVP_CIPHER_CTX* e_ctx, EVP_CIPHER_CTX* d_ctx) {
// check key_hex and iv_hex length
if (key_hex.length() != AES_GCM_KEY_LENGTH * 2 ||
iv_hex.length() != AES_GCM_IV_LENGTH * 2) {
return -4;
}
unsigned char key[AES_GCM_KEY_LENGTH];
unsigned char iv[AES_GCM_IV_LENGTH];
int ret = Basic::hex_to_byte(key_hex, key);
if (ret < 0) {
return -5;
}
ret = Basic::hex_to_byte(iv_hex, iv);
if (ret < 0) {
return -5;
}
return aes_gcm_key(key, iv, e_ctx, d_ctx);
}
int AesGcm::encrypt_aes_gcm(const unsigned char* plaintext, const int& len,
const unsigned char* key, const unsigned char* iv,
unsigned char* ciphertext, int& out_len) {
EVP_CIPHER_CTX* ctx = NULL;
int ret = 0;
int update_len = 0;
int ciphertext_len = 0;
unsigned char tag_char[AES_GCM_TAG_LENGTH];
if (!(ctx = EVP_CIPHER_CTX_new())) {
return -1;
}
// initial context
ret = aes_gcm_key(key, iv, ctx, NULL);
if (ret) {
EVP_CIPHER_CTX_free(ctx);
return -1;
}
// encryption
ret = EVP_EncryptUpdate(ctx, ciphertext, &update_len, plaintext, len);
if (ret != 1) {
EVP_CIPHER_CTX_free(ctx);
return -2;
}
ciphertext_len = update_len;
ret = EVP_EncryptFinal_ex(ctx, ciphertext + ciphertext_len, &update_len);
if (1 != ret) {
EVP_CIPHER_CTX_free(ctx);
return -3;
}
ciphertext_len += update_len;
// Get the tags for authentication
ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, AES_GCM_TAG_LENGTH,
tag_char);
if (1 != ret) {
EVP_CIPHER_CTX_free(ctx);
return -4;
}
EVP_CIPHER_CTX_free(ctx);
// append the tags to the end of encryption text
for (int i = 0; i < AES_GCM_TAG_LENGTH; ++i) {
ciphertext[ciphertext_len + i] = tag_char[i];
}
out_len = ciphertext_len + AES_GCM_TAG_LENGTH;
return 0;
}
int AesGcm::decrypt_aes_gcm(const unsigned char* ciphertext, const int& len,
const unsigned char* key, const unsigned char* iv,
unsigned char* plaintext, int& out_len) {
EVP_CIPHER_CTX* ctx = NULL;
int ret = 0;
int update_len = 0;
int cipher_len = 0;
int plaintext_len = 0;
unsigned char tag_char[AES_GCM_TAG_LENGTH];
// get the tag at the end of ciphertext
for (int i = 0; i < AES_GCM_TAG_LENGTH; ++i) {
tag_char[i] = ciphertext[len - AES_GCM_TAG_LENGTH + i];
}
cipher_len = len - AES_GCM_TAG_LENGTH;
// initial aes context
if (!(ctx = EVP_CIPHER_CTX_new())) {
return -1;
}
ret = aes_gcm_key(key, iv, NULL, ctx);
if (ret) {
EVP_CIPHER_CTX_free(ctx);
return -1;
}
// decryption
ret = EVP_DecryptUpdate(ctx, plaintext, &update_len, ciphertext, cipher_len);
if (ret != 1) {
EVP_CIPHER_CTX_free(ctx);
return -2;
}
plaintext_len = update_len;
// check if the tag is equal to the decrption tag
ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, AES_GCM_TAG_LENGTH,
tag_char);
if (!ret) {
EVP_CIPHER_CTX_free(ctx);
// decrption failed
return -3;
}
ret = EVP_DecryptFinal_ex(ctx, plaintext + update_len, &update_len);
if (ret <= 0) {
EVP_CIPHER_CTX_free(ctx);
return -4;
}
plaintext_len += update_len;
EVP_CIPHER_CTX_free(ctx);
out_len = plaintext_len;
return 0;
}
} // namespace crypto
} // namespace util
} // namespace fastdeploy

View File

@@ -0,0 +1,133 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "fastdeploy/encryption/util/include/crypto/base64.h"
namespace fastdeploy {
namespace baidu {
namespace base {
namespace base64 {
using std::string;
namespace {
const string base64_chars = // NOLINT
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
inline bool is_base64(unsigned char c) {
return isalnum(c) || (c == '+') || (c == '/');
}
inline size_t encode_len(size_t input_len) { return (input_len + 2) / 3 * 4; }
void encode_char_array(unsigned char *encode_block,
const unsigned char *decode_block) {
encode_block[0] = (decode_block[0] & 0xfc) >> 2;
encode_block[1] =
((decode_block[0] & 0x03) << 4) + ((decode_block[1] & 0xf0) >> 4);
encode_block[2] =
((decode_block[1] & 0x0f) << 2) + ((decode_block[2] & 0xc0) >> 6);
encode_block[3] = decode_block[2] & 0x3f;
}
void decode_char_array(unsigned char *encode_block,
unsigned char *decode_block) {
for (int i = 0; i < 4; ++i) {
encode_block[i] = base64_chars.find(encode_block[i]);
}
decode_block[0] = (encode_block[0] << 2) + ((encode_block[1] & 0x30) >> 4);
decode_block[1] =
((encode_block[1] & 0xf) << 4) + ((encode_block[2] & 0x3c) >> 2);
decode_block[2] = ((encode_block[2] & 0x3) << 6) + encode_block[3];
}
} // namespace
string base64_encode(const string &input) {
string output;
size_t i = 0;
unsigned char decode_block[3];
unsigned char encode_block[4];
for (string::size_type len = 0; len != input.size(); ++len) {
decode_block[i++] = input[len];
if (i == 3) {
encode_char_array(encode_block, decode_block);
for (i = 0; i < 4; ++i) {
output += base64_chars[encode_block[i]];
}
i = 0;
}
}
if (i > 0) {
for (size_t j = i; j < 3; ++j) {
decode_block[j] = '\0';
}
encode_char_array(encode_block, decode_block);
for (size_t j = 0; j < i + 1; ++j) {
output += base64_chars[encode_block[j]];
}
while (i++ < 3) {
output += '=';
}
}
return output;
}
string base64_decode(const string &encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int len = 0;
unsigned char encode_block[4];
unsigned char decode_block[3];
string output;
while (in_len-- && (encoded_string[len] != '=') &&
is_base64(encoded_string[len])) {
encode_block[i++] = encoded_string[len];
len++;
if (i == 4) {
decode_char_array(encode_block, decode_block);
for (int j = 0; j < 3; ++j) {
output += decode_block[j];
}
i = 0;
}
}
if (i > 0) {
for (int j = i; j < 4; ++j) {
encode_block[j] = 0;
}
decode_char_array(encode_block, decode_block);
for (int j = 0; j < i - 1; ++j) {
output += decode_block[j];
}
}
return output;
}
} // namespace base64
} // namespace base
} // namespace baidu
} // namespace fastdeploy

View File

@@ -0,0 +1,81 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "fastdeploy/encryption/util/include/crypto/basic.h"
namespace fastdeploy {
namespace util {
namespace crypto {
int Basic::byte_to_hex(const unsigned char* in_byte, int len,
std::string& out_hex) {
std::ostringstream oss;
oss << std::hex << std::setfill('0');
for (int i = 0; i < len; ++i) {
oss << std::setw(2) << int(in_byte[i]);
}
out_hex = oss.str();
return 0;
}
int Basic::hex_to_byte(const std::string& in_hex, unsigned char* out_byte) {
int i = 0;
int j = 0;
int len = in_hex.length() / 2;
const unsigned char* hex;
if (in_hex.length() % 2 != 0 || out_byte == NULL) {
return -1;
}
hex = (unsigned char*)in_hex.c_str();
for (; j < len; i += 2, ++j) {
unsigned char high = hex[i];
unsigned char low = hex[i + 1];
if (high >= '0' && high <= '9') {
high = high - '0';
} else if (high >= 'A' && high <= 'F') {
high = high - 'A' + 10;
} else if (high >= 'a' && high <= 'f') {
high = high - 'a' + 10;
} else {
return -2;
}
if (low >= '0' && low <= '9') {
low = low - '0';
} else if (low >= 'A' && low <= 'F') {
low = low - 'A' + 10;
} else if (low >= 'a' && low <= 'f') {
low = low - 'a' + 10;
} else {
return -2;
}
out_byte[j] = high << 4 | low;
}
return 0;
}
int Basic::random(unsigned char* random, int len) {
std::random_device rd;
int i = 0;
if (len <= 0 || random == NULL) {
return -1;
}
for (; i < len; ++i) {
random[i] = rd() % 256;
}
return 0;
}
} // namespace crypto
} // namespace util
} // namespace fastdeploy

View File

@@ -0,0 +1,85 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <openssl/sha.h>
#include <iomanip>
#include <sstream>
#include "fastdeploy/encryption/util/include/crypto/sha256_utils.h"
namespace fastdeploy {
namespace util {
namespace crypto {
void SHA256Utils::sha256(const void* data, size_t len, unsigned char* md) {
SHA256_CTX sha_ctx = {};
SHA256_Init(&sha_ctx);
SHA256_Update(&sha_ctx, data, len);
SHA256_Final(md, &sha_ctx);
}
std::vector<unsigned char> SHA256Utils::sha256(const void* data, size_t len) {
std::vector<unsigned char> md(32);
sha256(data, len, &md[0]);
return md;
}
std::vector<unsigned char> SHA256Utils::sha256(
const std::vector<unsigned char>& data) {
return sha256(&data[0], data.size());
}
std::string SHA256Utils::sha256_string(const void* data, size_t len) {
std::vector<unsigned char> md = sha256(data, len);
std::ostringstream oss;
oss << std::hex << std::setfill('0');
for (unsigned char c : md) {
oss << std::setw(2) << int(c);
}
return oss.str();
}
std::string SHA256Utils::sha256_string(const std::vector<unsigned char>& data) {
return sha256_string(&data[0], data.size());
}
std::string SHA256Utils::sha256_string(const std::string& string) {
return sha256_string(string.c_str(), string.size());
}
std::string SHA256Utils::sha256_file(const std::string& path) {
FILE* file = fopen(path.c_str(), "rb");
if (!file) {
return "";
}
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha_ctx = {};
SHA256_Init(&sha_ctx);
const int size = 32768;
void* buffer = malloc(size);
if (!buffer) {
fclose(file);
return "";
}
int read = 0;
while ((read = fread(buffer, 1, size, file))) {
SHA256_Update(&sha_ctx, buffer, read);
}
SHA256_Final(hash, &sha_ctx);
std::ostringstream oss;
oss << std::hex << std::setfill('0');
for (unsigned char c : hash) {
oss << std::setw(2) << int(c);
}
fclose(file);
free(buffer);
return oss.str();
}
} // namespace crypto
} // namespace util
} // namespace fastdeploy

View File

@@ -0,0 +1,225 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifdef LINUX
#include <unistd.h>
#include <dirent.h>
#endif
#ifdef WIN32
#include <windows.h>
#include <io.h>
#endif
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <iostream>
#include "fastdeploy/encryption/util/include/io_utils.h"
#include "fastdeploy/encryption/include/model_code.h"
#include "fastdeploy/encryption/util/include/log.h"
namespace fastdeploy {
namespace ioutil {
int read_file(const char* file_path, unsigned char** dataptr, size_t* sizeptr) {
FILE* fp = NULL;
fp = fopen(file_path, "rb");
if (fp == NULL) {
LOGD("[M]open file(%s) failed", file_path);
return CODE_OPEN_FAILED;
}
fseek(fp, 0, SEEK_END);
*sizeptr = ftell(fp);
*dataptr = (unsigned char*)malloc(sizeof(unsigned char) * (*sizeptr));
fseek(fp, 0, SEEK_SET);
fread(*dataptr, 1, *sizeptr, fp);
fclose(fp);
return CODE_OK;
}
int read_with_pos_and_length(const char* file_path, unsigned char* dataptr,
size_t pos, size_t length) {
if (dataptr == NULL) {
LOGD("Read file pos dataptr = NULL");
return CODE_READ_FILE_PTR_IS_NULL;
}
FILE* fp = NULL;
if ((fp = fopen(file_path, "rb")) == NULL) {
LOGD("[M]open file(%s) failed", file_path);
return CODE_OPEN_FAILED;
}
fseek(fp, pos, SEEK_SET);
fread(dataptr, 1, length, fp);
fclose(fp);
return CODE_OK;
}
int read_with_pos(const char* file_path, size_t pos, unsigned char** dataptr,
size_t* sizeptr) {
FILE* fp = NULL;
if ((fp = fopen(file_path, "rb")) == NULL) {
LOGD("[M]open file(%s) failed when read_with_pos", file_path);
return CODE_OPEN_FAILED;
}
fseek(fp, 0, SEEK_END);
size_t filesize = ftell(fp);
*sizeptr = filesize - pos;
*dataptr = (unsigned char*)malloc(sizeof(unsigned char) * (filesize - pos));
fseek(fp, pos, SEEK_SET);
fread(*dataptr, 1, filesize - pos, fp);
fclose(fp);
return CODE_OK;
}
int write_file(const char* file_path, const unsigned char* dataptr,
size_t sizeptr) {
FILE* fp = NULL;
if ((fp = fopen(file_path, "wb")) == NULL) {
LOGD("[M]open file(%s) failed", file_path);
return CODE_OPEN_FAILED;
}
fwrite(dataptr, 1, sizeptr, fp);
fclose(fp);
return CODE_OK;
}
int append_file(const char* file_path, const unsigned char* data, size_t len) {
FILE* fp = fopen(file_path, "ab+");
if (fp == NULL) {
LOGD("[M]open file(%s) failed when append_file", file_path);
return CODE_OPEN_FAILED;
}
fwrite(data, sizeof(char), len, fp);
fclose(fp);
return CODE_OK;
}
size_t read_file_size(const char* file_path) {
FILE* fp = NULL;
fp = fopen(file_path, "rb");
if (fp == NULL) {
LOGD("[M]open file(%s) failed when read_file_size", file_path);
return 0;
}
fseek(fp, 0, SEEK_END);
size_t filesize = ftell(fp);
fclose(fp);
return filesize;
}
int read_file_to_file(const char* src_path, const char* dst_path) {
FILE* infp = NULL;
if ((infp = fopen(src_path, "rb")) == NULL) {
LOGD("[M]read src file failed when read_file_to_file");
return CODE_OPEN_FAILED;
}
fseek(infp, 0, SEEK_END);
size_t insize = ftell(infp);
char* content = reinterpret_cast<char*>(malloc(sizeof(char) * insize));
fseek(infp, 0, SEEK_SET);
fread(content, 1, insize, infp);
fclose(infp);
FILE* outfp = NULL;
if ((outfp = fopen(dst_path, "wb")) == NULL) {
LOGD("[M]open dst file failed when read_file_to_file");
return CODE_OPEN_FAILED;
}
fwrite(content, 1, insize, outfp);
fclose(outfp);
free(content);
return CODE_OK;
}
int read_dir_files(const char* dir_path,
std::vector<std::string>& files) { // NOLINT
#ifdef LINUX
struct dirent* ptr;
DIR* dir = NULL;
dir = opendir(dir_path);
if (dir == NULL) {
return -1; // CODE_NOT_EXIST_DIR
}
while ((ptr = readdir(dir)) != NULL) {
if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
files.push_back(ptr->d_name);
}
}
closedir(dir);
#endif
#ifdef WIN32
intptr_t handle;
struct _finddata_t fileinfo;
std::string tmp_dir(dir_path);
std::string::size_type idx = tmp_dir.rfind("\\*");
if (idx == std::string::npos || idx != tmp_dir.length() - 1) {
tmp_dir.append("\\*");
}
handle = _findfirst(tmp_dir.c_str(), &fileinfo);
if (handle == -1) {
return -1;
}
do {
std::cout << "File name = " << fileinfo.name << std::endl;
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0) {
files.push_back(fileinfo.name);
}
} while (!_findnext(handle, &fileinfo));
std::cout << files.size() << std::endl;
for (size_t i = 0; i < files.size(); i++) {
std::cout << files[i] << std::endl;
}
_findclose(handle);
#endif
return files.size();
}
int dir_exist_or_mkdir(const char* dir) {
#ifdef WIN32
if (CreateDirectory(dir, NULL)) {
// return CODE_OK;
} else {
return CODE_MKDIR_FAILED;
}
#endif
#ifdef LINUX
if (access(dir, 0) != 0) {
mkdir(dir, S_IRWXU | S_IRWXG | S_IRWXO);
}
#endif
return CODE_OK;
}
} // namespace ioutil
} // namespace fastdeploy

View File

@@ -0,0 +1,144 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <sys/timeb.h>
#include <string.h>
#include <algorithm>
#include <iterator>
#include "fastdeploy/encryption/include/model_code.h"
#include "fastdeploy/encryption/util/include/system_utils.h"
#include "fastdeploy/encryption/util/include/crypto/basic.h"
#include "fastdeploy/encryption/util/include/crypto/sha256_utils.h"
#include "fastdeploy/encryption/util/include/io_utils.h"
#include "fastdeploy/encryption/util/include/log.h"
#include "fastdeploy/encryption/util/include/constant/constant_model.h"
namespace fastdeploy {
namespace util {
int SystemUtils::intN(int n) { return rand() % n; }
std::string SystemUtils::random_key_iv(int len) {
unsigned char* tmp = (unsigned char*)malloc(sizeof(unsigned char) * len);
int ret = util::crypto::Basic::random(tmp, len);
std::string tmp_str(reinterpret_cast<const char*>(tmp), len);
free(tmp);
return tmp_str;
}
std::string SystemUtils::random_str(int len) {
unsigned char* tmp = (unsigned char*)malloc(sizeof(unsigned char) * len);
int ret = util::crypto::Basic::random(tmp, len);
std::string tmp_str(reinterpret_cast<const char*>(tmp), len);
free(tmp);
return tmp_str;
}
int SystemUtils::check_key_match(const char* key, const char* filepath) {
std::string aes_key_iv(key);
std::string sha256_aes_key_iv =
util::crypto::SHA256Utils::sha256_string(aes_key_iv);
unsigned char* data_pos = (unsigned char*)malloc(sizeof(unsigned char) * 64);
int ret = ioutil::read_with_pos_and_length(
filepath, data_pos, constant::MAGIC_NUMBER_LEN + constant::VERSION_LEN,
64);
if (ret != CODE_OK) {
LOGD("[M]read file failed when check key");
return ret;
}
std::string check_str(reinterpret_cast<char*>(data_pos), 64);
if (strcmp(sha256_aes_key_iv.c_str(), check_str.c_str()) != 0) {
return CODE_KEY_NOT_MATCH;
}
free(data_pos);
return CODE_OK;
}
int SystemUtils::check_key_match(const std::string& key,
std::istream& cipher_stream) {
cipher_stream.seekg(0, std::ios::beg);
std::string sha256_aes_key_iv = util::crypto::SHA256Utils::sha256_string(key);
int check_len = 64;
std::string data_pos_str;
cipher_stream.seekg(constant::MAGIC_NUMBER_LEN + constant::VERSION_LEN);
std::copy_n(std::istreambuf_iterator<char>(cipher_stream), check_len,
std::back_inserter(data_pos_str));
if (data_pos_str.size() != check_len) {
LOGD("[M]read file failed when check key");
return CODE_OPEN_FAILED;
}
if (data_pos_str == sha256_aes_key_iv) {
return CODE_OK;
}
return CODE_KEY_NOT_MATCH;
}
/**
*
* @param filepath
* @return 0 - file encrypted 1 - file unencrypted
*/
int SystemUtils::check_file_encrypted(const char* filepath) {
size_t read_len = constant::MAGIC_NUMBER_LEN + constant::VERSION_LEN;
unsigned char* data_pos =
(unsigned char*)malloc(sizeof(unsigned char) * read_len);
if (ioutil::read_with_pos_and_length(filepath, data_pos, 0, read_len) !=
CODE_OK) {
LOGD("check file failed when read %s(file)", filepath);
return CODE_OPEN_FAILED;
}
std::string tag(constant::MAGIC_NUMBER);
tag.append(constant::VERSION);
std::string check_str(reinterpret_cast<char*>(data_pos), read_len);
int ret_cmp = strcmp(tag.c_str(), check_str.c_str()) == 0 ? 0 : 1;
free(data_pos);
return ret_cmp;
}
int SystemUtils::check_file_encrypted(std::istream& cipher_stream) {
cipher_stream.seekg(0, std::ios::beg);
size_t read_len = constant::MAGIC_NUMBER_LEN + constant::VERSION_LEN;
std::string data_pos_str;
std::copy_n(std::istreambuf_iterator<char>(cipher_stream), read_len,
std::back_inserter(data_pos_str));
if (data_pos_str.size() != read_len) {
LOGD("check file failed when read cipher stream");
return CODE_OPEN_FAILED;
}
std::string tag(constant::MAGIC_NUMBER);
tag.append(constant::VERSION);
if (data_pos_str == tag) {
return 0;
}
return 1;
}
int SystemUtils::check_pattern_exist(const std::vector<std::string>& vecs,
const std::string& pattern) {
if (std::find(vecs.begin(), vecs.end(), pattern) == vecs.end()) {
return -1; // not exist
} else {
return 0; // exist
}
}
} // namespace util
} // namespace fastdeploy

8
fastdeploy/pybind/main.cc.in Normal file → Executable file
View File

@@ -20,6 +20,7 @@ void BindFDTensor(pybind11::module&);
void BindRuntime(pybind11::module&);
void BindFDModel(pybind11::module&);
void BindVision(pybind11::module&);
void BindEncryption(pybind11::module&);
void BindText(pybind11::module&);
void BindPipeline(pybind11::module&);
@@ -166,6 +167,13 @@ PYBIND11_MODULE(@PY_LIBRARY_NAME@, m) {
m.def_submodule("pipeline", "Pipeline module of FastDeploy.");
BindPipeline(pipeline_module);
#endif
#ifdef ENABLE_ENCRYPTION
auto encryption_module =
m.def_submodule("encryption", "Encryption module of FastDeploy.");
BindEncryption(encryption_module);
#endif
#ifdef ENABLE_TEXT
auto text_module =
m.def_submodule("text", "Text module of FastDeploy.");

4
fastdeploy/pybind/main.h Normal file → Executable file
View File

@@ -32,6 +32,10 @@
#include "fastdeploy/text.h"
#endif
#ifdef ENABLE_ENCRYPTION
#include "fastdeploy/encryption.h"
#endif
#include "fastdeploy/core/float16.h"
namespace fastdeploy {

1
python/fastdeploy/__init__.py Normal file → Executable file
View File

@@ -36,5 +36,6 @@ from . import c_lib_wrap as C
from . import vision
from . import pipeline
from . import text
from . import encryption
from .download import download, download_and_decompress, download_model, get_model_list
from . import serving

View File

@@ -0,0 +1,16 @@
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
from .encryption import *

View File

@@ -0,0 +1,41 @@
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from .. import c_lib_wrap as C
def generate_key():
"""generate a key for encryption
:return: key(str)
"""
return C.encryption.generate_key()
def encrypt(input, key=None):
"""Encrypt a input string with key.
:param: input: (str) The input str for encryption
:param: key: (str,optional) The key for encryption(if not given, generate automatically.)
:return: pair(str, str) [encrypted string, key]
"""
if key is None:
key = generate_key()
return C.encryption.encrypt(input, key)
def decrypt(cipher, key):
"""Decrypt a input cipher with key.
:param: cipher: (str) The input str for decryption
:param: key: (str) The key for decryption
:return: str(The decrypted str)
"""
return C.encryption.decrypt(cipher, key)

View File

@@ -68,6 +68,7 @@ setup_configs["ENABLE_TRT_BACKEND"] = os.getenv("ENABLE_TRT_BACKEND", "OFF")
setup_configs["ENABLE_LITE_BACKEND"] = os.getenv("ENABLE_LITE_BACKEND", "OFF")
setup_configs["PADDLELITE_URL"] = os.getenv("PADDLELITE_URL", "OFF")
setup_configs["ENABLE_VISION"] = os.getenv("ENABLE_VISION", "OFF")
setup_configs["ENABLE_ENCRYPTION"] = os.getenv("ENABLE_ENCRYPTION", "OFF")
setup_configs["ENABLE_FLYCV"] = os.getenv("ENABLE_FLYCV", "OFF")
setup_configs["ENABLE_TEXT"] = os.getenv("ENABLE_TEXT", "OFF")
setup_configs["WITH_GPU"] = os.getenv("WITH_GPU", "OFF")

View File

@@ -0,0 +1,9 @@
import fastdeploy as fd
import os
if __name__ == "__main__":
input = "Hello"
cipher, key = fd.encryption.encrypt(input)
output = fd.encryption.decrypt(cipher, key)
assert input == output, "test encryption failed"
print("test encryption success")