Spring cleaning
[platform/core/test/security-tests.git] / src / ckm / ckm-common.cpp
index 19020c1..c50f2d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000-2020 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.
  * @version    1.0
  */
 #include <string>
-
+#include <fstream>
 #include <sys/smack.h>
+#include <ckm/ckm-type.h>
 #include <ckmc/ckmc-type.h>
 #include <ckm-common.h>
 #include <tests_common.h>
-#include <access_provider2.h>
 #include <ckm/ckm-control.h>
 #include <ckm/ckm-manager.h>
 #include <ckmc/ckmc-control.h>
 #include <ckmc/ckmc-manager.h>
-#include <service_manager.h>
-
-const char* SERVICE[] = {
-        "central-key-manager-listener.service",
-        "central-key-manager.service" };
-
-void start_service(ServiceIdx idx)
-{
-    ServiceManager sm(SERVICE[idx]);
-    sm.startService();
-}
-
-void stop_service(ServiceIdx idx)
-{
-    ServiceManager sm(SERVICE[idx]);
-    sm.stopService();
-}
-
+#include <fcntl.h>
+#include <unistd.h>
+#include <unordered_map>
 
-void switch_to_storage_user(const char* label)
-{
-    AccessProvider ap(label);
-    ap.allowAPI("key-manager::api-storage", "rw");
-    ap.applyAndSwithToUser(APP_UID, APP_GID);
-}
+const std::string SMACK_USER_APP_PREFIX = "User::Pkg::";
+const char *SYSTEM_LABEL = ckmc_owner_id_system;
+const char *TEST_LABEL = "test_label";
+const char *TEST_LABEL_2 = "test_label_2";
+const char *TEST_LABEL_3 = "test_label_3";
+const char *TEST_LABEL_4 = "test_label_4";
+const char *TEST_LABEL_5 = "test_label_5";
 
-void switch_to_storage_ocsp_user(const char* label)
+void generate_random(size_t random_bytes, char *output)
 {
-    AccessProvider ap(label);
-    ap.allowAPI("key-manager::api-storage", "rw");
-    ap.allowAPI("key-manager::api-ocsp", "rw");
-    ap.applyAndSwithToUser(APP_UID, APP_GID);
-}
+    RUNNER_ASSERT(random_bytes>0 && output);
 
-DBCleanup::~DBCleanup()
-{
-    // Let it throw. If db can't be cleared further tests are unreliable
-    CKM::ManagerShPtr mgr = CKM::Manager::create();
-    for(const auto& it:m_aliases)
-        mgr->removeAlias(it);
-    m_aliases.clear();
+    std::ifstream is("/dev/urandom", std::ifstream::binary);
+    RUNNER_ASSERT_MSG(is, "Failed to read /dev/urandom");
+    is.read(output, random_bytes);
+    if(static_cast<std::streamsize>(random_bytes) != is.gcount()) {
+        RUNNER_ASSERT_MSG(false,
+                          "Not enough bytes read from /dev/urandom: " << random_bytes << "!=" <<
+                          is.gcount());
+    }
 }
 
