From b59d1481d42fe05a6c6cf15151de771a4633e401 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Wed, 3 Feb 2021 14:31:31 +0100 Subject: [PATCH 01/16] Release 0.1.41 * Remove useless socket description timeout initialization * Check sockets received from services * Cynara socket tests * Make SocketDescription getters const * Validate cynara sockets * Refrain from retrying close(int) (per man 2 close) * Catch exceptions before returning to cynara * Use eventfd instead of pipes for notifications * Add randomized socket manager stress test * Prevent writing to a socket marked as closed * Refactor SocketManager's timeout queue * Add timeout queue stress test * Add check for connection counter in the server * Start SocketManager as not working Change-Id: I40682e7d061bbc4e522b1193b328e81abbe6e8e9 --- packaging/key-manager.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/key-manager.spec b/packaging/key-manager.spec index 6562f65..e96f8e7 100644 --- a/packaging/key-manager.spec +++ b/packaging/key-manager.spec @@ -11,7 +11,7 @@ Name: key-manager Summary: Central Key Manager and utilities -Version: 0.1.40 +Version: 0.1.41 Release: 1 Group: Security/Secure Storage License: Apache-2.0 and BSD-3-Clause -- 2.7.4 From 4dbecbea768395cdebc8d9bae71ba1ccb51b20f0 Mon Sep 17 00:00:00 2001 From: INSUN PYO Date: Tue, 2 Feb 2021 17:57:32 +0900 Subject: [PATCH 02/16] Change systemd-devel package name Change-Id: Ia1df8a4567c2f72ef1777bd70b831220fce0b0a4 --- CMakeLists.txt | 2 +- packaging/key-manager.spec | 3 +-- src/manager/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ae2a33..19ff954 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,7 +121,7 @@ PKG_CHECK_MODULES(KEY_MANAGER_DEP glib-2.0 openssl1.1 libsmack - libsystemd-daemon + libsystemd capi-base-common capi-system-info libxml-2.0 diff --git a/packaging/key-manager.spec b/packaging/key-manager.spec index e96f8e7..7606920 100644 --- a/packaging/key-manager.spec +++ b/packaging/key-manager.spec @@ -26,8 +26,7 @@ BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(openssl1.1) BuildRequires: libattr-devel BuildRequires: pkgconfig(libsmack) -BuildRequires: pkgconfig(libsystemd-daemon) -BuildRequires: pkgconfig(libsystemd-journal) +BuildRequires: pkgconfig(libsystemd) BuildRequires: pkgconfig(libxml-2.0) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(security-manager) diff --git a/src/manager/CMakeLists.txt b/src/manager/CMakeLists.txt index c614ab4..ced080a 100644 --- a/src/manager/CMakeLists.txt +++ b/src/manager/CMakeLists.txt @@ -3,7 +3,7 @@ PKG_CHECK_MODULES(COMMON_DEP dlog openssl1.1 libsmack - libsystemd-journal + libsystemd ) SET(KEY_MANAGER_COMMON_VERSION_MAJOR 1) -- 2.7.4 From 51fc7176c39334cb83bae3c15beafa2b8e271740 Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Tue, 9 Feb 2021 11:03:25 +0100 Subject: [PATCH 03/16] Release 0.1.42 * Updated to match recent systemd changes Change-Id: I053812d12e9ae4fce5664def0d8bf8adde9f379e --- packaging/key-manager.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/key-manager.spec b/packaging/key-manager.spec index 7606920..0583787 100644 --- a/packaging/key-manager.spec +++ b/packaging/key-manager.spec @@ -11,7 +11,7 @@ Name: key-manager Summary: Central Key Manager and utilities -Version: 0.1.41 +Version: 0.1.42 Release: 1 Group: Security/Secure Storage License: Apache-2.0 and BSD-3-Clause -- 2.7.4 From db003d1a179e8d863a14b8506ebe0fa9466c2303 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Thu, 18 Feb 2021 10:43:19 +0100 Subject: [PATCH 04/16] Remove unnecessary cast to double in db perf test Change-Id: I7ef26e137010f303c378cb135404a39bf13ec181 --- misc/db_perf/test_db_perf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/db_perf/test_db_perf.cpp b/misc/db_perf/test_db_perf.cpp index a7a6780..b48ad18 100644 --- a/misc/db_perf/test_db_perf.cpp +++ b/misc/db_perf/test_db_perf.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd. All rights reserved * * Contact: Dongsun Lee * @@ -71,7 +71,7 @@ public: ~Perf() { auto end_time = high_resolution_clock::now(); - double time_elapsed_ms = duration_cast(end_time - m_start_time).count(); + auto time_elapsed_ms = duration_cast(end_time - m_start_time).count(); BOOST_TEST_MESSAGE("\t time elapsed: " << time_elapsed_ms << "[ms], number of " << m_operation << ": " << m_iterations); -- 2.7.4 From 6a829f3ea085ad8a6217082a451006f003cecf08 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Thu, 18 Feb 2021 13:16:28 +0100 Subject: [PATCH 05/16] Suppress TEEC deprecated declarations warnings Change-Id: Iaaf6d24ceef6f981398f6c780f41c420555ee191 --- src/manager/crypto/platform/decider.cpp | 5 +---- src/manager/crypto/tz-backend/tz-context.cpp | 4 +++- src/manager/crypto/tz-backend/tz-memory.cpp | 4 +++- src/manager/crypto/tz-backend/tz-serializer.h | 3 +-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/manager/crypto/platform/decider.cpp b/src/manager/crypto/platform/decider.cpp index 25ec1a8..93cd7ae 100644 --- a/src/manager/crypto/platform/decider.cpp +++ b/src/manager/crypto/platform/decider.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2015-2021 Samsung Electronics Co., Ltd. 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. @@ -29,9 +29,6 @@ #ifdef TZ_BACKEND_ENABLED #include - -#include -#include #endif // TZ_BACKEND_ENABLED namespace CKM { diff --git a/src/manager/crypto/tz-backend/tz-context.cpp b/src/manager/crypto/tz-backend/tz-context.cpp index df421f7..b2e55db 100644 --- a/src/manager/crypto/tz-backend/tz-context.cpp +++ b/src/manager/crypto/tz-backend/tz-context.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd. 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. @@ -19,6 +19,8 @@ * @version 1.0 */ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + #include #include #include diff --git a/src/manager/crypto/tz-backend/tz-memory.cpp b/src/manager/crypto/tz-backend/tz-memory.cpp index 324463d..fd94303 100644 --- a/src/manager/crypto/tz-backend/tz-memory.cpp +++ b/src/manager/crypto/tz-backend/tz-memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd 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. @@ -20,6 +20,8 @@ * @brief TrustZone Shared Memory wrapper definitions */ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + #include #include #include diff --git a/src/manager/crypto/tz-backend/tz-serializer.h b/src/manager/crypto/tz-backend/tz-serializer.h index a3fbbd9..b865477 100644 --- a/src/manager/crypto/tz-backend/tz-serializer.h +++ b/src/manager/crypto/tz-backend/tz-serializer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2019-2021 Samsung Electronics Co., Ltd 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. @@ -26,7 +26,6 @@ #include #include -#include #include #include -- 2.7.4 From ed0f61d49c0a954c9c619efe3157d18053654ec4 Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Wed, 3 Mar 2021 14:56:26 +0100 Subject: [PATCH 06/16] Fix coverage generation in rpm 4.14.1 Debug source package directories now have different names. Change-Id: I40f13e79fc90569b9f2f8d03a5a03c3759186363 --- unit-tests/key-manager-coverage.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unit-tests/key-manager-coverage.sh.in b/unit-tests/key-manager-coverage.sh.in index 0870ac7..4b506ca 100644 --- a/unit-tests/key-manager-coverage.sh.in +++ b/unit-tests/key-manager-coverage.sh.in @@ -18,7 +18,7 @@ find / -iname "*.gcda" -exec rm {} \; ckm-unit-tests # copy source files -cp -rp $SRCS_DIR/* "@CMAKE_BINARY_DIR@" +cp -rp $SRCS_DIR*/* "@CMAKE_BINARY_DIR@" # copy gcda files cp -r "@COVERAGE_BUILD_DIR@"/* "@COVERAGE_DIR@" -- 2.7.4 From c03e31df22f61c40869d7d6356dc32e8c606365d Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Thu, 13 May 2021 14:53:32 +0200 Subject: [PATCH 07/16] Open legacy db in R/W mode If due to a failure during previous transaction a rollback journal is generated, the original legacy database has to be restored to the original state before it can be dumped. However, it can't be done unless the database is opened in R/W mode. Change-Id: Icc455f4e820a5be8b0628e95895680e9cbb14eb6 --- src/manager/sqlcipher/sqlcipher.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manager/sqlcipher/sqlcipher.c b/src/manager/sqlcipher/sqlcipher.c index 2c749fc..97059a2 100644 --- a/src/manager/sqlcipher/sqlcipher.c +++ b/src/manager/sqlcipher/sqlcipher.c @@ -236143,7 +236143,7 @@ __attribute__((visibility("default"))) char *dumpLegacyDb(const char *dbPath, co sqlite3 *db; - int rc = sqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READONLY, 0); + int rc = sqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READWRITE, 0); if (!rc && !(rc = sqlite3_key(db, pass, passSize)) && !(rc = sqlite3_exec(db, "PRAGMA cipher_compatibility=2", 0, 0, 0))) rc = sqlite3_db_dump(db, ssout, (void*)&out); -- 2.7.4 From b1a23b8744a0d3c4fb7b96424c812fa4c0af112b Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Thu, 13 May 2021 15:34:32 +0200 Subject: [PATCH 08/16] Release 0.1.43 * Open legacy db in R/W mode * Fix coverage generation in rpm 4.14.1 * Suppress TEEC deprecated declarations warnings * Remove unnecessary cast to double in db perf test Change-Id: I44b581084930e2253ea3112e362733f47a0c9479 --- packaging/key-manager.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/key-manager.spec b/packaging/key-manager.spec index 0583787..1756d16 100644 --- a/packaging/key-manager.spec +++ b/packaging/key-manager.spec @@ -11,7 +11,7 @@ Name: key-manager Summary: Central Key Manager and utilities -Version: 0.1.42 +Version: 0.1.43 Release: 1 Group: Security/Secure Storage License: Apache-2.0 and BSD-3-Clause -- 2.7.4 From 0f9101e780fce6e00c7e99304e2e9432b3b838d1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20Szaknis?= Date: Thu, 20 May 2021 12:30:06 +0200 Subject: [PATCH 09/16] Add test to xml-utils.cpp Change-Id: I74c1130c20245ade53dbb86c72e38528409be23f --- unit-tests/CMakeLists.txt | 1 + unit-tests/test_xml-utils.cpp | 83 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 unit-tests/test_xml-utils.cpp diff --git a/unit-tests/CMakeLists.txt b/unit-tests/CMakeLists.txt index 30eaac0..23813f6 100644 --- a/unit-tests/CMakeLists.txt +++ b/unit-tests/CMakeLists.txt @@ -90,6 +90,7 @@ SET(UNIT_TESTS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test_ss-crypto.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_sw-backend.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_xml-parser.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_xml-utils.cpp ${MANAGER_PATH}/client/client-common.cpp ${MANAGER_PATH}/client-async/descriptor-set.cpp diff --git a/unit-tests/test_xml-utils.cpp b/unit-tests/test_xml-utils.cpp new file mode 100644 index 0000000..47ef62e --- /dev/null +++ b/unit-tests/test_xml-utils.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd 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 +#include +#include +#include "ckm/ckm-raw-buffer.h" +#include "xml-utils.h" + +namespace { + +const std::string WHITECHAR_REMOVAL_INPUT = + "\t\v\r some_value \n\ + some_value \t\v\r \n\ + \t\v\r some_value \t\v\r \n\ + \t\v\r \n\ + "; + +const std::string WHITECHAR_REMOVAL_OUTPUT = + R"( some_value + some_value + some_value +)"; + +const std::string SINGLE_LINE_INPUT = + "\t\v\r some_value \t\v\r"; + +const std::string SINGLE_LINE_OUTPUT = + "some_value"; + +const std::string WHITECHARS = "\r\n\v\t "; + +bool contains_whitespace(const std::string& str) { + return str.find_first_of(WHITECHARS) != std::string::npos; +} + +} + +BOOST_AUTO_TEST_SUITE(XML_UTILS_TEST) + +POSITIVE_TEST_CASE(TrimTest) { + BOOST_REQUIRE(CKM::XML::trimEachLine(WHITECHAR_REMOVAL_INPUT) == WHITECHAR_REMOVAL_OUTPUT); + BOOST_REQUIRE(CKM::XML::trim(SINGLE_LINE_INPUT) == SINGLE_LINE_OUTPUT); + + const CKM::RawBuffer buffer_input(SINGLE_LINE_INPUT.begin(), SINGLE_LINE_INPUT.end()); + const CKM::RawBuffer buffer_output(SINGLE_LINE_OUTPUT.begin(), SINGLE_LINE_OUTPUT.end()); + const CKM::RawBuffer converted = CKM::XML::removeWhiteChars(buffer_input); + BOOST_REQUIRE(converted == buffer_output); +} + +NEGATIVE_TEST_CASE(TrimTest) { + std::string raw_bytes; + for (unsigned int c=0; c < 0x100; ++c) + raw_bytes += static_cast(c); + + BOOST_REQUIRE(!contains_whitespace(CKM::XML::trim(raw_bytes))); + + const std::size_t length = 0x1'000'000; + std::string long_random_string; + std::random_device rd; + std::uniform_int_distribution<> distb(0, 0x100); + for (std::size_t i=0; i < length; ++i) + long_random_string += static_cast(distb(rd)); + BOOST_REQUIRE(!contains_whitespace(CKM::XML::trim(long_random_string))); + + BOOST_REQUIRE(CKM::XML::trim("") == ""); +} + +BOOST_AUTO_TEST_SUITE_END() + -- 2.7.4 From eaba3ca8539ded916e9b2253ed02923d9b074026 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20Szaknis?= Date: Thu, 20 May 2021 17:16:14 +0200 Subject: [PATCH 10/16] Add tests for AliasSupport class Change-Id: I509160e10ca4ac00418d3ee408c32915c6aa5511 --- unit-tests/CMakeLists.txt | 1 + unit-tests/test_client-common.cpp | 54 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 unit-tests/test_client-common.cpp diff --git a/unit-tests/CMakeLists.txt b/unit-tests/CMakeLists.txt index 23813f6..643ae55 100644 --- a/unit-tests/CMakeLists.txt +++ b/unit-tests/CMakeLists.txt @@ -68,6 +68,7 @@ SET(UNIT_TESTS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test_base64.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_binary-queue.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_certificate.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_client-common.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_comm-manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_crypto-logic.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_data-type.cpp diff --git a/unit-tests/test_client-common.cpp b/unit-tests/test_client-common.cpp new file mode 100644 index 0000000..9c306bf --- /dev/null +++ b/unit-tests/test_client-common.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd 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 +#include +#include "client-common.h" + +namespace { +const std::string OWNER_ID = "some_id"; +const std::string NAME = "some_name"; + +const std::string EMPTY_OWNER_ID = ""; +} + +BOOST_AUTO_TEST_SUITE(CLIENT_COMMON) + +POSITIVE_TEST_CASE(AliasTest) { + const auto alias = CKM::AliasSupport::merge(OWNER_ID, NAME); + const auto alias_support = CKM::AliasSupport(alias); + + BOOST_REQUIRE(!alias_support.isOwnerEmpty()); + BOOST_REQUIRE(alias_support.getName() == NAME); + BOOST_REQUIRE(alias_support.getOwner() == OWNER_ID); + + const auto empty_owner_alias = CKM::AliasSupport::merge(EMPTY_OWNER_ID, NAME); + const auto empty_owner_alias_support = CKM::AliasSupport(empty_owner_alias); + + BOOST_REQUIRE(empty_owner_alias_support.isOwnerEmpty()); + BOOST_REQUIRE(empty_owner_alias_support.getName() == NAME); + BOOST_REQUIRE(empty_owner_alias_support.getOwner() == EMPTY_OWNER_ID); +} + +NEGATIVE_TEST_CASE(AliasTest) { + const auto empty_alias = CKM::AliasSupport::merge("", ""); + const auto empty_alias_support = CKM::AliasSupport(empty_alias); + BOOST_REQUIRE(empty_alias_support.isOwnerEmpty()); + BOOST_REQUIRE(empty_alias_support.getName() == ""); + BOOST_REQUIRE(empty_alias_support.getOwner() == ""); +} + +BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 0e7dafb754dc075b422203b86bdf874aba31ecc9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20Szaknis?= Date: Fri, 21 May 2021 10:18:35 +0200 Subject: [PATCH 11/16] Add tests for ckmc-type-converter.cpp Change-Id: Idd90ad6f954ec491d718b955bea2f43624986160 --- unit-tests/CMakeLists.txt | 1 + unit-tests/test_ckmc_converter.cpp | 95 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 unit-tests/test_ckmc_converter.cpp diff --git a/unit-tests/CMakeLists.txt b/unit-tests/CMakeLists.txt index 643ae55..6f8636f 100644 --- a/unit-tests/CMakeLists.txt +++ b/unit-tests/CMakeLists.txt @@ -68,6 +68,7 @@ SET(UNIT_TESTS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test_base64.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_binary-queue.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_certificate.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_ckmc_converter.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_client-common.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_comm-manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_crypto-logic.cpp diff --git a/unit-tests/test_ckmc_converter.cpp b/unit-tests/test_ckmc_converter.cpp new file mode 100644 index 0000000..9a9d41e --- /dev/null +++ b/unit-tests/test_ckmc_converter.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd 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 +#include "boost_macros_wrapper.h" +#include "ckmc-type-converter.h" + +namespace { + +const std::pair CKMC_ERRORS[] = { + {CKM_API_SUCCESS, CKMC_ERROR_NONE}, + {CKM_API_ERROR_SOCKET, CKMC_ERROR_SOCKET}, + {CKM_API_ERROR_BAD_REQUEST, CKMC_ERROR_BAD_REQUEST}, + {CKM_API_ERROR_BAD_RESPONSE, CKMC_ERROR_BAD_RESPONSE}, + {CKM_API_ERROR_SEND_FAILED, CKMC_ERROR_SEND_FAILED}, + {CKM_API_ERROR_RECV_FAILED, CKMC_ERROR_RECV_FAILED}, + {CKM_API_ERROR_AUTHENTICATION_FAILED, CKMC_ERROR_AUTHENTICATION_FAILED}, + {CKM_API_ERROR_INPUT_PARAM, CKMC_ERROR_INVALID_PARAMETER}, + {CKM_API_ERROR_BUFFER_TOO_SMALL, CKMC_ERROR_BUFFER_TOO_SMALL}, + {CKM_API_ERROR_OUT_OF_MEMORY, CKMC_ERROR_OUT_OF_MEMORY}, + {CKM_API_ERROR_ACCESS_DENIED, CKMC_ERROR_PERMISSION_DENIED}, + {CKM_API_ERROR_SERVER_ERROR, CKMC_ERROR_SERVER_ERROR}, + {CKM_API_ERROR_DB_LOCKED, CKMC_ERROR_DB_LOCKED}, + {CKM_API_ERROR_DB_ERROR, CKMC_ERROR_DB_ERROR}, + {CKM_API_ERROR_DB_ALIAS_EXISTS, CKMC_ERROR_DB_ALIAS_EXISTS}, + {CKM_API_ERROR_DB_ALIAS_UNKNOWN, CKMC_ERROR_DB_ALIAS_UNKNOWN}, + {CKM_API_ERROR_VERIFICATION_FAILED, CKMC_ERROR_VERIFICATION_FAILED}, + {CKM_API_ERROR_INVALID_FORMAT, CKMC_ERROR_INVALID_FORMAT}, + {CKM_API_ERROR_FILE_ACCESS_DENIED, CKMC_ERROR_FILE_ACCESS_DENIED}, + {CKM_API_ERROR_NOT_EXPORTABLE, CKMC_ERROR_NOT_EXPORTABLE}, + {CKM_API_ERROR_FILE_SYSTEM, CKMC_ERROR_FILE_SYSTEM}, + {CKM_API_ERROR_NOT_SUPPORTED, CKMC_ERROR_NOT_SUPPORTED}, + {CKM_API_ERROR_UNKNOWN, CKMC_ERROR_UNKNOWN} +}; + +const std::pair CKMC_OSCP_STATUSES[] = { + {CKM_API_OCSP_STATUS_GOOD, CKMC_OCSP_STATUS_GOOD}, + {CKM_API_OCSP_STATUS_UNSUPPORTED, CKMC_OCSP_ERROR_UNSUPPORTED}, + {CKM_API_OCSP_STATUS_REVOKED, CKMC_OCSP_STATUS_REVOKED}, + {CKM_API_OCSP_STATUS_NET_ERROR, CKMC_OCSP_ERROR_NET}, + {CKM_API_OCSP_STATUS_INVALID_URL, CKMC_OCSP_ERROR_INVALID_URL}, + {CKM_API_OCSP_STATUS_INVALID_RESPONSE, CKMC_OCSP_ERROR_INVALID_RESPONSE}, + {CKM_API_OCSP_STATUS_REMOTE_ERROR, CKMC_OCSP_ERROR_REMOTE}, + {CKM_API_OCSP_STATUS_INTERNAL_ERROR, CKMC_OCSP_ERROR_INTERNAL} +}; + +} + +BOOST_AUTO_TEST_SUITE(CKMCTypeConverter) + +POSITIVE_TEST_CASE(CKMCErrorsAndStatusses) { + for (auto & i : CKMC_ERRORS) { + BOOST_REQUIRE(to_ckmc_error(i.first) == i.second); + } + + for (auto & i : CKMC_OSCP_STATUSES) { + BOOST_REQUIRE(to_ckmc_ocsp_status(i.first) == i.second); + } + + int permissionMask = 0; + + int status = access_to_permission_mask(CKMC_AR_READ, permissionMask); + BOOST_REQUIRE(status == CKMC_ERROR_NONE); + BOOST_REQUIRE(permissionMask == CKMC_PERMISSION_READ); + + status = access_to_permission_mask(CKMC_AR_READ_REMOVE, permissionMask); + BOOST_REQUIRE(status == CKMC_ERROR_NONE); + BOOST_REQUIRE(permissionMask == (CKMC_PERMISSION_READ | CKMC_PERMISSION_REMOVE)); +} + +NEGATIVE_TEST_CASE(CKMCErrorsAndStatusses) { + const int some_random_value = 0x1eadbeef; + BOOST_REQUIRE(to_ckmc_error(some_random_value) == CKMC_ERROR_UNKNOWN); + BOOST_REQUIRE(to_ckmc_ocsp_status(some_random_value) == CKMC_OCSP_STATUS_UNKNOWN); + + int permissionMask = 0; + int status = access_to_permission_mask(static_cast(some_random_value), permissionMask); + BOOST_REQUIRE(status == CKMC_ERROR_INVALID_PARAMETER); + BOOST_REQUIRE(permissionMask == 0); +} + +BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 4072ec2e90d248a217e1d8819ba3705a26314dde Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20Szaknis?= Date: Fri, 21 May 2021 16:17:20 +0200 Subject: [PATCH 12/16] Add tests for `try_catch` and `try_catch_enclosure` Change-Id: If74b22ad53961a32c75d3d7feae48f2a41d09508 --- unit-tests/test_client-common.cpp | 77 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/unit-tests/test_client-common.cpp b/unit-tests/test_client-common.cpp index 9c306bf..34a60fb 100644 --- a/unit-tests/test_client-common.cpp +++ b/unit-tests/test_client-common.cpp @@ -15,14 +15,50 @@ */ #include +#include +#include +#include #include +#include +#include +#include "ckm/ckm-error.h" #include "client-common.h" +#include "message-buffer.h" namespace { const std::string OWNER_ID = "some_id"; const std::string NAME = "some_name"; const std::string EMPTY_OWNER_ID = ""; + +const auto throw_forced_unwind = [] { + pthread_exit(NULL); + return 0; +}; + +static_assert( + std::is_same_v, + "`try_catch` and `try_catch_enclosure declarations doesn't match." +); +using ConvertingFunction = decltype(CKM::try_catch); + +void test_forced_unwind_throw(ConvertingFunction func) { + // I used this custom try-catch insted of BOOST_CHECK_THROW, + // beacuse the abi::__forced_unwind exception needs to be rethrown + // for thread cancellation not to occur. + + bool __forced_unwind_thrown = false; + std::thread([func, &__forced_unwind_thrown] { + try { + func(throw_forced_unwind); + } catch (const abi::__forced_unwind& ) { + __forced_unwind_thrown = true; + throw; + } + }).join(); + + BOOST_REQUIRE(__forced_unwind_thrown); +} } BOOST_AUTO_TEST_SUITE(CLIENT_COMMON) @@ -51,4 +87,45 @@ NEGATIVE_TEST_CASE(AliasTest) { BOOST_REQUIRE(empty_alias_support.getOwner() == ""); } +POSITIVE_TEST_CASE(try_catch_test) { + const auto throw_message_buffer_base_exception = [] { + throw CKM::MessageBuffer::Exception::Base("", "", 0); + return 0; + }; + const auto throw_runtime_error = [] { + throw std::runtime_error(""); + return 0; + }; + const auto throw_unknown_exception = [] { + struct {} annonymous; + throw annonymous; + return 0; + }; + const auto throw_bad_alloc = [] { throw std::bad_alloc(); return 0; }; + const auto throw_msgbuffer_exception = [] { + throw CKM::MessageBuffer::Exception(); + return 0; + }; + const auto no_throw = [] { return 0; }; + + BOOST_REQUIRE(CKM::try_catch(throw_message_buffer_base_exception) == CKM_API_ERROR_UNKNOWN); + BOOST_REQUIRE(CKM::try_catch(throw_runtime_error) == CKM_API_ERROR_UNKNOWN); + BOOST_REQUIRE(CKM::try_catch(throw_unknown_exception) == CKM_API_ERROR_UNKNOWN); + BOOST_REQUIRE(CKM::try_catch(throw_msgbuffer_exception) == CKM_API_ERROR_UNKNOWN); + BOOST_REQUIRE(CKM::try_catch(no_throw) == CKM_API_SUCCESS); + test_forced_unwind_throw(&CKM::try_catch); + + BOOST_REQUIRE(CKM::try_catch_enclosure(throw_bad_alloc) == CKMC_ERROR_OUT_OF_MEMORY); + BOOST_REQUIRE(CKM::try_catch_enclosure(throw_runtime_error) == CKMC_ERROR_UNKNOWN); + BOOST_REQUIRE(CKM::try_catch_enclosure(throw_unknown_exception) == CKMC_ERROR_UNKNOWN); + BOOST_REQUIRE(CKM::try_catch_enclosure(no_throw) == CKM_API_SUCCESS); + test_forced_unwind_throw(&CKM::try_catch_enclosure); + +} + +NEGATIVE_TEST_CASE(try_catch_test) { + BOOST_REQUIRE(CKM::try_catch(nullptr) == CKM_API_ERROR_UNKNOWN); + BOOST_REQUIRE(CKM::try_catch_enclosure(nullptr) == CKMC_ERROR_UNKNOWN); +} + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 0c279f20524238a79bb9e48960f680e9b8f875c3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20Szaknis?= Date: Wed, 21 Apr 2021 17:28:08 +0200 Subject: [PATCH 13/16] Use fixed object ID in TZ backend Calculate the object ID as a hash of credentials and alias instead of using a random ID. Change-Id: Ice164d6f8eda9acd157c4d74f47d45fef49f6ddc --- common/colour_log_formatter.cpp | 2 +- data/gumd/10_key-manager.post.in | 0 doc/images/capi_key_manager_overview_diagram.png | Bin src/include/ckm/ckm-error.h | 4 + src/include/ckmc/ckmc-type.h | 4 +- src/manager/crypto/generic-backend/gstore.h | 16 +++- src/manager/crypto/sw-backend/store.cpp | 21 ++++- src/manager/crypto/sw-backend/store.h | 16 ++-- src/manager/crypto/tz-backend/internals.cpp | 53 +++++------- src/manager/crypto/tz-backend/internals.h | 16 ++-- src/manager/crypto/tz-backend/store.cpp | 35 +++++--- src/manager/crypto/tz-backend/store.h | 16 ++-- src/manager/crypto/tz-backend/tz-context.cpp | 100 +++++++++++------------ src/manager/crypto/tz-backend/tz-context.h | 28 +++---- src/manager/crypto/tz-backend/tz-memory.cpp | 15 +++- src/manager/service/ckm-logic.cpp | 98 +++++++++++++++------- src/manager/service/ckm-logic.h | 13 +-- src/manager/service/crypto-logic.cpp | 18 +++- src/manager/service/crypto-logic.h | 8 +- unit-tests/test_crypto-logic.cpp | 16 +++- unit-tests/test_sw-backend.cpp | 64 ++++++++++++--- 21 files changed, 351 insertions(+), 192 deletions(-) mode change 100755 => 100644 data/gumd/10_key-manager.post.in mode change 100755 => 100644 doc/images/capi_key_manager_overview_diagram.png diff --git a/common/colour_log_formatter.cpp b/common/colour_log_formatter.cpp index 9c31a2c..a00a37d 100644 --- a/common/colour_log_formatter.cpp +++ b/common/colour_log_formatter.cpp @@ -134,7 +134,7 @@ colour_log_formatter::test_unit_start( } else { output << "Running test "; } - output << test_unit_type_name(tu) << " \"" << test_unit_name(tu) + output << test_unit_type_name(tu) << " \"" << test_unit_name(tu) << "\"" << std::endl; } diff --git a/data/gumd/10_key-manager.post.in b/data/gumd/10_key-manager.post.in old mode 100755 new mode 100644 diff --git a/doc/images/capi_key_manager_overview_diagram.png b/doc/images/capi_key_manager_overview_diagram.png old mode 100755 new mode 100644 diff --git a/src/include/ckm/ckm-error.h b/src/include/ckm/ckm-error.h index 788eaef..4347b0e 100644 --- a/src/include/ckm/ckm-error.h +++ b/src/include/ckm/ckm-error.h @@ -94,6 +94,10 @@ /*! \brief indicating that device needed to run API is not supported */ #define CKM_API_ERROR_NOT_SUPPORTED -21 +/*! \brief indicating that Hash(ObjectId) calculation failed */ +#define CKM_API_ERROR_HASH_ERROR -22 + + #define CKM_API_OCSP_STATUS_GOOD (1<<0) #define CKM_API_OCSP_STATUS_UNSUPPORTED (1<<1) #define CKM_API_OCSP_STATUS_UNKNOWN (1<<2) diff --git a/src/include/ckmc/ckmc-type.h b/src/include/ckmc/ckmc-type.h index a182519..d047eaf 100644 --- a/src/include/ckmc/ckmc-type.h +++ b/src/include/ckmc/ckmc-type.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2021 Samsung Electronics Co., Ltd 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. @@ -578,7 +578,7 @@ int ckmc_pkcs12_new(ckmc_key_s *private_key, ckmc_cert_s *cert, ckmc_cert_list_s * @see #ckmc_cert_s * @see #ckmc_cert_list_s */ -int ckmc_load_from_pkcs12_file(const char *file_path, const char *passphrase, ckmc_key_s **private_key, ckmc_cert_s **cert, ckmc_cert_list_s **ca_cert_list) TIZEN_DEPRECATED_API; +int ckmc_load_from_pkcs12_file(const char *file_path, const char *passphrase, ckmc_key_s **private_key, ckmc_cert_s **cert, ckmc_cert_list_s **ca_cert_list) TIZEN_DEPRECATED_API; /** diff --git a/src/manager/crypto/generic-backend/gstore.h b/src/manager/crypto/generic-backend/gstore.h index 0a16d42..2e26bda 100644 --- a/src/manager/crypto/generic-backend/gstore.h +++ b/src/manager/crypto/generic-backend/gstore.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2015-2021 Samsung Electronics Co., Ltd. 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. @@ -27,6 +27,8 @@ #include #include #include +#include +#include namespace CKM { namespace Crypto { @@ -44,15 +46,21 @@ public: virtual GObjUPtr getObject(const Token &, const Password &) = 0; virtual TokenPair generateAKey(const CryptoAlgorithm &, const Password &, - const Password &) = 0; - virtual Token generateSKey(const CryptoAlgorithm &, const Password &) = 0; + const Password &, + const RawBuffer &, + const RawBuffer &) = 0; + + virtual Token generateSKey(const CryptoAlgorithm &, + const Password &, + const RawBuffer &) = 0; /* * EncryptionParams parameter makes sense only on device with built-in key. * EncryptionParams parameter is used for decryption of Data. * If Data is not encrypted it's ok to pass empty EncryptionParams. */ - virtual Token import(const Data &, const Password &, const EncryptionParams &) = 0; + virtual Token import(const Data &, const Password &, const EncryptionParams &, + const RawBuffer &) = 0; virtual void destroy(const Token &) = 0; virtual ~GStore() {} diff --git a/src/manager/crypto/sw-backend/store.cpp b/src/manager/crypto/sw-backend/store.cpp index 5c846ed..3c5b898 100644 --- a/src/manager/crypto/sw-backend/store.cpp +++ b/src/manager/crypto/sw-backend/store.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 - 2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2021 Samsung Electronics Co., Ltd 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. @@ -143,6 +143,11 @@ RawBuffer pack(const RawBuffer &data, const Password &pass) return SerializeMessage(scheme, packed); } +std::string rawToHexString(const RawBuffer &raw) +{ + return hexDump(raw); +} + } // namespace anonymous Store::Store(CryptoBackend backendId) @@ -175,8 +180,12 @@ GObjUPtr Store::getObject(const Token &token, const Password &pass) TokenPair Store::generateAKey(const CryptoAlgorithm &algorithm, const Password &prvPass, - const Password &pubPass) + const Password &pubPass, + const RawBuffer &hashPriv, + const RawBuffer &hashPub) { + LogDebug("Hash of Private key credentials = " << rawToHexString(hashPriv)); + LogDebug("Hash of Public key credentials = " << rawToHexString(hashPub)); Internals::DataPair ret = Internals::generateAKey(algorithm); return std::make_pair( Token(m_backendId, ret.first.type, pack(ret.first.buffer, prvPass)), @@ -184,14 +193,18 @@ TokenPair Store::generateAKey(const CryptoAlgorithm &algorithm, } Token Store::generateSKey(const CryptoAlgorithm &algorithm, - const Password &pass) + const Password &pass, + const RawBuffer &hash) { + LogDebug("Hash of AES Key credentials = " << rawToHexString(hash)); Internals::Data ret = Internals::generateSKey(algorithm); return Token(m_backendId, ret.type, pack(ret.buffer, pass)); } -Token Store::import(const Data &data, const Password &pass, const EncryptionParams &e) +Token Store::import(const Data &data, const Password &pass, const EncryptionParams &e, + const RawBuffer &hash) { + LogDebug("Hash of Data credentials = " << rawToHexString(hash)); if (!e.iv.empty()) ThrowErr(Exc::Crypto::OperationNotSupported, "Encrypted import is not yet supported on software backend!"); diff --git a/src/manager/crypto/sw-backend/store.h b/src/manager/crypto/sw-backend/store.h index 479c698..6acbbd0 100644 --- a/src/manager/crypto/sw-backend/store.h +++ b/src/manager/crypto/sw-backend/store.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 - 2018 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2021 Samsung Electronics Co., Ltd 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. @@ -32,10 +32,16 @@ public: explicit Store(CryptoBackend backendId); virtual GObjUPtr getObject(const Token &, const Password &); - virtual TokenPair generateAKey(const CryptoAlgorithm &, const Password &, - const Password &); - virtual Token generateSKey(const CryptoAlgorithm &, const Password &); - virtual Token import(const Data &data, const Password &, const EncryptionParams &); + virtual TokenPair generateAKey(const CryptoAlgorithm &, + const Password &, + const Password &, + const RawBuffer &, + const RawBuffer &); + virtual Token generateSKey(const CryptoAlgorithm &, + const Password &, + const RawBuffer &); + virtual Token import(const Data &data, const Password &, const EncryptionParams &, + const RawBuffer &); virtual void destroy(const Token &) {} }; diff --git a/src/manager/crypto/tz-backend/internals.cpp b/src/manager/crypto/tz-backend/internals.cpp index 8b72f48..0c4c022 100644 --- a/src/manager/crypto/tz-backend/internals.cpp +++ b/src/manager/crypto/tz-backend/internals.cpp @@ -173,17 +173,15 @@ RawBuffer generateIV() return result; } -Data generateSKey(const CryptoAlgorithm &alg, +void generateSKey(const CryptoAlgorithm &alg, const Password &pwd, const RawBuffer &iv, - RawBuffer &tag) + RawBuffer &tag, + const RawBuffer &hash) { AlgoType keyType = unpack(alg, ParamName::ALGO_TYPE); int keyBits = unpack(alg, ParamName::GEN_KEY_LEN); - Data keyData; - keyData.type = DataType(KeyType::KEY_AES); - if (!pwd.empty()) { if (iv.empty()) { ThrowErr(Exc::InputParam, "Key generation with password encryption requires an IV"); @@ -192,29 +190,27 @@ Data generateSKey(const CryptoAlgorithm &alg, RawBuffer pwdBuf(pwd.begin(), pwd.end()); TrustZoneContext::Instance().generateSKeyPwd(getGenSKeyType(keyType), pwdBuf, iv, keyBits, - keyData.data, tag); + tag, hash); } else { TrustZoneContext::Instance().generateSKey(getGenSKeyType(keyType), keyBits, - keyData.data); + hash); } - return keyData; } -DataPair generateAKey(const CryptoAlgorithm &alg, +AlgoType generateAKey(const CryptoAlgorithm &alg, const Password &pubPwd, const Password &privPwd, const RawBuffer &pubPwdIv, const RawBuffer &privPwdIv, RawBuffer &pubTag, - RawBuffer &privTag) + RawBuffer &privTag, + const RawBuffer &hashPriv, + const RawBuffer &hashPub) { AlgoType keyType = unpack(alg, ParamName::ALGO_TYPE); int keyBits = unpack(alg, ParamName::GEN_KEY_LEN); - Data pubKeyData; - Data privKeyData; - RawBuffer pubPwdBuf; if (!pubPwd.empty()) pubPwdBuf.assign(pubPwd.begin(), pubPwd.end()); @@ -225,24 +221,18 @@ DataPair generateAKey(const CryptoAlgorithm &alg, switch (keyType) { case AlgoType::RSA_GEN: { - pubKeyData.type = DataType(KeyType::KEY_RSA_PUBLIC); - privKeyData.type = DataType(KeyType::KEY_RSA_PRIVATE); - TrustZoneContext::Instance().generateRSAKey(keyBits, pubPwdBuf, pubPwdIv, privPwdBuf, privPwdIv, - pubKeyData.data, pubTag, - privKeyData.data, - privTag); + privTag, + hashPriv, + hashPub); break; } case AlgoType::DSA_GEN: { - pubKeyData.type = DataType(KeyType::KEY_DSA_PUBLIC); - privKeyData.type = DataType(KeyType::KEY_DSA_PRIVATE); - RawBuffer prime; RawBuffer subprime; RawBuffer base; @@ -255,10 +245,10 @@ DataPair generateAKey(const CryptoAlgorithm &alg, pubPwdIv, privPwdBuf, privPwdIv, - pubKeyData.data, pubTag, - privKeyData.data, - privTag); + privTag, + hashPriv, + hashPub); break; } default: { @@ -267,7 +257,7 @@ DataPair generateAKey(const CryptoAlgorithm &alg, } } - return DataPair(pubKeyData, privKeyData); + return keyType; } void destroyKey(const RawBuffer &key) @@ -275,15 +265,15 @@ void destroyKey(const RawBuffer &key) TrustZoneContext::Instance().executeDestroy(key); } -RawBuffer importData(const Data &data, +void importData(const Data &data, const EncryptionParams &encData, const Password &pwd, const RawBuffer &pwdIV, - RawBuffer &tag) + RawBuffer &tag, + const RawBuffer &hash) { const auto dataType = toTzDataType(data.type); - RawBuffer result; RawBuffer pwdBuf(pwd.begin(), pwd.end()); uint32_t keySizeBits = data.data.size() * 8; @@ -294,9 +284,8 @@ RawBuffer importData(const Data &data, pwdIV, keySizeBits, Params::DERIVED_KEY_LENGTH_BITS, - result, - tag); - return result; + tag, + hash); } RawBuffer getData(const RawBuffer &dataId, diff --git a/src/manager/crypto/tz-backend/internals.h b/src/manager/crypto/tz-backend/internals.h index b66351c..3322eee 100644 --- a/src/manager/crypto/tz-backend/internals.h +++ b/src/manager/crypto/tz-backend/internals.h @@ -39,24 +39,28 @@ using KeyIdPair = std::pair; RawBuffer generateIV(); -DataPair generateAKey(const CryptoAlgorithm &alg, +AlgoType generateAKey(const CryptoAlgorithm &alg, const Password &pubPwd, const Password &privPwd, const RawBuffer &pubPwdIv, const RawBuffer &privPwdIv, RawBuffer &pubTag, - RawBuffer &privTag); + RawBuffer &privTag, + const RawBuffer &hashPriv, + const RawBuffer &hashPub); -Data generateSKey(const CryptoAlgorithm &alg, +void generateSKey(const CryptoAlgorithm &alg, const Password &pwd, const RawBuffer &iv, - RawBuffer &tag); + RawBuffer &tag, + const RawBuffer &hash); -RawBuffer importData(const Data &key, +void importData(const Data &key, const EncryptionParams &encData, const Password &pwd, const RawBuffer &pwdIV, - RawBuffer &tag); + RawBuffer &tag, + const RawBuffer &hash); RawBuffer getData(const RawBuffer &dataId, const Pwd &pwd); diff --git a/src/manager/crypto/tz-backend/store.cpp b/src/manager/crypto/tz-backend/store.cpp index ba7de98..d5c348d 100644 --- a/src/manager/crypto/tz-backend/store.cpp +++ b/src/manager/crypto/tz-backend/store.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 - 2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2021 Samsung Electronics Co., Ltd 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. @@ -127,7 +127,7 @@ GObjUPtr Store::getObject(const Token &token, const Password &pass) } TokenPair Store::generateAKey(const CryptoAlgorithm &alg, const Password &privPass, - const Password &pubPass) + const Password &pubPass, const RawBuffer &hashPriv, const RawBuffer &hashPub) { RawBuffer pubIv, privIv; RawBuffer pubTag, privTag; @@ -138,15 +138,27 @@ TokenPair Store::generateAKey(const CryptoAlgorithm &alg, const Password &privPa privIv = Internals::generateIV(); } - Internals::DataPair ret = Internals::generateAKey(alg, pubPass, privPass, pubIv, privIv, pubTag, privTag); + AlgoType keyType; + DataType pubType, privType; + keyType = Internals::generateAKey(alg, pubPass, privPass, pubIv, privIv, pubTag, privTag, hashPriv, hashPub); + if(keyType == AlgoType::RSA_GEN){ + pubType = DataType(KeyType::KEY_RSA_PUBLIC); + privType = DataType(KeyType::KEY_RSA_PRIVATE); + } + else if(keyType == AlgoType::DSA_GEN){ + pubType= DataType(KeyType::KEY_DSA_PUBLIC); + privType = DataType(KeyType::KEY_DSA_PRIVATE); + } return std::make_pair( - Token(m_backendId, ret.second.type, pack(ret.second.data, privPass, privIv, privTag)), - Token(m_backendId, ret.first.type, pack(ret.first.data, pubPass, pubIv, pubTag)) + Token(m_backendId, privType, pack(hashPriv, privPass, privIv, privTag)), + Token(m_backendId, pubType, pack(hashPub, pubPass, pubIv, pubTag)) ); } -Token Store::generateSKey(const CryptoAlgorithm &alg, const Password &pass) +Token Store::generateSKey(const CryptoAlgorithm &alg, + const Password &pass, + const RawBuffer &hash) { RawBuffer iv; RawBuffer tag; @@ -155,11 +167,12 @@ Token Store::generateSKey(const CryptoAlgorithm &alg, const Password &pass) iv = Internals::generateIV(); } - Data ret = Internals::generateSKey(alg, pass, iv, tag); - return Token(m_backendId, ret.type, pack(ret.data, pass, iv, tag)); + Internals::generateSKey(alg, pass, iv, tag, hash); + return Token(m_backendId, DataType(KeyType::KEY_AES), pack(hash, pass, iv, tag)); } -Token Store::import(const Data &data, const Password &pass, const EncryptionParams &e) +Token Store::import(const Data &data, const Password &pass, const EncryptionParams &e, + const RawBuffer &hash) { if (!data.type.isBinaryData() && !data.type.isKey()) ThrowErr(Exc::Crypto::DataTypeNotSupported, "Invalid data provided for import"); @@ -172,8 +185,8 @@ Token Store::import(const Data &data, const Password &pass, const EncryptionPara passIV = Internals::generateIV(); } - RawBuffer dataId = Internals::importData(data, e, pass, passIV, tag); - return Token(m_backendId, data.type, pack(dataId, pass, passIV, tag)); + Internals::importData(data, e, pass, passIV, tag, hash); + return Token(m_backendId, data.type, pack(hash, pass, passIV, tag)); } void Store::destroy(const Token &token) diff --git a/src/manager/crypto/tz-backend/store.h b/src/manager/crypto/tz-backend/store.h index 664c756..21e3519 100644 --- a/src/manager/crypto/tz-backend/store.h +++ b/src/manager/crypto/tz-backend/store.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 - 2018 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2021 Samsung Electronics Co., Ltd 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. @@ -32,10 +32,16 @@ public: explicit Store(CryptoBackend backendId); virtual GObjUPtr getObject(const Token &, const Password &); - virtual TokenPair generateAKey(const CryptoAlgorithm &, const Password &, - const Password &); - virtual Token generateSKey(const CryptoAlgorithm &, const Password &); - virtual Token import(const Data &, const Password &, const EncryptionParams &); + virtual TokenPair generateAKey(const CryptoAlgorithm &, + const Password &, + const Password &, + const RawBuffer &, + const RawBuffer &); + virtual Token generateSKey(const CryptoAlgorithm &, + const Password &, + const RawBuffer &); + virtual Token import(const Data &, const Password &, const EncryptionParams &, + const RawBuffer &); virtual void destroy(const Token &); // TODO device key ID is needed here to support importEncrypted diff --git a/src/manager/crypto/tz-backend/tz-context.cpp b/src/manager/crypto/tz-backend/tz-context.cpp index b2e55db..2e0ffd9 100644 --- a/src/manager/crypto/tz-backend/tz-context.cpp +++ b/src/manager/crypto/tz-backend/tz-context.cpp @@ -111,43 +111,40 @@ void TrustZoneContext::generateIV(RawBuffer& iv) void TrustZoneContext::generateSKey(tz_algo_type algo, uint32_t keySizeBits, - RawBuffer &keyId) + const RawBuffer &hash) { // command ID = CMD_GENERATE_KEY - TZSerializer sOut; - sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE)); - - TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT); + TZSerializer sIn; + sIn.Push(new TZSerializableBinary(hash)); + TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT); + sIn.Serialize(inMemory); TEEC_Operation op; op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE); op.params[0].value.a = algo; op.params[0].value.b = keySizeBits; - op.params[1].memref.parent = outMemory.Get(); + op.params[1].memref.parent = inMemory.Get(); op.params[1].memref.offset = 0; - op.params[1].memref.size = outMemory.Get()->size; + op.params[1].memref.size = inMemory.Get()->size; Execute(CMD_GENERATE_KEY, &op); - - sOut.Deserialize(outMemory); - sOut.Pull(keyId); } void TrustZoneContext::generateSKeyPwd(tz_algo_type algo, const RawBuffer &pwd, const RawBuffer &iv, const uint32_t keySizeBits, - RawBuffer &keyId, - RawBuffer &pwdTag) + RawBuffer &pwdTag, + const RawBuffer &hash) { // command ID = CMD_GENERATE_KEY_PWD TZSerializer sIn; sIn.Push(new TZSerializablePwdData(pwd, iv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS)); + sIn.Push(new TZSerializableBinary(hash)); TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT); sIn.Serialize(inMemory); TZSerializer sOut; - sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE)); sOut.Push(new TZSerializableBinary(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES)); TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT); @@ -165,8 +162,11 @@ void TrustZoneContext::generateSKeyPwd(tz_algo_type algo, Execute(CMD_GENERATE_KEY_PWD, &op); sOut.Deserialize(outMemory); - sOut.Pull(keyId); sOut.Pull(pwdTag); + + if (pwdTag.size() != Params::DEFAULT_AES_GCM_TAG_LEN_BYTES) { + ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key tag"); + } } void TrustZoneContext::GenerateAKey(tz_command commandId, @@ -176,10 +176,10 @@ void TrustZoneContext::GenerateAKey(tz_command commandId, const RawBuffer &pubPwdIv, const RawBuffer &privPwd, const RawBuffer &privPwdIv, - RawBuffer &pubKeyId, RawBuffer &pubKeyTag, - RawBuffer &privKeyId, - RawBuffer &privKeyTag) + RawBuffer &privKeyTag, + const RawBuffer &hashPriv, + const RawBuffer &hashPub) { uint32_t pubTagSize = 0; uint32_t privTagSize = 0; @@ -196,19 +196,14 @@ void TrustZoneContext::GenerateAKey(tz_command commandId, sIn.Push(new TZSerializablePwdData(privPwd, privPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS)); privTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3; } - + sIn.Push(new TZSerializableBinary(hashPriv)); + sIn.Push(new TZSerializableBinary(hashPub)); TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT); sIn.Serialize(inMemory); TZSerializer sOut; - sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE)); - if (pubTagSize) { - sOut.Push(new TZSerializableBinary(pubTagSize)); - } - sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE)); - if (privTagSize) { - sOut.Push(new TZSerializableBinary(privTagSize)); - } + sOut.Push(new TZSerializableBinary(pubTagSize)); + sOut.Push(new TZSerializableBinary(privTagSize)); TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT); @@ -225,15 +220,10 @@ void TrustZoneContext::GenerateAKey(tz_command commandId, Execute(commandId, &op); sOut.Deserialize(outMemory); - - sOut.Pull(pubKeyId); - if (pubPwdExists) { sOut.Pull(pubKeyTag); } - sOut.Pull(privKeyId); - if (privPwdExists) { sOut.Pull(privKeyTag); } @@ -244,10 +234,10 @@ void TrustZoneContext::generateRSAKey(uint32_t keySizeBits, const RawBuffer &pubPwdIv, const RawBuffer &privPwd, const RawBuffer &privPwdIv, - RawBuffer &pubKeyId, RawBuffer &pubKeyTag, - RawBuffer &privKeyId, - RawBuffer &privKeyTag) + RawBuffer &privKeyTag, + const RawBuffer &hashPriv, + const RawBuffer &hashPub) { // command ID = CMD_GENERATE_RSA_KEYPAIR TZSerializer sIn; @@ -259,10 +249,10 @@ void TrustZoneContext::generateRSAKey(uint32_t keySizeBits, pubPwdIv, privPwd, privPwdIv, - pubKeyId, pubKeyTag, - privKeyId, - privKeyTag); + privKeyTag, + hashPriv, + hashPub); } void TrustZoneContext::generateDSAKey(uint32_t keySizeBits, @@ -273,10 +263,10 @@ void TrustZoneContext::generateDSAKey(uint32_t keySizeBits, const RawBuffer &pubPwdIv, const RawBuffer &privPwd, const RawBuffer &privPwdIv, - RawBuffer &pubKeyId, RawBuffer &pubKeyTag, - RawBuffer &privKeyId, - RawBuffer &privKeyTag) + RawBuffer &privKeyTag, + const RawBuffer &hashPriv, + const RawBuffer &hashPub) { // command ID = CMD_GENERATE_DSA_KEYPAIR TZSerializer sIn; @@ -291,10 +281,10 @@ void TrustZoneContext::generateDSAKey(uint32_t keySizeBits, pubPwdIv, privPwd, privPwdIv, - pubKeyId, pubKeyTag, - privKeyId, - privKeyTag); + privKeyTag, + hashPriv, + hashPub); } void TrustZoneContext::executeCrypt(tz_command cmd, @@ -595,10 +585,11 @@ void TrustZoneContext::importData( const RawBuffer &iv, const uint32_t keySizeBits, const uint32_t pwdTagSizeBits, - RawBuffer &dataId, - RawBuffer &pwdTag) + RawBuffer &pwdTag, + const RawBuffer &hash) { // command ID = CMD_IMPORT_DATA + LogDebug("TrustZoneContext::importData data size = [" << data.size() << "]"); TZSerializer sIn; sIn.Push(new TZSerializableFlag(dataType)); sIn.Push(new TZSerializableBinary(data)); @@ -611,12 +602,13 @@ void TrustZoneContext::importData( if (pwd_flag) sIn.Push(new TZSerializablePwdData(pwd, iv, pwdTagSizeBits)); + sIn.Push(new TZSerializableBinary(hash)); + TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT); sIn.Serialize(inMemory); TZSerializer sOut; - sOut.Push(new TZSerializableBinary(KM_DATA_ID_SIZE)); if (pwd_flag) { sOut.Push(new TZSerializableBinary(pwdTagSizeBits / 8)); } @@ -624,8 +616,15 @@ void TrustZoneContext::importData( TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT); TEEC_Operation op; - op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE, + if (pwd_flag) { + op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_NONE); + } + else { + op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE, + TEEC_NONE, TEEC_NONE); + } + op.params[1].memref.parent = inMemory.Get(); op.params[1].memref.offset = 0; op.params[1].memref.size = inMemory.Get()->size; @@ -635,13 +634,12 @@ void TrustZoneContext::importData( Execute(CMD_IMPORT_DATA, &op); - sOut.Deserialize(outMemory); - sOut.Pull(dataId); if (pwd_flag) { + sOut.Deserialize(outMemory); sOut.Pull(pwdTag); } - LogDebug("Imported object ID is (hex): " << rawToHexString(dataId)); + LogDebug("Imported object ID is (hex): " << rawToHexString(hash)); } void TrustZoneContext::GetDataSize(const RawBuffer &dataId, uint32_t &dataSize) @@ -692,6 +690,8 @@ void TrustZoneContext::getData(const RawBuffer &dataId, uint32_t data_size = 0; GetDataSize(dataId, data_size); + LogDebug("GetData data_size = [" << data_size << "]"); + TZSerializer sOut; sOut.Push(new TZSerializableBinary(data_size)); TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT); diff --git a/src/manager/crypto/tz-backend/tz-context.h b/src/manager/crypto/tz-backend/tz-context.h index 05c336e..0ccfbc5 100644 --- a/src/manager/crypto/tz-backend/tz-context.h +++ b/src/manager/crypto/tz-backend/tz-context.h @@ -42,22 +42,22 @@ public: void generateIV(RawBuffer &iv); void generateSKey(tz_algo_type algo, uint32_t keySizeBits, - RawBuffer &keyId); + const RawBuffer &hash); void generateSKeyPwd(tz_algo_type algo, const RawBuffer &pwd, const RawBuffer &iv, const uint32_t pwdKeySizeBits, - RawBuffer &keyId, - RawBuffer &pwdTag); + RawBuffer &pwdTag, + const RawBuffer &hash); void generateRSAKey(uint32_t keySizeBits, const RawBuffer &pubPwd, const RawBuffer &pubPwdIv, const RawBuffer &privPwd, const RawBuffer &privPwdIv, - RawBuffer &pubKeyId, RawBuffer &pubKeyTag, - RawBuffer &privKeyId, - RawBuffer &privKeyTag); + RawBuffer &privKeyTag, + const RawBuffer &hashPriv, + const RawBuffer &hashPub); void generateDSAKey(uint32_t keySizeBits, const RawBuffer &prime, const RawBuffer &subprime, @@ -66,10 +66,10 @@ public: const RawBuffer &pubPwdIv, const RawBuffer &privPwd, const RawBuffer &privPwdIv, - RawBuffer &pubKeyId, RawBuffer &pubKeyTag, - RawBuffer &privKeyId, - RawBuffer &privKeyTag); + RawBuffer &privKeyTag, + const RawBuffer &hashPriv, + const RawBuffer &hashPub); void importData(uint32_t dataType, const RawBuffer &data, @@ -78,8 +78,8 @@ public: const RawBuffer &pwdIV, const uint32_t keySizeBits, const uint32_t powTagSizeBits, - RawBuffer &keyId, - RawBuffer &pwdTag); + RawBuffer &pwdTag, + const RawBuffer &hash); void executeCrypt(tz_command cmd, tz_algo_type algo, @@ -148,10 +148,10 @@ private: const RawBuffer &pubPwdIv, const RawBuffer &privPwd, const RawBuffer &privPwdIv, - RawBuffer &pubKeyId, RawBuffer &pubKeyTag, - RawBuffer &privKeyId, - RawBuffer &privKeyTag); + RawBuffer &privKeyTag, + const RawBuffer &hashPriv, + const RawBuffer &hashPub); TEEC_Context m_Context; TEEC_Session m_Session; diff --git a/src/manager/crypto/tz-backend/tz-memory.cpp b/src/manager/crypto/tz-backend/tz-memory.cpp index fd94303..2904e37 100644 --- a/src/manager/crypto/tz-backend/tz-memory.cpp +++ b/src/manager/crypto/tz-backend/tz-memory.cpp @@ -49,13 +49,19 @@ void TrustZoneMemory::Allocate(TEEC_Context &context, const size_t size, const u m_SharedMemory.flags = flags; LogDebug("Allocating " << size << " bytes of shared TZ memory, flags: " << flags); - TEEC_Result result = TEEC_AllocateSharedMemory(&context, &m_SharedMemory); - if (result != TEEC_SUCCESS) { + if(size != 0) { + TEEC_Result result = TEEC_AllocateSharedMemory(&context, &m_SharedMemory); + if (result != TEEC_SUCCESS) { ThrowErr(Exc::Crypto::InternalError, "TZ failed to register memory: ", static_cast(result)); + } + memset(m_SharedMemory.buffer, 0, m_SharedMemory.size); + } + else { + m_SharedMemory.buffer = NULL; + m_SharedMemory.size = 0; } - memset(m_SharedMemory.buffer, 0, m_SharedMemory.size); } TEEC_SharedMemory* TrustZoneMemory::Get() const @@ -65,7 +71,8 @@ TEEC_SharedMemory* TrustZoneMemory::Get() const void TrustZoneMemory::Release() { - TEEC_ReleaseSharedMemory(&m_SharedMemory); + if(m_SharedMemory.size != 0) + TEEC_ReleaseSharedMemory(&m_SharedMemory); } } // namespace Internals diff --git a/src/manager/service/ckm-logic.cpp b/src/manager/service/ckm-logic.cpp index fcbf0ac..393386d 100644 --- a/src/manager/service/ckm-logic.cpp +++ b/src/manager/service/ckm-logic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014-2021 Samsung Electronics Co., Ltd. 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. @@ -75,7 +75,7 @@ template int tryRet(F &&f) { try { - static_assert(sizeof(int) == sizeof std::forward(f)()); + static_assert(std::is_same_v(f)()), int>); return std::forward(f)(); } catch (const Exc::Exception &e) { return e.error(); @@ -101,7 +101,7 @@ int toBinaryData(const Crypto::Data &input, Crypto::Data &output) return CKM_API_ERROR_INPUT_PARAM; } - output = std::move(Crypto::Data(input.type, output_key->getDER())); + output = Crypto::Data(input.type, output_key->getDER()); } else if (input.type.isCertificate() || input.type.isChainCert()) { CertificateShPtr cert = CKM::Certificate::create(input.data, DataFormat::FORM_DER); @@ -111,7 +111,7 @@ int toBinaryData(const Crypto::Data &input, Crypto::Data &output) return CKM_API_ERROR_INPUT_PARAM; } - output = std::move(Crypto::Data(input.type, cert->getDER())); + output = Crypto::Data(input.type, cert->getDER()); } else { output = input; } @@ -520,14 +520,15 @@ DB::Row CKMLogic::createEncryptedRow( const Name &name, const ClientId &owner, const Crypto::Data &data, - const Policy &policy) + const Policy &policy, + const RawBuffer &hash) { Crypto::GStore &store = m_decider.getStore(data.type, policy); // do not encrypt data with password during cc_mode on Token token = store.import(data, m_accessControl.isCCMode() ? "" : policy.password, - Crypto::EncryptionParams()); + Crypto::EncryptionParams(), hash); DB::Row row(std::move(token), name, owner, static_cast(policy.extractable)); crypto.encryptRow(row); @@ -591,7 +592,8 @@ int CKMLogic::extractPKCS12Data( const PKCS12Serializable &pkcs, const PolicySerializable &keyPolicy, const PolicySerializable &certPolicy, - DB::RowVector &output) + DB::RowVector &output, + const Credentials &cred) { // private key is mandatory auto key = pkcs.getKey(); @@ -601,6 +603,10 @@ int CKMLogic::extractPKCS12Data( return CKM_API_ERROR_INVALID_FORMAT; } + auto digest = CryptoLogic::makeHash(name, owner, cred.clientUid); + if (digest.empty()) + return CKM_API_ERROR_HASH_ERROR; + Crypto::Data keyData(DataType(key->getType()), key->getDER()); int retCode = verifyBinaryData(keyData); @@ -608,7 +614,7 @@ int CKMLogic::extractPKCS12Data( return retCode; output.push_back(createEncryptedRow(crypto, name, owner, keyData, - keyPolicy)); + keyPolicy, digest)); // certificate is mandatory auto cert = pkcs.getCertificate(); @@ -625,7 +631,7 @@ int CKMLogic::extractPKCS12Data( return retCode; output.push_back(createEncryptedRow(crypto, name, owner, certData, - certPolicy)); + certPolicy, digest)); // CA cert chain unsigned int cert_index = 0; @@ -639,7 +645,7 @@ int CKMLogic::extractPKCS12Data( return retCode; output.push_back(createEncryptedRow(crypto, name, owner, caCertData, - certPolicy)); + certPolicy, digest)); } return CKM_API_SUCCESS; @@ -755,7 +761,8 @@ int CKMLogic::checkDataPermissionsHelper(const Credentials &accessorCred, Crypto::GObjUPtr CKMLogic::rowToObject( UserData &handler, DB::Row row, - const Password &password) + const Password &password, + const RawBuffer &hash) { Crypto::GStore &store = m_decider.getStore(row); @@ -776,7 +783,7 @@ Crypto::GObjUPtr CKMLogic::rowToObject( store.destroy(row); // import it to store with new scheme: data -> pass(data) - Token token = store.import(Crypto::Data(row.dataType, row.data), pass, Crypto::EncryptionParams()); + Token token = store.import(Crypto::Data(row.dataType, row.data), pass, Crypto::EncryptionParams(), hash); // get it from the store (it can be different than the data we imported into store) obj = store.getObject(token, pass); @@ -835,9 +842,13 @@ int CKMLogic::readDataHelper( if (CKM_API_SUCCESS != retCode) return retCode; + auto digest = CryptoLogic::makeHash(name, owner, cred.clientUid); + if (digest.empty()) + return CKM_API_ERROR_HASH_ERROR; + // decrypt row for (auto &row : rows) - objs.push_back(rowToObject(handler, std::move(row), password)); + objs.push_back(rowToObject(handler, std::move(row), password, digest)); // rowToObject may modify db transaction.commit(); @@ -900,7 +911,11 @@ int CKMLogic::readDataHelper( if (CKM_API_SUCCESS != retCode) return retCode; - obj = rowToObject(handler, std::move(row), password); + auto digest = CryptoLogic::makeHash(name, owner, cred.clientUid); + if (digest.empty()) + return CKM_API_ERROR_HASH_ERROR; + + obj = rowToObject(handler, std::move(row), password, digest); // rowToObject may modify db transaction.commit(); @@ -1137,7 +1152,7 @@ int CKMLogic::importInitialData( // Inital values are always imported with root credentials. Client id is not important. Credentials rootCred(0, ""); - + ClientId owner(CLIENT_ID_SYSTEM); auto &handler = selectDatabase(rootCred, CLIENT_ID_SYSTEM); // check if save is possible @@ -1150,23 +1165,27 @@ int CKMLogic::importInitialData( Crypto::GStore &store = m_decider.getStore(data.type, policy, !encParams.iv.empty()); - Token token; + Token token; + + auto digest = CryptoLogic::makeHash(name, owner, rootCred.clientUid); + if (digest.empty()) + return CKM_API_ERROR_HASH_ERROR; - if (encParams.iv.empty()) { - // Data are not encrypted, let's try to verify them - Crypto::Data binaryData; + if (encParams.iv.empty()) { + // Data are not encrypted, let's try to verify them + Crypto::Data binaryData; if (CKM_API_SUCCESS != (retCode = toBinaryData(data, binaryData))) return retCode; - token = store.import(binaryData, - m_accessControl.isCCMode() ? "" : policy.password, - encParams); - } else { - token = store.import(data, - m_accessControl.isCCMode() ? "" : policy.password, - encParams); - } + token = store.import(binaryData, + m_accessControl.isCCMode() ? "" : policy.password, + encParams, digest); + } else { + token = store.import(data, + m_accessControl.isCCMode() ? "" : policy.password, + encParams, digest); + } DB::Row row(std::move(token), name, CLIENT_ID_SYSTEM, static_cast(policy.extractable)); @@ -1208,9 +1227,13 @@ int CKMLogic::saveDataHelper( if (retCode != CKM_API_SUCCESS) return retCode; + auto digest = CryptoLogic::makeHash(name, owner, cred.clientUid); + if (digest.empty()) + return CKM_API_ERROR_HASH_ERROR; + // save the data DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, owner, - data, policy); + data, policy, digest); handler.database.saveRow(encryptedRow); transaction.commit(); @@ -1244,7 +1267,7 @@ int CKMLogic::saveDataHelper( // extract and encrypt the data DB::RowVector encryptedRows; retCode = extractPKCS12Data(handler.crypto, name, owner, pkcs, keyPolicy, - certPolicy, encryptedRows); + certPolicy, encryptedRows, cred); if (retCode != CKM_API_SUCCESS) return retCode; @@ -1280,12 +1303,16 @@ int CKMLogic::createKeyAESHelper( if (retCode != CKM_API_SUCCESS) return retCode; + auto digest = CryptoLogic::makeHash(name, owner, cred.clientUid); + if (digest.empty()) + return CKM_API_ERROR_HASH_ERROR; + // create key in store CryptoAlgorithm keyGenAlgorithm; keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN); keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, size); Token key = m_decider.getStore(DataType::KEY_AES, - policy).generateSKey(keyGenAlgorithm, policy.password); + policy).generateSKey(keyGenAlgorithm, policy.password, digest); // save the data DB::Row row(std::move(key), name, owner, @@ -1342,9 +1369,18 @@ int CKMLogic::createKeyPairHelper( bool exportable = policyPrivate.extractable || policyPublic.extractable; Policy lessRestricted(Password(), exportable, policyPrivate.backend); + auto digestPriv = CryptoLogic::makeHash(namePrivate, explicitOwnerPrivate, cred.clientUid); + if (digestPriv.empty()) + return CKM_API_ERROR_HASH_ERROR; + + auto digestPub = CryptoLogic::makeHash(namePublic, explicitOwnerPublic, cred.clientUid); + if (digestPub.empty()) + return CKM_API_ERROR_HASH_ERROR; + TokenPair keys = m_decider.getStore(policyPrivate, dt.first, dt.second).generateAKey(keyGenParams, policyPrivate.password, - policyPublic.password); + policyPublic.password, + digestPriv, digestPub); DB::Crypto::Transaction transactionPriv(&handlerPriv.database); // in case the same database is used for private and public - the second diff --git a/src/manager/service/ckm-logic.h b/src/manager/service/ckm-logic.h index 97281d2..b22f1a0 100644 --- a/src/manager/service/ckm-logic.h +++ b/src/manager/service/ckm-logic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014-2021 Samsung Electronics Co., Ltd. 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. @@ -219,7 +219,6 @@ public: const Policy &policy); int unlockSystemDB(); - private: // select private/system database depending on asking uid and owner id. // output: database handler for effective owner @@ -263,7 +262,8 @@ private: const Name &name, const ClientId &owner, const Crypto::Data &data, - const Policy &policy); + const Policy &policy, + const RawBuffer &hash); int getPKCS12Helper( const Credentials &cred, @@ -282,7 +282,8 @@ private: const PKCS12Serializable &pkcs, const PolicySerializable &keyPolicy, const PolicySerializable &certPolicy, - DB::RowVector &output); + DB::RowVector &output, + const Credentials &cred); int removeDataHelper( const Credentials &cred, @@ -300,8 +301,8 @@ private: Crypto::GObjUPtr rowToObject( UserData &handler, DB::Row row, - const Password &password); - + const Password &password, + const RawBuffer &hash); protected: int readDataHelper( bool exportFlag, diff --git a/src/manager/service/crypto-logic.cpp b/src/manager/service/crypto-logic.cpp index 2dcf715..810200c 100644 --- a/src/manager/service/crypto-logic.cpp +++ b/src/manager/service/crypto-logic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 - 2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2014 - 2021 Samsung Electronics Co., Ltd 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. @@ -30,6 +30,7 @@ #include #include +#include #include @@ -238,5 +239,20 @@ void CryptoLogic::decBase64(RawBuffer &data) data = std::move(decdata); } +RawBuffer CryptoLogic::makeHash( + const std::string& name, + const std::string& owner, + uid_t uid) +{ + const std::string msg = name + owner + std::to_string(uid); + RawBuffer digest(SHA512_DIGEST_LENGTH); + auto msg_ptr = reinterpret_cast(msg.data()); + + if (!SHA512(msg_ptr, msg.length(), digest.data())) + return RawBuffer(); + + return digest; +} + } // namespace CKM diff --git a/src/manager/service/crypto-logic.h b/src/manager/service/crypto-logic.h index 75cad96..df6131c 100644 --- a/src/manager/service/crypto-logic.h +++ b/src/manager/service/crypto-logic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 - 2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2014 - 2021 Samsung Electronics Co., Ltd 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. @@ -48,6 +48,11 @@ public: const RawBuffer &applicationKey); void removeKey(const ClientId &client); + static RawBuffer makeHash( + const std::string& name, + const std::string& owner, + uid_t uid); + /* * v1 encryption. * Token returned from store is encrypted with app key and @@ -112,5 +117,6 @@ private: void encBase64(RawBuffer &data); }; + } // namespace CKM diff --git a/unit-tests/test_crypto-logic.cpp b/unit-tests/test_crypto-logic.cpp index c06e2a7..b0b8c27 100644 --- a/unit-tests/test_crypto-logic.cpp +++ b/unit-tests/test_crypto-logic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 - 2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd 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. @@ -23,7 +23,6 @@ #include #include #include - #include "test_common.h" using namespace CKM; @@ -32,6 +31,7 @@ namespace { constexpr char TEST_CLIENT[] = "test_client"; constexpr char TEST_NAME[] = "test_name"; +constexpr uid_t TEST_UID = 0; const auto TEST_KEY = createRandom(32); const auto TEST_DATA = createRandom(10); @@ -131,7 +131,11 @@ POSITIVE_TEST_CASE(row_encryption) Crypto::Data data(DataType::BINARY_DATA, TEST_DATA); Crypto::Decider decider; Crypto::GStore &store = decider.getStore(data.type, policy); - Token token = store.import(data, policy.password, Crypto::EncryptionParams()); + + const auto digest = CryptoLogic::makeHash(TEST_NAME, TEST_CLIENT, TEST_UID); + BOOST_REQUIRE(!digest.empty()); + + Token token = store.import(data, policy.password, Crypto::EncryptionParams(), digest); DB::Row row(token, TEST_NAME, TEST_CLIENT, static_cast(policy.extractable)); @@ -157,7 +161,11 @@ NEGATIVE_TEST_CASE(row_encryption) Crypto::Data data(DataType::BINARY_DATA, TEST_DATA); Crypto::Decider decider; Crypto::GStore &store = decider.getStore(data.type, policy); - Token token = store.import(data, policy.password, Crypto::EncryptionParams()); + + const auto digest = CryptoLogic::makeHash(TEST_NAME, TEST_CLIENT, TEST_UID); + BOOST_REQUIRE(!digest.empty()); + + Token token = store.import(data, policy.password, Crypto::EncryptionParams(), digest); DB::Row row(token, TEST_NAME, TEST_CLIENT, static_cast(policy.extractable)); diff --git a/unit-tests/test_sw-backend.cpp b/unit-tests/test_sw-backend.cpp index 0232d99..9ac80c3 100644 --- a/unit-tests/test_sw-backend.cpp +++ b/unit-tests/test_sw-backend.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd 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. @@ -29,6 +29,7 @@ #include #include #include +#include #include using namespace CKM; @@ -37,8 +38,28 @@ using namespace CKM::Crypto::SW; namespace { +const Name TEST_NAME = "test_data"; +const Name TEST_NAME2 = "test_data2"; +const ClientId TEST_OWNER = "test_owner"; +const uid_t TEST_UID = 0; + Store STORE(CryptoBackend::OpenSSL); +RawBuffer makeTestDigest() +{ + auto digest = CryptoLogic::makeHash(TEST_NAME, TEST_OWNER, TEST_UID); + BOOST_REQUIRE(!digest.empty()); + return digest; +} + +std::pair makePubPrivTestDigest() +{ + auto digestPub = CryptoLogic::makeHash(TEST_NAME, TEST_OWNER, TEST_UID); + auto digestPriv = CryptoLogic::makeHash(TEST_NAME2, TEST_OWNER, TEST_UID); + BOOST_REQUIRE(!digestPub.empty() && !digestPriv.empty()); + return std::make_pair(std::move(digestPub), std::move(digestPriv)); +} + void checkKey(const Token& token, KeyType keyType, const Password& pass) { DataType dataType(keyType); @@ -83,7 +104,10 @@ const GObjUPtrPair& generateObjUPtrPair(AlgoType algo, int param) gen.setParam(ParamName::GEN_EC, param); else gen.setParam(ParamName::GEN_KEY_LEN, param); - auto keyPair = STORE.generateAKey(gen, "", ""); + + const auto [digestPub, digestPriv] = makePubPrivTestDigest(); + + auto keyPair = STORE.generateAKey(gen, "", "", digestPriv, digestPub); GObjUPtrPair pair; BOOST_REQUIRE_NO_THROW(pair.prv = STORE.getObject(keyPair.first, "")); @@ -133,7 +157,10 @@ GObjUPtr generateAes(int len) ca.setParam(ParamName::GEN_KEY_LEN, len); Token token; - BOOST_REQUIRE_NO_THROW(token = STORE.generateSKey(ca, "")); + + const auto digest = makeTestDigest(); + + BOOST_REQUIRE_NO_THROW(token = STORE.generateSKey(ca, "", digest)); GObjUPtr obj; BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, "")); @@ -218,7 +245,10 @@ POSITIVE_TEST_CASE(generateAKey) auto& types = algo2types.at(algo); TokenPair tokenPair; - BOOST_REQUIRE_NO_THROW(tokenPair = STORE.generateAKey(ca, prvPass, pubPass)); + + const auto [digestPub, digestPriv] = makePubPrivTestDigest(); + + BOOST_REQUIRE_NO_THROW(tokenPair = STORE.generateAKey(ca, prvPass, pubPass, digestPriv, digestPub)); checkKey(tokenPair.first, types.first, prvPass); checkKey(tokenPair.second, types.second, pubPass); }; @@ -255,7 +285,8 @@ NEGATIVE_TEST_CASE(generateAKey) auto invalidGen = [&] { - BOOST_REQUIRE_THROW(STORE.generateAKey(*ca, "", ""), Exc::Crypto::InputParam); + const auto [digestPub, digestPriv] = makePubPrivTestDigest(); + BOOST_REQUIRE_THROW(STORE.generateAKey(*ca, "", "", digestPriv, digestPub), Exc::Crypto::InputParam); }; invalidGen(); @@ -304,7 +335,8 @@ POSITIVE_TEST_CASE(generateSKey) auto testSKey = [&](const Password& pass = "") { Token token; - BOOST_REQUIRE_NO_THROW(token = STORE.generateSKey(ca, pass)); + const auto digest = makeTestDigest(); + BOOST_REQUIRE_NO_THROW(token = STORE.generateSKey(ca, pass, digest)); checkKey(token, KeyType::KEY_AES, pass); }; @@ -324,7 +356,8 @@ NEGATIVE_TEST_CASE(generateSKey) auto invalidGen = [&] { - BOOST_REQUIRE_THROW(STORE.generateSKey(*ca, ""), Exc::Crypto::InputParam); + const auto digest = makeTestDigest(); + BOOST_REQUIRE_THROW(STORE.generateSKey(*ca, "", digest), Exc::Crypto::InputParam); }; invalidGen(); @@ -566,6 +599,7 @@ NEGATIVE_TEST_CASE(symmetricEncryptDecryptCbc) * happens to be a valid padding. In such case make sure that the length of the * decrypted data is different. */ + BOOST_REQUIRE(decrypted.size() != data.size()); } catch (const Exc::Crypto::InputParam&) { // This is fine @@ -906,7 +940,9 @@ POSITIVE_TEST_CASE(importGetObjectDestroy) Data data(DataType::BINARY_DATA, buffer); EncryptionParams ep; Token token; - BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep)); + const auto digest = makeTestDigest(); + + BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep, digest)); BOOST_REQUIRE(token.backendId == CryptoBackend::OpenSSL); BOOST_REQUIRE(token.dataType == data.type); BOOST_REQUIRE(!token.data.empty()); @@ -924,7 +960,9 @@ NEGATIVE_TEST_CASE(import) Data data(DataType::BINARY_DATA, createRandom(16)); EncryptionParams ep; ep.iv = createRandom(16); - BOOST_REQUIRE_THROW(STORE.import(data, "pass", ep), Exc::Crypto::OperationNotSupported); + const auto digest = makeTestDigest(); + + BOOST_REQUIRE_THROW(STORE.import(data, "pass", ep, digest), Exc::Crypto::OperationNotSupported); } NEGATIVE_TEST_CASE(getObject) @@ -932,7 +970,9 @@ NEGATIVE_TEST_CASE(getObject) Data data(DataType::BINARY_DATA, createRandom(16)); EncryptionParams ep; Token token; - BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep)); + const auto digest = makeTestDigest(); + + BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep, digest)); BOOST_REQUIRE_THROW(STORE.getObject(token, "wrongpass"), Exc::Crypto::AuthenticationFailed); @@ -952,7 +992,9 @@ POSITIVE_TEST_CASE(certImportGetObject) EncryptionParams ep; Data data(DataType::CERTIFICATE, cert.getBinary()); Token token; - BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "", ep)); + const auto digest = makeTestDigest(); + + BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "", ep, digest)); BOOST_REQUIRE(token.dataType == DataType::CERTIFICATE); GObjUPtr obj; -- 2.7.4 From f133f939fdb7b63eeb822a3c0e07e888e006cbd6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20Szaknis?= Date: Mon, 28 Jun 2021 14:22:49 +0200 Subject: [PATCH 14/16] Release 0.1.44 * Use fixed object ID in TZ backend * Add more tests to increase coverage Change-Id: I989df7e1b5b8c9f783014b40b4eb700c263d1cd3 --- packaging/key-manager.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/key-manager.spec b/packaging/key-manager.spec index 1756d16..38eab99 100644 --- a/packaging/key-manager.spec +++ b/packaging/key-manager.spec @@ -11,7 +11,7 @@ Name: key-manager Summary: Central Key Manager and utilities -Version: 0.1.43 +Version: 0.1.44 Release: 1 Group: Security/Secure Storage License: Apache-2.0 and BSD-3-Clause -- 2.7.4 From 0e7b6f56e6ebcf9d31cc30e0758978ca76d5ce5c Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Tue, 27 Jul 2021 08:01:47 +0200 Subject: [PATCH 15/16] Deprecate ckmc_ocsp_check API OCSP test certificate management is problematic, and Tizen platform has another ocsp API in OpenSSL which can be officially recommended. Change-Id: Ifc115c300e79a64b65361deaa848ee396e654240 --- src/include/ckmc/ckmc-manager.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/include/ckmc/ckmc-manager.h b/src/include/ckmc/ckmc-manager.h index 4d90b66..3797156 100644 --- a/src/include/ckmc/ckmc-manager.h +++ b/src/include/ckmc/ckmc-manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2021 Samsung Electronics Co., Ltd 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. @@ -752,6 +752,7 @@ int ckmc_get_cert_chain_with_trustedcert(const ckmc_cert_s *cert, const ckmc_cer /** + * @deprecated Deprecated since 6.5. Use raw OpenSSL instead. * @brief Perform OCSP that checks certificate is whether revoked or not. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * @privlevel public @@ -771,7 +772,8 @@ int ckmc_get_cert_chain_with_trustedcert(const ckmc_cert_s *cert, const ckmc_cer * @see ckmc_get_cert_chain()) * @see ckmc_cert_list_all_free() */ -int ckmc_ocsp_check(const ckmc_cert_list_s *pcert_chain_list, ckmc_ocsp_status_e *ocsp_status); +int ckmc_ocsp_check(const ckmc_cert_list_s *pcert_chain_list, ckmc_ocsp_status_e *ocsp_status) +TIZEN_DEPRECATED_API; /** -- 2.7.4 From 42c41c87130031f4a72c95c6021ca90699cc72ca Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Tue, 27 Jul 2021 08:39:17 +0200 Subject: [PATCH 16/16] Release 0.1.45 * Deprecate ckmc_ocsp_check API Change-Id: I248a647047782f6a7f403cd51b3c9b76152936b0 --- packaging/key-manager.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/key-manager.spec b/packaging/key-manager.spec index 38eab99..90754b6 100644 --- a/packaging/key-manager.spec +++ b/packaging/key-manager.spec @@ -11,7 +11,7 @@ Name: key-manager Summary: Central Key Manager and utilities -Version: 0.1.44 +Version: 0.1.45 Release: 1 Group: Security/Secure Storage License: Apache-2.0 and BSD-3-Clause -- 2.7.4