From 99f1aa50d19cb6f13d5269276547cadc55a0f3bb Mon Sep 17 00:00:00 2001 From: sebaszm Date: Thu, 7 Sep 2023 17:53:02 +0200 Subject: [PATCH 1/2] [cryptography] Add test key generator --- Source/cryptography/tests/CMakeLists.txt | 6 + .../tests/test_key_generator/CMakeLists.txt | 39 ++++++ .../tests/test_key_generator/Module.cpp | 22 ++++ .../tests/test_key_generator/Module.h | 29 +++++ .../tests/test_key_generator/main.cpp | 118 ++++++++++++++++++ 5 files changed, 214 insertions(+) create mode 100644 Source/cryptography/tests/test_key_generator/CMakeLists.txt create mode 100644 Source/cryptography/tests/test_key_generator/Module.cpp create mode 100644 Source/cryptography/tests/test_key_generator/Module.h create mode 100644 Source/cryptography/tests/test_key_generator/main.cpp diff --git a/Source/cryptography/tests/CMakeLists.txt b/Source/cryptography/tests/CMakeLists.txt index d1f33d4e..040ce4e3 100644 --- a/Source/cryptography/tests/CMakeLists.txt +++ b/Source/cryptography/tests/CMakeLists.txt @@ -14,8 +14,10 @@ # 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. + option(BUILD_CRYPTOGRAPHY_TESTS "Build cryptography test" OFF) option(BUILD_CRYPTOGRAPHY_RPC_TESTS "Build cryptography rpc test" OFF) +option(BUILD_CRYPTOGRAPHY_TEST_KEY_GEN "Build test key generator" OFF) if (BUILD_CRYPTOGRAPHY_TESTS) add_subdirectory(cryptography_test) @@ -24,3 +26,7 @@ endif() if (BUILD_CRYPTOGRAPHY_RPC_TESTS) add_subdirectory(rpc_cryptography_test) endif() + +if (BUILD_CRYPTOGRAPHY_TEST_KEY_GEN) + add_subdirectory(test_key_generator) +endif() diff --git a/Source/cryptography/tests/test_key_generator/CMakeLists.txt b/Source/cryptography/tests/test_key_generator/CMakeLists.txt new file mode 100644 index 00000000..7e8a03c5 --- /dev/null +++ b/Source/cryptography/tests/test_key_generator/CMakeLists.txt @@ -0,0 +1,39 @@ +# If not stated otherwise in this file or this component's LICENSE file the +# following copyright and licenses apply: +# +# Copyright 2023 Metrological +# +# 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. + +find_package(${NAMESPACE}Core REQUIRED) +find_package(OpenSSL) + +add_executable(cgkeygen + Module.cpp + main.cpp) + +include_directories(${CMAKE_CURRENT_LIST_DIR}/../../../cryptography) +include_directories($) + +set_target_properties(cgkeygen PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES) + +target_link_libraries(cgkeygen + PRIVATE + ${NAMESPACE}Cryptography + ${NAMESPACE}Core::${NAMESPACE}Core + ssl + crypto) + +install(TARGETS cgkeygen DESTINATION bin) diff --git a/Source/cryptography/tests/test_key_generator/Module.cpp b/Source/cryptography/tests/test_key_generator/Module.cpp new file mode 100644 index 00000000..b734eff3 --- /dev/null +++ b/Source/cryptography/tests/test_key_generator/Module.cpp @@ -0,0 +1,22 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2023 Metrological + * + * 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 "Module.h" + +MODULE_NAME_DECLARATION(BUILD_REFERENCE) diff --git a/Source/cryptography/tests/test_key_generator/Module.h b/Source/cryptography/tests/test_key_generator/Module.h new file mode 100644 index 00000000..1a1e96cc --- /dev/null +++ b/Source/cryptography/tests/test_key_generator/Module.h @@ -0,0 +1,29 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2023 Metrological + * + * 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 MODULE_NAME +#define MODULE_NAME CryptographyTestKeyGenerator +#endif + +#include + +#undef EXTERNAL +#define EXTERNAL diff --git a/Source/cryptography/tests/test_key_generator/main.cpp b/Source/cryptography/tests/test_key_generator/main.cpp new file mode 100644 index 00000000..766016e7 --- /dev/null +++ b/Source/cryptography/tests/test_key_generator/main.cpp @@ -0,0 +1,118 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2023 Metrological + * + * 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 "Module.h" + +#include + +#include +#include + +#include +#include + +namespace { + +using namespace WPEFramework; + +static constexpr Exchange::CryptographyVault VAULT = Exchange::CRYPTOGRAPHY_VAULT_PLATFORM; + +static bool GenerateAESKey(const std::string passphrase, const uint32_t iterations, const uint16_t sizeBits, const std::string name, const string connector = "") +{ + bool result = false; + + Exchange::ICryptography* crypto = Exchange::ICryptography::Instance(connector); + + printf("Generating %d-bit AES key with PKBDF2 (HMAC-256, %d iterations)...\n", sizeBits, iterations); + + if (crypto == nullptr) { + printf("Cryptography not available!\n"); + } + else if ((iterations != 0) && (sizeBits % 8 == 0) && (sizeBits <= 512)) { + + Exchange::IVault* vault = crypto->Vault(VAULT); + + const uint16_t size = (sizeBits / 8); + + if (vault != nullptr) { + uint8_t salt[16]; + uint8_t* hash = new uint8_t[size]; + + RAND_bytes(salt, sizeof(salt)); + + if (PKCS5_PBKDF2_HMAC(passphrase.c_str(), passphrase.size(), salt, sizeof(salt), iterations, EVP_sha256(), size, hash)) { + + const uint32_t keyId = vault->Import(size, hash); + + ::memset(hash, 0xFF, size); + + uint8_t encryptedKey[64]; + const uint16_t encryptedKeySize = vault->Get(keyId, sizeof(encryptedKey), encryptedKey); + + Core::File keyFile(name); + + if ((keyFile.Exists() == false) && (keyFile.Create() == true)) { + keyFile.Write(encryptedKey, encryptedKeySize); + keyFile.Close(); + + printf("Genenerated AES key %s\n", keyFile.Name().c_str()); + result = true; + } + + vault->Delete(keyId); + } + + delete[] hash; + + vault->Release(); + } + } + else { + printf("Invalid parameters!\n"); + } + + if (crypto != nullptr) { + crypto->Release(); + } + + return (result); +} + +} + + +int main(const int argc, const char* argv[]) +{ + int result = 0; + + if ((argc == 5) || (argc == 4)) { + uint32_t iterations = (argc == 5? atoi(argv[4]) : 500000); + + if (GenerateAESKey(argv[2], iterations, atoi(argv[3]), argv[1]) == false) { + printf("FAILED to generate a key!\n"); + result = 1; + } + } + else { + printf("usage: %s [iterations]\n", argv[0]); + } + + return (result); +} + From a0147d30d833641f1411aa3d8082a387cb7499a0 Mon Sep 17 00:00:00 2001 From: sebaszm Date: Mon, 11 Sep 2023 11:03:23 +0200 Subject: [PATCH 2/2] Add vault on cmd line --- .../tests/test_key_generator/CMakeLists.txt | 3 +- .../tests/test_key_generator/main.cpp | 38 ++++++++++++++----- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Source/cryptography/tests/test_key_generator/CMakeLists.txt b/Source/cryptography/tests/test_key_generator/CMakeLists.txt index 7e8a03c5..bb20a387 100644 --- a/Source/cryptography/tests/test_key_generator/CMakeLists.txt +++ b/Source/cryptography/tests/test_key_generator/CMakeLists.txt @@ -16,6 +16,7 @@ # limitations under the License. find_package(${NAMESPACE}Core REQUIRED) +find_package(${NAMESPACE}Cryptography REQUIRED) find_package(OpenSSL) add_executable(cgkeygen @@ -31,8 +32,8 @@ set_target_properties(cgkeygen PROPERTIES target_link_libraries(cgkeygen PRIVATE - ${NAMESPACE}Cryptography ${NAMESPACE}Core::${NAMESPACE}Core + ${NAMESPACE}Cryptography::${NAMESPACE}Cryptography ssl crypto) diff --git a/Source/cryptography/tests/test_key_generator/main.cpp b/Source/cryptography/tests/test_key_generator/main.cpp index 766016e7..cd6d5373 100644 --- a/Source/cryptography/tests/test_key_generator/main.cpp +++ b/Source/cryptography/tests/test_key_generator/main.cpp @@ -31,9 +31,8 @@ namespace { using namespace WPEFramework; -static constexpr Exchange::CryptographyVault VAULT = Exchange::CRYPTOGRAPHY_VAULT_PLATFORM; - -static bool GenerateAESKey(const std::string passphrase, const uint32_t iterations, const uint16_t sizeBits, const std::string name, const string connector = "") +static bool GenerateAESKey(const std::string passphrase, const uint32_t iterations, const uint16_t sizeBits, const std::string name, + const Exchange::CryptographyVault vaultId, const string connector = "") { bool result = false; @@ -46,7 +45,7 @@ static bool GenerateAESKey(const std::string passphrase, const uint32_t iteratio } else if ((iterations != 0) && (sizeBits % 8 == 0) && (sizeBits <= 512)) { - Exchange::IVault* vault = crypto->Vault(VAULT); + Exchange::IVault* vault = crypto->Vault(vaultId); const uint16_t size = (sizeBits / 8); @@ -101,16 +100,37 @@ int main(const int argc, const char* argv[]) { int result = 0; - if ((argc == 5) || (argc == 4)) { - uint32_t iterations = (argc == 5? atoi(argv[4]) : 500000); + if ((argc == 6) || (argc == 5)) { + uint32_t iterations = (argc == 6? atoi(argv[5]) : 500000); + + Exchange::CryptographyVault vaultId = static_cast(~0); - if (GenerateAESKey(argv[2], iterations, atoi(argv[3]), argv[1]) == false) { - printf("FAILED to generate a key!\n"); + if (::strcmp(argv[4], "netflix") == 0) { + vaultId = Exchange::CRYPTOGRAPHY_VAULT_NETFLIX; + } + else if (::strcmp(argv[4], "provisionig") == 0) { + vaultId = Exchange::CRYPTOGRAPHY_VAULT_PROVISIONING; + } + else if (::strcmp(argv[4], "platform") == 0) { + vaultId = Exchange::CRYPTOGRAPHY_VAULT_PLATFORM; + } + else if (::strcmp(argv[4], "default") == 0) { + vaultId = Exchange::CRYPTOGRAPHY_VAULT_DEFAULT; + } + + if (vaultId != static_cast(~0)) { + if (GenerateAESKey(argv[2], iterations, atoi(argv[3]), argv[1], vaultId) == false) { + printf("FAILED to generate a key!\n"); + result = 1; + } + } + else { + printf("invalid vault (must be default, netflix, provisioning or platform)\n"); result = 1; } } else { - printf("usage: %s [iterations]\n", argv[0]); + printf("usage: %s [iterations]\n", argv[0]); } return (result);