-// returns process label
-CharPtr get_label()
-{
+std::string getLabel() {
     int ret;
-    char* my_label = NULL;
-    RUNNER_ASSERT_MSG(0 <= (ret = smack_new_label_from_self(&my_label)),
+    char* myLabel = NULL;
+    RUNNER_ASSERT_MSG(0 <= (ret = smack_new_label_from_self(&myLabel)),
                          "Failed to get smack label for self. Error: " << ret);
+    RUNNER_ASSERT_MSG(myLabel, "NULL smack label");
+    std::string result = myLabel;
+    free(myLabel);
+    return result;
+}
 
-    return CharPtr(my_label, free);
+std::string getOwnerIdFromSelf() {
+    const std::string& prefix = SMACK_USER_APP_PREFIX;
+    std::string smack = getLabel();
+    if (0 == smack.compare(0, prefix.size(), prefix))
+        return smack.substr(prefix.size(), std::string::npos);
+    return "/" + smack;
 }
 
 std::string aliasWithLabel(const char *label, const char *alias)
@@ -94,29 +85,16 @@ std::string aliasWithLabel(const char *label, const char *alias)
     return std::string(alias);
 }
 
-// changes process label
-void change_label(const char* label)
+std::string aliasWithLabelFromSelf(const char *alias)
 {
-    int ret = smack_set_label_for_self(label);
-    RUNNER_ASSERT_MSG(0 == ret, "Error in smack_set_label_for_self. Error: " << ret);
-}
+    std::ostringstream oss;
+    oss << getOwnerIdFromSelf() << ckmc_label_name_separator << alias;
 
-ScopedLabel::ScopedLabel(const char* label) : m_original_label(get_label())
-{
-    change_label(label);
-}
-
-ScopedLabel::~ScopedLabel()
-{
-    /*
-     * Let it throw. If we can't restore label then remaining tests results will be
-     * unreliable anyway.
-     */
-    change_label(m_original_label.get());
+    return oss.str();
 }
 
-const char * CKMCErrorToString(int error) {
 #define ERRORDESCRIBE(name) case name: return #name
+const char * CKMCErrorToString(int error) {
     switch(error) {
         ERRORDESCRIBE(CKMC_ERROR_NONE);
         ERRORDESCRIBE(CKMC_ERROR_INVALID_PARAMETER);
@@ -139,11 +117,12 @@ const char * CKMCErrorToString(int error) {
         ERRORDESCRIBE(CKMC_ERROR_FILE_ACCESS_DENIED);
         ERRORDESCRIBE(CKMC_ERROR_NOT_EXPORTABLE);
         ERRORDESCRIBE(CKMC_ERROR_FILE_SYSTEM);
+        ERRORDESCRIBE(CKMC_ERROR_NOT_SUPPORTED);
         ERRORDESCRIBE(CKMC_ERROR_UNKNOWN);
         default: return "Error not defined";
     }
-#undef ERRORDESCRIBE
 }
+#undef ERRORDESCRIBE
 
 std::string CKMCReadableError(int error) {
     std::string output("Error: ");
@@ -153,22 +132,222 @@ std::string CKMCReadableError(int error) {
     return output;
 }
 
+void save_data(const char* alias, const char *data, size_t len, const char* password,
+               int expected_err, bool exportable)
+{
+    RUNNER_ASSERT(alias);
+    RUNNER_ASSERT(data);
+
+    ckmc_raw_buffer_s buffer;
+    buffer.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data));
+    buffer.size = len;
+    ckmc_policy_s policy;
+    policy.password = const_cast<char*>(password);
+    policy.extractable = exportable;
+    int ret = ckmc_save_data(alias, buffer, policy);
+    RUNNER_ASSERT_MSG(expected_err == ret, "Saving data failed. "
+                      << CKMCErrorToString(ret) << " while expected: "
+                      << CKMCErrorToString(expected_err));
+}
+
+void save_data(const char* alias, const char *data, int expected_err, bool exportable)
+{
+    save_data(alias, data, strlen(data), nullptr, expected_err, exportable);
+}
+
+void save_data(const char* alias, const char *data, size_t len, int expected_err, bool exportable)
+{
+    save_data(alias, data, len, nullptr, expected_err, exportable);
+}
+
+ScopedSaveData::ScopedSaveData(const char* alias, const char *data, int expected_err) : m_alias(alias)
+{
+    save_data(alias, data, expected_err);
+}
+
+ScopedSaveData::~ScopedSaveData()
+{
+    /*
+     * Let it throw. If we can't remove data then remaining tests results will be
+     * unreliable anyway.
+     */
+    check_remove_allowed(m_alias.c_str());
+}
+
+ScopedDBUnlock::ScopedDBUnlock(uid_t user_id, const char* passwd) : m_uid(user_id)
+{
+    int temp;
+    RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == (temp = ckmc_unlock_user_key(user_id, passwd)), CKMCErrorToString(temp));
+}
+ScopedDBUnlock::~ScopedDBUnlock()
+{
+    int temp;
+    RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == (temp = ckmc_lock_user_key(m_uid)), CKMCErrorToString(temp));
+}
+
+void check_remove_allowed(const char* alias)
+{
+    int ret = ckmc_remove_alias(alias);
+    // remove, but ignore non existing
+    RUNNER_ASSERT_MSG((CKMC_ERROR_NONE == ret) || (CKMC_ERROR_DB_ALIAS_UNKNOWN == ret),
+                         "Removing data failed: " << CKMCErrorToString(ret));
+}
+
+void check_remove_denied(const char* alias)
+{
+    int ret = ckmc_remove_alias(alias);
+    RUNNER_ASSERT_MSG(
+            CKMC_ERROR_PERMISSION_DENIED == ret,
+            "App with different label shouldn't have rights to remove this data. "
+            << CKMCReadableError(ret));
+}
+
+void check_remove_not_visible(const char* alias)
+{
+    int ret = ckmc_remove_alias(alias);
+    RUNNER_ASSERT_MSG(
+            CKMC_ERROR_DB_ALIAS_UNKNOWN == ret,
+            "App with different label shouldn't have rights to see this data. "
+            << CKMCReadableError(ret));
+}
+
+void check_read(const char* alias,
+                const char *label,
+                const char *test_data,
+                size_t len,
+                int expected_code)
+{
+    ckmc_raw_buffer_s* buffer = NULL;
+    int ret = ckmc_get_data(aliasWithLabel(label, alias).c_str(), NULL, &buffer);
+    RUNNER_ASSERT_MSG(expected_code == ret, "Getting data failed. "
+                      "Expected " << CKMCErrorToString(expected_code) << ", "
+                      "while result " << CKMCErrorToString(ret));
+
+    if(expected_code == CKMC_ERROR_NONE)
+    {
+        // compare data with expected
+        RUNNER_ASSERT_MSG(
+                buffer->size == len,
+                "Extracted data length do not match expected data length (encrypted?):" <<
+                buffer->size << "!=" << len);
+
+        RUNNER_ASSERT_MSG(
+                memcmp(const_cast<const char*>(reinterpret_cast<char*>(buffer->data)),
+                       test_data, buffer->size) == 0,
+                "Extracted data do not match expected data (encrypted?).");
+
+        ckmc_buffer_free(buffer);
+    }
+}
+
+void check_read(const char* alias, const char *label, const char *test_data, int expected_code)
+{
+    check_read(alias, label, test_data, strlen(test_data), expected_code);
+}
+
+void check_read_allowed(const char* alias, const char *data)
+{
+    // try to read previously saved data - label taken implicitly
+    check_read(alias, NULL, data);
+}
+
+void check_read_not_visible(const char* alias)
+{
+    // try to read previously saved data - label taken implicitly
+    {
+        ckmc_raw_buffer_s* buffer = NULL;
+        int ret = ckmc_get_data(alias, NULL, &buffer);
+        RUNNER_ASSERT_MSG(CKMC_ERROR_DB_ALIAS_UNKNOWN == ret,
+                            "App with different label shouldn't have rights to see this data. " << CKMCErrorToString(ret));
+        ckmc_buffer_free(buffer);
+    }
+}
+
+void check_key(const char *alias, int expected_error, ckmc_key_type_e expected_type)
+{
+    ckmc_key_s *test_key = NULL;
+    int temp = ckmc_get_key(alias, 0, &test_key);
+    RUNNER_ASSERT_MSG(
+            expected_error == temp,
+            "received: " << CKMCReadableError(temp) << " while expected: " << CKMCReadableError(expected_error));
+    if(expected_type != CKMC_KEY_NONE)
+    {
+        RUNNER_ASSERT_MSG(
+                test_key->key_type == expected_type,
+                "received type: " << test_key->key_type << " while expected type: " << expected_type);
+    }
+    ckmc_key_free(test_key);
+}
+void check_key_allowed(const char *alias, ckmc_key_type_e expected_type)
+{
+    check_key(alias, CKMC_ERROR_NONE, expected_type);
+}
+void check_key_not_visible(const char *alias)
+{
+    check_key(alias, CKMC_ERROR_DB_ALIAS_UNKNOWN);
+}
+void check_cert_allowed(const char *alias)
+{
+    ckmc_cert_s *test_cert = NULL;
+    int temp = ckmc_get_cert(alias, 0, &test_cert);
+    ckmc_cert_free(test_cert);
+    RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == temp, CKMCReadableError(temp));
+
+}
+void check_cert_not_visible(const char *alias)
+{
+    ckmc_cert_s *test_cert = NULL;
+    int temp = ckmc_get_cert(alias, 0, &test_cert);
+    ckmc_cert_free(test_cert);
+    RUNNER_ASSERT_MSG(CKMC_ERROR_DB_ALIAS_UNKNOWN == temp,
+                      "App with different label shouldn't have rights to see this cert. " << CKMCErrorToString(temp));
+}
+
+void allow_access(const char* alias, const char* accessor, int permissionMask)
+{
+    // data removal should revoke this access
+    int ret = ckmc_set_permission(alias, accessor, permissionMask);
+    RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == ret, "Trying to allow access returned: "
+                        << CKMCErrorToString(ret));
+}
+
+void allow_access_negative(const char* alias, const char* accessor, int permissionMask, int expectedCode)
+{
+    // data removal should revoke this access
+    int ret = ckmc_set_permission(alias, accessor, permissionMask);
+    RUNNER_ASSERT_MSG(expectedCode == ret, "Trying to allow access returned "
+                        << CKMCErrorToString(ret) << ", while expected: "
+                        << CKMCErrorToString(expectedCode));
+}
+
+void deny_access(const char* alias, const char* accessor)
+{
+    int ret = ckmc_set_permission(alias, accessor, CKMC_PERMISSION_NONE);
+    RUNNER_ASSERT_MSG(CKMC_ERROR_NONE == ret, "Denying access failed. Error: "
+                        << CKMCErrorToString(ret));
+}
+
+void deny_access_negative(const char* alias, const char* accessor, int expectedCode)
+{
+    int ret = ckmc_set_permission(alias, accessor, CKMC_PERMISSION_NONE);
+    RUNNER_ASSERT_MSG(expectedCode == ret, "Denying access failed. "
+                        << CKMCErrorToString(ret) << ", while expected: "
+                        << CKMCErrorToString(expectedCode));
+}
+
 void unlock_user_data(uid_t user_id, const char *passwd)
 {
     int ret;
     auto control = CKM::Control::create();
     RUNNER_ASSERT_MSG(CKM_API_SUCCESS == (ret = control->unlockUserKey(user_id, passwd)),
-                      "Error=" << CKM::ErrorToString(ret));
+                      "Error=" << CKM::APICodeToString(ret));
 }
 
 void remove_user_data(uid_t user_id)
 {
-    int ret;
     auto control = CKM::Control::create();
-    RUNNER_ASSERT_MSG(CKM_API_SUCCESS == (ret = control->lockUserKey(user_id)),
-                      "Error=" << CKM::ErrorToString(ret));
-    RUNNER_ASSERT_MSG(CKM_API_SUCCESS == (ret = control->removeUserData(user_id)),
-                      "Remove user data failed with error: " << CKM::ErrorToString(ret));
+    control->lockUserKey(user_id);
+    control->removeUserData(user_id);
 }
 
 void reset_user_data(uid_t user_id, const char *passwd)
