From ae2c1068f246aeab0f0d692454126e82c567416a Mon Sep 17 00:00:00 2001 From: Dongsun Lee Date: Mon, 22 Apr 2019 17:34:53 +0900 Subject: [PATCH] Add KONAI SE plugin Change-Id: I1fb423ae44f5df1dad3bf3fadfd7e8e6fd308875 Signed-off-by: Dongsun Lee --- dcm-daemon/CMakeLists.txt | 13 +- dcm-daemon/konaise-backend/CMakeLists.txt | 5 + dcm-daemon/konaise-backend/konaise.h | 65 +++++ dcm-daemon/konaise-backend/ksebackend.cpp | 106 +++++++ dcm-daemon/konaise-backend/ksebackend.h | 59 ++++ dcm-daemon/konaise-backend/ksebackendcontext.cpp | 217 ++++++++++++++ dcm-daemon/konaise-backend/ksebackendcontext.h | 49 ++++ packaging/device-certificate-manager.spec | 1 + tools/CMakeLists.txt | 20 +- tools/konaise_tool.cpp | 346 +++++++++++++++++++++++ 10 files changed, 875 insertions(+), 6 deletions(-) create mode 100644 dcm-daemon/konaise-backend/CMakeLists.txt create mode 100644 dcm-daemon/konaise-backend/konaise.h create mode 100644 dcm-daemon/konaise-backend/ksebackend.cpp create mode 100644 dcm-daemon/konaise-backend/ksebackend.h create mode 100644 dcm-daemon/konaise-backend/ksebackendcontext.cpp create mode 100644 dcm-daemon/konaise-backend/ksebackendcontext.h create mode 100644 tools/konaise_tool.cpp diff --git a/dcm-daemon/CMakeLists.txt b/dcm-daemon/CMakeLists.txt index 2d8a157..b1089c2 100644 --- a/dcm-daemon/CMakeLists.txt +++ b/dcm-daemon/CMakeLists.txt @@ -50,6 +50,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(dummy-backend) add_subdirectory(see-backend) +add_subdirectory(konaise-backend) IF(ENABLE_DUMMY_BACKEND) SET(DUMMY_BACKEND_OBJECTS $) @@ -57,6 +58,7 @@ IF(ENABLE_DUMMY_BACKEND) ENDIF(ENABLE_DUMMY_BACKEND) SET(SEE_BACKEND_OBJECTS $) +SET(KSE_BACKEND_OBJECTS $) ###### Main executable ####### @@ -75,20 +77,21 @@ add_executable(device-certificate-managerd ${PROTO_HDRS} ${DUMMY_BACKEND_OBJECTS} ${SEE_BACKEND_OBJECTS} + ${KSE_BACKEND_OBJECTS} ) - + add_dependencies(device-certificate-managerd protobuf_generated) ApplyCxx11Standard(device-certificate-managerd) ###### Framework linking ####### -target_link_libraries(device-certificate-managerd +target_link_libraries(device-certificate-managerd ${Boost_LOG_LIBRARY} ${Boost_THREAD_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} - ${Boost_SYSTEM_LIBRARY} + ${Boost_SYSTEM_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MBEDTLS_LIB} ${MBEDCRYPTO_LIB} @@ -102,7 +105,7 @@ ENDIF(DLOG_FOUND) IF(ENABLE_SYSTEMD_SUPPORT) target_link_libraries(device-certificate-managerd ${SYSTEMD_LIBRARIES}) -ENDIF(ENABLE_SYSTEMD_SUPPORT) +ENDIF(ENABLE_SYSTEMD_SUPPORT) IF(CYNARA_FOUND) target_link_libraries(device-certificate-managerd ${CYNARA_LIBRARIES}) @@ -110,5 +113,5 @@ ENDIF(CYNARA_FOUND) ###### Installation ####### -install(TARGETS device-certificate-managerd +install(TARGETS device-certificate-managerd RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/dcm-daemon/konaise-backend/CMakeLists.txt b/dcm-daemon/konaise-backend/CMakeLists.txt new file mode 100644 index 0000000..43ff818 --- /dev/null +++ b/dcm-daemon/konaise-backend/CMakeLists.txt @@ -0,0 +1,5 @@ +add_library(kse-backend + OBJECT + ksebackend.cpp + ksebackendcontext.cpp) +add_dependencies(kse-backend protobuf_generated) diff --git a/dcm-daemon/konaise-backend/konaise.h b/dcm-daemon/konaise-backend/konaise.h new file mode 100644 index 0000000..1b3f908 --- /dev/null +++ b/dcm-daemon/konaise-backend/konaise.h @@ -0,0 +1,65 @@ +/****************************************************************** + * + * Copyright 2019 Samsung Electronics 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 USE_KONAISE_HEADERS +#include +#else + +#ifndef _KONAISE_SECURITY_H_ +#define _KONAISE_SECURITY_H_ + +typedef struct _hal_init_param { + uint32_t i2c_port; + uint32_t gpio; +} hal_init_param; + + +typedef struct _hal_data { + void *data; + uint32_t data_len; + void *priv; +} hal_data; + +typedef enum { + HAL_HASH_MD5, + HAL_HASH_SHA1, + HAL_HASH_SHA224, + HAL_HASH_SHA256, + HAL_HASH_SHA384, + HAL_HASH_SHA512, + HAL_HASH_UNKNOWN, +} hal_hash_type; + +typedef enum { + HAL_ECDSA_BRAINPOOL_P256R1, + HAL_ECDSA_BRAINPOOL_P384R1, + HAL_ECDSA_BRAINPOOL_P512R1, + HAL_ECDSA_SEC_P256R1, + HAL_ECDSA_SEC_P384R1, + HAL_ECDSA_SEC_P512R1, +} hal_ecdsa_curve; + +typedef struct _hal_ecdsa_mode { + hal_ecdsa_curve curve; + hal_hash_type hash_t; +} hal_ecdsa_mode; + + +#endif + +#endif diff --git a/dcm-daemon/konaise-backend/ksebackend.cpp b/dcm-daemon/konaise-backend/ksebackend.cpp new file mode 100644 index 0000000..98f7168 --- /dev/null +++ b/dcm-daemon/konaise-backend/ksebackend.cpp @@ -0,0 +1,106 @@ +/****************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * + * Author: Dongsun Lee + * + * 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 "ksebackend.h" +#include "ksebackendcontext.h" +#include "logging.h" +#include + +#include "konaise.h" + +#define KSE_LIB_NAME "libkonaise.so" + +crypto_backend_registration kse_backend::kse_crypto_backend_registration; + +kse_backend::kse_backend() : + fKseInitOK(false), + fDllResolver(std::string(KSE_LIB_NAME)) +{ + BOOST_LOG_FUNCTION(); + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Constructed KSE backend"; +} + +kse_backend::~kse_backend() { + BOOST_LOG_FUNCTION(); + if(fKseInitOK) { + try { + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Deinitializing KSE backend"; + fDllResolver.invoke(nullptr, "hal_deinit"); + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Deinitialized KSE backend"; + } catch(...) { + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Exception caught when deinitializing KSE backend"; + } + } +} + +void kse_backend::initialize_kse() { + if(fKseInitOK) + return; + + BOOST_LOG_FUNCTION(); + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Initializing KSE backend"; + + std::unique_lock locker(fKSEMutex); + + try { + hal_init_param init_parm = {}; + int error = fDllResolver.invoke(nullptr, "hal_init", &init_parm); + + if(error != 0) { + BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "KSE framework init failure: " << error; + fKseInitOK = false; + } else { + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "KSE framework initialized"; + fKseInitOK = true; + } + } catch(...) { + BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception when initializing KSE backend"; + fKseInitOK = false; + } +} + +std::shared_ptr kse_backend::create_client_context( + const std::string& serviceName, + const std::string& usage, + const std::string& key_type) +{ + BOOST_LOG_FUNCTION(); + initialize_kse(); + + if(!fKseInitOK) + throw std::runtime_error("KSE not initialized"); + + return std::make_shared(std::static_pointer_cast(shared_from_this()), key_type); +} + +float kse_backend::will_handle_service(const std::string&, + const std::string&) +{ + BOOST_LOG_FUNCTION(); + if(!fDllResolver.ensure_loaded()) + return -1.0f; + + initialize_kse(); + + if(!fKseInitOK) + return -1.0f; + + return 1.0f; +} diff --git a/dcm-daemon/konaise-backend/ksebackend.h b/dcm-daemon/konaise-backend/ksebackend.h new file mode 100644 index 0000000..484897f --- /dev/null +++ b/dcm-daemon/konaise-backend/ksebackend.h @@ -0,0 +1,59 @@ +/****************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * + * Author: Dongsun Lee + * + * 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. + * + ******************************************************************/ + + +#ifndef DCM_DAEMON_KSE_BACKEND_KSEBACKEND_H_ +#define DCM_DAEMON_KSE_BACKEND_KSEBACKEND_H_ + +#include "abstractcryptobackend.h" +#include "cryptobackendroster.h" +#include +#include + +class kse_backend: public asbtract_crypto_backend +{ +public: + kse_backend(); + virtual ~kse_backend(); + + virtual std::shared_ptr create_client_context( + const std::string& serviceName, + const std::string& usage, + const std::string& key_type) override; + + virtual float will_handle_service(const std::string& serviceName, + const std::string& usage); + + inline dll_resolver& get_dll_resolver() { + return fDllResolver; + } + + static crypto_backend_registration kse_crypto_backend_registration; + +private: + void initialize_kse(); + +private: + bool fKseInitOK = false; + std::mutex fKSEMutex; + dll_resolver fDllResolver; +}; + +#endif /* DCM_DAEMON_KSE_BACKEND_KSEBACKEND_H_ */ diff --git a/dcm-daemon/konaise-backend/ksebackendcontext.cpp b/dcm-daemon/konaise-backend/ksebackendcontext.cpp new file mode 100644 index 0000000..f931f1e --- /dev/null +++ b/dcm-daemon/konaise-backend/ksebackendcontext.cpp @@ -0,0 +1,217 @@ +/****************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * + * Author: Dongsun Lee + * + * 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 "ksebackendcontext.h" +#include "logging.h" +#include "konaise.h" +#include "mbedtls_wrapper.h" +#include "cert_utils.h" + +#include + +#include +#include + +#define PRIVATE_KEY_INDEX 1 +#define SUBCA_CERT_INDEX 2 +#define LEAF_CERT_INDEX 3 + +static int kse_get_certificate_key = 0; +static int kse_get_ecdsa_signature_key = 1; + +kse_backend_context::kse_backend_context(std::shared_ptr backend, const std::string& keyType) : + fBackendPtr(backend) +{ + BOOST_LOG_FUNCTION(); + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) + << "Created new KSE with key " << keyType; + + if(keyType.empty() || keyType == "ECDSA") { + fKeyType = CRYPTO_KEY_TYPE_ECDSA; + } else { + throw std::invalid_argument("Unsupported key type"); + } + + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) + << "Created new KSE context at " << this; +} + +kse_backend_context::~kse_backend_context() +{ + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) + << "Deleting KSE context " << this; +} + +int kse_backend_context::get_certificate(unsigned int index, std::string& outcert) +{ + hal_data cert = {0}; + const char *method_name = "hal_get_certificate"; + + auto backend = fBackendPtr.lock(); + if(!backend) { + BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) + << "Unable to acquire backend pointer"; + return -EINVAL; + } + + auto& resolver(backend->get_dll_resolver()); + int error = resolver.invoke(&kse_get_certificate_key, + method_name, index, &cert); + if(error != 0) { + BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) + << "Failed to get certificate. error=" << error; + return -EINVAL; + } + +#ifdef ENABLE_DEBUG_LODDING + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) + << "KSE: Got certificate with " << cert.data_len + << " bytes and index " << index; +#endif + try { + outcert.assign((const char *)cert.data, cert.data_len); + } catch(...) { + BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) + << "KSE: Got exception when assigning data"; + free(cert.data); + throw; + } + free(cert.data); + + return 0; +} + +int kse_backend_context::request_certificate_chain(std::string& mutable_chain) +{ + BOOST_LOG_FUNCTION(); +#ifdef ENABLE_DEBUG_LODDING + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) + << "KSE : Request certificate chain"; +#endif + + std::string leaf_cert; + std::string subca_cert; + + int error = 0; + + if(error = get_certificate(LEAF_CERT_INDEX, leaf_cert)) + return error; + if(error = get_certificate(SUBCA_CERT_INDEX, subca_cert)) + return error; + + x509_crt_rewriter cert_writer; + if(error = cert_writer.parse(reinterpret_cast(leaf_cert.c_str()), + leaf_cert.length()+1)) { + return error; + } + if(error = cert_writer.parse(reinterpret_cast(subca_cert.c_str()), + subca_cert.length()+1)) { + return error; + } + cert_writer.sort_chain(); + + mutable_chain.append(cert_writer.emit_pem()); + +#ifdef ENABLE_DEBUG_LODDING + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) + << "Requested certificate in " << this; +#endif + + return 0; +} + +int kse_backend_context::sign_crypto_data(MessageDigestType digestType, const std::string& dataToSign, + std::string& digestResult) +{ + BOOST_LOG_FUNCTION(); + hal_data hashed_data = { }; + hal_data signed_data = { }; + + hashed_data.data = (void *)dataToSign.c_str(); + hashed_data.data_len = dataToSign.size(); + + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "KSE: Sign " << hashed_data.data_len << " bytes"; + + auto backend = fBackendPtr.lock(); + + if(!backend) { + BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Unable to acquire backend pointer"; + return -EINVAL; + } + + auto& resolver(backend->get_dll_resolver()); + +#ifdef ENABLE_DEBUG_LODDING + try { + std::string hex; + boost::algorithm::hex((const unsigned char *)hashed_data.data, + (const unsigned char *)hashed_data.data + hashed_data.data_len, + std::back_inserter(hex)); + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Hashed data is " << hex; + } catch(...) { + } +#endif + + const char *method_name = "hal_ecdsa_sign_md"; + hal_ecdsa_mode mode = {HAL_ECDSA_SEC_P256R1, HAL_HASH_UNKNOWN}; + + int error = resolver.invoke( + &kse_get_ecdsa_signature_key, method_name, + &hashed_data, PRIVATE_KEY_INDEX, &mode, &signed_data); + + if(error != 0) { + BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << + "Unable to generate ECDSA signature in " << + this << + " (" << error << ") : " << + mbedtls_error_to_string(error); + + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + +#ifdef ENABLE_DEBUG_LODDING + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Signature length is " << signed_data.data_len; + + try { + std::string hex; + boost::algorithm::hex((const unsigned char *)signed_data.data, + (const unsigned char *)signed_data.data + signed_data.data_len, + std::back_inserter(hex)); + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Hex signature is " << hex; + } catch(...) { + } + BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "KSE: Generated ECDSA signature"; +#endif + + digestResult.assign((const char *)signed_data.data, signed_data.data_len); + + free(signed_data.data); + return 0; +} + +CryptoKeyType kse_backend_context::key_type() +{ + return fKeyType; +} + +unsigned int kse_backend_context::key_length() +{ + return 256; +} diff --git a/dcm-daemon/konaise-backend/ksebackendcontext.h b/dcm-daemon/konaise-backend/ksebackendcontext.h new file mode 100644 index 0000000..5253119 --- /dev/null +++ b/dcm-daemon/konaise-backend/ksebackendcontext.h @@ -0,0 +1,49 @@ +/****************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * + * Author: Dongsun Lee + * + * 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. + * + ******************************************************************/ + +#ifndef DCM_DAEMON_KSE_BACKEND_KSEBACKENDCONTEXT_H_ +#define DCM_DAEMON_KSE_BACKEND_KSEBACKENDCONTEXT_H_ + +#include "abstractcryptobackendcontext.h" +#include "ksebackend.h" + +class kse_backend_context final : public abstract_crypto_backend_context { +public: + kse_backend_context(std::shared_ptr backend, const std::string& keyType); + virtual ~kse_backend_context(); + + virtual int request_certificate_chain(std::string& mutable_chain) override; + + virtual int sign_crypto_data(MessageDigestType digestType, const std::string& dataToSign, + std::string& digestResult) override; + + virtual CryptoKeyType key_type() override; + + virtual unsigned int key_length() override; + +private: + int get_certificate(unsigned int index, std::string& cert); + +private: + CryptoKeyType fKeyType; + std::weak_ptr fBackendPtr; +}; + +#endif /* DCM_DAEMON_KSE_BACKEND_KSEBACKENDCONTEXT_H_ */ diff --git a/packaging/device-certificate-manager.spec b/packaging/device-certificate-manager.spec index ef19f83..bf5e107 100644 --- a/packaging/device-certificate-manager.spec +++ b/packaging/device-certificate-manager.spec @@ -115,3 +115,4 @@ fi %{_bindir}/dcm_example_capi %{_bindir}/dcm_api_test %{_bindir}/dcm_test_cert_rewriter +%{_bindir}/dcm_konaise_tool diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 064d1a4..bb06898 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,3 +1,21 @@ add_executable(helper_bin2c bin2c.c) - \ No newline at end of file + +####################################################################################### +# For SE_KONAI +ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK) +include_directories(${Boost_INCLUDE_DIRS}) +link_directories(${Boost_LIBRARY_DIRS}) + +include_directories(../dcm-daemon ../dcm-daemon/konaise-backend) + +add_executable(dcm_konaise_tool + ../dcm-daemon/dllresolver.cpp + konaise_tool.cpp) +target_link_libraries(dcm_konaise_tool + ${Boost_LOG_LIBRARY} + device-certificate-manager + dl) +install(TARGETS dcm_konaise_tool RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +####################################################################################### + diff --git a/tools/konaise_tool.cpp b/tools/konaise_tool.cpp new file mode 100644 index 0000000..225dd24 --- /dev/null +++ b/tools/konaise_tool.cpp @@ -0,0 +1,346 @@ +/****************************************************************** + * + * Copyright 2019 Samsung Electronics All Rights Reserved. + * + * Author: Dongsun Lee + * + * 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 +#include +#include +#include +#include "konaise.h" + +#define KSE_LIB_NAME "libkonaise.so" + +static int kse_cert_get = 0x00; +static int kse_cert_add = 0x01; +static int kse_cert_del = 0x02; +static int kse_key_get = 0x10; +static int kse_key_add = 0x11; +static int kse_key_del = 0x12; +static int kse_ec_sign = 0x21; +static int kse_ec_verify= 0x22; + + +typedef enum { + /* AES */ + HAL_KEY_AES_128,// 128 bits aes algorithm + HAL_KEY_AES_192, // 192 bits aes algorithm + HAL_KEY_AES_256, // 256 bits aes algorithm + /* RSA */ + HAL_KEY_RSA_1024, // 1024 bits rsa algorithm + HAL_KEY_RSA_2048, // 2048 bits rsa algorithm + HAL_KEY_RSA_3072, // 3072 bits rsa algorithm + HAL_KEY_RSA_4096, + /* ECC: it doesn't support whole algorithm that mbedTLS support. it's have to be added*/ + HAL_KEY_ECC_BRAINPOOL_P256R1, // ecc brainpool curve for p256r1 + HAL_KEY_ECC_BRAINPOOL_P384R1, // ecc brainpool curve for p384r1 + HAL_KEY_ECC_BRAINPOOL_P512R1, // ecc brainpool curve for p512r1 + HAL_KEY_ECC_SEC_P256R1, // nist curve for p256r1 + HAL_KEY_ECC_SEC_P384R1, // nist curve for p384r1 + HAL_KEY_ECC_SEC_P512R1, // nist curve for p512r1 + /* Hmac */ + HAL_KEY_HMAC_MD5, // hmac with md5 + HAL_KEY_HMAC_SHA1, // hmac with sha1 + HAL_KEY_HMAC_SHA224, // hmac with sha224 + HAL_KEY_HMAC_SHA256, // hmac with sha256 + HAL_KEY_HMAC_SHA384, // hmac with sha384 + HAL_KEY_HMAC_SHA512, // hmac with sha512 + /* DH */ + HAL_KEY_DH_1024, + HAL_KEY_DH_2048, + HAL_KEY_UNKNOWN, +} hal_key_type; + + +class SEKonai { +public: + SEKonai(const std::string& libraryName) : + fDllResolver(libraryName) + { + loaded = fDllResolver.ensure_loaded(); + } + + ~SEKonai(){ + } + + bool is_loaded() { + return loaded; + } + + void get_cert(int idx, const std::string& fileName){ + hal_data cert = {0}; + + const char *method_name = "hal_get_certificate"; + int error = fDllResolver.invoke(&kse_cert_get, + method_name, idx, &cert); + if(error == 0) { + write_file(fileName, cert); + std::cout << "SUCCEEDED in " << method_name << "." << std::endl; + } else { + std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl; + } + } + + void get_key(hal_key_type key_type, int idx, const std::string& fileName) { + hal_data data = {0}; + const char *method_name = "hal_get_key"; + int error = fDllResolver.invoke(&kse_key_get, + method_name, key_type, idx, &data); + if(error == 0) { + write_file(fileName, data); + std::cout << "SUCCEEDED in " << method_name << "." << std::endl; + } else { + std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl; + } + } + + void add_cert(const std::string& fileName, int idx) { + hal_data *data = read_file(fileName); + const char *method_name = "hal_set_certificate"; + int error = fDllResolver.invoke(&kse_cert_add, + method_name, idx, data); + if(error == 0) { + std::cout << "SUCCEEDED in " << method_name << "." << std::endl; + } else { + std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl; + } + free_hal_data(data); + } + + void add_key(const std::string& fileName, hal_key_type key_type, int idx, + const std::string& privFileName) { + hal_data *key = read_file(fileName); + hal_data *priKey = {0}; + if(privFileName.size() != 0) + priKey = read_file(privFileName); + const char *method_name = "hal_set_key"; + int error = fDllResolver.invoke( + &kse_key_add, method_name, key_type, idx, key, priKey); + if(error == 0) { + std::cout << "SUCCEEDED in " << method_name << "." << std::endl; + } else { + std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl; + } + free_hal_data(key); + free_hal_data(priKey); + } + + void del_cert(int idx) { + const char *method_name = "hal_remove_certificate"; + int error = fDllResolver.invoke(&kse_key_del, method_name, idx); + if(error == 0) { + std::cout << "SUCCEEDED in " << method_name << "." << std::endl; + } else { + std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl; + } + } + + void del_key(hal_key_type key_type, int idx) { + const char *method_name = "hal_remove_key"; + int error = fDllResolver.invoke(&kse_key_del, method_name, + key_type, idx); + if(error == 0) { + std::cout << "SUCCEEDED in " << method_name << "." << std::endl; + } else { + std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl; + } + } + + void ec_sec_p256r1_sign(std::string hash_file, int key_idx, std::string sig_file) { + hal_data *hashed_data = read_file(hash_file); + hal_data signed_data = {0}; + + const char *method_name = "hal_ecdsa_sign_md"; + hal_ecdsa_mode mode = {HAL_ECDSA_SEC_P256R1, HAL_HASH_UNKNOWN}; + int error = fDllResolver.invoke( + &kse_ec_sign, method_name, + hashed_data, key_idx, &mode, &signed_data); + if(error == 0) { + write_file(sig_file, signed_data); + std::cout << "SUCCEEDED in " << method_name << "." << std::endl; + } else { + std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl; + } + free_hal_data(hashed_data); + free(signed_data.data); + } + + void ec_sec_p256r1_verify(std::string hash_file, int key_idx, std::string sig_file) { + // ec_sign hash_file key_index key_type sigfile(out) + hal_data *hashed_data = read_file(hash_file); + hal_data *signed_data = read_file(sig_file); + + const char *method_name = "hal_ecdsa_verify_md"; + hal_ecdsa_mode mode = {HAL_ECDSA_SEC_P256R1, HAL_HASH_UNKNOWN}; + int error = fDllResolver.invoke( + &kse_ec_verify, method_name, + mode, hashed_data, signed_data, key_idx); + if(error == 0) { + std::cout << "SUCCEEDED in " << method_name << "." << std::endl; + } else { + std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl; + } + free_hal_data(hashed_data); + free_hal_data(signed_data); + } + + hal_key_type get_key_type(const std::string& keyType) { + if(keyType.compare("HAL_KEY_AES_128") == 0) return HAL_KEY_AES_128; + if(keyType.compare("HAL_KEY_AES_192") == 0) return HAL_KEY_AES_192; + if(keyType.compare("HAL_KEY_AES_256") == 0) return HAL_KEY_AES_256; + if(keyType.compare("HAL_KEY_RSA_1024") == 0) return HAL_KEY_RSA_1024; + if(keyType.compare("HAL_KEY_RSA_2048") == 0) return HAL_KEY_RSA_2048; + if(keyType.compare("HAL_KEY_RSA_3072") == 0) return HAL_KEY_RSA_3072; + if(keyType.compare("HAL_KEY_RSA_4096") == 0) return HAL_KEY_RSA_4096; + if(keyType.compare("HAL_KEY_ECC_BRAINPOOL_P256R1") == 0) return HAL_KEY_ECC_BRAINPOOL_P256R1; + if(keyType.compare("HAL_KEY_ECC_BRAINPOOL_P384R1") == 0) return HAL_KEY_ECC_BRAINPOOL_P384R1; + if(keyType.compare("HAL_KEY_ECC_BRAINPOOL_P512R1") == 0) return HAL_KEY_ECC_BRAINPOOL_P512R1; + if(keyType.compare("HAL_KEY_ECC_SEC_P256R1") == 0) return HAL_KEY_ECC_SEC_P256R1; + if(keyType.compare("HAL_KEY_ECC_SEC_P384R1") == 0) return HAL_KEY_ECC_SEC_P384R1; + if(keyType.compare("HAL_KEY_ECC_SEC_P512R1") == 0) return HAL_KEY_ECC_SEC_P512R1; + if(keyType.compare("HAL_KEY_HMAC_MD5") == 0) return HAL_KEY_HMAC_MD5; + if(keyType.compare("HAL_KEY_HMAC_SHA1") == 0) return HAL_KEY_HMAC_SHA1; + if(keyType.compare("HAL_KEY_HMAC_SHA224") == 0) return HAL_KEY_HMAC_SHA224; + if(keyType.compare("HAL_KEY_HMAC_SHA256") == 0) return HAL_KEY_HMAC_SHA256; + if(keyType.compare("HAL_KEY_HMAC_SHA384") == 0) return HAL_KEY_HMAC_SHA384; + if(keyType.compare("HAL_KEY_HMAC_SHA512") == 0) return HAL_KEY_HMAC_SHA512; + if(keyType.compare("HAL_KEY_DH_1024") == 0) return HAL_KEY_DH_1024; + if(keyType.compare("HAL_KEY_DH_2048") == 0) return HAL_KEY_DH_2048; + return HAL_KEY_UNKNOWN; + } + + std::string get_key_type_str(hal_key_type keyType) { + switch(keyType) { + case HAL_KEY_AES_128: return std::string("HAL_KEY_AES_128"); + case HAL_KEY_AES_192: return std::string("HAL_KEY_AES_192"); + case HAL_KEY_AES_256: return std::string("HAL_KEY_AES_256"); + case HAL_KEY_RSA_1024: return std::string("HAL_KEY_RSA_1024"); + case HAL_KEY_RSA_2048: return std::string("HAL_KEY_RSA_2048"); + case HAL_KEY_RSA_3072: return std::string("HAL_KEY_RSA_3072"); + case HAL_KEY_RSA_4096: return std::string("HAL_KEY_RSA_4096"); + case HAL_KEY_ECC_BRAINPOOL_P256R1: return std::string("HAL_KEY_ECC_BRAINPOOL_P256R1"); + case HAL_KEY_ECC_BRAINPOOL_P384R1: return std::string("HAL_KEY_ECC_BRAINPOOL_P384R1"); + case HAL_KEY_ECC_BRAINPOOL_P512R1: return std::string("HAL_KEY_ECC_BRAINPOOL_P512R1"); + case HAL_KEY_ECC_SEC_P256R1: return std::string("HAL_KEY_ECC_SEC_P256R1"); + case HAL_KEY_ECC_SEC_P384R1: return std::string("HAL_KEY_ECC_SEC_P384R1"); + case HAL_KEY_ECC_SEC_P512R1: return std::string("HAL_KEY_ECC_SEC_P512R1"); + case HAL_KEY_HMAC_MD5: return std::string("HAL_KEY_HMAC_MD5"); + case HAL_KEY_HMAC_SHA1: return std::string("HAL_KEY_HMAC_SHA1"); + case HAL_KEY_HMAC_SHA224: return std::string("HAL_KEY_HMAC_SHA224"); + case HAL_KEY_HMAC_SHA256: return std::string("HAL_KEY_HMAC_SHA256"); + case HAL_KEY_HMAC_SHA384: return std::string("HAL_KEY_HMAC_SHA384"); + case HAL_KEY_HMAC_SHA512: return std::string("HAL_KEY_HMAC_SHA512"); + case HAL_KEY_DH_1024: return std::string("HAL_KEY_DH_1024"); + case HAL_KEY_DH_2048: return std::string("HAL_KEY_DH_2048"); + default: return std::string("HAL_KEY_UNKNOWN"); + } + } + +private: + dll_resolver fDllResolver; + bool loaded; + + void free_hal_data(hal_data *data) { + if(data == NULL) + return; + if(data->data != NULL) + free(data->data); + free(data); + } + + void write_file(const std::string& fileName, hal_data in) { + std::fstream outfile; + outfile = std::fstream(fileName, std::ios::out | std::ios::binary); + outfile.write((char*)in.data, in.data_len); + outfile.close(); + } + + hal_data* read_file(const std::string& fileName) { + if(fileName.size() == 0) + return NULL; + std::ifstream input(fileName, std::ios::binary); + std::vector buffer(std::istreambuf_iterator(input), {}); + unsigned char* data = (unsigned char*) malloc(buffer.size()); + for(int i = 0; i < buffer.size(); i++) + data[i] = buffer[i]; + hal_data *ret = (hal_data *) malloc(sizeof(hal_data)); + ret->data = data; + ret->data_len = buffer.size(); + ret->priv = NULL; + return ret; + } +}; + +void print_usage(char *prog_name) { + std::cout << prog_name << " command opt1 opt2 . . . " << std::endl; + std::cout << " example: " << prog_name << " get_cert index outfile" << std::endl; + std::cout << " example: " << prog_name << " add_cert infile index" << std::endl; + std::cout << " example: " << prog_name << " del_cert index" << std::endl; + std::cout << " example: " << prog_name << " get_key key_type index outfile" << std::endl; + std::cout << " example: " << prog_name << " add_key infile key_type index in_privfile"< 3) { + se.get_cert(std::stoi(argv[2]), std::string(argv[3])); + }else if((cmd.compare("add_cert") == 0) && argc > 3) { + se.add_cert(std::string(argv[2]), std::stoi(argv[3])); + }else if((cmd.compare("del_cert") == 0) && argc > 2) { + se.del_cert(std::stoi(argv[2])); + }else if((cmd.compare("get_key") == 0) && argc > 4) { + se.get_key(se.get_key_type(std::string(argv[2])), + std::stoi(argv[3]), std::string(argv[4])); + }else if((cmd.compare("add_key") == 0) && argc >= 5) { + char * priv_file = nullptr; + if(argc > 5) + priv_file = argv[5]; + se.add_key(std::string(argv[2]), se.get_key_type(std::string(argv[3])), + std::stoi(argv[4]), std::string(priv_file)); + }else if((cmd.compare("del_key") == 0) && argc > 3) { + se.del_key(se.get_key_type(std::string(argv[2])), std::stoi(argv[3])); + }else if((cmd.compare("ec_sec_p256r1_sign") == 0) && argc > 4) { + se.ec_sec_p256r1_sign(std::string(argv[2]), std::stoi(argv[3]), + std::string(argv[4])); + }else if((cmd.compare("ec_sec_p256r1_verify") == 0) && argc > 4) { + se.ec_sec_p256r1_verify(std::string(argv[2]), std::stoi(argv[3]), + std::string(argv[4])); + }else { + print_usage(argv[0]); + return -1; + } + + return 0; +} -- 2.7.4