const char* PASSWORD = "test-password";
const char* USER_PASS = "user-pass";
+struct Algo {
+ ckmc_algo_type_e type;
+ size_t initVector;
+};
+
+const Algo KEM_ALGO = {CKMC_ALGO_KEM, 0};
+const Algo AES_CBC_ALGO = {CKMC_ALGO_AES_CBC, 16};
+
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;
+CKM::Alias encapsulated_secret_alias = "kem-shared-secret-encaps";
+CKM::Alias decapsulated_secret_alias = "kem-shared-secret-decaps";
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 };
+ParamListPtr kem_params_768;
+ckmc_raw_buffer_s* DEFAULT_IV = nullptr;
+ckmc_kem_type_e kem_type_768 = ckmc_kem_type_e::CKMC_ML_KEM_768;
+
+std::map<ckmc_kem_type_e, std::pair<CKM::Alias, CKM::Alias>> kem_types_keys_aliases = {
+ {ckmc_kem_type_e::CKMC_ML_KEM_768, {private_key_alias, public_key_alias}},
+ {ckmc_kem_type_e::CKMC_ML_KEM_1024, {private_key_alias_second, public_key_alias_second}},
+};
+
+ParamListPtr getDefaultParams(const Algo &algo) {
+ ckmc_param_list_h handle = nullptr;
+
+ assert_positive(ckmc_generate_new_params, algo.type, &handle);
+ ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free);
+
+ if (algo.initVector) {
+ DEFAULT_IV = createRandomBufferCAPI(algo.initVector);
+ setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV);
+ }
+
+ return params;
+}
+
+void assert_encaps_decaps_positive(ParamListPtr params,
+ CKM::Alias private_key_alias,
+ CKM::Alias public_key_alias,
+ CKM::Alias encapsulated_secret_alias,
+ CKM::Alias decapsulated_secret_alias,
+ ckmc_policy_s encapsulated_secret_policy,
+ ckmc_policy_s decapsulated_secret_policy) {
+ ckmc_raw_buffer_s *ciphertext = nullptr;
+ assert_positive(ckmc_encapsulate_key,
+ params.get(),
+ public_key_alias.c_str(),
+ nullptr,
+ encapsulated_secret_alias.c_str(),
+ encapsulated_secret_policy,
+ &ciphertext);
+
+ assert_positive(ckmc_decapsulate_key,
+ params.get(),
+ private_key_alias.c_str(),
+ PASSWORD,
+ decapsulated_secret_alias.c_str(),
+ decapsulated_secret_policy,
+ ciphertext);
+
+ ckmc_buffer_free(ciphertext);
+}
+
void remove_keys_aliases()
{
ckmc_remove_alias(private_key_alias.c_str());
}
};
+class KemEncapsDecapsGroupFixture : 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);
+
+ kem_params_768 = getDefaultParams(KEM_ALGO);
+ setParam(kem_params_768,
+ CKMC_PARAM_KEM_TYPE,
+ ckmc_kem_type_e::CKMC_ML_KEM_768);
+
+ assert_positive(ckmc_create_key_pair_kem,
+ ckmc_kem_type_e::CKMC_ML_KEM_768,
+ private_key_alias.c_str(),
+ public_key_alias.c_str(),
+ UNEXPORTABLE_PW,
+ UNEXPORTABLE);
+
+ assert_positive(ckmc_create_key_pair_kem,
+ ckmc_kem_type_e::CKMC_ML_KEM_1024,
+ private_key_alias_second.c_str(),
+ public_key_alias_second.c_str(),
+ UNEXPORTABLE_PW,
+ UNEXPORTABLE);
+ }
+
+ void Finish() override
+ {
+ remove_keys_aliases();
+
+ assert_positive(ckmc_lock_user_key, OWNER_USER_ID);
+ assert_positive(ckmc_remove_user_data, OWNER_USER_ID);
+ }
+};
+
+class KemEncapsDecapsFixture
+{
+public:
+ virtual void init(const std::string&)
+ {
+ }
+
+ virtual void finish()
+ {
+ ckmc_remove_alias(encapsulated_secret_alias.c_str());
+ ckmc_remove_alias(decapsulated_secret_alias.c_str());
+ }
+};
+
RUNNER_TEST_GROUP_INIT_ENV(CKMC_CREATE_KEYPAIR_KEM, KemCreateKeypairGroupFixture);
RUNNER_TEST(KEM_create_key, KemCreateKeypairFixture)
ckmc_key_free(public_key_second);
}
}
+
+RUNNER_TEST_GROUP_INIT_ENV(CKMC_ENCAPS_DECAPS_KEM, KemEncapsDecapsGroupFixture);
+
+RUNNER_TEST(KEM_encaps_decaps_check_keys, KemEncapsDecapsFixture)
+{
+ for (const auto& [kem_type, keys] : kem_types_keys_aliases)
+ {
+ CKM::Alias private_key_alias = keys.first;
+ CKM::Alias public_key_alias = keys.second;
+
+ ParamListPtr params = getDefaultParams(KEM_ALGO);
+ setParam(params, CKMC_PARAM_KEM_TYPE, kem_type);
+
+ AliasRemover removers[] = {encapsulated_secret_alias.c_str(), decapsulated_secret_alias.c_str()};
+
+ size_t current_aliases_num = count_aliases(ALIAS_KEY);
+
+ assert_encaps_decaps_positive(params,
+ private_key_alias,
+ public_key_alias,
+ encapsulated_secret_alias,
+ decapsulated_secret_alias,
+#ifdef TZ_BACKEND
+ UNEXPORTABLE_PW, UNEXPORTABLE
+#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);
+
+#ifdef TZ_BACKEND
+ ckmc_raw_buffer_s *encrypted = nullptr;
+ ckmc_raw_buffer_s *decrypted = nullptr;
+ ckmc_raw_buffer_s *dataToEncrypt = createRandomBufferCAPI(32);
+ params = getDefaultParams(AES_CBC_ALGO);
+ assert_positive(ckmc_encrypt_data,
+ params.get(),
+ encapsulated_secret_alias.c_str(),
+ PASSWORD,
+ *dataToEncrypt,
+ &encrypted);
+
+ assert_positive(ckmc_decrypt_data,
+ params.get(),
+ decapsulated_secret_alias.c_str(),
+ nullptr,
+ *encrypted,
+ &decrypted);
+
+ assert_buffers_equal(dataToEncrypt, decrypted);
+
+ ckmc_buffer_free(dataToEncrypt);
+ ckmc_buffer_free(encrypted);
+ ckmc_buffer_free(decrypted);
+#else
+ ckmc_key_s *encapsulated_secret = nullptr;
+ assert_positive(ckmc_get_key,
+ encapsulated_secret_alias.c_str(),
+ PASSWORD,
+ &encapsulated_secret);
+
+ assert_key_type_equal(CKMC_KEY_AES, encapsulated_secret->key_type);
+ assert_key_valid(encapsulated_secret, 32);
+
+ ckmc_key_s *decapsulated_secret = nullptr;
+ assert_positive(ckmc_get_key,
+ decapsulated_secret_alias.c_str(),
+ nullptr,
+ &decapsulated_secret);
+
+ assert_key_type_equal(CKMC_KEY_AES, decapsulated_secret->key_type);
+ assert_key_valid(decapsulated_secret, 32);
+
+ assert_keys_equal(encapsulated_secret, decapsulated_secret);
+
+ ckmc_key_free(encapsulated_secret);
+ ckmc_key_free(decapsulated_secret);
+#endif
+ }
+}
+
+RUNNER_TEST(KEM_encaps_decaps_invalid_parameter, KemEncapsDecapsFixture)
+{
+ ParamListPtr aes_cbc_params = getDefaultParams(AES_CBC_ALGO);
+
+ ckmc_raw_buffer_s *ciphertext;
+ assert_invalid_param(ckmc_encapsulate_key,
+ nullptr,
+ public_key_alias.c_str(),
+ nullptr,
+ encapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ &ciphertext);
+
+ assert_invalid_param(ckmc_encapsulate_key,
+ kem_params_768.get(),
+ nullptr,
+ nullptr,
+ encapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ &ciphertext);
+
+ assert_invalid_param(ckmc_encapsulate_key,
+ kem_params_768.get(),
+ public_key_alias.c_str(),
+ nullptr,
+ nullptr,
+ UNEXPORTABLE,
+ &ciphertext);
+
+ assert_invalid_param(ckmc_encapsulate_key,
+ kem_params_768.get(),
+ private_key_alias.c_str(),
+ PASSWORD,
+ encapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ &ciphertext);
+
+ assert_invalid_param(ckmc_encapsulate_key,
+ aes_cbc_params.get(),
+ public_key_alias.c_str(),
+ nullptr,
+ encapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ &ciphertext);
+
+ ciphertext = createRandomBufferCAPI(1);
+ assert_invalid_param(ckmc_decapsulate_key,
+ nullptr,
+ private_key_alias.c_str(),
+ nullptr,
+ decapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ ciphertext);
+
+ assert_invalid_param(ckmc_decapsulate_key,
+ kem_params_768.get(),
+ nullptr,
+ nullptr,
+ decapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ ciphertext);
+
+ assert_invalid_param(ckmc_decapsulate_key,
+ kem_params_768.get(),
+ private_key_alias.c_str(),
+ nullptr,
+ nullptr,
+ UNEXPORTABLE,
+ ciphertext);
+
+ assert_invalid_param(ckmc_decapsulate_key,
+ kem_params_768.get(),
+ private_key_alias.c_str(),
+ nullptr,
+ decapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ nullptr);
+
+ assert_invalid_param(ckmc_decapsulate_key,
+ kem_params_768.get(),
+ public_key_alias.c_str(),
+ nullptr,
+ decapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ ciphertext);
+
+ assert_invalid_param(ckmc_decapsulate_key,
+ aes_cbc_params.get(),
+ private_key_alias.c_str(),
+ PASSWORD,
+ decapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ ciphertext);
+
+ ckmc_buffer_free(ciphertext);
+}
+
+RUNNER_TEST(KEM_encaps_decaps_invalid_password, KemEncapsDecapsFixture)
+{
+ ckmc_raw_buffer_s *ciphertext;
+ assert_result(CKMC_ERROR_AUTHENTICATION_FAILED,
+ ckmc_encapsulate_key,
+ kem_params_768.get(),
+ public_key_alias.c_str(),
+ "invalidpassword",
+ encapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ &ciphertext);
+
+ ciphertext = createRandomBufferCAPI(1);
+ assert_result(CKMC_ERROR_AUTHENTICATION_FAILED,
+ ckmc_decapsulate_key,
+ kem_params_768.get(),
+ private_key_alias.c_str(),
+ "invalidpassword",
+ decapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ ciphertext);
+
+ ckmc_buffer_free(ciphertext);
+}
+
+RUNNER_TEST(KEM_encaps_decaps_alias_exists, KemEncapsDecapsFixture)
+{
+ assert_encaps_decaps_positive(kem_params_768,
+ private_key_alias,
+ public_key_alias,
+ encapsulated_secret_alias,
+ decapsulated_secret_alias,
+ UNEXPORTABLE_PW,
+ UNEXPORTABLE);
+
+ // on next attempt to generate keys with the same alias, expect fail (alias exists)
+ ckmc_raw_buffer_s *ciphertext = nullptr;
+ assert_result(CKMC_ERROR_DB_ALIAS_EXISTS,
+ ckmc_encapsulate_key,
+ kem_params_768.get(),
+ public_key_alias.c_str(),
+ nullptr,
+ encapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ &ciphertext);
+
+ ciphertext = createRandomBufferCAPI(1);
+ assert_result(CKMC_ERROR_DB_ALIAS_EXISTS,
+ ckmc_decapsulate_key,
+ kem_params_768.get(),
+ private_key_alias.c_str(),
+ PASSWORD,
+ decapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ ciphertext);
+
+ ckmc_buffer_free(ciphertext);
+}
+
+RUNNER_TEST(KEM_encaps_decaps_alias_unknown, KemEncapsDecapsFixture)
+{
+ // check case when private/public keys aliases do not exist
+ ckmc_raw_buffer_s *ciphertext;
+ assert_result(CKMC_ERROR_DB_ALIAS_UNKNOWN,
+ ckmc_encapsulate_key,
+ kem_params_768.get(),
+ new_alias.c_str(),
+ nullptr,
+ encapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ &ciphertext);
+
+ ciphertext = createRandomBufferCAPI(1);
+ assert_result(CKMC_ERROR_DB_ALIAS_UNKNOWN,
+ ckmc_decapsulate_key,
+ kem_params_768.get(),
+ new_alias.c_str(),
+ PASSWORD,
+ decapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ ciphertext);
+
+ ckmc_buffer_free(ciphertext);
+}
+
+RUNNER_TEST(KEM_encaps_decaps_invalid_alias, KemEncapsDecapsFixture)
+{
+ ckmc_raw_buffer_s *ciphertext;
+ assert_invalid_param(ckmc_encapsulate_key,
+ kem_params_768.get(),
+ public_key_alias.c_str(),
+ nullptr,
+ "encaps invalid alias",
+ UNEXPORTABLE,
+ &ciphertext);
+
+ ciphertext = createRandomBufferCAPI(1);
+ assert_invalid_param(ckmc_decapsulate_key,
+ kem_params_768.get(),
+ private_key_alias.c_str(),
+ PASSWORD,
+ "decaps invalid alias",
+ UNEXPORTABLE,
+ ciphertext);
+
+ ckmc_buffer_free(ciphertext);
+}
+
+RUNNER_TEST(KEM_encaps_decaps_kem_type_mismatch, KemEncapsDecapsFixture)
+{
+ ckmc_raw_buffer_s *ciphertext = nullptr;
+ assert_positive(ckmc_encapsulate_key,
+ kem_params_768.get(),
+ public_key_alias.c_str(),
+ nullptr,
+ encapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ &ciphertext);
+
+ ParamListPtr kem_params_1024 = getDefaultParams(KEM_ALGO);
+ setParam(kem_params_1024,
+ CKMC_PARAM_KEM_TYPE,
+ ckmc_kem_type_e::CKMC_ML_KEM_1024);
+ assert_invalid_param(ckmc_decapsulate_key,
+ kem_params_1024.get(),
+ private_key_alias.c_str(),
+ PASSWORD,
+ decapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ ciphertext);
+
+ ckmc_buffer_free(ciphertext);
+}
+
+RUNNER_TEST(KEM_encaps_decaps_create_keys_mismatch, KemEncapsDecapsFixture)
+{
+ // check case when en/decapsulation KEM type differs from private/public key KEM type
+ ckmc_raw_buffer_s *ciphertext = nullptr;
+ assert_invalid_param(ckmc_encapsulate_key,
+ kem_params_768.get(),
+ public_key_alias_second.c_str(),
+ nullptr,
+ encapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ &ciphertext);
+
+ ciphertext = createRandomBufferCAPI(1);
+ assert_invalid_param(ckmc_decapsulate_key,
+ kem_params_768.get(),
+ private_key_alias_second.c_str(),
+ PASSWORD,
+ decapsulated_secret_alias.c_str(),
+ UNEXPORTABLE,
+ ciphertext);
+
+ ckmc_buffer_free(ciphertext);
+}