Added tests for Update API. 72/315472/45
authorAndrei Vakulich <a.vakulich@samsung.com>
Thu, 18 Jul 2024 15:18:07 +0000 (17:18 +0200)
committerAndrei Vakulich <a.vakulich@samsung.com>
Thu, 7 Nov 2024 14:40:15 +0000 (15:40 +0100)
Change-Id: I2948736744093c8d9d47e3af69502f6b4473d9a6

src/ckm/ckm-common.cpp
src/ckm/ckm-common.h
src/ckm/privileged/capi-access_control.cpp
src/ckm/unprivileged/CMakeLists.txt
src/ckm/unprivileged/update-api.cpp [new file with mode: 0644]

index f46b128efaa2b961ce30af63f3ca14ab6387d9c8..1569089b1e67346ed68945ba611d2e36b5167053 100644 (file)
@@ -135,6 +135,37 @@ std::string CKMCReadableError(int error) {
     return output;
 }
 
+CKM::Password toPassword(const char *str)
+{
+    return str == nullptr ? CKM::Password() : CKM::Password(str);
+}
+
+void ckmSaveKey(const ckmc_key_s& key, const CKM::Alias& alias,
+                const CKM::Policy& policy, int expected)
+{
+    callCKMManagerKeyFunc(key, alias, policy, &CKM::Manager::saveKey, expected);
+}
+
+void ckmUpdateKey(const ckmc_key_s& key, const CKM::Alias& alias,
+                  CKM::Policy policy, int expected)
+{
+    policy.overwritable = true;
+    callCKMManagerKeyFunc(key, alias, policy, &CKM::Manager::saveKey, expected);
+}
+
+void ckmSaveData(const ckmc_raw_buffer_s& data, const CKM::Alias& alias,
+                 const CKM::Policy& policy, int expected)
+{
+    callCKMManagerDataFunc(data, alias, policy, &CKM::Manager::saveData, expected);
+}
+
+void ckmUpdateData(const ckmc_raw_buffer_s& data, const CKM::Alias& alias,
+                   CKM::Policy policy, int expected)
+{
+    policy.overwritable = true;
+    callCKMManagerDataFunc(data, alias, policy, &CKM::Manager::saveData, expected);
+}
+
 void save_data(const char* alias, const char *data, size_t len, const char* password,
                int expected_err, bool exportable)
 {
@@ -459,6 +490,11 @@ bool isPasswordProtected(const ckmc_policy_s& policy)
     return policy.password != nullptr;
 }
 
+bool isPasswordProtected(const CKM::Policy& policy)
+{
+    return !policy.password.empty();
+}
+
 CKM::BackendId backend()
 {
 #ifdef TZ_BACKEND
@@ -592,6 +628,21 @@ void compare_AES_keys(ckmc_key_s *first, ckmc_key_s *second)
     // bypassing password intentionally
 }
 
+KeyPtr createKeyPtr(ckmc_key_s* key)
+{
+    return KeyPtr(key, &ckmc_key_free);
+}
+
+CertPtr createCertPtr(ckmc_cert_s* cert)
+{
+    return CertPtr(cert, &ckmc_cert_free);
+}
+
+PKSC12Ptr createPKCS12Ptr(ckmc_pkcs12_s* pkcs12)
+{
+    return PKSC12Ptr(pkcs12, &ckmc_pkcs12_free);
+}
+
 ParamListPtr createParamListPtr()
 {
     ckmc_param_list_h list = NULL;
@@ -637,6 +688,42 @@ void assert_keys_equal(const ckmc_key_s* b1, const ckmc_key_s* b2, bool equal)
     }
 }
 