@@ -176,3 +355,234 @@ void reset_user_data(uid_t user_id, const char *passwd)
     remove_user_data(user_id);
     unlock_user_data(user_id, passwd);
 }
+
+ckmc_raw_buffer_s prepare_message_buffer(const char * input)
+{
+    ckmc_raw_buffer_s retval;
+    retval.data = const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(input));
+    retval.size = strlen(input);
+    return retval;
+}
+
+void check_alias_list(const CKM::AliasVector& expected)
+{
+    ckmc_alias_list_s *aliasList = NULL;
+    int ret = ckmc_get_data_alias_list(&aliasList);
+    RUNNER_ASSERT_MSG(ret == 0, "Failed to get the list of data aliases. " << ret << " / " << CKMCErrorToString(ret));
+
+    CKM::AliasVector actual;
+    ckmc_alias_list_s *plist = aliasList;
+    while(plist)
+    {
+        actual.push_back(plist->alias);
+        plist = plist->next;
+    }
+    ckmc_alias_list_all_free(aliasList);
+
+    RUNNER_ASSERT_MSG(expected == actual, "Actual list of aliases differ from expected list.");
+}
+
+void check_alias_info_list_helper(const CKM::AliasPwdVector& expected, const CKM::AliasPwdVector& actual,
+        const std::string &userSmackLabel)
+{
+    std::string errorLogMsg;
+    std::unordered_map<std::string, bool> aliasPwdMap;
+
+    RUNNER_ASSERT_MSG(expected.size() == actual.size(), "Aliases item count differs, expected: " <<
+        expected.size() << " actual: " << actual.size());
+
+    for (const auto &it : actual)
+    {
+        aliasPwdMap[std::get<0>(it)] = std::get<1>(it);
+    }
+
+
+    for (const auto &it : expected)
+    {
+        auto aliasPwd = aliasPwdMap.find(userSmackLabel + std::get<0>(it));
+        if (aliasPwd != aliasPwdMap.end()) {
+            if (aliasPwd->second != std::get<1>(it)) {
+                errorLogMsg += "Alias: " + std::get<0>(it) + " has wrong encryption status: "
+                                + std::to_string(std::get<1>(it)) + "\n";
+            }
+        }
+        else {
+            errorLogMsg += "Expected alias: " + std::get<0>(it) + " not found.\n";
+        }
+    }
+
+    if (!errorLogMsg.empty()) {
+        for (const auto &it : actual)
+        {
+            errorLogMsg += "Actual alias: " + std::get<0>(it) + " status: "
+                + std::to_string(std::get<1>(it)) + "\n";
+        }
+        RUNNER_FAIL_MSG("Actual list of aliases differ from expected list.\n" + errorLogMsg);
+    }
+}
+
+void check_alias_info_list(const CKM::AliasPwdVector& expected)
+{
+    ckmc_alias_info_list_s *aliasInfoList = NULL;
+    int ret = ckmc_get_data_alias_info_list(&aliasInfoList);
+    RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Failed to get the list of data aliases. " << ret << " / "
+                      << CKMCErrorToString(ret));
+
+    CKM::AliasPwdVector actual;
+    ckmc_alias_info_list_s *plist = aliasInfoList;
+    char* alias;
+    bool isPasswordProtected;
+    unsigned int it = 0;
+    while (plist)
+    {
+        ret = ckmc_alias_info_get_alias(plist->info, &alias);
+        RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Failed to get alias. " << ret << " / "
+                          << CKMCErrorToString(ret));
+        ret = ckmc_alias_info_is_password_protected(plist->info, &isPasswordProtected);
+        RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Failed to get password protection status" << ret << " / "
+                          << CKMCErrorToString(ret));
+        RUNNER_ASSERT_MSG(alias != nullptr, "Got null alias. Iterator: " << it);
+        actual.push_back(std::make_pair(alias, isPasswordProtected));
+        plist = plist->next;
+        it++;
+    }
+    ckmc_alias_info_list_all_free(aliasInfoList);
+    check_alias_info_list_helper(expected, actual);
+}
+
+size_t count_aliases(alias_type_ type, size_t minimum_initial_element_count)
+{
+    ckmc_alias_list_s *aliasList = NULL;
+    int ec;
+    switch(type)
+    {
+        case ALIAS_KEY:
+            ec = ckmc_get_key_alias_list(&aliasList);
+            break;
+
+        case ALIAS_CERT:
+            ec = ckmc_get_cert_alias_list(&aliasList);
+            break;
+
+        case ALIAS_DATA:
+            ec = ckmc_get_data_alias_list(&aliasList);
+            break;
+        default:
+            RUNNER_ASSERT_MSG(false, "Unsupported value ALIAS_KEY == " << (int)type);
+    }
+
+    if(ec == CKMC_ERROR_DB_ALIAS_UNKNOWN)
+        return 0;
+
+    RUNNER_ASSERT_MSG(ec == CKMC_ERROR_NONE,
+                      "Error: alias list failed, ec: " << CKMCErrorToString(ec));
+
+    ckmc_alias_list_s *plist = aliasList;
+    size_t return_count = 0;
+    while(plist)
+    {
+        plist = plist->next;
+        return_count ++;
+    }
+    ckmc_alias_list_all_free(aliasList);
+
+    RUNNER_ASSERT_MSG(
+      return_count >= minimum_initial_element_count,
+      "Error: alias list failed, current element count: " << return_count <<
+      " while expected minimal count of " << minimum_initial_element_count <<
+      " elements");
+
+    return return_count;
+}
+
+std::string sharedDatabase(const CKM::Alias & alias)
+{
+    return aliasWithLabel(ckmc_owner_id_system, alias.c_str());
+}
+
+ckmc_raw_buffer_s* createRandomBufferCAPI(size_t random_bytes)
+{
+    ckmc_raw_buffer_s* buffer = NULL;
+    char* data = static_cast<char*>(malloc(random_bytes*sizeof(char)));
+    RUNNER_ASSERT(data);
+    generate_random(random_bytes, data);
+    int ret = ckmc_buffer_new(reinterpret_cast<unsigned char*>(data), random_bytes, &buffer);
+    RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Buffer creation failed: " << CKMCErrorToString(ret));
+    return buffer;
+}
+
+CKM::RawBuffer createRandomBuffer(size_t random_bytes)
+{
+    char buffer[random_bytes];
+    generate_random(random_bytes, buffer);
+    return CKM::RawBuffer(buffer, buffer + random_bytes);
+}
+
+ckmc_key_s *generate_AES_key(size_t lengthBits, const char *passwd)
+{
+    ckmc_key_s *retval = reinterpret_cast<ckmc_key_s *>(malloc(sizeof(ckmc_key_s)));
+    RUNNER_ASSERT(retval != NULL);
+
+    RUNNER_ASSERT(lengthBits%8 == 0);
+    char *char_key_AES = reinterpret_cast<char*>(malloc(lengthBits/8));
+    RUNNER_ASSERT(char_key_AES != NULL);
+    generate_random(lengthBits/8, char_key_AES);
+
+    retval->raw_key  = reinterpret_cast<unsigned char *>(char_key_AES);
+    retval->key_size = lengthBits/8;
+    retval->key_type = CKMC_KEY_AES;
+    retval->password = passwd?strdup(passwd):NULL;
+
+    return retval;
+}
+
+void validate_AES_key(ckmc_key_s *analyzed)
+{
+    RUNNER_ASSERT_MSG(analyzed, "provided key is NULL");
+    RUNNER_ASSERT_MSG(analyzed->raw_key != NULL, "provided key is empty");
+    RUNNER_ASSERT_MSG(analyzed->key_size==(128/8) ||
+                      analyzed->key_size==(192/8) ||
+                      analyzed->key_size==(256/8), "provided key length is invalid");
+    RUNNER_ASSERT_MSG(analyzed->key_type = CKMC_KEY_AES, "expected AES key, while got: " << analyzed->key_type);
+}
+
+void compare_AES_keys(ckmc_key_s *first, ckmc_key_s *second)
+{
+    validate_AES_key(first);
+    validate_AES_key(second);
+    RUNNER_ASSERT_MSG(
+        (first->key_size==second->key_size) &&
+        (memcmp(first->raw_key, second->raw_key, first->key_size)==0),
+        "data has been modified in key manager");
+    // bypassing password intentionally
+}
+
+ParamListPtr createParamListPtr()
+{
+    ckmc_param_list_h list = NULL;
+    assert_positive(ckmc_param_list_new, &list);
+    return ParamListPtr(list, ckmc_param_list_free);
+}
+
+void assert_buffers_equal(const ckmc_raw_buffer_s b1, const ckmc_raw_buffer_s b2, bool equal)
+{
+    if(equal) {
+        RUNNER_ASSERT_MSG(b1.size == b2.size, "Buffer size differs: " << b1.size << "!=" << b2.size);
+        RUNNER_ASSERT_MSG(0 == memcmp(b1.data, b2.data, b1.size), "Buffer contents differ");
+    } else {
+        RUNNER_ASSERT_MSG(b1.size != b2.size || 0 != memcmp(b1.data, b2.data, b1.size),
+                          "Buffers should be different");
+    }
+}
+
+RawBufferPtr create_raw_buffer(ckmc_raw_buffer_s* buffer)
+{
+    return RawBufferPtr(buffer, ckmc_buffer_free);
+}
+
+CKM::Policy generate_ckm_policy(int iterator_nr) {
+    if (iterator_nr % 2) { // policy with password and with / without extractable flag
+        return CKM::Policy(CKM::Password("test_pwd"), iterator_nr % 4);
+    }
+    return CKM::Policy();
+}