CKM: Add ECDH tests 34/288534/7
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 17 Feb 2023 10:39:10 +0000 (11:39 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 16 Mar 2023 10:10:36 +0000 (11:10 +0100)
Change-Id: I79dc55e11c9c61db1074b1e70a856999d4632d56

src/ckm/unprivileged/CMakeLists.txt
src/ckm/unprivileged/key-derivation.cpp [new file with mode: 0644]

index 8b8dfda..256b96e 100644 (file)
@@ -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 (file)
index 0000000..1a8a1fc
--- /dev/null
@@ -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 <string>
+#include <vector>
+#include <unordered_map>
+
+#include <dpl/test/test_runner.h>
+#include <ckm-common.h>
+#include <ckmc/ckmc-manager.h>
+#include <ckmc/ckmc-control.h>
+
+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<char*>(PASSWORD), false };
+const ckmc_policy_s EXPORTABLE_PW { const_cast<char*>(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);
+}