+void assert_cert_equal(const ckmc_cert_s* cert1, const ckmc_cert_s* cert2, bool equal)
+{
+    if(equal) {
+        RUNNER_ASSERT_MSG(cert1->cert_size == cert2->cert_size,
+                          "Certs size differs: " << cert1->cert_size
+                          << "!=" << cert2->cert_size);
+        RUNNER_ASSERT_MSG(0 == memcmp(cert1->raw_cert, cert2->raw_cert,
+                          cert1->cert_size), "Certs contents differ");
+    } else {
+        RUNNER_ASSERT_MSG(cert1->cert_size != cert2->cert_size ||
+                          0 != memcmp(cert1->raw_cert, cert2->raw_cert, cert1->cert_size),
+                          "Certs should be different");
+    }
+}
+
+void assert_ca_equal(const ckmc_cert_list_s* ca1, const ckmc_cert_list_s* ca2)
+{
+    size_t length1 = getListLength(ca1), length2 = getListLength(ca2);
+    RUNNER_ASSERT_MSG(length1 == length2, "The chain certificates size differs "
+                      << length1 << " != " << length2);
+
+    while (ca1)
+    {
+        assert_cert_equal(ca1->cert, ca2->cert);
+        ca1 = ca1->next;
+        ca2 = ca2->next;
+    }
+}
+
+void assert_pkcs12_equal(const ckmc_pkcs12_s* pkcs12_1, const ckmc_pkcs12_s* pkcs12_2)
+{
+    assert_keys_equal(pkcs12_1->priv_key, pkcs12_2->priv_key);
+    assert_cert_equal(pkcs12_1->cert, pkcs12_2->cert);
+    assert_ca_equal(pkcs12_1->ca_chain, pkcs12_2->ca_chain);
+}
+
 void assert_key_type_equal(const ckmc_key_type_e t1, const ckmc_key_type_e t2)
 {
     RUNNER_ASSERT_MSG(t1 == t2,
index 05b7e003fc396736860e38391f4d602be701cfaf..d7efa38beca9254f10aa56b06eed2a9cf15b1daf 100644 (file)
@@ -25,7 +25,9 @@
 #include <memory>
 #include <stdexcept>
 #include <unordered_map>
+#include <functional>
 #include <ckm/ckm-type.h>
+#include <ckm/ckm-manager.h>
 #include <ckm/ckm-manager-async.h>
 #include <ckmc/ckmc-type.h>
 #include <ckmc/ckmc-error.h>
@@ -61,12 +63,89 @@ void assert_positive(F&& func, Args... args)
     assert_result(CKMC_ERROR_NONE, std::move(func), args...);
 }
 
+template <typename Func, typename... Args>
+void assert_db_alias_unknown(Func&& func, Args&&... args)
+{
+    assert_result(CKMC_ERROR_DB_ALIAS_UNKNOWN, std::forward<Func>(func),
+                  std::forward<Args>(args)...);
+}
+
 template <typename F, typename... Args>
-void assert_invalid_param(F&& func, Args... args)
+void assert_invalid_param(F&& func, Args&&... args)
 {
     assert_result(CKMC_ERROR_INVALID_PARAMETER, std::move(func), args...);
 }
 
+// RUNNER_ERROR_MSG wrappers
+template <typename Func, typename... Args>
+void error_msg_result(int expected, Func&& func, Args&&... args)
+{
+    int ret = std::invoke(std::forward<Func>(func), std::forward<Args>(args)...);
+    if (ret != expected)
+    {
+        RUNNER_ERROR_MSG("Expected: " << CKMCErrorToString(expected) << "(" << expected << ")"
+                         " got: " << CKMCErrorToString(ret) << "(" << ret << ")");
+    }
+}
+
+template <typename Func, typename... Args>
+void error_msg_positive(Func&& func, Args&&... args)
+{
+    error_msg_result(CKMC_ERROR_NONE, std::forward<Func>(func), std::forward<Args>(args)...);
+}
+
+// RUNNER_ASSERT wrappers for CKM error codes
+template <typename Func, typename... Args>
+void ckm_assert_result(int expected, Func&& func, Args&&... args)
+{
+    int ret = std::invoke(std::forward<Func>(func), std::forward<Args>(args)...);
+    RUNNER_ASSERT_MSG(ret == expected,
+                      "Expected: " << CKM::APICodeToString(expected) << "(" << expected << ")"
+                      " got: " << CKM::APICodeToString(ret) << "(" << ret << ")");
+}
+
+CKM::Password toPassword(const char *str);
+
+template <typename Func>
+void callCKMManagerKeyFunc(const ckmc_key_s& key, const CKM::Alias& alias,
+                           const CKM::Policy& policy, Func&& func, int expected = CKMC_ERROR_NONE)
+{
+    CKM::RawBuffer buffer(key.raw_key, key.raw_key + key.key_size);
+    CKM::KeyShPtr ckmKey;
+    if (key.key_type == CKMC_KEY_AES)
+    {
+        ckmKey = CKM::Key::createAES(buffer);
+    } else if (key.key_type == CKMC_KEY_KEM_PRIVATE) {
+        ckmKey = CKM::Key::createKEM(CKM::KeyType::KEY_KEM_PRIVATE,
+                                     buffer, toPassword(key.password));
+    } else if (key.key_type == CKMC_KEY_KEM_PUBLIC) {
+        ckmKey = CKM::Key::createKEM(CKM::KeyType::KEY_KEM_PUBLIC,
+                                     buffer, toPassword(key.password));
+    } else {
+        ckmKey = CKM::Key::create(buffer, toPassword(key.password));
+    }
+    ckm_assert_result(expected, std::forward<Func>(func), *CKM::Manager::create(),
+                      alias.c_str(), ckmKey, policy);
+}
+
+void ckmSaveKey(const ckmc_key_s& key, const CKM::Alias& alias,
+                const CKM::Policy& policy, int expected = CKMC_ERROR_NONE);
+void ckmUpdateKey(const ckmc_key_s& key, const CKM::Alias& alias,
+                  CKM::Policy policy, int expected = CKMC_ERROR_NONE);
+
+template <typename Func>
+void callCKMManagerDataFunc(const ckmc_raw_buffer_s& data, const CKM::Alias& alias,
+                            const CKM::Policy& policy, Func&& func, int expected = CKMC_ERROR_NONE)
+{
+    CKM::RawBuffer buffer(data.data, data.data + data.size);
+    ckm_assert_result(expected, std::forward<Func>(func), *CKM::Manager::create(),
+                      alias.c_str(), buffer, policy);
+}
+
+void ckmSaveData(const ckmc_raw_buffer_s& data, const CKM::Alias& alias,
+                 const CKM::Policy& policy, int expected = CKMC_ERROR_NONE);
+void ckmUpdateData(const ckmc_raw_buffer_s& data, const CKM::Alias& alias,
+                   CKM::Policy policy, int expected = CKMC_ERROR_NONE);
 
 // list operations
 template <typename T>
@@ -94,6 +173,7 @@ void save_data(const char* alias, const char *data, int expected_err = CKMC_ERRO
                bool exportable = true);
 void save_data(const char* alias, const char *data, size_t len,
                int expected_err = CKMC_ERROR_NONE, bool exportable = true);
+
 class ScopedSaveData
 {
 public:
@@ -158,6 +238,7 @@ CKM::BackendId get_self_key_alias_backend(const std::string& key);
 CKM::BackendId get_self_data_alias_backend(const std::string& key);
 
 bool isPasswordProtected(const ckmc_policy_s&);
+bool isPasswordProtected(const CKM::Policy&);
 
 struct Info {
     Info(const CKM::Alias &alias,
@@ -172,6 +253,11 @@ struct Info {
          const CKM::BackendId backend = CKM::BackendId::SW) :
         Info(alias, isPasswordProtected(policy), backend) {}
 
+    Info(const CKM::Alias &alias,
+         const CKM::Policy &policy,
+         const CKM::BackendId backend = CKM::BackendId::SW) :
+        Info(alias, isPasswordProtected(policy), backend) {}
+
     Info(const CKM::Alias &alias,
          const ckmc_policy_s &policy,
          const CKM::Alias &aliasWithSameBackend,
@@ -267,6 +353,16 @@ void check_self_data_alias_info_list(const bool shouldHaveSameSize,
                           std::forward<Args>(args)...);
 }
 
+template <typename... Args>
+void check_self_certificate_alias_info_list(const bool shouldHaveSameSize,
+                                            Args&&... args)
+{
+    check_alias_info_list(ckmc_get_cert_alias_info_list,
+                          getOwnerIdFromSelf(),
+                          shouldHaveSameSize,
+                          std::forward<Args>(args)...);
+}
+
 template <typename Func>
 CKM::BackendId get_alias_backend(Func&& getAliasInfoList,
                                  const std::string &userSmackLabel,
@@ -355,15 +451,40 @@ typedef std::shared_ptr<ckmc_raw_buffer_s> RawBufferPtr;
 typedef std::shared_ptr<struct __ckmc_param_list> ParamListPtr;
 typedef std::shared_ptr<struct __ckmc_cipher_ctx> CipherCtxPtr;
 
+using KeyPtr = std::unique_ptr<ckmc_key_s, decltype(&ckmc_key_free)>;
+KeyPtr createKeyPtr(ckmc_key_s* key);
+
+using CertPtr = std::unique_ptr<ckmc_cert_s, decltype(&ckmc_cert_free)>;
+CertPtr createCertPtr(ckmc_cert_s* cert);
+
+using PKSC12Ptr = std::unique_ptr<ckmc_pkcs12_s, decltype(&ckmc_pkcs12_free)>;
+PKSC12Ptr createPKCS12Ptr(ckmc_pkcs12_s* pkcs12);
+
 ParamListPtr createParamListPtr();
 void setParam(ParamListPtr& params, ckmc_param_name_e name, ckmc_raw_buffer_s* buffer);
 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_cert_equal(const ckmc_cert_s* cert1, const ckmc_cert_s* cert2, bool equal=true);
+void assert_ca_equal(const ckmc_cert_list_s* ca1, const ckmc_cert_list_s* ca2);
+void assert_pkcs12_equal(const ckmc_pkcs12_s* pkcs12_1, const ckmc_pkcs12_s* pkcs12_2);
+
 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);
 
+template <typename T>
+size_t getListLength(T* head)
+{
+    size_t length = 0;
+    while (head)
+    {
+        ++length;
+        head = head->next;
+    }
+    return length;
+}
+
 RawBufferPtr create_raw_buffer(ckmc_raw_buffer_s* buffer);
 
 CipherCtxPtr create_cipher_ctx(ckmc_cipher_ctx_h ctx);
index 905198efc01f1a11d1aa169e248b8c2372e1ddec..12891df463a61eb51df0c04570e9faa5652e7ce9 100644 (file)
@@ -735,6 +735,134 @@ RUNNER_CHILD_TEST(T3111_control_deny_access_as_user, RemoveDataEnv<USER_ID_1>)
                       "Ordinary user should not be able to use control API. Error " << CKMCErrorToString(ret));
 }
 
+// tries to use update API from another app
+RUNNER_CHILD_TEST(T3112_control_allow_update_as_user, RemoveDataEnv<USER_ID_1>)
+{
+    ScopedDBUnlock unlock(USER_ID_1, APP_PASS_1);
+    ckmc_policy_s policy { nullptr, true };
+    ckmc_raw_buffer_s data { (unsigned char*)TEST_DATA, strlen(TEST_DATA) };
+
+    // prepare: add data
+    {
+        ScopedAppContext ctx(APP_LABEL_1, USER_ID_1, GROUP_ID_1);
+        save_data(TEST_ALIAS, TEST_DATA);
+    }
+
+    // test
+    {
+        ScopedAppContext ctx(APP_LABEL_2, USER_ID_2, GROUP_ID_2);
+        assert_result(CKMC_ERROR_PERMISSION_DENIED, ckmc_update_data,
+                      aliasWithLabel(APP_LABEL_1, TEST_ALIAS).c_str(),
+                      data, policy);
+    }
+
+    // test
+    {
+        ScopedAppContext ctx(APP_LABEL_2, USER_ID_2, GROUP_ID_1);
+        assert_result(CKMC_ERROR_PERMISSION_DENIED, ckmc_update_data,
+                      aliasWithLabel(APP_LABEL_1, TEST_ALIAS).c_str(),
+                      data, policy);
+    }
+
+    // test
+    {
+        ScopedAppContext ctx(APP_LABEL_2, USER_ID_1, GROUP_ID_1);
+        assert_result(CKMC_ERROR_PERMISSION_DENIED, ckmc_update_data,
+                      aliasWithLabel(APP_LABEL_1, TEST_ALIAS).c_str(),
+                      data, policy);
+    }
+
+    // add data permissions
+    {
+        ScopedAppContext ctx(APP_LABEL_1, USER_ID_1, GROUP_ID_1);
+        assert_positive(ckmc_set_permission, aliasWithLabel(APP_LABEL_1, TEST_ALIAS).c_str(),
+                        APP_LABEL_2, CKMC_PERMISSION_REMOVE | CKMC_PERMISSION_READ);
+    }
+
+    // test
+    {
+        ScopedAppContext ctx(APP_LABEL_2, USER_ID_1, GROUP_ID_1);
+        assert_result(CKMC_ERROR_PERMISSION_DENIED, ckmc_update_data,
+                      aliasWithLabel(APP_LABEL_1, TEST_ALIAS).c_str(),
+                      data, policy);
+    }
+}
+
+// tries to get data after updating it from another app
+RUNNER_CHILD_TEST(T3113_control_allow_access_after_update_as_user, RemoveDataEnv<USER_ID_1>)
+{
+    ScopedDBUnlock unlock(USER_ID_1, APP_PASS_1);
+    ckmc_policy_s policy { nullptr, true };
+
+    // prepare: add data
+    {
+        ScopedAppContext ctx(APP_LABEL_1, USER_ID_1, GROUP_ID_1);
+        save_data(TEST_ALIAS, TEST_DATA);
+    }
+
+    // test
+    {
+        ScopedAppContext ctx(APP_LABEL_2, USER_ID_1, GROUP_ID_1);
+        ckmc_raw_buffer_s* data = nullptr;
+        assert_result(CKMC_ERROR_DB_ALIAS_UNKNOWN, ckmc_get_data,
+                      aliasWithLabel(APP_LABEL_1, TEST_ALIAS).c_str(),
+                      policy.password, &data);
+    }
+
+    // add data permissions
+    {
+        ScopedAppContext ctx(APP_LABEL_1, USER_ID_1, GROUP_ID_1);
+        assert_positive(ckmc_set_permission, aliasWithLabel(APP_LABEL_1, TEST_ALIAS).c_str(),
+                        APP_LABEL_2, CKMC_PERMISSION_READ);
+    }
+
+    // test
+    {
+        ScopedAppContext ctx(APP_LABEL_2, USER_ID_1, GROUP_ID_1);
+        ckmc_raw_buffer_s* data = nullptr;
+        assert_positive(ckmc_get_data,
+                        aliasWithLabel(APP_LABEL_1, TEST_ALIAS).c_str(),
+                        policy.password, &data);
+        ckmc_buffer_free(data);
+    }
+
+    // update
+    {
+        ScopedAppContext ctx(APP_LABEL_1, USER_ID_1, GROUP_ID_1);
+        ckmc_raw_buffer_s data { (unsigned char*)TEST_DATA, strlen(TEST_DATA) };
+        assert_positive(ckmc_update_data,
+                        aliasWithLabel(APP_LABEL_1, TEST_ALIAS).c_str(),
+                        data, policy);
+    }
+
+    // test
+    {
+        ScopedAppContext ctx(APP_LABEL_2, USER_ID_1, GROUP_ID_1);
+        ckmc_raw_buffer_s* data = nullptr;
+        assert_result(CKMC_ERROR_DB_ALIAS_UNKNOWN, ckmc_get_data,
+                      aliasWithLabel(APP_LABEL_1, TEST_ALIAS).c_str(),
+                      policy.password, &data);
+        ckmc_buffer_free(data);
+    }
+
+    // add data permissions
+    {
+        ScopedAppContext ctx(APP_LABEL_1, USER_ID_1, GROUP_ID_1);
+        assert_positive(ckmc_set_permission, aliasWithLabel(APP_LABEL_1, TEST_ALIAS).c_str(),
+                        APP_LABEL_2, CKMC_PERMISSION_READ);
+    }
+
+    // test
+    {
+        ScopedAppContext ctx(APP_LABEL_2, USER_ID_1, GROUP_ID_1);
+        ckmc_raw_buffer_s* data = nullptr;
+        assert_positive(ckmc_get_data,
+                        aliasWithLabel(APP_LABEL_1, TEST_ALIAS).c_str(),
+                        policy.password, &data);
+        ckmc_buffer_free(data);
+    }
+}
+
 // tries to read other application data with permission
 RUNNER_TEST(T3121_control_access_allowed, RemoveDataEnv<USER_ID_1>)
 {
index ba69950649b3aca46df8df1bd45f5c5be68d994a..58a243d6e87dc41ffa9472441067ea3d478927bc 100644 (file)
@@ -27,6 +27,7 @@ SET(CKM_SOURCES
     sign-verify.cpp
     key-wrapping.cpp
     key-derivation.cpp
+    update-api.cpp
     main.cpp
 )
 
diff --git a/src/ckm/unprivileged/update-api.cpp b/src/ckm/unprivileged/update-api.cpp
new file mode 100644 (file)
index 0000000..c2adea4
--- /dev/null
@@ -0,0 +1,2173 @@
+/*
+ *  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
+ *
+ *
+ * @file       update-api.cpp
+ * @author     Andrei Vakulich (a.vakulich@samsung.com)
+ * @version    1.0
+ */
+
+#include <array>
+#include <memory>
+
+#include <dpl/test/test_runner.h>
+#include <tests_common.h>
+#include <ckm-common.h>
+#include <ckmc/ckmc-manager.h>
+#include <ckmc/ckmc-control.h>
+#include <ckmc/ckmc-extended.h>
+
+using namespace CKM;
+
+namespace {
+
+const char* USER_PASSWORD = "db-password";
+
+class OwnerUserEnv : public RemoveDataEnv<OWNER_USER_ID>
+{
+public:
+    void Init() {
+        RemoveDataEnv<OWNER_USER_ID>::init("");
+        error_msg_positive(ckmc_unlock_user_key, OWNER_USER_ID, USER_PASSWORD);
+    }
+    void Finish() {
+        // lock is performed by remove_user_data() in RemoveDataEnv
+        RemoveDataEnv<OWNER_USER_ID>::finish();
+    }
+};
+
+const PolicyBackend TZ_BACKEND_ID =
+#ifdef TZ_BACKEND
+    PolicyBackend::FORCE_HARDWARE;
+#else
+    PolicyBackend::FORCE_SOFTWARE;
+#endif
+const PolicyBackend SW_BACKEND_ID = PolicyBackend::FORCE_SOFTWARE;
+
+Policy TZ_POLICY(Password(), false, TZ_BACKEND_ID);
+Policy SW_POLICY(Password("sw-policy"), false, SW_BACKEND_ID);
+
+const ckmc_policy_s NON_EXPORTABLE_POLICY { nullptr, false };
+const ckmc_policy_s NON_EXPORTABLE_PASSWORD_POLICY_0 {
+    const_cast<char*>("non-exportable-password-0"), false };
+const ckmc_policy_s NON_EXPORTABLE_PASSWORD_POLICY_1 {
+    const_cast<char*>("non-exportable-password-1"), false };
+const ckmc_policy_s EXPORTABLE_POLICY { nullptr, true };
+const ckmc_policy_s EXPORTABLE_PASSWORD_POLICY_0 {
+    const_cast<char*>("exportable-password-1"), true };
+const ckmc_policy_s EXPORTABLE_PASSWORD_POLICY_1 {
+    const_cast<char*>("exportable-password-2"), true };
+
+unsigned char WRONG_RAW_DATA[] = "wrong-raw-data";
+
+struct KeyCtx
+{
+    const char* alias;
+    KeyPtr key;
+    ckmc_policy_s policy;
+};
+
+struct AsymmetricKey
+{
+    KeyCtx privateKey;
+    KeyCtx publicKey;
+};
+
+template<typename Keys, typename Func>
+void saveUpdateAsymmetricKeyHelper(const char *privateKeyAlias, const char *publicKeyAlias,
+    const ckmc_policy_s &policy, Keys& keys, Func&& func)
+{
+    AliasRemover aliasRemovers[] = { privateKeyAlias, publicKeyAlias };
+
+    assert_positive(ckmc_save_key, privateKeyAlias,
+                    *keys[0].privateKey.key, policy);
+    assert_positive(ckmc_save_key, publicKeyAlias,
+                    *keys[0].publicKey.key, policy);
+
+    assert_positive(ckmc_update_key, privateKeyAlias,
+                    *keys[1].privateKey.key, policy);
+    assert_positive(ckmc_update_key, publicKeyAlias,
+                    *keys[1].publicKey.key, policy);
+
+    std::forward<Func>(func)(privateKeyAlias, policy.password,
+                             publicKeyAlias, policy.password);
+    std::forward<Func>(func)(privateKeyAlias, policy.password,
+                             keys[1].publicKey.alias, keys[1].publicKey.policy.password);
+}
+
+template<typename Keys, typename Func>
+void updateUpdateAsymmetricKeyHelper(const char *privateKeyAlias, const char *publicKeyAlias,
+    const ckmc_policy_s &policy, Keys& keys, Func&& func)
+{
+    AliasRemover aliasRemovers[] = { privateKeyAlias, publicKeyAlias };
+
+    assert_positive(ckmc_update_key, privateKeyAlias,
+                    *keys[0].privateKey.key, policy);
+    assert_positive(ckmc_update_key, publicKeyAlias,
+                    *keys[0].publicKey.key, policy);
+
+    std::forward<Func>(func)(privateKeyAlias, policy.password,
+                             publicKeyAlias, policy.password);
+    std::forward<Func>(func)(privateKeyAlias, policy.password,
+                             keys[0].publicKey.alias, keys[0].publicKey.policy.password);
+
+    assert_positive(ckmc_update_key, privateKeyAlias,
+                    *keys[1].privateKey.key, policy);
+    assert_positive(ckmc_update_key, publicKeyAlias,
+                    *keys[1].publicKey.key, policy);
+
+    std::forward<Func>(func)(privateKeyAlias, policy.password,
+                             publicKeyAlias, policy.password);
+    std::forward<Func>(func)(privateKeyAlias, policy.password,
+                             keys[1].publicKey.alias, keys[1].publicKey.policy.password);
+}
+
+template<typename Keys, typename Func>
+void saveUpdateAsymmetricKeyWithAnotherExportabilityHelper(
+    const char *privateKeyAlias, const char *publicKeyAlias, Keys& keys, Func&& func)
+{
+    AliasRemover aliasRemovers[] = { privateKeyAlias, publicKeyAlias };
+
+    assert_positive(ckmc_save_key, privateKeyAlias,
+                    *keys[0].privateKey.key, NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_save_key, publicKeyAlias,
+                    *keys[0].publicKey.key, NON_EXPORTABLE_POLICY);
+
+    check_self_key_alias_info_list(false,
+                                   Info(privateKeyAlias, NON_EXPORTABLE_POLICY, backend()),
+                                   Info(publicKeyAlias, NON_EXPORTABLE_POLICY, backend()));
+
+
+    assert_positive(ckmc_update_key, privateKeyAlias,
+                    *keys[1].privateKey.key, EXPORTABLE_POLICY);
+    assert_positive(ckmc_update_key, publicKeyAlias,
+                    *keys[1].publicKey.key, EXPORTABLE_POLICY);
+
+    check_self_key_alias_info_list(false,
+                                   Info(privateKeyAlias, EXPORTABLE_POLICY,
+                                        CKM::BackendId::SW),
+                                   Info(publicKeyAlias, EXPORTABLE_POLICY,
+                                        CKM::BackendId::SW));
+
+    std::forward<Func>(func)(privateKeyAlias, EXPORTABLE_POLICY.password,
+                             publicKeyAlias, EXPORTABLE_POLICY.password);
+    std::forward<Func>(func)(privateKeyAlias, NON_EXPORTABLE_POLICY.password,
+                             keys[1].publicKey.alias, keys[1].publicKey.policy.password);
+
+    ckmc_key_s *key = nullptr;
+    assert_positive(ckmc_get_key, privateKeyAlias, EXPORTABLE_POLICY.password, &key);
+    auto keyPtr = createKeyPtr(key);
+    assert_keys_equal(key, keys[1].privateKey.key.get());
+}
+
+template<typename Keys, typename Func>
+void saveUpdateAsymmetricKeyWithAnotherPasswordHelper(
+    const char *privateKeyAlias, const char *publicKeyAlias, Keys& keys, Func&& func)
+{
+    AliasRemover aliasRemovers[] = { privateKeyAlias, publicKeyAlias };
+
+    assert_positive(ckmc_save_key, privateKeyAlias,
+                    *keys[0].privateKey.key, EXPORTABLE_POLICY);
+    assert_positive(ckmc_save_key, publicKeyAlias,
+                    *keys[0].publicKey.key, EXPORTABLE_POLICY);
+
+    assert_positive(ckmc_update_key, privateKeyAlias,
+                    *keys[1].privateKey.key, EXPORTABLE_PASSWORD_POLICY_0);
+    assert_positive(ckmc_update_key, publicKeyAlias,
+                    *keys[1].publicKey.key, EXPORTABLE_PASSWORD_POLICY_0);
+
+    std::forward<Func>(func)(privateKeyAlias, EXPORTABLE_PASSWORD_POLICY_0.password,
+                             publicKeyAlias, EXPORTABLE_PASSWORD_POLICY_0.password);
+    std::forward<Func>(func)(privateKeyAlias, EXPORTABLE_PASSWORD_POLICY_0.password,
+                             keys[1].publicKey.alias, keys[1].publicKey.policy.password);
+
+    assert_positive(ckmc_update_key, privateKeyAlias,
+                    *keys[2].privateKey.key, EXPORTABLE_PASSWORD_POLICY_1);
+    assert_positive(ckmc_update_key, publicKeyAlias,
+                    *keys[2].publicKey.key, EXPORTABLE_PASSWORD_POLICY_1);
+
+    std::forward<Func>(func)(privateKeyAlias, EXPORTABLE_PASSWORD_POLICY_1.password,
+                             publicKeyAlias, EXPORTABLE_PASSWORD_POLICY_1.password);
+    std::forward<Func>(func)(privateKeyAlias, EXPORTABLE_PASSWORD_POLICY_1.password,
+                             keys[2].publicKey.alias, keys[2].publicKey.policy.password);
+}
+
+template<typename Keys, typename Func>
+void saveUpdateAsymmetricKeyWithAnotherBackendHelper(
+    const char *privateKeyAlias, const char *publicKeyAlias, Keys& keys, Func&& func)
+{
+    AliasRemover aliasRemovers[] = { privateKeyAlias, publicKeyAlias };
+
+    ckmSaveKey(*keys[0].privateKey.key, privateKeyAlias, TZ_POLICY);
+    ckmSaveKey(*keys[0].publicKey.key, publicKeyAlias, TZ_POLICY);
+
+    check_self_key_alias_info_list(false,
+                                   Info(privateKeyAlias, TZ_POLICY, backend()),
+                                   Info(publicKeyAlias, TZ_POLICY, backend()));
+
+    ckmUpdateKey(*keys[1].privateKey.key, privateKeyAlias, SW_POLICY);
+    ckmUpdateKey(*keys[1].publicKey.key, publicKeyAlias, SW_POLICY);
+
+    check_self_key_alias_info_list(false,
+                                   Info(privateKeyAlias, SW_POLICY, CKM::BackendId::SW),
+                                   Info(publicKeyAlias, SW_POLICY, CKM::BackendId::SW));
+
+    std::forward<Func>(func)(privateKeyAlias, SW_POLICY.password.c_str(),
+                             publicKeyAlias, SW_POLICY.password.c_str());
+    std::forward<Func>(func)(privateKeyAlias, SW_POLICY.password.c_str(),
+                             keys[1].publicKey.alias, keys[1].publicKey.policy.password);
+
+    ckmUpdateKey(*keys[2].privateKey.key, privateKeyAlias, TZ_POLICY);
+    ckmUpdateKey(*keys[2].publicKey.key, publicKeyAlias, TZ_POLICY);
+
+    check_self_key_alias_info_list(false,
+                                   Info(privateKeyAlias, TZ_POLICY, backend()),
+                                   Info(publicKeyAlias, TZ_POLICY, backend()));
+
+    std::forward<Func>(func)(privateKeyAlias, TZ_POLICY.password.c_str(),
+                             publicKeyAlias, TZ_POLICY.password.c_str());
+    std::forward<Func>(func)(privateKeyAlias, TZ_POLICY.password.c_str(),
+                             keys[2].publicKey.alias, keys[2].publicKey.policy.password);
+}
+
+template<typename Keys>
+void saveUpdateAsymmetricKeyWithInvalidParametersHelper(
+    const char *privateKeyAlias, const ckmc_policy_s &policy, Keys& keys)
+{
+    AliasRemover aliasRemovers[] = { privateKeyAlias };
+
+    assert_positive(ckmc_save_key, privateKeyAlias,
+                    *keys[0].privateKey.key, policy);
+
+    assert_result(CKMC_ERROR_INVALID_PARAMETER, ckmc_update_key, nullptr,
+                  *keys[1].privateKey.key, policy);
+
+    auto wrongKey = *keys[0].privateKey.key;
+    wrongKey.key_size = 0;
+    assert_result(CKMC_ERROR_INVALID_PARAMETER, ckmc_update_key, privateKeyAlias,
+                  wrongKey, NON_EXPORTABLE_POLICY);
+
+    wrongKey.key_size = keys[0].privateKey.key->key_size;
+    wrongKey.raw_key = nullptr;
+    assert_result(CKMC_ERROR_INVALID_PARAMETER, ckmc_update_key, privateKeyAlias,
+                  wrongKey, NON_EXPORTABLE_POLICY);
+}
+
+template<typename Keys>
+void saveUpdateAsymmetricKeyWithLockedDBHelper(
+    const char *privateKeyAlias, Keys& keys)
+{
+    AliasRemover aliasRemovers[] = { privateKeyAlias };
+
+    assert_positive(ckmc_save_key, privateKeyAlias,
+                    *keys[0].privateKey.key, NON_EXPORTABLE_POLICY);
+
+    assert_positive(ckmc_lock_user_key, OWNER_USER_ID);
+    assert_result(CKMC_ERROR_DB_LOCKED, ckmc_update_key, privateKeyAlias,
+                  *keys[1].privateKey.key, NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_unlock_user_key, OWNER_USER_ID, USER_PASSWORD);
+}
+
+template<typename Keys>
+void saveUpdateAsymmetricKeyWithWrongKeyHelper(
+    const char *privateKeyAlias, Keys& keys, ckmc_key_type_e type)
+{
+    AliasRemover aliasRemovers[] = { privateKeyAlias };
+
+    assert_positive(ckmc_save_key, privateKeyAlias,
+                    *keys[0].privateKey.key, NON_EXPORTABLE_POLICY);
+
+    ckmc_key_s wrongKey = {
+        WRONG_RAW_DATA, std::size(WRONG_RAW_DATA), type, nullptr
+    };
+    assert_result(CKMC_ERROR_INVALID_FORMAT, ckmc_update_key, privateKeyAlias,
+                  wrongKey, NON_EXPORTABLE_POLICY);
+}
+
+} // namespace anonymous
+
+namespace {
+
+const size_t RSA_KEY_SIZE = 1024;
+
+std::array<AsymmetricKey, 3> rsaKeys = { {
+    {
+        KeyCtx{ "RSA_PRIVATE_KEY_0", createKeyPtr(nullptr), EXPORTABLE_POLICY },
+        KeyCtx{ "RSA_PUBLIC_KEY_0", createKeyPtr(nullptr), EXPORTABLE_POLICY }
+    },
+    {
+        KeyCtx{ "RSA_PRIVATE_KEY_1", createKeyPtr(nullptr), EXPORTABLE_POLICY },
+        KeyCtx{ "RSA_PUBLIC_KEY_1", createKeyPtr(nullptr), EXPORTABLE_POLICY }
+    },
+    {
+        KeyCtx{ "RSA_PRIVATE_KEY_2", createKeyPtr(nullptr), EXPORTABLE_POLICY },
+        KeyCtx{ "RSA_PUBLIC_KEY_2", createKeyPtr(nullptr), EXPORTABLE_POLICY }
+    }
+} };
+
+const char* RSA_PRIVATE_KEY_ALIAS = "RSA_PRIVATE_KEY";
+const char* RSA_PUBLIC_KEY_ALIAS = "RSA_PUBLIC_KEY";
+
+void checkRSAKeysMatching(const char* privateAlias, const char* privatePassword,
+                          const char* publicAlias, const char* publicPassword)
+{
+    auto plain = create_raw_buffer(createRandomBufferCAPI(86));
+
+    auto params = createParamListPtr();
+    setParam(params, CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_RSA_OAEP);
+    setParam(params, CKMC_PARAM_ED_OAEP_HASH, CKMC_HASH_SHA1);
+
+    ckmc_raw_buffer_s* encrypted = nullptr;
+    assert_positive(ckmc_encrypt_data, params.get(), publicAlias,
+                    publicPassword, *plain.get(), &encrypted);
+    auto encryptedPtr = create_raw_buffer(encrypted);
+
+    ckmc_raw_buffer_s* decrypted = nullptr;
+    assert_positive(ckmc_decrypt_data, params.get(), privateAlias,
+                    privatePassword, *encrypted, &decrypted);
+    auto decryptedPtr = create_raw_buffer(decrypted);
+
+    assert_buffers_equal(plain.get(), decrypted);
+}
+
+class RSAKeys
+{
+public:
+    void Init()
+    {
+        for (auto& rsaKey : rsaKeys)
+        {
+            error_msg_positive(ckmc_create_key_pair_rsa, RSA_KEY_SIZE,
+                               rsaKey.privateKey.alias, rsaKey.publicKey.alias,
+                               rsaKey.privateKey.policy, rsaKey.privateKey.policy);
+
+            ckmc_key_s *key = nullptr;
+            error_msg_positive(ckmc_get_key, rsaKey.privateKey.alias,
+                               rsaKey.privateKey.policy.password, &key);
+            rsaKey.privateKey.key = createKeyPtr(key);
+
+            key = nullptr;
+            error_msg_positive(ckmc_get_key, rsaKey.publicKey.alias,
+                               rsaKey.publicKey.policy.password, &key);
+            rsaKey.publicKey.key = createKeyPtr(key);
+        }
+    }
+
+    void Finish()
+    {
+        for (const auto& key : rsaKeys)
+        {
+            error_msg_positive(ckmc_remove_alias, key.privateKey.alias);
+            error_msg_positive(ckmc_remove_alias, key.publicKey.alias);
+        }
+    }
+};
+
+class RSAKeysTestGroup : public RSAKeys, public DPL::Test::TestGroup, public OwnerUserEnv
+{
+public:
+    void Init() override
+    {
+        OwnerUserEnv::Init();
+        RSAKeys::Init();
+    }
+
+    void Finish() override
+    {
+        RSAKeys::Finish();
+        OwnerUserEnv::Finish();
+    }
+};
+
+} // namespace anonymous
+
+RUNNER_TEST_GROUP_INIT_ENV(CKM_UPDATE_API_RSA_KEYS, RSAKeysTestGroup);
+
+RUNNER_TEST(TUA_0010_save_update_RSA_key)
+{
+    saveUpdateAsymmetricKeyHelper(RSA_PRIVATE_KEY_ALIAS, RSA_PUBLIC_KEY_ALIAS,
+                                  NON_EXPORTABLE_POLICY, rsaKeys, checkRSAKeysMatching);
+}
+
+RUNNER_TEST(TUA_0011_update_update_RSA_key)
+{
+    updateUpdateAsymmetricKeyHelper(RSA_PRIVATE_KEY_ALIAS, RSA_PUBLIC_KEY_ALIAS,
+                                    NON_EXPORTABLE_POLICY, rsaKeys, checkRSAKeysMatching);
+}
+
+RUNNER_TEST(TUA_0012_save_update_RSA_key_with_another_exportability)
+{
+    saveUpdateAsymmetricKeyWithAnotherExportabilityHelper(RSA_PRIVATE_KEY_ALIAS,
+                                                          RSA_PUBLIC_KEY_ALIAS,
+                                                          rsaKeys, checkRSAKeysMatching);
+}
+
+RUNNER_TEST(TUA_0013_save_update_RSA_key_with_another_password)
+{
+    saveUpdateAsymmetricKeyWithAnotherPasswordHelper(RSA_PRIVATE_KEY_ALIAS, RSA_PUBLIC_KEY_ALIAS,
+                                                     rsaKeys, checkRSAKeysMatching);
+}
+
+RUNNER_TEST(TUA_0014_save_update_RSA_key_with_another_backend)
+{
+    saveUpdateAsymmetricKeyWithAnotherBackendHelper(RSA_PRIVATE_KEY_ALIAS, RSA_PUBLIC_KEY_ALIAS,
+                                                    rsaKeys, checkRSAKeysMatching);
+}
+
+RUNNER_TEST(TUA_0015_save_update_RSA_key_with_invalid_parameters)
+{
+    saveUpdateAsymmetricKeyWithInvalidParametersHelper(RSA_PRIVATE_KEY_ALIAS,
+                                                       NON_EXPORTABLE_POLICY, rsaKeys);
+}
+
+RUNNER_TEST(TUA_0016_save_update_RSA_key_with_locked_db)
+{
+    saveUpdateAsymmetricKeyWithLockedDBHelper(RSA_PRIVATE_KEY_ALIAS, rsaKeys);
+}
+
+RUNNER_TEST(TUA_0017_save_update_wrong_RSA_key)
+{
+    saveUpdateAsymmetricKeyWithWrongKeyHelper(RSA_PRIVATE_KEY_ALIAS, rsaKeys,
+                                              CKMC_KEY_RSA_PRIVATE);
+}
+
+namespace {
+
+struct Algo {
+    ckmc_algo_type_e type;
+    size_t initVector;
+};
+
+const Algo KEM_ALGO = { CKMC_ALGO_KEM, 0 };
+const ckmc_kem_type_e KEM_TYPE = ckmc_kem_type_e::CKMC_ML_KEM_768;
+const Algo AES_CBC_ALGO = {CKMC_ALGO_AES_CBC, 16};
+
+std::array<AsymmetricKey, 3> kemKeys = { {
+    {
+        KeyCtx{ "KEM_PRIVATE_KEY_0", createKeyPtr(nullptr), EXPORTABLE_POLICY },
+        KeyCtx{ "KEM_PUBLIC_KEY_0", createKeyPtr(nullptr), EXPORTABLE_POLICY }
+    },
+    {
+        KeyCtx{ "KEM_PRIVATE_KEY_1", createKeyPtr(nullptr), EXPORTABLE_POLICY },
+        KeyCtx{ "KEM_PUBLIC_KEY_1", createKeyPtr(nullptr), EXPORTABLE_POLICY }
+    },
+    {
+        KeyCtx{ "KEM_PRIVATE_KEY_2", createKeyPtr(nullptr), EXPORTABLE_POLICY },
+        KeyCtx{ "KEM_PUBLIC_KEY_2", createKeyPtr(nullptr), EXPORTABLE_POLICY }
+    }
+} };
+
+const char* KEM_PRIVATE_KEY_ALIAS = "KEM_PRIVATE_KEY";
+const char* KEM_PUBLIC_KEY_ALIAS = "KEM_PUBLIC_KEY";
+const char* ENCAPSULATED_SECRET_ALIAS = "ENCAPSULATED_SECRET";
+const char* DECAPSULATED_SECRET_ALIAS = "DECAPSULATED_SECRET";
+
+ParamListPtr getDefaultParams(const Algo &algo) {
+    ckmc_param_list_h handle = nullptr;
+
+    assert_positive(ckmc_generate_new_params, algo.type, &handle);
+    auto params = ParamListPtr(handle, ckmc_param_list_free);
+
+    if (algo.initVector) {
+        setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(algo.initVector));
+    }
+
+    return params;
+}
+
+void checkKEMKeysMatching(const char* privateAlias, const char* privateKeyPassword,
+                          const char* publicAlias, const char* publicKeyPassword)
+{
+    AliasRemover removers[] = { ENCAPSULATED_SECRET_ALIAS, DECAPSULATED_SECRET_ALIAS };
+
+    auto params = getDefaultParams(KEM_ALGO);
+    setParam(params, CKMC_PARAM_KEM_TYPE, KEM_TYPE);
+
+    ckmc_raw_buffer_s *ciphertext = nullptr;
+
+    assert_positive(ckmc_encapsulate_key,
+                    params.get(),
+                    publicAlias,
+                    publicKeyPassword,
+                    ENCAPSULATED_SECRET_ALIAS,
+                    NON_EXPORTABLE_POLICY,
+                    &ciphertext);
+
+    auto ciphertextPtr = create_raw_buffer(ciphertext);
+
+    assert_positive(ckmc_decapsulate_key,
+                    params.get(),
+                    privateAlias,
+                    privateKeyPassword,
+                    DECAPSULATED_SECRET_ALIAS,
+                    NON_EXPORTABLE_POLICY,
+                    ciphertext);
+
+    auto plain = create_raw_buffer(createRandomBufferCAPI(32));
+    params = getDefaultParams(AES_CBC_ALGO);
+
+    ckmc_raw_buffer_s *encrypted = nullptr;
+    assert_positive(ckmc_encrypt_data,
+                    params.get(),
+                    ENCAPSULATED_SECRET_ALIAS,
+                    NON_EXPORTABLE_POLICY.password,
+                    *plain.get(),
+                    &encrypted);
+    auto encryptedPtr = create_raw_buffer(encrypted);
+
+    ckmc_raw_buffer_s *decrypted = nullptr;
+    assert_positive(ckmc_decrypt_data,
+                    params.get(),
+                    DECAPSULATED_SECRET_ALIAS,
+                    NON_EXPORTABLE_POLICY.password,
+                    *encrypted,
+                    &decrypted);
+    auto decryptedPtr = create_raw_buffer(decrypted);
+
+    assert_buffers_equal(plain.get(), decrypted);
+}
+
+class KEMKeys
+{
+public:
+    void Init()
+    {
+        for (auto& kemKey : kemKeys)
+        {
+            error_msg_positive(ckmc_create_key_pair_kem, KEM_TYPE,
+                               kemKey.privateKey.alias, kemKey.publicKey.alias,
+                               kemKey.privateKey.policy, kemKey.privateKey.policy);
+
+            ckmc_key_s *key = nullptr;
+            error_msg_positive(ckmc_get_key, kemKey.privateKey.alias,
+                               kemKey.privateKey.policy.password, &key);
+            kemKey.privateKey.key = createKeyPtr(key);
+
+            key = nullptr;
+            error_msg_positive(ckmc_get_key, kemKey.publicKey.alias,
+                               kemKey.publicKey.policy.password, &key);
+            kemKey.publicKey.key = createKeyPtr(key);
+        }
+    }
+
+    void Finish()
+    {
+        for (const auto& key : kemKeys)
+        {
+            error_msg_positive(ckmc_remove_alias, key.privateKey.alias);
+            error_msg_positive(ckmc_remove_alias, key.publicKey.alias);
+        }
+    }
+};
+
+class KEMKeysTestGroup : public KEMKeys, public DPL::Test::TestGroup, public OwnerUserEnv
+{
+public:
+    void Init() override
+    {
+        OwnerUserEnv::Init();
+        KEMKeys::Init();
+    }
+
+    void Finish() override
+    {
+        KEMKeys::Finish();
+        OwnerUserEnv::Finish();
+    }
+};
+
+} // namespace anonymous
+
+RUNNER_TEST_GROUP_INIT_ENV(CKM_UPDATE_API_KEM_KEYS, KEMKeysTestGroup);
+
+RUNNER_TEST(TUA_0020_save_update_KEM_key)
+{
+    saveUpdateAsymmetricKeyHelper(KEM_PRIVATE_KEY_ALIAS, KEM_PUBLIC_KEY_ALIAS,
+                                  NON_EXPORTABLE_POLICY, kemKeys, checkKEMKeysMatching);
+}
+
+RUNNER_TEST(TUA_0021_update_update_KEM_key)
+{
+    updateUpdateAsymmetricKeyHelper(KEM_PRIVATE_KEY_ALIAS, KEM_PUBLIC_KEY_ALIAS,
+                                    NON_EXPORTABLE_POLICY, kemKeys, checkKEMKeysMatching);
+}
+
+RUNNER_TEST(TUA_0022_save_update_KEM_key_with_another_exportability)
+{
+    saveUpdateAsymmetricKeyWithAnotherExportabilityHelper(KEM_PRIVATE_KEY_ALIAS,
+                                                          KEM_PUBLIC_KEY_ALIAS, kemKeys,
+                                                          checkKEMKeysMatching);
+}
+
+RUNNER_TEST(TUA_0023_save_update_KEM_key_with_another_password)
+{
+    saveUpdateAsymmetricKeyWithAnotherPasswordHelper(KEM_PRIVATE_KEY_ALIAS, KEM_PUBLIC_KEY_ALIAS,
+                                                     kemKeys, checkKEMKeysMatching);
+}
+
+RUNNER_TEST(TUA_0024_save_update_KEM_key_with_another_backend)
+{
+    saveUpdateAsymmetricKeyWithAnotherBackendHelper(KEM_PRIVATE_KEY_ALIAS, KEM_PUBLIC_KEY_ALIAS,
+                                                    kemKeys, checkKEMKeysMatching);
+}
+
+RUNNER_TEST(TUA_0025_save_update_KEM_key_with_invalid_parameters)
+{
+    saveUpdateAsymmetricKeyWithInvalidParametersHelper(KEM_PRIVATE_KEY_ALIAS,
+                                                       NON_EXPORTABLE_POLICY, kemKeys);
+}
+
+RUNNER_TEST(TUA_0026_save_update_KEM_key_with_locked_db)
+{
+    saveUpdateAsymmetricKeyWithLockedDBHelper(KEM_PRIVATE_KEY_ALIAS, kemKeys);
+}
+
+RUNNER_TEST(TUA_0027_save_update_wrong_KEM_key)
+{
+    saveUpdateAsymmetricKeyWithWrongKeyHelper(KEM_PRIVATE_KEY_ALIAS, kemKeys,
+                                              CKMC_KEY_KEM_PRIVATE);
+}
+
+namespace {
+
+std::array<AsymmetricKey, 3> dsaKeys = { {
+    {
+        KeyCtx{ "DSA_PRIVATE_KEY_0", createKeyPtr(nullptr), EXPORTABLE_POLICY },
+        KeyCtx{ "DSA_PUBLIC_KEY_0", createKeyPtr(nullptr), EXPORTABLE_POLICY }
+    },
+    {
+        KeyCtx{ "DSA_PRIVATE_KEY_1", createKeyPtr(nullptr), EXPORTABLE_POLICY },
+        KeyCtx{ "DSA_PUBLIC_KEY_1", createKeyPtr(nullptr), EXPORTABLE_POLICY }
+    },
+    {
+        KeyCtx{ "DSA_PRIVATE_KEY_2", createKeyPtr(nullptr), EXPORTABLE_POLICY },
+        KeyCtx{ "DSA_PUBLIC_KEY_2", createKeyPtr(nullptr), EXPORTABLE_POLICY }
+    }
+} };
+
+const char* DSA_PRIVATE_KEY_ALIAS = "DSA_PRIVATE_KEY";
+const char* DSA_PUBLIC_KEY_ALIAS = "DSA_PUBLIC_KEY";
+
+void checkSignatureVerification(const char* privateAlias, const char* privatePassword,
+                                const char* publicAlias, const char* publicPassword)
+{
+    ckmc_raw_buffer_s message = prepare_message_buffer("message");
+    ckmc_hash_algo_e hashAlgo = CKMC_HASH_SHA1;
+    ckmc_rsa_padding_algo_e padAlgo = CKMC_PKCS1_PADDING;
+    ckmc_raw_buffer_s *signature = nullptr;
+
+    assert_positive(ckmc_create_signature,
+                    privateAlias,
+                    privatePassword,
+                    message,
+                    hashAlgo,
+                    padAlgo,
+                    &signature);
+
+    auto signaturePtr = create_raw_buffer(signature);
+
+    assert_positive(ckmc_verify_signature,
+                    publicAlias,
+                    publicPassword,
+                    message,
+                    *signature,
+                    hashAlgo,
+                    padAlgo);
+}
+
+class DSAKeys
+{
+public:
+    void Init()
+    {
+        for (auto& keyPair : dsaKeys)
+        {
+            error_msg_positive(ckmc_create_key_pair_dsa, m_dsaKeySize, keyPair.privateKey.alias,
+                               keyPair.publicKey.alias, keyPair.privateKey.policy,
+                               keyPair.privateKey.policy);
+
+            ckmc_key_s *key = nullptr;
+            error_msg_positive(ckmc_get_key, keyPair.privateKey.alias,
+                               keyPair.privateKey.policy.password, &key);
+            keyPair.privateKey.key = createKeyPtr(key);
+
+            key = nullptr;
+            error_msg_positive(ckmc_get_key, keyPair.publicKey.alias,
+                               keyPair.publicKey.policy.password, &key);
+            keyPair.publicKey.key = createKeyPtr(key);
+        }
+    }
+
+    void Finish()
+    {
+        for (const auto& key : dsaKeys)
+        {
+            error_msg_positive(ckmc_remove_alias, key.privateKey.alias);
+            error_msg_positive(ckmc_remove_alias, key.publicKey.alias);
+        }
+    }
+
+private:
+    const size_t m_dsaKeySize = 1024;
+};
+
+class DSAKeysTestGroup : public DSAKeys, public DPL::Test::TestGroup, public OwnerUserEnv
+{
+public:
+    void Init() override
+    {
+        OwnerUserEnv::Init();
+        DSAKeys::Init();
+    }
+
+    void Finish() override
+    {
+        DSAKeys::Finish();
+        OwnerUserEnv::Finish();
+    }
+};
+
+} // namespace anonymous
+
+RUNNER_TEST_GROUP_INIT_ENV(CKM_UPDATE_API_DSA_KEYS, DSAKeysTestGroup);
+
+RUNNER_TEST(TUA_0030_save_update_DSA_key)
+{
+    saveUpdateAsymmetricKeyHelper(DSA_PRIVATE_KEY_ALIAS, DSA_PUBLIC_KEY_ALIAS,
+                                  EXPORTABLE_POLICY, dsaKeys, checkSignatureVerification);
+}
+
+RUNNER_TEST(TUA_0031_update_update_DSA_key)
+{
+    updateUpdateAsymmetricKeyHelper(DSA_PRIVATE_KEY_ALIAS, DSA_PUBLIC_KEY_ALIAS,
+                                    EXPORTABLE_POLICY, dsaKeys, checkSignatureVerification);
+}
+
+RUNNER_TEST(TUA_0033_save_update_DSA_key_with_another_password)
+{
+    saveUpdateAsymmetricKeyWithAnotherPasswordHelper(DSA_PRIVATE_KEY_ALIAS, DSA_PUBLIC_KEY_ALIAS,
+                                                     dsaKeys, checkSignatureVerification);
+}
+
+RUNNER_TEST(TUA_0035_save_update_DSA_key_with_invalid_parameters)
+{
+    saveUpdateAsymmetricKeyWithInvalidParametersHelper(DSA_PRIVATE_KEY_ALIAS,
+                                                       EXPORTABLE_POLICY, dsaKeys);
+}
+
+RUNNER_TEST(TUA_0036_save_update_DSA_key_with_locked_db)
+{
+    saveUpdateAsymmetricKeyWithLockedDBHelper(DSA_PRIVATE_KEY_ALIAS, dsaKeys);
+}
+
+RUNNER_TEST(TUA_0037_save_update_wrong_DSA_key)
+{
+    saveUpdateAsymmetricKeyWithWrongKeyHelper(DSA_PRIVATE_KEY_ALIAS, dsaKeys, CKMC_KEY_DSA_PRIVATE);
+}
+
+namespace {
+
+std::array<AsymmetricKey, 3> ecdsaKeys = { {
+    {
+        KeyCtx{ "ECDSA_PRIVATE_KEY_0", createKeyPtr(nullptr), EXPORTABLE_POLICY },
+        KeyCtx{ "ECDSA_PUBLIC_KEY_0", createKeyPtr(nullptr), EXPORTABLE_POLICY }
+    },
+    {
+        KeyCtx{ "ECDSA_PRIVATE_KEY_1", createKeyPtr(nullptr), EXPORTABLE_POLICY },
+        KeyCtx{ "ECDSA_PUBLIC_KEY_1", createKeyPtr(nullptr), EXPORTABLE_POLICY }
+    },
+    {
+        KeyCtx{ "ECDSA_PRIVATE_KEY_2", createKeyPtr(nullptr), EXPORTABLE_POLICY },
+        KeyCtx{ "ECDSA_PUBLIC_KEY_2", createKeyPtr(nullptr), EXPORTABLE_POLICY }
+    }
+} };
+
+const char* ECDSA_PRIVATE_KEY_ALIAS = "ECDSA_PRIVATE_KEY_ALIAS";
+const char* ECDSA_PUBLIC_KEY_ALIAS = "ECDSA_PUBLIC_KEY_ALIAS";
+
+class ECDSAKeys
+{
+public:
+    void Init()
+    {
+        for (auto& keyPair : ecdsaKeys)
+        {
+            error_msg_positive(ckmc_create_key_pair_ecdsa, m_ecType, keyPair.privateKey.alias,
+                               keyPair.publicKey.alias, keyPair.privateKey.policy,
+                               keyPair.privateKey.policy);
+
+            ckmc_key_s *key = nullptr;
+            error_msg_positive(ckmc_get_key, keyPair.privateKey.alias,
+                               keyPair.privateKey.policy.password, &key);
+            keyPair.privateKey.key = createKeyPtr(key);
+
+            key = nullptr;
+            error_msg_positive(ckmc_get_key, keyPair.publicKey.alias,
+                               keyPair.publicKey.policy.password, &key);
+            keyPair.publicKey.key = createKeyPtr(key);
+        }
+    }
+
+    void Finish()
+    {
+        for (const auto& key : ecdsaKeys)
+        {
+            error_msg_positive(ckmc_remove_alias, key.privateKey.alias);
+            error_msg_positive(ckmc_remove_alias, key.publicKey.alias);
+        }
+    }
+
+private:
+    const ckmc_ec_type_e m_ecType = CKMC_EC_PRIME192V1;
+};
+
+class ECDSAKeysTestGroup : public ECDSAKeys, public DPL::Test::TestGroup, public OwnerUserEnv
+{
+public:
+    void Init() override
+    {
+        OwnerUserEnv::Init();
+        ECDSAKeys::Init();
+    }
+
+    void Finish() override
+    {
+        ECDSAKeys::Finish();
+        OwnerUserEnv::Finish();
+    }
+};
+
+} // namespace anonymous
+
+RUNNER_TEST_GROUP_INIT_ENV(CKM_UPDATE_API_ECDSA_KEYS, ECDSAKeysTestGroup);
+
+RUNNER_TEST(TUA_0040_save_update_ECDSA_key)
+{
+    saveUpdateAsymmetricKeyHelper(ECDSA_PRIVATE_KEY_ALIAS, ECDSA_PUBLIC_KEY_ALIAS,
+                                  NON_EXPORTABLE_POLICY, ecdsaKeys, checkSignatureVerification);
+}
+
+RUNNER_TEST(TUA_0041_update_update_ECDSA_key)
+{
+    updateUpdateAsymmetricKeyHelper(ECDSA_PRIVATE_KEY_ALIAS, ECDSA_PUBLIC_KEY_ALIAS,
+                                    NON_EXPORTABLE_POLICY, ecdsaKeys, checkSignatureVerification);
+}
+
+RUNNER_TEST(TUA_0042_save_update_ECDSA_key_with_another_exportability)
+{
+    saveUpdateAsymmetricKeyWithAnotherExportabilityHelper(
+        ECDSA_PRIVATE_KEY_ALIAS, ECDSA_PUBLIC_KEY_ALIAS, ecdsaKeys, checkSignatureVerification);
+}
+
+RUNNER_TEST(TUA_0043_save_update_ECDSA_key_with_another_password)
+{
+    saveUpdateAsymmetricKeyWithAnotherPasswordHelper(
+        ECDSA_PRIVATE_KEY_ALIAS, ECDSA_PUBLIC_KEY_ALIAS, ecdsaKeys, checkSignatureVerification);
+}
+
+RUNNER_TEST(TUA_0044_save_update_ECDSA_key_with_another_backend)
+{
+    saveUpdateAsymmetricKeyWithAnotherBackendHelper(
+        ECDSA_PRIVATE_KEY_ALIAS, ECDSA_PUBLIC_KEY_ALIAS, ecdsaKeys, checkSignatureVerification);
+}
+
+RUNNER_TEST(TUA_0045_save_update_ECDSA_key_with_invalid_parameters)
+{
+    saveUpdateAsymmetricKeyWithInvalidParametersHelper(ECDSA_PRIVATE_KEY_ALIAS,
+                                                       NON_EXPORTABLE_POLICY, ecdsaKeys);
+}
+
+RUNNER_TEST(TUA_0046_save_update_ECDSA_key_with_locked_db)
+{
+    saveUpdateAsymmetricKeyWithLockedDBHelper(ECDSA_PRIVATE_KEY_ALIAS, ecdsaKeys);
+}
+
+RUNNER_TEST(TUA_0047_save_update_wrong_ECDSA_key)
+{
+    saveUpdateAsymmetricKeyWithWrongKeyHelper(ECDSA_PRIVATE_KEY_ALIAS, ecdsaKeys,
+                                              CKMC_KEY_ECDSA_PRIVATE);
+}
+
+namespace {
+
+std::array<KeyCtx, 4> aesKeys = { {
+    { "AES_KEY_0", createKeyPtr(nullptr), NON_EXPORTABLE_POLICY },
+    { "AES_KEY_1", createKeyPtr(nullptr), NON_EXPORTABLE_POLICY },
+    { "AES_KEY_2", createKeyPtr(nullptr), NON_EXPORTABLE_PASSWORD_POLICY_0 },
+    { "AES_KEY_3", createKeyPtr(nullptr), NON_EXPORTABLE_PASSWORD_POLICY_1 }
+} };
+
+const char* AES_KEY_ALIAS = "AES_KEY";
+
+void checkAESKeysMatching(const char* aesKeyAlias1, const char* password1,
+                          const char* aesKeyAlias2, const char* password2)
+{
+    auto plain = create_raw_buffer(createRandomBufferCAPI(512));
+    auto iv = create_raw_buffer(createRandomBufferCAPI(16));
+
+    auto params = createParamListPtr();
+    setParam(params, CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_AES_CTR);
+    setParam(params, CKMC_PARAM_ED_IV, iv.get());
+
+    ckmc_raw_buffer_s* encrypted = nullptr;
+    assert_positive(ckmc_encrypt_data, params.get(), aesKeyAlias1,
+                    password1, *plain.get(), &encrypted);
+    auto encryptedPtr = create_raw_buffer(encrypted);
+
+    ckmc_raw_buffer_s* decrypted = nullptr;
+    assert_positive(ckmc_decrypt_data, params.get(), aesKeyAlias2,
+                    password2, *encrypted, &decrypted);
+    auto decryptedPtr = create_raw_buffer(decrypted);
+
+    assert_buffers_equal(plain.get(), decrypted);
+}
+
+class AESKeys
+{
+public:
+    void Init()
+    {
+        for (auto& key : aesKeys)
+        {
+            key.key = createKeyPtr(generate_AES_key(m_aesKeyLength, nullptr));
+            error_msg_positive(ckmc_save_key, key.alias, *key.key, key.policy);
+        }
+    }
+
+    void Finish()
+    {
+        for (const auto& key : aesKeys)
+        {
+            error_msg_positive(ckmc_remove_alias, key.alias);
+        }
+    }
+
+private:
+    const size_t m_aesKeyLength = 192;
+};
+
+class AESKeysTestGroup : public AESKeys, public DPL::Test::TestGroup, public OwnerUserEnv
+{
+public:
+    void Init() override
+    {
+        OwnerUserEnv::Init();
+        AESKeys::Init();
+    }
+
+    void Finish() override
+    {
+        AESKeys::Finish();
+        OwnerUserEnv::Finish();
+    }
+};
+
+} // namespace anonymous
+
+RUNNER_TEST_GROUP_INIT_ENV(CKM_UPDATE_API_AES_KEYS, AESKeysTestGroup);
+
+RUNNER_TEST(TUA_0050_save_update_AES_key)
+{
+    AliasRemover aliasRemover(AES_KEY_ALIAS);
+
+    assert_positive(ckmc_save_key, AES_KEY_ALIAS, *aesKeys[0].key, NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_update_key, AES_KEY_ALIAS, *aesKeys[1].key, NON_EXPORTABLE_POLICY);
+
+    checkAESKeysMatching(aesKeys[1].alias, aesKeys[1].policy.password,
+                         AES_KEY_ALIAS, NON_EXPORTABLE_POLICY.password);
+}
+
+RUNNER_TEST(TUA_0051_update_update_AES_key)
+{
+    AliasRemover aliasRemover(AES_KEY_ALIAS);
+
+    assert_positive(ckmc_update_key, AES_KEY_ALIAS, *aesKeys[0].key, NON_EXPORTABLE_POLICY);
+
+    checkAESKeysMatching(aesKeys[0].alias, aesKeys[0].policy.password,
+                         AES_KEY_ALIAS, NON_EXPORTABLE_POLICY.password);
+
+    assert_positive(ckmc_update_key, AES_KEY_ALIAS, *aesKeys[1].key, NON_EXPORTABLE_POLICY);
+
+    checkAESKeysMatching(aesKeys[1].alias, aesKeys[1].policy.password,
+                         AES_KEY_ALIAS, NON_EXPORTABLE_POLICY.password);
+}
+
+RUNNER_TEST(TUA_0052_save_update_AES_key_with_another_exportability)
+{
+    AliasRemover aliasRemover(AES_KEY_ALIAS);
+
+    assert_positive(ckmc_save_key, AES_KEY_ALIAS, *aesKeys[0].key, NON_EXPORTABLE_POLICY);
+    check_self_key_alias_info_list(false, Info(AES_KEY_ALIAS, NON_EXPORTABLE_POLICY, backend()));
+
+    assert_positive(ckmc_update_key, AES_KEY_ALIAS, *aesKeys[1].key, EXPORTABLE_POLICY);
+    check_self_key_alias_info_list(false, Info(AES_KEY_ALIAS, EXPORTABLE_POLICY,
+                                               CKM::BackendId::SW));
+
+    checkAESKeysMatching(aesKeys[1].alias, aesKeys[1].policy.password,
+                         AES_KEY_ALIAS, EXPORTABLE_POLICY.password);
+
+    ckmc_key_s *key = nullptr;
+    assert_positive(ckmc_get_key, AES_KEY_ALIAS, EXPORTABLE_POLICY.password, &key);
+    auto keyPtr = createKeyPtr(key);
+    assert_keys_equal(key, aesKeys[1].key.get());
+}
+
+RUNNER_TEST(TUA_0053_save_update_AES_key_with_another_password)
+{
+    AliasRemover aliasRemover(AES_KEY_ALIAS);
+
+    assert_positive(ckmc_save_key, AES_KEY_ALIAS, *aesKeys[0].key, NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_update_key, AES_KEY_ALIAS,
+                    *aesKeys[2].key, NON_EXPORTABLE_PASSWORD_POLICY_0);
+
+    checkAESKeysMatching(aesKeys[2].alias, aesKeys[2].policy.password,
+                         AES_KEY_ALIAS, NON_EXPORTABLE_PASSWORD_POLICY_0.password);
+
+    assert_positive(ckmc_update_key, AES_KEY_ALIAS,
+                    *aesKeys[3].key, NON_EXPORTABLE_PASSWORD_POLICY_1);
+
+    checkAESKeysMatching(aesKeys[3].alias, aesKeys[3].policy.password,
+                         AES_KEY_ALIAS, NON_EXPORTABLE_PASSWORD_POLICY_1.password);
+}
+
+RUNNER_TEST(TUA_0054_save_update_AES_key_with_another_backend)
+{
+    AliasRemover aliasRemover(AES_KEY_ALIAS);
+
+    ckmSaveKey(*aesKeys[0].key, AES_KEY_ALIAS, TZ_POLICY);
+    check_self_key_alias_info_list(false, Info(AES_KEY_ALIAS, TZ_POLICY, backend()));
+
+    ckmUpdateKey(*aesKeys[1].key, AES_KEY_ALIAS, SW_POLICY);
+    check_self_key_alias_info_list(false, Info(AES_KEY_ALIAS, SW_POLICY, CKM::BackendId::SW));
+
+    checkAESKeysMatching(aesKeys[1].alias, aesKeys[1].policy.password,
+                         AES_KEY_ALIAS, SW_POLICY.password.c_str());
+
+    ckmUpdateKey(*aesKeys[2].key, AES_KEY_ALIAS, TZ_POLICY);
+    check_self_key_alias_info_list(false, Info(AES_KEY_ALIAS, TZ_POLICY, backend()));
+
+    checkAESKeysMatching(aesKeys[2].alias, aesKeys[2].policy.password,
+                         AES_KEY_ALIAS, TZ_POLICY.password.c_str());
+}
+
+RUNNER_TEST(TUA_0055_save_update_AES_key_with_invalid_parameters)
+{
+    AliasRemover aliasRemover(AES_KEY_ALIAS);
+
+    assert_positive(ckmc_save_key, AES_KEY_ALIAS, *aesKeys[0].key, NON_EXPORTABLE_POLICY);
+
+    assert_result(CKMC_ERROR_INVALID_PARAMETER, ckmc_update_key, nullptr,
+                  *aesKeys[1].key, NON_EXPORTABLE_POLICY);
+
+    auto wrongAesKey = *aesKeys[0].key;
+
+    wrongAesKey.password = const_cast<char*>(USER_PASSWORD);
+    assert_result(CKMC_ERROR_INVALID_PARAMETER, ckmc_update_key, AES_KEY_ALIAS,
+                  wrongAesKey, NON_EXPORTABLE_POLICY);
+
+    wrongAesKey.password = aesKeys[0].key->password;
+    wrongAesKey.key_size = 0;
+    assert_result(CKMC_ERROR_INVALID_PARAMETER, ckmc_update_key, AES_KEY_ALIAS,
+                  wrongAesKey, NON_EXPORTABLE_POLICY);
+
+    wrongAesKey.key_size = aesKeys[0].key->key_size;
+    wrongAesKey.raw_key = nullptr;
+    assert_result(CKMC_ERROR_INVALID_PARAMETER, ckmc_update_key, AES_KEY_ALIAS,
+                  wrongAesKey, NON_EXPORTABLE_POLICY);
+}
+
+RUNNER_TEST(TUA_0056_save_update_AES_key_with_locked_db)
+{
+    AliasRemover aliasRemover(AES_KEY_ALIAS);
+
+    assert_positive(ckmc_save_key, AES_KEY_ALIAS, *aesKeys[0].key, NON_EXPORTABLE_POLICY);
+
+    assert_positive(ckmc_lock_user_key, OWNER_USER_ID);
+    assert_result(CKMC_ERROR_DB_LOCKED, ckmc_update_key, AES_KEY_ALIAS,
+                  *aesKeys[1].key, NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_unlock_user_key, OWNER_USER_ID, USER_PASSWORD);
+}
+
+RUNNER_TEST(TUA_0057_save_update_wrong_AES_key)
+{
+    AliasRemover aliasRemover(AES_KEY_ALIAS);
+
+    assert_positive(ckmc_save_key, AES_KEY_ALIAS, *aesKeys[0].key, NON_EXPORTABLE_POLICY);
+
+    ckmc_key_s wrongAesKey = {
+        WRONG_RAW_DATA, std::size(WRONG_RAW_DATA), CKMC_KEY_AES, nullptr
+    };
+    assert_result(CKMC_ERROR_INVALID_FORMAT, ckmc_update_key, AES_KEY_ALIAS,
+                  wrongAesKey, NON_EXPORTABLE_POLICY);
+}
+
+namespace {
+
+using DataCtx = RawBufferPtr;
+
+std::array<DataCtx, 2> data = { {
+    create_raw_buffer(createRandomBufferCAPI(32)),
+    create_raw_buffer(createRandomBufferCAPI(32))
+} };
+
+const char* DATA_ALIASES_UPDATED = "secret1";
+const char* DATA_ALIASES_STORED = "secret2";
+
+ParamListPtr generateDerivationParams()
+{
+    const uint64_t U32 = 32;
+    const ckmc_kdf_prf_e HMAC256 = CKMC_KDF_PRF_HMAC_SHA256;
+    const ckmc_kbkdf_mode_e COUNTER = CKMC_KBKDF_MODE_COUNTER;
+    const ckmc_kbkdf_counter_location_e BEFORE = CKMC_KBKDF_COUNTER_BEFORE_FIXED;
+    const RawBufferPtr CTX = create_raw_buffer(createRandomBufferCAPI(12));
+    const RawBufferPtr LAB = create_raw_buffer(createRandomBufferCAPI(16));
+
+    auto derivationParams = createParamListPtr();
+    setParam(derivationParams, CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_KBKDF);
+    setParam(derivationParams, CKMC_PARAM_KDF_LEN, U32);
+    setParam(derivationParams, CKMC_PARAM_KDF_PRF, HMAC256);
+    setParam(derivationParams, CKMC_PARAM_KBKDF_MODE, COUNTER);
+    setParam(derivationParams, CKMC_PARAM_KBKDF_COUNTER_LOCATION, BEFORE);
+    setParam(derivationParams, CKMC_PARAM_KBKDF_CONTEXT, CTX.get());
+    setParam(derivationParams, CKMC_PARAM_KBKDF_LABEL, LAB.get());
+
+    return derivationParams;
+}
+
+ParamListPtr generateEncryptionParams()
+{
+    ckmc_param_list_h handle = nullptr;
+    assert_positive(ckmc_generate_new_params, CKMC_ALGO_AES_CBC, &handle);
+    auto encryptionParams = ParamListPtr(handle, ckmc_param_list_free);
+    ckmc_raw_buffer_s* DEFAULT_IV = createRandomBufferCAPI(16);
+    setParam(encryptionParams, CKMC_PARAM_ED_IV, DEFAULT_IV);
+    return encryptionParams;
+}
+
+void checkDataMatching(const char* dataAlias1, const char* password1,
+                       const char* dataAlias2, const char* password2)
+{
+    const char* DERIVED_ALIAS1 = "derived1";
+    const char* DERIVED_ALIAS2 = "derived2";
+
+    AliasRemover aliasRemovers[] = { DERIVED_ALIAS1, DERIVED_ALIAS2 };
+
+    auto derivationParams = generateDerivationParams();
+
+    assert_positive(ckmc_key_derive,
+                    derivationParams.get(),
+                    dataAlias1,
+                    password1,
+                    DERIVED_ALIAS1,
+                    NON_EXPORTABLE_POLICY);
+
+    assert_positive(ckmc_key_derive,
+                    derivationParams.get(),
+                    dataAlias2,
+                    password2,
+                    DERIVED_ALIAS2,
+                    NON_EXPORTABLE_POLICY);
+
+    const auto randomData = create_raw_buffer(createRandomBufferCAPI(16));
+    ckmc_raw_buffer_s* encrypted = nullptr;
+    auto encryptedPtr = create_raw_buffer(encrypted);
+    ckmc_raw_buffer_s* decrypted = nullptr;
+    auto decryptedPtr = create_raw_buffer(decrypted);
+
+    auto encryptionParams = generateEncryptionParams();
+
+    assert_positive(ckmc_encrypt_data,
+                    encryptionParams.get(),
+                    DERIVED_ALIAS1,
+                    nullptr,
+                    *randomData.get(),
+                    &encrypted);
+
+    assert_positive(ckmc_decrypt_data,
+                    encryptionParams.get(),
+                    DERIVED_ALIAS2,
+                    nullptr,
+                    *encrypted,
+                    &decrypted);
+
+    assert_buffers_equal(randomData.get(), decrypted);
+}
+
+class Data
+{
+public:
+    void Init()
+    {
+        error_msg_positive(ckmc_save_data, DATA_ALIASES_STORED, *data[1], NON_EXPORTABLE_POLICY);
+    }
+
+    void Finish()
+    {
+        error_msg_positive(ckmc_remove_alias, DATA_ALIASES_STORED);
+    }
+};
+
+class DataTestGroup : public Data, public DPL::Test::TestGroup, public OwnerUserEnv
+{
+public:
+    void Init() override
+    {
+        OwnerUserEnv::Init();
+        Data::Init();
+    }
+
+    void Finish() override
+    {
+        Data::Finish();
+        OwnerUserEnv::Finish();
+    }
+};
+
+} // namespace anonymous
+
+RUNNER_TEST_GROUP_INIT_ENV(CKM_UPDATE_API_DATA, DataTestGroup);
+
+RUNNER_TEST(TUA_0060_save_update_data)
+{
+    AliasRemover aliasRemovers(DATA_ALIASES_UPDATED);
+
+    assert_positive(ckmc_save_data, DATA_ALIASES_UPDATED,
+                    *data[0], NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_update_data, DATA_ALIASES_UPDATED,
+                    *data[1], NON_EXPORTABLE_POLICY);
+
+    checkDataMatching(DATA_ALIASES_UPDATED, NON_EXPORTABLE_POLICY.password,
+                      DATA_ALIASES_STORED, NON_EXPORTABLE_POLICY.password);
+}
+
+RUNNER_TEST(TUA_0061_update_update_data)
+{
+    AliasRemover aliasRemovers(DATA_ALIASES_UPDATED);
+
+    assert_positive(ckmc_update_data, DATA_ALIASES_UPDATED,
+                    *data[0], NON_EXPORTABLE_POLICY);
+
+    checkDataMatching(DATA_ALIASES_UPDATED, NON_EXPORTABLE_POLICY.password,
+                      DATA_ALIASES_UPDATED, NON_EXPORTABLE_POLICY.password);
+
+    assert_positive(ckmc_update_data, DATA_ALIASES_UPDATED, *data[1],
+                    NON_EXPORTABLE_POLICY);
+
+    checkDataMatching(DATA_ALIASES_UPDATED, NON_EXPORTABLE_POLICY.password,
+                      DATA_ALIASES_STORED, NON_EXPORTABLE_POLICY.password);
+}
+
+RUNNER_TEST(TUA_0062_save_update_data_with_another_exportability)
+{
+    AliasRemover aliasRemovers(DATA_ALIASES_UPDATED);
+
+    assert_positive(ckmc_save_data, DATA_ALIASES_UPDATED, *data[0], NON_EXPORTABLE_POLICY);
+    check_self_data_alias_info_list(false, Info(DATA_ALIASES_UPDATED, NON_EXPORTABLE_POLICY,
+                                                backend()));
+
+    assert_positive(ckmc_update_data, DATA_ALIASES_UPDATED, *data[1], EXPORTABLE_POLICY);
+    check_self_data_alias_info_list(false, Info(DATA_ALIASES_UPDATED, EXPORTABLE_POLICY,
+                                                backend()));
+
+    checkDataMatching(DATA_ALIASES_UPDATED, EXPORTABLE_POLICY.password,
+                      DATA_ALIASES_STORED, NON_EXPORTABLE_POLICY.password);
+
+    ckmc_raw_buffer_s *buffer = nullptr;
+    assert_positive(ckmc_get_data, DATA_ALIASES_UPDATED, EXPORTABLE_POLICY.password, &buffer);
+    auto bufferPtr = create_raw_buffer(buffer);
+    assert_buffers_equal(buffer, data[1].get());
+}
+
+RUNNER_TEST(TUA_0063_save_update_data_with_another_password)
+{
+    AliasRemover aliasRemovers(DATA_ALIASES_UPDATED);
+
+    assert_positive(ckmc_save_data, DATA_ALIASES_UPDATED,
+                    *data[0], NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_update_data, DATA_ALIASES_UPDATED,
+                    *data[1], NON_EXPORTABLE_PASSWORD_POLICY_0);
+
+    checkDataMatching(DATA_ALIASES_UPDATED, NON_EXPORTABLE_PASSWORD_POLICY_0.password,
+                      DATA_ALIASES_STORED, NON_EXPORTABLE_POLICY.password);
+
+    assert_positive(ckmc_update_data, DATA_ALIASES_UPDATED,
+                    *data[1], NON_EXPORTABLE_PASSWORD_POLICY_1);
+
+    checkDataMatching(DATA_ALIASES_UPDATED, NON_EXPORTABLE_PASSWORD_POLICY_1.password,
+                      DATA_ALIASES_STORED, NON_EXPORTABLE_POLICY.password);
+}
+
+RUNNER_TEST(TUA_0064_save_update_data_with_another_backend)
+{
+    AliasRemover aliasRemovers(DATA_ALIASES_UPDATED);
+
+    ckmSaveData(*data[0], DATA_ALIASES_UPDATED, TZ_POLICY);
+    check_self_data_alias_info_list(false, Info(DATA_ALIASES_UPDATED, TZ_POLICY, backend()));
+
+    ckmUpdateData(*data[1], DATA_ALIASES_UPDATED, SW_POLICY);
+    check_self_data_alias_info_list(false, Info(DATA_ALIASES_UPDATED, SW_POLICY,
+                                                CKM::BackendId::SW));
+
+    checkDataMatching(DATA_ALIASES_UPDATED, SW_POLICY.password.c_str(),
+                      DATA_ALIASES_STORED, NON_EXPORTABLE_POLICY.password);
+
+    ckmUpdateData(*data[1], DATA_ALIASES_UPDATED, TZ_POLICY);
+    check_self_data_alias_info_list(false, Info(DATA_ALIASES_UPDATED, TZ_POLICY, backend()));
+
+    checkDataMatching(DATA_ALIASES_UPDATED, TZ_POLICY.password.c_str(),
+                      DATA_ALIASES_STORED, NON_EXPORTABLE_POLICY.password);
+}
+
+RUNNER_TEST(TUA_0065_save_update_data_with_invalid_parameters)
+{
+    AliasRemover aliasRemovers(DATA_ALIASES_UPDATED);
+
+    assert_positive(ckmc_save_data, DATA_ALIASES_UPDATED, *data[0], NON_EXPORTABLE_POLICY);
+
+    assert_result(CKMC_ERROR_INVALID_PARAMETER, ckmc_update_data,
+                  nullptr, *data[1], NON_EXPORTABLE_POLICY);
+
+    auto wrongData = *data[0];
+    wrongData.size = 0;
+    assert_result(CKMC_ERROR_INVALID_PARAMETER, ckmc_update_data,
+                  DATA_ALIASES_UPDATED, wrongData, NON_EXPORTABLE_POLICY);
+
+    wrongData.size = data[0]->size;
+    wrongData.data = nullptr;
+    assert_result(CKMC_ERROR_INVALID_PARAMETER, ckmc_update_data,
+                  DATA_ALIASES_UPDATED, wrongData, NON_EXPORTABLE_POLICY);
+}
+
+RUNNER_TEST(TUA_0066_save_update_data_with_locked_db)
+{
+    AliasRemover aliasRemovers(DATA_ALIASES_UPDATED);
+
+    assert_positive(ckmc_save_data, DATA_ALIASES_UPDATED, *data[0], NON_EXPORTABLE_POLICY);
+
+    assert_positive(ckmc_lock_user_key, OWNER_USER_ID);
+    assert_result(CKMC_ERROR_DB_LOCKED, ckmc_update_data, DATA_ALIASES_UPDATED,
+                  *data[1], NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_unlock_user_key, OWNER_USER_ID, USER_PASSWORD);
+}
+
+namespace {
+
+struct CertificateAndKeyContext
+{
+    std::string certRawData;
+    CertPtr cert;
+    std::string keyRawData;
+    KeyPtr key;
+    const char* keyAlias;
+    const ckmc_policy_s keyPolicy;
+};
+
+std::array<CertificateAndKeyContext, 2> certificateAndKeyContexts = { {
+    {
+        "-----BEGIN CERTIFICATE-----\n"
+        "MIIDUzCCAxECCQCer/fKcXtJgTALBglghkgBZQMEAwIwgYsxCzAJBgNVBAYTAlBM\n"
+        "MQ8wDQYDVQQIDAZQb2xhbmQxDzANBgNVBAcMBldhcnNhdzEQMA4GA1UECgwHU2Ft\n"
+        "c3VuZzEMMAoGA1UECwwDS1NGMRMwEQYDVQQDDAptLmthcnBpdWsyMSUwIwYJKoZI\n"
+        "hvcNAQkBFhZtLmthcnBpdWsyQHNhbXN1bmcuY29tMCAXDTE0MDkyNjEzNTQwN1oY\n"
+        "DzIxNDAwOTA1MTM1NDA3WjCBizELMAkGA1UEBhMCUEwxDzANBgNVBAgMBlBvbGFu\n"
+        "ZDEPMA0GA1UEBwwGV2Fyc2F3MRAwDgYDVQQKDAdTYW1zdW5nMQwwCgYDVQQLDANL\n"
+        "U0YxEzARBgNVBAMMCm0ua2FycGl1azIxJTAjBgkqhkiG9w0BCQEWFm0ua2FycGl1\n"
+        "azJAc2Ftc3VuZy5jb20wggG3MIIBKwYHKoZIzjgEATCCAR4CgYEA9Bhh7ZA4onkY\n"
+        "uDNQbYR4EwkJ6RpD505hB0GF6yppUNp2LanvNcQXcyXY88MB6OdP7Rikbu1H2zP4\n"
+        "gONCtdxKW58Za7h9bFzYjxcObZsS52F9DP7sv3C4sX4xNWApfhUgbfzKaRCJOkOs\n"
+        "06tV7teu3G/v26PdI8dlykIuQXQZmH8CFQCHsIV0njb2yC3ggfKz+exH+g5jAQKB\n"
+        "gBVLYfVCMjUz5XJH+xYU3A8W8rpSLqZKIK2d9mbXqhpz8QK1bvNQUlSRZo+o1ZYV\n"
+        "mJn3Mx2YuiifHZNKdBNweCqe5a+HV2RSl1Yv/TV9famZKlogGslsmPHUOJMlSIdh\n"
+        "MfMwVny4/rNtjEtEFE1WnaTr1W6MKH1EBbizVo8fmWFrA4GFAAKBgQCaPjrlkAyX\n"
+        "kBitWo+w0xZN4OSk13SsCzZ/PG+5zOgMRaFm2XbiC04YsGCi4NFOd9kaiP7w1CsP\n"
+        "iqG6Vwv0T/VcoxBl/hp6jEqTDSrM6z0ungjDO9wGOdI+jZS0UjVahgC4ZLDHhrOa\n"
+        "CjfxcHruO3e416b/Rm2CjhOzjKdoSFUWVzALBglghkgBZQMEAwIDLwAwLAIUHa+A\n"
+        "5xo8O/tPuH9gXkr1mee6kRYCFGNycJ1xkc3nIJaEQOtGfDe7S71A\n"
+        "-----END CERTIFICATE-----\n",
+        createCertPtr(nullptr),
+        "-----BEGIN DSA PRIVATE KEY-----\n"
+        "MIIBuwIBAAKBgQD0GGHtkDiieRi4M1BthHgTCQnpGkPnTmEHQYXrKmlQ2nYtqe81\n"
+        "xBdzJdjzwwHo50/tGKRu7UfbM/iA40K13EpbnxlruH1sXNiPFw5tmxLnYX0M/uy/\n"
+        "cLixfjE1YCl+FSBt/MppEIk6Q6zTq1Xu167cb+/bo90jx2XKQi5BdBmYfwIVAIew\n"
+        "hXSeNvbILeCB8rP57Ef6DmMBAoGAFUth9UIyNTPlckf7FhTcDxbyulIupkogrZ32\n"
+        "ZteqGnPxArVu81BSVJFmj6jVlhWYmfczHZi6KJ8dk0p0E3B4Kp7lr4dXZFKXVi/9\n"
+        "NX19qZkqWiAayWyY8dQ4kyVIh2Ex8zBWfLj+s22MS0QUTVadpOvVbowofUQFuLNW\n"
+        "jx+ZYWsCgYEAmj465ZAMl5AYrVqPsNMWTeDkpNd0rAs2fzxvuczoDEWhZtl24gtO\n"
+        "GLBgouDRTnfZGoj+8NQrD4qhulcL9E/1XKMQZf4aeoxKkw0qzOs9Lp4IwzvcBjnS\n"
+        "Po2UtFI1WoYAuGSwx4azmgo38XB67jt3uNem/0Ztgo4Ts4ynaEhVFlcCFGMH+Z9l\n"
+        "vonbjii3BYe4AIdkzOvp\n"
+        "-----END DSA PRIVATE KEY-----\n",
+        createKeyPtr(nullptr),
+        "PRIVATE_KEY_0",
+        NON_EXPORTABLE_POLICY
+    },
+    {
+        "-----BEGIN CERTIFICATE-----\n"
+        "MIICijCCAfOgAwIBAgIJAMvaNHQ1ozT8MA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNV\n"
+        "BAYTAlBMMQ0wCwYDVQQIDARMb2R6MQ0wCwYDVQQHDARMb2R6MRAwDgYDVQQKDAdT\n"
+        "YW1zdW5nMREwDwYDVQQLDAhTZWN1cml0eTEMMAoGA1UEAwwDQ0tNMB4XDTE0MDcw\n"
+        "MjEyNDE0N1oXDTE3MDcwMTEyNDE0N1owXjELMAkGA1UEBhMCUEwxDTALBgNVBAgM\n"
+        "BExvZHoxDTALBgNVBAcMBExvZHoxEDAOBgNVBAoMB1NhbXN1bmcxETAPBgNVBAsM\n"
+        "CFNlY3VyaXR5MQwwCgYDVQQDDANDS00wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ\n"
+        "AoGBAMIpv0GRN06MJNco+L8fkVIa7KuDM5EG1HecJODtJGcvjvM0YSOXbCSCxj1k\n"
+        "7dQkebSDLkoyNZ4K5RWRIPcbjon2huDVtgmK8JAEkrF+J4DyxY602rUzx6YcYryj\n"
+        "eyNpGSWueCaTbFIKzm8UlWUKW7MBhSas8ObrgLf6fjJbikEJAgMBAAGjUDBOMB0G\n"
+        "A1UdDgQWBBQuW9DuITahZJ6saVZZI0aBlis5vzAfBgNVHSMEGDAWgBQuW9DuITah\n"
+        "ZJ6saVZZI0aBlis5vzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAB2X\n"
+        "GNtJopBJR3dCpzDONknr/c6qcsPVa3nH4c7qzy6F+4bgqa5IObnoF8zUrvD2sMAO\n"
+        "km3C/N+Qzt8Rb7ORM6U4tlPp1kZ5t6PKjghhNaiYwVm9A/Zm+wyAmRIkQiYDr4MX\n"
+        "e+bRAkPmJeEWpaav1lvvBnFzGSGJrnSSeWUegGyn\n"
+        "-----END CERTIFICATE-----\n",
+        createCertPtr(nullptr),
+        "-----BEGIN RSA PRIVATE KEY-----\n"
+        "MIICXQIBAAKBgQDCKb9BkTdOjCTXKPi/H5FSGuyrgzORBtR3nCTg7SRnL47zNGEj\n"
+        "l2wkgsY9ZO3UJHm0gy5KMjWeCuUVkSD3G46J9obg1bYJivCQBJKxfieA8sWOtNq1\n"
+        "M8emHGK8o3sjaRklrngmk2xSCs5vFJVlCluzAYUmrPDm64C3+n4yW4pBCQIDAQAB\n"
+        "AoGAd1IWgiHO3kuLvFome7XXpaB8P27SutZ6rcLcewnhLDRy4g0XgTrmL43abBJh\n"
+        "gdSkooVXZity/dvuKpHUs2dQ8W8zYiFFsHfu9qqLmLP6SuBPyUCvlUDH5BGfjjxI\n"
+        "5qGWIowj/qGHKpbQ7uB+Oe2BHwbHao0zFZIkfKqY0mX9U00CQQDwF/4zQcGS1RX/\n"
+        "229gowTsvSGVmm8cy1jGst6xkueEuOEZ/AVPO1fjavz+nTziUk4E5lZHAj18L6Hl\n"
+        "iO29LRujAkEAzwbEWVhfTJewCZIFf3sY3ifXhGZhVKDHVzPBNyoft8Z+09DMHTJb\n"
+        "EYg85MIbR73aUyIWsEci/CPk6LPRNv47YwJAHtQF2NEFqPPhakPjzjXAaSFz0YDN\n"
+        "6ZWWpZTMEWL6hUkz5iE9EUpeY54WNB8+dRT6XZix1VZNTMfU8uMdG6BSHwJBAKYM\n"
+        "gm47AGz5eVujwD8op6CACk+KomRzdI+P1lh9s+T+E3mnDiAY5IxiXp0Ix0K6lyN4\n"
+        "wwPuerQLwi2XFKZsMYsCQQDOiSQFP9PfXh9kFzN6e89LxOdnqC/r9i5GDB3ea8eL\n"
+        "SCRprpzqOXZvOP1HBAEjsJ6k4f8Dqj1fm+y8ZcgAZUPr\n"
+        "-----END RSA PRIVATE KEY-----\n",
+        createKeyPtr(nullptr),
+        "PRIVATE_KEY_1",
+        NON_EXPORTABLE_POLICY
+    }
+} };
+
+const char* certificateAlias = "CERTIFICATE";
+
+class Certificates
+{
+public:
+    void Init()
+    {
+        for (auto& certificateAndKeyContext : certificateAndKeyContexts)
+        {
+            ckmc_cert_s* cert = nullptr;
+            error_msg_positive(ckmc_cert_new,
+                reinterpret_cast<unsigned char*>(const_cast<char*>(
+                    certificateAndKeyContext.certRawData.data())),
+                certificateAndKeyContext.certRawData.size(), CKMC_FORM_PEM, &cert);
+            certificateAndKeyContext.cert = createCertPtr(cert);
+
+            ckmc_key_s* key = nullptr;
+            error_msg_positive(ckmc_key_new,
+                reinterpret_cast<unsigned char*>(const_cast<char*>(
+                    certificateAndKeyContext.keyRawData.data())),
+                certificateAndKeyContext.keyRawData.size(), CKMC_KEY_NONE, nullptr, &key);
+            certificateAndKeyContext.key = createKeyPtr(key);
+
+            error_msg_positive(ckmc_save_key, certificateAndKeyContext.keyAlias,
+                               *certificateAndKeyContext.key, certificateAndKeyContext.keyPolicy);
+        }
+    }
+
+    void Finish()
+    {
+        for (const auto& certificate : certificateAndKeyContexts)
+        {
+            error_msg_positive(ckmc_remove_alias, certificate.keyAlias);
+        }
+    }
+};
+
+class CertificatesTestGroup : public Certificates, public DPL::Test::TestGroup, public OwnerUserEnv
+{
+public:
+    void Init() override
+    {
+        OwnerUserEnv::Init();
+        Certificates::Init();
+    }
+
+    void Finish() override
+    {
+        Certificates::Finish();
+        OwnerUserEnv::Finish();
+    }
+};
+
+} // namespace anonymous
+
+RUNNER_TEST_GROUP_INIT_ENV(CKM_UPDATE_API_CERT, CertificatesTestGroup);
+
+RUNNER_TEST(TUA_0070_save_update_cert)
+{
+    AliasRemover aliasRemover(certificateAlias);
+
+    assert_positive(ckmc_save_cert, certificateAlias, *certificateAndKeyContexts[0].cert,
+                    NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_update_cert, certificateAlias, *certificateAndKeyContexts[1].cert,
+                    NON_EXPORTABLE_POLICY);
+
+    checkSignatureVerification(certificateAndKeyContexts[1].keyAlias,
+                               certificateAndKeyContexts[1].keyPolicy.password,
+                               certificateAlias, NON_EXPORTABLE_POLICY.password);
+}
+
+RUNNER_TEST(TUA_0071_update_update_cert)
+{
+    AliasRemover aliasRemover(certificateAlias);
+
+    assert_positive(ckmc_update_cert, certificateAlias,
+                    *certificateAndKeyContexts[0].cert, NON_EXPORTABLE_POLICY);
+
+    checkSignatureVerification(certificateAndKeyContexts[0].keyAlias,
+                               certificateAndKeyContexts[0].keyPolicy.password,
+                               certificateAlias, NON_EXPORTABLE_POLICY.password);
+
+    assert_positive(ckmc_update_cert, certificateAlias,
+                    *certificateAndKeyContexts[1].cert, NON_EXPORTABLE_POLICY);
+
+    checkSignatureVerification(certificateAndKeyContexts[1].keyAlias,
+                               certificateAndKeyContexts[1].keyPolicy.password,
+                               certificateAlias, NON_EXPORTABLE_POLICY.password);
+}
+
+RUNNER_TEST(TUA_0072_save_update_cert_with_another_exportability)
+{
+    AliasRemover aliasRemover(certificateAlias);
+
+    assert_positive(ckmc_save_cert, certificateAlias,
+                    *certificateAndKeyContexts[0].cert, NON_EXPORTABLE_POLICY);
+    check_self_certificate_alias_info_list(false, Info(certificateAlias,
+                                                       NON_EXPORTABLE_POLICY,
+                                                       CKM::BackendId::SW));
+
+    assert_positive(ckmc_update_cert, certificateAlias,
+                    *certificateAndKeyContexts[1].cert, EXPORTABLE_POLICY);
+    check_self_certificate_alias_info_list(false, Info(certificateAlias,
+                                                       EXPORTABLE_POLICY,
+                                                       CKM::BackendId::SW));
+
+    checkSignatureVerification(certificateAndKeyContexts[1].keyAlias,
+                               certificateAndKeyContexts[1].keyPolicy.password,
+                               certificateAlias, EXPORTABLE_POLICY.password);
+
+    ckmc_cert_s *cert = nullptr;
+    assert_positive(ckmc_get_cert, certificateAlias, EXPORTABLE_POLICY.password, &cert);
+    auto certPtr = createCertPtr(cert);
+}
+
+RUNNER_TEST(TUA_0073_save_update_cert_with_another_password)
+{
+    AliasRemover aliasRemover(certificateAlias);
+
+    assert_positive(ckmc_save_cert, certificateAlias,
+                    *certificateAndKeyContexts[0].cert, NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_update_cert, certificateAlias, *certificateAndKeyContexts[1].cert,
+                    NON_EXPORTABLE_PASSWORD_POLICY_0);
+
+    checkSignatureVerification(certificateAndKeyContexts[1].keyAlias,
+                               certificateAndKeyContexts[1].keyPolicy.password,
+                               certificateAlias, NON_EXPORTABLE_PASSWORD_POLICY_0.password);
+
+    assert_positive(ckmc_update_cert, certificateAlias,
+                    *certificateAndKeyContexts[1].cert, NON_EXPORTABLE_PASSWORD_POLICY_1);
+
+    checkSignatureVerification(certificateAndKeyContexts[1].keyAlias,
+                               certificateAndKeyContexts[1].keyPolicy.password,
+                               certificateAlias, NON_EXPORTABLE_PASSWORD_POLICY_1.password);
+}
+
+RUNNER_TEST(TUA_0075_save_update_cert_with_invalid_parameters)
+{
+    AliasRemover aliasRemover(certificateAlias);
+
+    assert_positive(ckmc_save_cert, certificateAlias,
+                    *certificateAndKeyContexts[0].cert, NON_EXPORTABLE_POLICY);
+
+    assert_result(CKMC_ERROR_INVALID_PARAMETER, ckmc_update_cert, nullptr,
+                  *certificateAndKeyContexts[1].cert, NON_EXPORTABLE_POLICY);
+
+    auto wrongCert = *certificateAndKeyContexts[1].cert;
+    wrongCert.cert_size = 0;
+    assert_result(CKMC_ERROR_INVALID_PARAMETER, ckmc_update_cert,
+                  certificateAlias, wrongCert, NON_EXPORTABLE_POLICY);
+
+    wrongCert.cert_size = certificateAndKeyContexts[1].cert->cert_size;
+    wrongCert.raw_cert = nullptr;
+    assert_result(CKMC_ERROR_INVALID_PARAMETER, ckmc_update_cert,
+                  certificateAlias, wrongCert, NON_EXPORTABLE_POLICY);
+}
+
+RUNNER_TEST(TUA_0076_save_update_cert_with_locked_db)
+{
+    AliasRemover aliasRemover(certificateAlias);
+
+    assert_positive(ckmc_save_cert, certificateAlias,
+                    *certificateAndKeyContexts[0].cert, NON_EXPORTABLE_POLICY);
+
+    assert_positive(ckmc_lock_user_key, OWNER_USER_ID);
+    assert_result(CKMC_ERROR_DB_LOCKED, ckmc_update_cert, certificateAlias,
+                  *certificateAndKeyContexts[1].cert, NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_unlock_user_key, OWNER_USER_ID, USER_PASSWORD);
+}
+
+RUNNER_TEST(TUA_0077_save_update_wrong_cert)
+{
+    AliasRemover aliasRemover(certificateAlias);
+
+    assert_positive(ckmc_save_cert, certificateAlias,
+                    *certificateAndKeyContexts[0].cert, NON_EXPORTABLE_POLICY);
+
+    ckmc_cert_s wrongCertificate = {
+        WRONG_RAW_DATA, std::size(WRONG_RAW_DATA), CKMC_FORM_PEM
+    };
+    assert_result(CKMC_ERROR_INVALID_FORMAT, ckmc_update_cert, certificateAlias,
+                  wrongCertificate, NON_EXPORTABLE_POLICY);
+}
+
+namespace {
+
+const char* PKCS12_ALIAS = "PKCS12_ALIAS";
+ckmc_pkcs12_s* pkcs12 = nullptr;
+
+KeyPtr rsaPrivateKey = createKeyPtr(nullptr);
+
+class PKCS12Archive : public Certificates
+{
+public:
+    void Init()
+    {
+        Certificates::Init();
+        error_msg_positive(ckmc_create_key_pair_rsa, RSA_KEY_SIZE,
+                           RSA_PRIVATE_KEY_ALIAS, RSA_PUBLIC_KEY_ALIAS,
+                           EXPORTABLE_POLICY, EXPORTABLE_POLICY);
+
+        ckmc_key_s *key = nullptr;
+        error_msg_positive(ckmc_get_key, RSA_PRIVATE_KEY_ALIAS,
+                           EXPORTABLE_POLICY.password, &key);
+        rsaPrivateKey = createKeyPtr(key);
+
+        error_msg_positive(ckmc_pkcs12_load, CKM_TEST_DIR "/pkcs.p12", nullptr, &pkcs12);
+        m_pkcs12 = createPKCS12Ptr(pkcs12);
+    }
+
+    void Finish()
+    {
+        Certificates::Finish();
+        error_msg_positive(ckmc_remove_alias, RSA_PRIVATE_KEY_ALIAS);
+        error_msg_positive(ckmc_remove_alias, RSA_PUBLIC_KEY_ALIAS);
+    }
+
+private:
+    PKSC12Ptr m_pkcs12 = createPKCS12Ptr(nullptr);
+};
+
+class PKCS12TestGroup : public PKCS12Archive,
+                        public DPL::Test::TestGroup, public OwnerUserEnv
+{
+public:
+    void Init() override
+    {
+        OwnerUserEnv::Init();
+        PKCS12Archive::Init();
+    }
+
+    void Finish() override
+    {
+        PKCS12Archive::Finish();
+        OwnerUserEnv::Finish();
+    }
+};
+
+} // namespace anonymous
+
+RUNNER_TEST_GROUP_INIT_ENV(CKM_UPDATE_API_PKCS12, PKCS12TestGroup);
+
+RUNNER_TEST(TUA_0080_save_update_PKCS12_key)
+{
+    AliasRemover aliasRemover(PKCS12_ALIAS);
+
+    assert_positive(ckmc_save_pkcs12, PKCS12_ALIAS, pkcs12,
+                    NON_EXPORTABLE_POLICY, NON_EXPORTABLE_POLICY);
+
+    auto keyBackup = pkcs12->priv_key;
+
+    pkcs12->priv_key = rsaPrivateKey.get();
+    assert_positive(ckmc_update_pkcs12, PKCS12_ALIAS, pkcs12,
+                    NON_EXPORTABLE_POLICY, NON_EXPORTABLE_POLICY);
+    checkRSAKeysMatching(PKCS12_ALIAS, NON_EXPORTABLE_POLICY.password,
+                         RSA_PUBLIC_KEY_ALIAS, EXPORTABLE_POLICY.password);
+
+    pkcs12->priv_key = keyBackup;
+}
+
+RUNNER_TEST(TUA_0081_save_update_PKCS12_cert)
+{
+    AliasRemover aliasRemover(PKCS12_ALIAS);
+
+    assert_positive(ckmc_save_pkcs12, PKCS12_ALIAS, pkcs12,
+                    EXPORTABLE_POLICY, EXPORTABLE_POLICY);
+
+    auto certBackup = pkcs12->cert;
+
+    pkcs12->cert = certificateAndKeyContexts[0].cert.get();
+    assert_positive(ckmc_update_pkcs12, PKCS12_ALIAS, pkcs12,
+                    EXPORTABLE_POLICY, EXPORTABLE_POLICY);
+    checkSignatureVerification(certificateAndKeyContexts[0].keyAlias, EXPORTABLE_POLICY.password,
+                               PKCS12_ALIAS, EXPORTABLE_POLICY.password);
+
+    pkcs12->cert = certBackup;
+}
+
+RUNNER_TEST(TUA_0082_save_update_PKCS12_ca)
+{
+    AliasRemover aliasRemover = PKCS12_ALIAS;
+    const char* pkcs12TempAlias = "PKCS12_TEMP";
+
+    assert_positive(ckmc_save_pkcs12, PKCS12_ALIAS, pkcs12,
+                    EXPORTABLE_POLICY, EXPORTABLE_POLICY);
+
+    auto caChainBackup = pkcs12->ca_chain;
+
+    ckmc_pkcs12_s* pkcs12Updated = nullptr;
+    pkcs12->ca_chain = nullptr;
+    assert_positive(ckmc_update_pkcs12, PKCS12_ALIAS, pkcs12,
+                    EXPORTABLE_POLICY, EXPORTABLE_POLICY);
+    assert_positive(ckmc_get_pkcs12, PKCS12_ALIAS, nullptr, nullptr, &pkcs12Updated);
+    auto pkcs12UpdatedPtr = createPKCS12Ptr(pkcs12Updated);
+    auto length = getListLength(pkcs12Updated->ca_chain);
+    RUNNER_ASSERT_MSG(length == 0, "ca chain should have zero length, but got length = "
+                      << length);
+    assert_pkcs12_equal(pkcs12, pkcs12Updated);
+
+    ckmc_cert_list_s** curr = &pkcs12->ca_chain;
+    const size_t caChainLength = 16;
+    for (size_t i = 1; i <= caChainLength; ++i)
+    {
+        ckmc_cert_list_s* node = new ckmc_cert_list_s();
+        node->cert = certificateAndKeyContexts[i % 2].cert.get();
+        node->next = nullptr;
+        *curr = node;
+        curr = &node->next;
+
+        assert_positive(ckmc_update_pkcs12, PKCS12_ALIAS, pkcs12,
+                        EXPORTABLE_POLICY, EXPORTABLE_POLICY);
+        assert_positive(ckmc_get_pkcs12, PKCS12_ALIAS, nullptr, nullptr, &pkcs12Updated);
+        pkcs12UpdatedPtr = createPKCS12Ptr(pkcs12Updated);
+        length = getListLength(pkcs12Updated->ca_chain);
+        RUNNER_ASSERT_MSG(length == i, "ca chain should have length = " << i
+                          << ", but got length = " << length);
+
+        AliasRemover aliasRemover = pkcs12TempAlias;
+
+        assert_positive(ckmc_save_pkcs12, pkcs12TempAlias, pkcs12,
+                        EXPORTABLE_POLICY, EXPORTABLE_POLICY);
+        ckmc_pkcs12_s* pkcs12Temp = nullptr;
+        assert_positive(ckmc_get_pkcs12, pkcs12TempAlias, nullptr, nullptr, &pkcs12Temp);
+        auto pkcs12TempPtr = createPKCS12Ptr(pkcs12Temp);
+
+        assert_pkcs12_equal(pkcs12Temp, pkcs12Updated);
+    }
+
+    curr = &pkcs12->ca_chain;
+    for (size_t i = caChainLength; i >= 1; --i)
+    {
+        assert_positive(ckmc_update_pkcs12, PKCS12_ALIAS, pkcs12,
+                        EXPORTABLE_POLICY, EXPORTABLE_POLICY);
+        assert_positive(ckmc_get_pkcs12, PKCS12_ALIAS, nullptr, nullptr, &pkcs12Updated);
+        pkcs12UpdatedPtr = createPKCS12Ptr(pkcs12Updated);
+        length = getListLength(pkcs12Updated->ca_chain);
+        RUNNER_ASSERT_MSG(length == i, "ca chain should have length = " << i
+                          << ", but got length = " << length);
+
+        AliasRemover aliasRemover = pkcs12TempAlias;
+
+        assert_positive(ckmc_save_pkcs12, pkcs12TempAlias, pkcs12,
+                        EXPORTABLE_POLICY, EXPORTABLE_POLICY);
+        ckmc_pkcs12_s* pkcs12Temp = nullptr;
+        assert_positive(ckmc_get_pkcs12, pkcs12TempAlias, nullptr, nullptr, &pkcs12Temp);
+        auto pkcs12TempPtr = createPKCS12Ptr(pkcs12Temp);
+
+        assert_pkcs12_equal(pkcs12Temp, pkcs12Updated);
+
+        ckmc_cert_list_s* tempNext = (*curr)->next;
+        delete *curr;
+        *curr = tempNext;
+    }
+
+    assert_positive(ckmc_update_pkcs12, PKCS12_ALIAS, pkcs12,
+                    EXPORTABLE_POLICY, EXPORTABLE_POLICY);
+    assert_positive(ckmc_get_pkcs12, PKCS12_ALIAS, nullptr, nullptr, &pkcs12Updated);
+    pkcs12UpdatedPtr = createPKCS12Ptr(pkcs12Updated);
+    length = getListLength(pkcs12Updated->ca_chain);
+    RUNNER_ASSERT_MSG(length == 0, "ca chain should have zero length, but got length = "
+                      << length);
+    assert_pkcs12_equal(pkcs12, pkcs12Updated);
+
+    pkcs12->ca_chain = caChainBackup;
+}
+
+namespace {
+
+const char* ANY_TYPE_ALIAS = "ANY_TYPE_ALIAS";
+
+std::vector<ckmc_key_s> keys = { };
+
+void updatePKCS12(const char* alias, ckmc_pkcs12_s* pkcs12,
+                  const CertificateAndKeyContext& certificateAndKeyContext)
+{
+    auto keyBackup = pkcs12->priv_key;
+    auto certBackup = pkcs12->cert;
+
+    pkcs12->priv_key = certificateAndKeyContext.key.get();
+    pkcs12->cert = certificateAndKeyContext.cert.get();
+
+    assert_positive(ckmc_update_pkcs12, alias, pkcs12,
+                    NON_EXPORTABLE_POLICY, NON_EXPORTABLE_POLICY);
+    check_self_key_alias_info_list(false, Info(ANY_TYPE_ALIAS,
+                                               NON_EXPORTABLE_POLICY,
+                                               backend()));
+    check_self_certificate_alias_info_list(false, Info(ANY_TYPE_ALIAS,
+                                                       NON_EXPORTABLE_POLICY,
+                                                       CKM::BackendId::SW));
+    checkSignatureVerification(alias, NON_EXPORTABLE_POLICY.password,
+                               alias, NON_EXPORTABLE_POLICY.password);
+    checkSignatureVerification(certificateAndKeyContext.keyAlias,
+                               certificateAndKeyContext.keyPolicy.password,
+                               alias, NON_EXPORTABLE_POLICY.password);
+
+    pkcs12->priv_key = keyBackup;
+    pkcs12->cert = certBackup;
+}
+
+class AllTypes : public AESKeys, public RSAKeys, public DSAKeys, public ECDSAKeys, public KEMKeys,
+                 public Data, public PKCS12Archive
+{
+public:
+    void Init()
+    {
+        AESKeys::Init();
+        RSAKeys::Init();
+        DSAKeys::Init();
+        ECDSAKeys::Init();
+        KEMKeys::Init();
+        Data::Init();
+        PKCS12Archive::Init();
+
+        keys = {
+            *aesKeys[0].key,
+            *rsaKeys[0].privateKey.key,
+            *rsaKeys[0].publicKey.key,
+            *kemKeys[0].privateKey.key,
+            *kemKeys[0].publicKey.key,
+            *dsaKeys[0].privateKey.key,
+            *dsaKeys[0].publicKey.key,
+            *ecdsaKeys[0].privateKey.key,
+            *ecdsaKeys[0].publicKey.key
+        };
+    }
+
+    void Finish()
+    {
+        AESKeys::Finish();
+        RSAKeys::Finish();
+        DSAKeys::Finish();
+        ECDSAKeys::Finish();
+        KEMKeys::Finish();
+        Data::Finish();
+        PKCS12Archive::Finish();
+    }
+};
+
+class AllTypesTestGroup : public AllTypes, public DPL::Test::TestGroup, public OwnerUserEnv
+{
+public:
+    void Init() override
+    {
+        OwnerUserEnv::Init();
+        AllTypes::Init();
+    }
+
+    void Finish() override
+    {
+        AllTypes::Finish();
+        OwnerUserEnv::Finish();
+    }
+};
+
+} // namespace anonymous
+
+RUNNER_TEST_GROUP_INIT_ENV(CKM_UPDATE_API_DIFFERENT_TYPES, AllTypesTestGroup)
+
+RUNNER_TEST(TUA_0090_save_any_update_any)
+{
+    AliasRemover aliasRemover(ANY_TYPE_ALIAS);
+
+    // save pkcs12
+    updatePKCS12(ANY_TYPE_ALIAS, pkcs12, certificateAndKeyContexts[0]);
+
+    // update pkcs12 with aes key
+    assert_positive(ckmc_update_key, ANY_TYPE_ALIAS, *aesKeys[0].key, NON_EXPORTABLE_POLICY);
+    check_self_key_alias_info_list(false, Info(ANY_TYPE_ALIAS,
+                                               NON_EXPORTABLE_POLICY,
+                                               backend()));
+    checkAESKeysMatching(aesKeys[0].alias, aesKeys[0].policy.password,
+                         ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password);
+    ckmc_cert_s *cert = nullptr;
+    assert_db_alias_unknown(ckmc_get_cert, ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password, &cert);
+
+    // update aes key with certificate
+    assert_positive(ckmc_update_cert, ANY_TYPE_ALIAS, *certificateAndKeyContexts[0].cert,
+                    NON_EXPORTABLE_POLICY);
+    check_self_certificate_alias_info_list(false, Info(ANY_TYPE_ALIAS,
+                                                       NON_EXPORTABLE_POLICY,
+                                                       CKM::BackendId::SW));
+    checkSignatureVerification(certificateAndKeyContexts[0].keyAlias,
+                               NON_EXPORTABLE_POLICY.password,
+                               ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password);
+    ckmc_key_s *key = nullptr;
+    assert_db_alias_unknown(ckmc_get_key, ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password, &key);
+
+    // update certificate with kem key
+    assert_positive(ckmc_update_key, ANY_TYPE_ALIAS,
+                    *kemKeys[0].privateKey.key, NON_EXPORTABLE_POLICY);
+    check_self_key_alias_info_list(false, Info(ANY_TYPE_ALIAS,
+                                               NON_EXPORTABLE_POLICY,
+                                               backend()));
+    checkKEMKeysMatching(ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password,
+                         kemKeys[0].publicKey.alias, kemKeys[0].publicKey.policy.password);
+    assert_db_alias_unknown(ckmc_get_cert, ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password, &cert);
+
+    // update kem key with data
+    assert_positive(ckmc_update_data, ANY_TYPE_ALIAS,
+                    *data[1], NON_EXPORTABLE_POLICY);
+    check_self_data_alias_info_list(false, Info(ANY_TYPE_ALIAS,
+                                                NON_EXPORTABLE_POLICY,
+                                                backend()));
+    checkDataMatching(ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password,
+                      DATA_ALIASES_STORED, NON_EXPORTABLE_POLICY.password);
+    assert_db_alias_unknown(ckmc_get_key, ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password, &key);
+
+    // update kem key with pkcs12
+    updatePKCS12(ANY_TYPE_ALIAS, pkcs12, certificateAndKeyContexts[1]);
+
+    // update pkcs12 with data
+    assert_positive(ckmc_update_data, ANY_TYPE_ALIAS,
+                    *data[1], NON_EXPORTABLE_POLICY);
+    check_self_data_alias_info_list(false, Info(ANY_TYPE_ALIAS,
+                                                NON_EXPORTABLE_POLICY,
+                                                backend()));
+    checkDataMatching(ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password,
+                      DATA_ALIASES_STORED, NON_EXPORTABLE_POLICY.password);
+    assert_db_alias_unknown(ckmc_get_key, ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password, &key);
+    assert_db_alias_unknown(ckmc_get_cert, ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password, &cert);
+
+    // update data with cert
+    assert_positive(ckmc_update_cert, ANY_TYPE_ALIAS, *certificateAndKeyContexts[1].cert,
+                    NON_EXPORTABLE_POLICY);
+    check_self_certificate_alias_info_list(false, Info(ANY_TYPE_ALIAS,
+                                                       NON_EXPORTABLE_POLICY,
+                                                       CKM::BackendId::SW));
+    checkSignatureVerification(certificateAndKeyContexts[1].keyAlias,
+                               NON_EXPORTABLE_POLICY.password,
+                               ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password);
+    ckmc_raw_buffer_s* buffer = NULL;
+    assert_db_alias_unknown(ckmc_get_data, ANY_TYPE_ALIAS,
+                            NON_EXPORTABLE_POLICY.password, &buffer);
+
+    // update cert with ecdsa key
+    assert_positive(ckmc_update_key, ANY_TYPE_ALIAS, *ecdsaKeys[0].privateKey.key,
+                    NON_EXPORTABLE_POLICY);
+    check_self_key_alias_info_list(false, Info(ANY_TYPE_ALIAS,
+                                               NON_EXPORTABLE_POLICY,
+                                               backend()));
+    checkSignatureVerification(ANY_TYPE_ALIAS, EXPORTABLE_POLICY.password,
+                               ecdsaKeys[0].publicKey.alias,
+                               ecdsaKeys[0].publicKey.policy.password);
+    assert_db_alias_unknown(ckmc_get_cert, ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password, &cert);
+
+    // update ecdsa key with pkcs12
+    updatePKCS12(ANY_TYPE_ALIAS, pkcs12, certificateAndKeyContexts[0]);
+}
+
+RUNNER_TEST(TUA_0091_save_any_update_AES_key)
+{
+    for (const auto& key : keys)
+    {
+        AliasRemover aliasRemover(ANY_TYPE_ALIAS);
+
+        assert_positive(ckmc_save_key, ANY_TYPE_ALIAS, key, NON_EXPORTABLE_POLICY);
+        assert_positive(ckmc_update_key, ANY_TYPE_ALIAS, *aesKeys[1].key, NON_EXPORTABLE_POLICY);
+
+        checkAESKeysMatching(aesKeys[1].alias, aesKeys[1].policy.password,
+                             ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password);
+    }
+
+    for (const auto& rawData : data)
+    {
+        AliasRemover aliasRemovers(ANY_TYPE_ALIAS);
+
+        assert_positive(ckmc_save_data, ANY_TYPE_ALIAS,
+                        *rawData, NON_EXPORTABLE_POLICY);
+        assert_positive(ckmc_update_key, ANY_TYPE_ALIAS, *aesKeys[1].key, NON_EXPORTABLE_POLICY);
+
+        checkAESKeysMatching(aesKeys[1].alias, aesKeys[1].policy.password,
+                             ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password);
+    }
+
+    for (const auto& certificateAndKeyContext : certificateAndKeyContexts)
+    {
+        AliasRemover aliasRemovers(ANY_TYPE_ALIAS);
+
+        assert_positive(ckmc_save_cert, ANY_TYPE_ALIAS,
+                        *certificateAndKeyContext.cert, NON_EXPORTABLE_POLICY);
+        assert_positive(ckmc_update_key, ANY_TYPE_ALIAS, *aesKeys[1].key, NON_EXPORTABLE_POLICY);
+
+        checkAESKeysMatching(aesKeys[1].alias, aesKeys[1].policy.password,
+                             ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password);
+    }
+
+    AliasRemover aliasRemover(ANY_TYPE_ALIAS);
+
+    assert_positive(ckmc_save_pkcs12, ANY_TYPE_ALIAS, pkcs12,
+                    NON_EXPORTABLE_POLICY, NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_update_key, ANY_TYPE_ALIAS, *aesKeys[1].key, NON_EXPORTABLE_POLICY);
+
+    checkAESKeysMatching(aesKeys[1].alias, aesKeys[1].policy.password,
+                         ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password);
+
+    ckmc_cert_s *cert = nullptr;
+    assert_db_alias_unknown(ckmc_get_cert, ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password, &cert);
+}
+
+RUNNER_TEST(TUA_0092_save_any_update_data)
+{
+    for (const auto& key : keys)
+    {
+        AliasRemover aliasRemovers(ANY_TYPE_ALIAS);
+
+        assert_positive(ckmc_save_key, ANY_TYPE_ALIAS,
+                        key, NON_EXPORTABLE_POLICY);
+        assert_positive(ckmc_update_data, ANY_TYPE_ALIAS,
+                        *data[1], NON_EXPORTABLE_POLICY);
+
+        checkDataMatching(ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password,
+                          DATA_ALIASES_STORED, NON_EXPORTABLE_POLICY.password);
+    }
+
+    for (const auto& certificateAndKeyContext : certificateAndKeyContexts)
+    {
+        AliasRemover aliasRemovers(ANY_TYPE_ALIAS);
+
+        assert_positive(ckmc_save_cert, ANY_TYPE_ALIAS,
+                        *certificateAndKeyContext.cert, NON_EXPORTABLE_POLICY);
+        assert_positive(ckmc_update_data, ANY_TYPE_ALIAS,
+                        *data[1], NON_EXPORTABLE_POLICY);
+
+        checkDataMatching(ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password,
+                          DATA_ALIASES_STORED, NON_EXPORTABLE_POLICY.password);
+    }
+
+    AliasRemover aliasRemover(ANY_TYPE_ALIAS);
+
+    assert_positive(ckmc_save_pkcs12, ANY_TYPE_ALIAS, pkcs12,
+                    NON_EXPORTABLE_POLICY, NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_update_data, ANY_TYPE_ALIAS,
+                    *data[1], NON_EXPORTABLE_POLICY);
+
+    checkDataMatching(ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password,
+                      DATA_ALIASES_STORED, NON_EXPORTABLE_POLICY.password);
+
+    ckmc_key_s *key = nullptr;
+    assert_db_alias_unknown(ckmc_get_key, ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password, &key);
+    ckmc_cert_s *cert = nullptr;
+    assert_db_alias_unknown(ckmc_get_cert, ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password, &cert);
+}
+
+RUNNER_TEST(TUA_0093_save_any_update_cert)
+{
+    for (const auto& key : keys)
+    {
+        AliasRemover aliasRemover(ANY_TYPE_ALIAS);
+
+        assert_positive(ckmc_save_key, ANY_TYPE_ALIAS,
+                        key, NON_EXPORTABLE_POLICY);
+        assert_positive(ckmc_update_cert, ANY_TYPE_ALIAS, *certificateAndKeyContexts[1].cert,
+                        NON_EXPORTABLE_POLICY);
+
+        checkSignatureVerification(certificateAndKeyContexts[1].keyAlias,
+                                   NON_EXPORTABLE_POLICY.password,
+                                   ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password);
+    }
+
+    for (const auto& rawData : data)
+    {
+        AliasRemover aliasRemover(ANY_TYPE_ALIAS);
+
+        assert_positive(ckmc_save_data, ANY_TYPE_ALIAS,
+                        *rawData, NON_EXPORTABLE_POLICY);
+        assert_positive(ckmc_update_cert, ANY_TYPE_ALIAS, *certificateAndKeyContexts[1].cert,
+                        NON_EXPORTABLE_POLICY);
+
+        checkSignatureVerification(certificateAndKeyContexts[1].keyAlias,
+                                   NON_EXPORTABLE_POLICY.password,
+                                   ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password);
+    }
+
+    AliasRemover aliasRemover(ANY_TYPE_ALIAS);
+
+    assert_positive(ckmc_save_pkcs12, ANY_TYPE_ALIAS, pkcs12,
+                    NON_EXPORTABLE_POLICY, NON_EXPORTABLE_POLICY);
+    assert_positive(ckmc_update_cert, ANY_TYPE_ALIAS, *certificateAndKeyContexts[1].cert,
+                    NON_EXPORTABLE_POLICY);
+
+    checkSignatureVerification(certificateAndKeyContexts[1].keyAlias,
+                               NON_EXPORTABLE_POLICY.password,
+                               ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password);
+
+    ckmc_key_s *key = nullptr;
+    assert_db_alias_unknown(ckmc_get_key, ANY_TYPE_ALIAS, NON_EXPORTABLE_POLICY.password, &key);
+}
+
+RUNNER_TEST(TUA_0094_save_any_update_PKCS12)
+{
+    for (const auto& key : keys)
+    {
+        AliasRemover aliasRemover(ANY_TYPE_ALIAS);
+
+        assert_positive(ckmc_save_key, ANY_TYPE_ALIAS, key, NON_EXPORTABLE_POLICY);
+
+        updatePKCS12(ANY_TYPE_ALIAS, pkcs12, certificateAndKeyContexts[0]);
+    }
+
+    for (const auto& rawData : data)
+    {
+        AliasRemover aliasRemover(ANY_TYPE_ALIAS);
+
+        assert_positive(ckmc_save_data, ANY_TYPE_ALIAS,
+                        *rawData, NON_EXPORTABLE_POLICY);
+
+        updatePKCS12(ANY_TYPE_ALIAS, pkcs12, certificateAndKeyContexts[0]);
+    }
+
+    for (const auto& certificateAndKeyContext : certificateAndKeyContexts)
+    {
+        AliasRemover aliasRemover(ANY_TYPE_ALIAS);
+
+        assert_positive(ckmc_save_cert, ANY_TYPE_ALIAS,
+                        *certificateAndKeyContext.cert, NON_EXPORTABLE_POLICY);
+
+        updatePKCS12(ANY_TYPE_ALIAS, pkcs12, certificateAndKeyContexts[0]);
+    }
+}