From: Krzysztof Jackiewicz Date: Fri, 17 Feb 2023 10:39:10 +0000 (+0100) Subject: CKM: Add ECDH tests X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Ftest%2Fsecurity-tests.git;a=commitdiff_plain;h=3319300ab4256a5be02593c99c91abc03aba5a90 CKM: Add ECDH tests Change-Id: I79dc55e11c9c61db1074b1e70a856999d4632d56 --- diff --git a/src/ckm/unprivileged/CMakeLists.txt b/src/ckm/unprivileged/CMakeLists.txt index 8b8dfda..256b96e 100644 --- a/src/ckm/unprivileged/CMakeLists.txt +++ b/src/ckm/unprivileged/CMakeLists.txt @@ -24,6 +24,7 @@ SET(CKM_SOURCES encryption-decryption-env.cpp encryption-decryption.cpp sign-verify.cpp + key-derivation.cpp main.cpp ) diff --git a/src/ckm/unprivileged/key-derivation.cpp b/src/ckm/unprivileged/key-derivation.cpp new file mode 100644 index 0000000..1a8a1fc --- /dev/null +++ b/src/ckm/unprivileged/key-derivation.cpp @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2023 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 +#include +#include +#include + +namespace { + +const char* PASSWORD = "test-password"; +const uid_t UID = 5001; + +struct KeyAliasPair +{ + std::string prv; + std::string pub; +}; + +const KeyAliasPair OURS = { "our_ec_private", "our_ec_public" }; +const KeyAliasPair PEERS = { "peer_ec_private", "peer_ec_public" }; +const KeyAliasPair PEERS2 = { "peer2_ec_private", "peer2_ec_public" }; +const KeyAliasPair WRONG = { "wrong_ec_private", "wrong_ec_public" }; +const KeyAliasPair RSA = { "rsa_private", "rsa_public" }; +const std::string DERIVED = "derived"; + +const ckmc_policy_s UNEXPORTABLE { nullptr, false }; +const ckmc_policy_s EXPORTABLE { nullptr, true }; +const ckmc_policy_s UNEXPORTABLE_PW { const_cast(PASSWORD), false }; +const ckmc_policy_s EXPORTABLE_PW { const_cast(PASSWORD), true }; + +class EcdhGroupFixture: public DPL::Test::TestGroup +{ +private: + void GenerateEC(ckmc_ec_type_e curve, + const KeyAliasPair& pair, + const ckmc_policy_s& policy_prv, + const ckmc_policy_s& policy_pub) + { + assert_positive(ckmc_create_key_pair_ecdsa, + curve, + pair.prv.c_str(), + pair.pub.c_str(), + policy_prv, + policy_pub); + } + +public: + void Init() override + { + remove_user_data(UID); + assert_positive(ckmc_unlock_user_key, UID, "db-pass"); + + GenerateEC(CKMC_EC_PRIME256V1, OURS, UNEXPORTABLE, EXPORTABLE); + GenerateEC(CKMC_EC_PRIME256V1, PEERS, UNEXPORTABLE_PW, EXPORTABLE); + GenerateEC(CKMC_EC_PRIME256V1, PEERS2, EXPORTABLE, EXPORTABLE); + GenerateEC(CKMC_EC_PRIME192V1, WRONG, UNEXPORTABLE, EXPORTABLE); + + assert_positive(ckmc_create_key_pair_rsa, + 1024, + RSA.prv.c_str(), + RSA.pub.c_str(), + UNEXPORTABLE, + EXPORTABLE); + } + + void Finish() override + { + int ret = ckmc_lock_user_key(UID); + if (ret != CKMC_ERROR_NONE) + RUNNER_ERROR_MSG("DB lock failed: " << CKMCErrorToString(ret)); + remove_user_data(UID); + } +}; + +struct DerivedFixture +{ + void init(const std::string&) + { + } + + void finish() + { + ckmc_remove_alias(DERIVED.c_str()); + } +}; + +RawBufferPtr getPublicKey(const std::string& pub_alias) +{ + ckmc_key_s *pubKey = nullptr; + assert_positive(ckmc_get_key, pub_alias.c_str(), "", &pubKey); + + ckmc_raw_buffer_s* pubBuffer = nullptr; + assert_positive(ckmc_buffer_new, pubKey->raw_key, pubKey->key_size, &pubBuffer); + ckmc_key_free(pubKey); + + return create_raw_buffer(pubBuffer); +} + +ParamListPtr getDefaultECDHParams(const std::string& pubAlias) +{ + auto ecdhParams = createParamListPtr(); + setParam(ecdhParams, CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_ECDH); + auto pubKey = getPublicKey(pubAlias); + setParam(ecdhParams, CKMC_PARAM_ECDH_PUBKEY, pubKey.get()); + return ecdhParams; +} + +void deriveEcdh(const std::string& prvAlias, + const std::string& prvPass, + const std::string& pubAlias, + const std::string& derivedAlias, + const ckmc_policy_s& derivedPolicy, + int expected) +{ + auto ecdhParams = getDefaultECDHParams(pubAlias); + + assert_result(expected, + ckmc_key_derive, + ecdhParams.get(), + prvAlias.c_str(), + prvPass.c_str(), + derivedAlias.c_str(), + derivedPolicy); +} + +RawBufferPtr deriveEcdhAndGet(const std::string& prvAlias, + const std::string& prvPass, + const std::string& pubAlias, + const std::string& derivedAlias, + const ckmc_policy_s& derivedPolicy) +{ + deriveEcdh(prvAlias, prvPass, pubAlias, derivedAlias, derivedPolicy, CKMC_ERROR_NONE); + + ckmc_raw_buffer_s *derivedBuffer = nullptr; + assert_positive(ckmc_get_data, derivedAlias.c_str(), derivedPolicy.password, &derivedBuffer); + + ckmc_remove_alias(derivedAlias.c_str()); + + return create_raw_buffer(derivedBuffer); +} + +void invalidDerive(const ParamListPtr& params) +{ + assert_invalid_param(ckmc_key_derive, + params.get(), + OURS.prv.c_str(), + "", + DERIVED.c_str(), + EXPORTABLE); +} + +} // namespace anonymous + +RUNNER_TEST_GROUP_INIT_ENV(CKM_DERIVE_ECDH, EcdhGroupFixture); + +RUNNER_TEST(TECDH_0010_positive, DerivedFixture) +{ + auto ourDerived = deriveEcdhAndGet(OURS.prv, "", PEERS.pub, DERIVED, EXPORTABLE); + auto peerDerived = deriveEcdhAndGet(PEERS.prv, PASSWORD, OURS.pub, DERIVED, EXPORTABLE_PW); + + assert_buffers_equal(ourDerived.get(), peerDerived.get()); + + auto wrongDerived = deriveEcdhAndGet(OURS.prv, "", PEERS2.pub, DERIVED, EXPORTABLE); + + assert_buffers_equal(ourDerived.get(), wrongDerived.get(), false); +} + +RUNNER_TEST(TECDH_0020_missing_arguments, DerivedFixture) +{ + auto ecdhParams = getDefaultECDHParams(PEERS.pub); + + assert_invalid_param(ckmc_key_derive, + nullptr, + OURS.prv.c_str(), + "", + DERIVED.c_str(), + EXPORTABLE); + + assert_invalid_param(ckmc_key_derive, + ecdhParams.get(), + nullptr, + "", + DERIVED.c_str(), + EXPORTABLE); + + assert_invalid_param(ckmc_key_derive, + ecdhParams.get(), + OURS.prv.c_str(), + "", + nullptr, + EXPORTABLE); +} + +RUNNER_TEST(TECDH_0030_unknown_alias, DerivedFixture) +{ + auto ecdhParams = getDefaultECDHParams(PEERS.pub); + + assert_result(CKMC_ERROR_DB_ALIAS_UNKNOWN, + ckmc_key_derive, + ecdhParams.get(), + "nonexistent-alias", + "", + DERIVED.c_str(), + EXPORTABLE); +} + +RUNNER_TEST(TECDH_0040_alias_exists, DerivedFixture) +{ + auto ecdhParams = getDefaultECDHParams(PEERS.pub); + + assert_positive(ckmc_key_derive, + ecdhParams.get(), + OURS.prv.c_str(), + "", + DERIVED.c_str(), + EXPORTABLE); + + assert_result(CKMC_ERROR_DB_ALIAS_EXISTS, + ckmc_key_derive, + ecdhParams.get(), + OURS.prv.c_str(), + "", + DERIVED.c_str(), + EXPORTABLE); +} + +RUNNER_TEST(TECDH_0050_derived_password, DerivedFixture) +{ + auto ecdhParams = getDefaultECDHParams(PEERS.pub); + + assert_positive(ckmc_key_derive, + ecdhParams.get(), + OURS.prv.c_str(), + "", + DERIVED.c_str(), + EXPORTABLE_PW); + + ckmc_raw_buffer_s *derived = nullptr; + assert_result(CKMC_ERROR_AUTHENTICATION_FAILED, ckmc_get_data, DERIVED.c_str(), "", &derived); + assert_result(CKMC_ERROR_AUTHENTICATION_FAILED, ckmc_get_data, DERIVED.c_str(), "pw", &derived); + + assert_positive(ckmc_remove_alias, DERIVED.c_str()); + + assert_positive(ckmc_key_derive, + ecdhParams.get(), + OURS.prv.c_str(), + "", + DERIVED.c_str(), + EXPORTABLE); + + assert_result(CKMC_ERROR_AUTHENTICATION_FAILED, ckmc_get_data, DERIVED.c_str(), "pw", &derived); + assert_result( + CKMC_ERROR_AUTHENTICATION_FAILED, ckmc_get_data, DERIVED.c_str(), PASSWORD, &derived); +} + +RUNNER_TEST(TECDH_0050_derived_unexportable, DerivedFixture) +{ + auto ecdhParams = getDefaultECDHParams(PEERS.pub); + + assert_positive(ckmc_key_derive, + ecdhParams.get(), + OURS.prv.c_str(), + "", + DERIVED.c_str(), + UNEXPORTABLE); + + ckmc_raw_buffer_s *derived = nullptr; + assert_result(CKMC_ERROR_NOT_EXPORTABLE, ckmc_get_data, DERIVED.c_str(), "", &derived); +} + +RUNNER_TEST(TECDH_0100_wrong_parameters, DerivedFixture) +{ + auto ecdhParams = createParamListPtr(); + + // no algo + invalidDerive(ecdhParams); + + // no pubkey + setParam(ecdhParams, CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_ECDH); + invalidDerive(ecdhParams); + + // garbage pubkey + ckmc_raw_buffer_s* garbage = createRandomBufferCAPI(1); + auto buffer = create_raw_buffer(garbage); + setParam(ecdhParams, CKMC_PARAM_ECDH_PUBKEY, buffer.get()); + invalidDerive(ecdhParams); + + // private key instead of pubkey + buffer = getPublicKey(PEERS2.prv); + setParam(ecdhParams, CKMC_PARAM_ECDH_PUBKEY, buffer.get()); + invalidDerive(ecdhParams); + + // wrong algo + buffer = getPublicKey(OURS.pub); + setParam(ecdhParams, CKMC_PARAM_ECDH_PUBKEY, buffer.get()); + setParam(ecdhParams, CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_KBKDF); + invalidDerive(ecdhParams); +} + +RUNNER_TEST(TECDH_0200_wrong_password, DerivedFixture) +{ + deriveEcdh(PEERS.prv, "", OURS.pub, DERIVED, UNEXPORTABLE, CKMC_ERROR_AUTHENTICATION_FAILED); + deriveEcdh(OURS.prv, + UNEXPORTABLE_PW.password, + PEERS.pub, + DERIVED, + UNEXPORTABLE, + CKMC_ERROR_AUTHENTICATION_FAILED); +} + +RUNNER_TEST(TECDH_0210_different_curves, DerivedFixture) +{ + deriveEcdh(OURS.prv, "", WRONG.pub, DERIVED, UNEXPORTABLE, CKMC_ERROR_INVALID_PARAMETER); + deriveEcdh(WRONG.prv, "", OURS.pub, DERIVED, UNEXPORTABLE, CKMC_ERROR_INVALID_PARAMETER); +} + +RUNNER_TEST(TECDH_0220_different_key_types, DerivedFixture) +{ + deriveEcdh(OURS.prv, "", RSA.pub, DERIVED, UNEXPORTABLE, CKMC_ERROR_INVALID_PARAMETER); + deriveEcdh(RSA.prv, "", OURS.pub, DERIVED, UNEXPORTABLE, CKMC_ERROR_INVALID_PARAMETER); +} + +RUNNER_TEST(TECDH_0230_public_instead_of_private, DerivedFixture) +{ + deriveEcdh(OURS.pub, "", OURS.pub, DERIVED, UNEXPORTABLE, CKMC_ERROR_INVALID_PARAMETER); +} + +RUNNER_TEST(TECDH_0230_wrong_key_types, DerivedFixture) +{ + deriveEcdh(RSA.prv, "", RSA.pub, DERIVED, UNEXPORTABLE, CKMC_ERROR_INVALID_PARAMETER); +}