Add ML-KEM keypair creation tests 11/314511/28
authorJakub Wlostowski <j.wlostowski@samsung.com>
Fri, 12 Jul 2024 11:39:39 +0000 (13:39 +0200)
committerJakub Wlostowski <j.wlostowski@samsung.com>
Tue, 27 Aug 2024 10:59:31 +0000 (12:59 +0200)
Change-Id: Id6d174d98066e65e0371498672a57ae001ab059e

src/ckm/ckm-common.cpp
src/ckm/ckm-common.h
src/ckm/unprivileged/CMakeLists.txt
src/ckm/unprivileged/kem-testcases.cpp [new file with mode: 0644]

index 4830257e0b01d10b11e005b4e3c435484fa80ac9..facc8250478f51d1dbe581c6cf037f4bcb025b5e 100644 (file)
@@ -637,6 +637,21 @@ void assert_keys_equal(const ckmc_key_s* b1, const ckmc_key_s* b2, bool equal)
     }
 }
 
+void assert_key_type_equal(const ckmc_key_type_e t1, const ckmc_key_type_e t2)
+{
+    RUNNER_ASSERT_MSG(t1 == t2,
+                     "Key Type Error: expected =" << static_cast<int>(t1) <<
+                     ", actual=" << static_cast<int>(t2));
+}
+
+void assert_key_valid(const ckmc_key_s* k, size_t valid_key_size)
+{
+    RUNNER_ASSERT_MSG(k != NULL, "Key is broken");
+
+    RUNNER_ASSERT_MSG(k->key_size == valid_key_size && k->raw_key != NULL,
+                     "Key is broken");
+}
+
 RawBufferPtr create_raw_buffer(ckmc_raw_buffer_s* buffer)
 {
     return RawBufferPtr(buffer, ckmc_buffer_free);
index 0af4c7d85720d948bdb9b7c97891048917eb51bd..8913c5750b24b438802ac1377a64b398c1bab565 100644 (file)
@@ -361,6 +361,8 @@ void setParam(ParamListPtr& params, ckmc_param_name_e name, uint64_t integer);
 
 void assert_buffers_equal(const ckmc_raw_buffer_s* b1, const ckmc_raw_buffer_s* b2, bool equal=true);
 void assert_keys_equal(const ckmc_key_s* b1, const ckmc_key_s* b2, bool equal=true);
+void assert_key_type_equal(const ckmc_key_type_e t1, const ckmc_key_type_e t2);
+void assert_key_valid(const ckmc_key_s* k, size_t valid_key_size);
 
 RawBufferPtr create_raw_buffer(ckmc_raw_buffer_s* buffer);
 
index 03837f83421d17f5cd9386b97d7a88a48d87f66c..ba69950649b3aca46df8df1bd45f5c5be68d994a 100644 (file)
@@ -21,6 +21,7 @@ SET(CKM_SOURCES
     async-api.cpp
     capi-certificate-chains.cpp
     capi-testcases.cpp
+    kem-testcases.cpp
     encryption-decryption-env.cpp
     encryption-decryption.cpp
     sign-verify.cpp
diff --git a/src/ckm/unprivileged/kem-testcases.cpp b/src/ckm/unprivileged/kem-testcases.cpp
new file mode 100644 (file)
index 0000000..a77ebbf
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+ *  Copyright (c) 2024 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 <dpl/test/test_runner.h>
+
+#include <ckmc/ckmc-manager.h>
+#include <ckmc/ckmc-extended.h>
+#include <ckmc/ckmc-control.h>
+#include <ckmc/ckmc-type.h>
+#include <ckmc/ckmc-error.h>
+#include <ckm-common.h>
+
+const char* PASSWORD = "test-password";
+const char* USER_PASS = "user-pass";
+
+CKM::Alias private_key_alias = "kem-priv-alias";
+CKM::Alias public_key_alias = "kem-pub-alias";
+CKM::Alias private_key_alias_second = "kem-priv-second";
+CKM::Alias public_key_alias_second = "kem-pub-second";
+CKM::Alias new_alias = "kem-test-new";
+
+ckmc_kem_type_e kem_type_768 = ckmc_kem_type_e::CKMC_ML_KEM_768;
+
+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 };
+
+void remove_keys_aliases()
+{
+       ckmc_remove_alias(private_key_alias.c_str());
+       ckmc_remove_alias(public_key_alias.c_str());
+       ckmc_remove_alias(private_key_alias_second.c_str());
+       ckmc_remove_alias(public_key_alias_second.c_str());
+       ckmc_remove_alias(new_alias.c_str());
+}
+
+class KemCreateKeypairGroupFixture : public DPL::Test::TestGroup
+{
+public:
+       void Init() override
+       {
+               assert_positive(ckmc_remove_user_data, OWNER_USER_ID);
+               assert_positive(ckmc_unlock_user_key, OWNER_USER_ID, USER_PASS);
+       }
+
+       void Finish() override
+       {
+               assert_positive(ckmc_lock_user_key, OWNER_USER_ID);
+               assert_positive(ckmc_remove_user_data, OWNER_USER_ID);
+       }
+};
+
+class KemCreateKeypairFixture
+{
+public:
+       virtual void init(const std::string&)
+       {
+       }
+
+       virtual void finish()
+       {
+               remove_keys_aliases();
+       }
+};
+
+RUNNER_TEST_GROUP_INIT_ENV(CKMC_CREATE_KEYPAIR_KEM, KemCreateKeypairGroupFixture);
+
+RUNNER_TEST(KEM_create_key, KemCreateKeypairFixture)
+{
+       /*
+               First element in pair - private key length in bytes
+               Second element in pair - public key length in bytes
+               Source: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.ipd.pdf
+                               Table 3. Sizes (in bytes) of keys and ciphertexts of ML-KEM
+       */
+       std::map<ckmc_kem_type_e, std::pair<size_t, size_t>> kem_types_sizes = {
+               {ckmc_kem_type_e::CKMC_ML_KEM_768, {2400, 1184}},
+               {ckmc_kem_type_e::CKMC_ML_KEM_1024, {3168, 1568}},
+       };
+
+       for (const auto& [kem_type, kem_key_sizes] : kem_types_sizes)
+       {
+               AliasRemover removers[] = {private_key_alias.c_str(), public_key_alias.c_str()};
+
+               size_t current_aliases_num = count_aliases(ALIAS_KEY);
+
+               assert_positive(ckmc_create_key_pair_kem,
+                                               kem_type,
+                                               private_key_alias.c_str(),
+                                               public_key_alias.c_str(),
+#ifdef TZ_BACKEND
+                                               UNEXPORTABLE_PW, EXPORTABLE
+#else
+                                               EXPORTABLE_PW, EXPORTABLE
+#endif
+                                               );
+
+               size_t actual_cnt = count_aliases(ALIAS_KEY);
+               RUNNER_ASSERT_MSG(
+                               (current_aliases_num + 2) == actual_cnt,
+                               "Error: expecting " << (current_aliases_num + 2) << " aliases, while found " << actual_cnt);
+
+#ifndef TZ_BACKEND
+               ckmc_key_s *private_key;
+               assert_positive(ckmc_get_key,
+                                               private_key_alias.c_str(),
+                                               PASSWORD,
+                                               &private_key);
+
+               assert_key_type_equal(CKMC_KEY_KEM_PRIVATE, private_key->key_type);
+               assert_key_valid(private_key, kem_key_sizes.first);
+
+               ckmc_key_free(private_key);
+#endif
+
+               ckmc_key_s *public_key;
+               assert_positive(ckmc_get_key,
+                                               public_key_alias.c_str(),
+                                               nullptr,
+                                               &public_key);
+
+               assert_key_type_equal(CKMC_KEY_KEM_PUBLIC, public_key->key_type);
+               assert_key_valid(public_key, kem_key_sizes.second);
+
+               ckmc_key_free(public_key);
+       }
+}
+
+RUNNER_TEST(KEM_create_keypair_random_keys, KemCreateKeypairFixture)
+{
+       assert_positive(ckmc_create_key_pair_kem,
+                                       kem_type_768,
+                                       private_key_alias.c_str(),
+                                       public_key_alias.c_str(),
+                                       EXPORTABLE,
+                                       EXPORTABLE);
+
+       assert_positive(ckmc_create_key_pair_kem,
+                                       kem_type_768,
+                                       private_key_alias_second.c_str(),
+                                       public_key_alias_second.c_str(),
+                                       EXPORTABLE_PW,
+                                       EXPORTABLE_PW);
+
+       ckmc_key_s *private_key_first;
+       assert_positive(ckmc_get_key,
+                                       private_key_alias.c_str(),
+                                       nullptr,
+                                       &private_key_first);
+       ckmc_key_s *public_key_first;
+       assert_positive(ckmc_get_key,
+                                       public_key_alias.c_str(),
+                                       nullptr,
+                                       &public_key_first);
+
+       ckmc_key_s *private_key_second;
+       assert_positive(ckmc_get_key,
+                                       private_key_alias_second.c_str(),
+                                       PASSWORD,
+                                       &private_key_second);
+       ckmc_key_s *public_key_second;
+       assert_positive(ckmc_get_key,
+                                       public_key_alias_second.c_str(),
+                                       PASSWORD,
+                                       &public_key_second);
+
+       assert_keys_equal(private_key_first, private_key_second, false);
+
+       assert_keys_equal(public_key_first, public_key_second, false);
+
+       ckmc_key_free(private_key_first);
+       ckmc_key_free(private_key_second);
+       ckmc_key_free(public_key_first);
+       ckmc_key_free(public_key_second);
+}
+
+RUNNER_TEST(KEM_create_keypair_alias_exists, KemCreateKeypairFixture)
+{
+       assert_positive(ckmc_create_key_pair_kem,
+                                       kem_type_768,
+                                       private_key_alias.c_str(),
+                                       public_key_alias.c_str(),
+                                       UNEXPORTABLE_PW,
+                                       EXPORTABLE);
+
+       // on next attempt to generate keys with the same alias, expect fail (alias exists)
+       assert_result(CKMC_ERROR_DB_ALIAS_EXISTS,
+                                 ckmc_create_key_pair_kem,
+                                 kem_type_768,
+                                 private_key_alias.c_str(),
+                                 public_key_alias.c_str(),
+                                 UNEXPORTABLE_PW,
+                                 EXPORTABLE);
+
+       // check case when only one alias exists
+       assert_result(CKMC_ERROR_DB_ALIAS_EXISTS,
+                                 ckmc_create_key_pair_kem,
+                                 kem_type_768,
+                                 new_alias.c_str(),
+                                 public_key_alias.c_str(),
+                                 UNEXPORTABLE_PW,
+                                 EXPORTABLE);
+
+       assert_result(CKMC_ERROR_DB_ALIAS_EXISTS,
+                                 ckmc_create_key_pair_kem,
+                                 kem_type_768,
+                                 private_key_alias.c_str(),
+                                 new_alias.c_str(),
+                                 UNEXPORTABLE_PW,
+                                 EXPORTABLE);
+}
+
+RUNNER_TEST(KEM_create_keypair_invalid_parameter, KemCreateKeypairFixture)
+{
+       ckmc_kem_type_e invalid_kem_type = static_cast<ckmc_kem_type_e>(5);
+       assert_invalid_param(ckmc_create_key_pair_kem,
+                                                invalid_kem_type,
+                                                private_key_alias.c_str(),
+                                                public_key_alias.c_str(),
+                                                UNEXPORTABLE_PW,
+                                                EXPORTABLE);
+       assert_invalid_param(ckmc_create_key_pair_kem,
+                                                kem_type_768,
+                                                nullptr,
+                                                public_key_alias.c_str(),
+                                                UNEXPORTABLE_PW,
+                                                EXPORTABLE);
+       assert_invalid_param(ckmc_create_key_pair_kem,
+                                                kem_type_768,
+                                                private_key_alias.c_str(),
+                                                nullptr,
+                                                UNEXPORTABLE_PW,
+                                                EXPORTABLE);
+}
+
+RUNNER_TEST(KEM_create_keypair_invalid_password, KemCreateKeypairFixture)
+{
+       assert_positive(ckmc_create_key_pair_kem,
+                                       kem_type_768,
+                                       private_key_alias.c_str(),
+                                       public_key_alias.c_str(),
+                                       EXPORTABLE_PW,
+                                       EXPORTABLE_PW);
+
+       ckmc_key_s *private_key;
+       assert_result(CKMC_ERROR_AUTHENTICATION_FAILED,
+                                 ckmc_get_key,
+                                 private_key_alias.c_str(),
+                                 "invalidpassword",
+                                 &private_key);
+
+       ckmc_key_s *public_key;
+       assert_result(CKMC_ERROR_AUTHENTICATION_FAILED,
+                                 ckmc_get_key,
+                                 public_key_alias.c_str(),
+                                 "invalidpassword",
+                                 &public_key);
+}
+
+RUNNER_TEST(KEM_create_remove_keys, KemCreateKeypairFixture)
+{
+       assert_positive(ckmc_create_key_pair_kem,
+                                       kem_type_768,
+                                       private_key_alias.c_str(),
+                                       public_key_alias.c_str(),
+                                       UNEXPORTABLE,
+                                       UNEXPORTABLE);
+
+       ckmc_remove_alias(private_key_alias.c_str());
+       ckmc_remove_alias(public_key_alias.c_str());
+
+       assert_positive(ckmc_create_key_pair_kem,
+                                       kem_type_768,
+                                       private_key_alias.c_str(),
+                                       public_key_alias.c_str(),
+                                       UNEXPORTABLE_PW,
+                                       UNEXPORTABLE_PW);
+
+       ckmc_remove_alias(private_key_alias.c_str());
+       ckmc_remove_alias(public_key_alias.c_str());
+}
+
+RUNNER_TEST(KEM_save_get_key, KemCreateKeypairFixture)
+{
+       for (const auto& kem_type : {ckmc_kem_type_e::CKMC_ML_KEM_768, ckmc_kem_type_e::CKMC_ML_KEM_1024})
+       {
+               AliasRemover removers[] = {private_key_alias.c_str(), public_key_alias.c_str(),
+                                                                 private_key_alias_second.c_str(), public_key_alias_second.c_str()};
+
+               assert_positive(ckmc_create_key_pair_kem,
+                                               kem_type,
+                                               private_key_alias.c_str(),
+                                               public_key_alias.c_str(),
+                                               EXPORTABLE_PW,
+                                               EXPORTABLE);
+
+               ckmc_key_s *private_key = nullptr;
+               assert_positive(ckmc_get_key,
+                                               private_key_alias.c_str(),
+                                               PASSWORD,
+                                               &private_key);
+               assert_positive(ckmc_save_key,
+                                               private_key_alias_second.c_str(),
+                                               *private_key,
+                                               EXPORTABLE);
+
+               ckmc_key_s *private_key_second = nullptr;
+               assert_positive(ckmc_get_key,
+                                               private_key_alias_second.c_str(),
+                                               nullptr,
+                                               &private_key_second);
+
+               assert_keys_equal(private_key, private_key_second);
+
+               ckmc_key_s *public_key = nullptr;
+               assert_positive(ckmc_get_key,
+                                               public_key_alias.c_str(),
+                                               nullptr,
+                                               &public_key);
+               assert_positive(ckmc_save_key,
+                                               public_key_alias_second.c_str(),
+                                               *public_key,
+                                               EXPORTABLE_PW);
+
+               ckmc_key_s *public_key_second = nullptr;
+               assert_positive(ckmc_get_key,
+                                               public_key_alias_second.c_str(),
+                                               PASSWORD,
+                                               &public_key_second);
+
+               assert_keys_equal(public_key, public_key_second);
+
+               ckmc_key_free(private_key);
+               ckmc_key_free(private_key_second);
+               ckmc_key_free(public_key);
+               ckmc_key_free(public_key_second);
+       }
+}