CKM: Implement asynchronous tests for encryption/decryption 02/43502/5
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 9 Jul 2015 12:20:03 +0000 (14:20 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 30 Jul 2015 08:54:38 +0000 (10:54 +0200)
[Feature] Encryption/decryption API implementation
[Solution] Add asynchronous environment to existing encryption/decryption tests

[Verification] Run ckm-tests --group=CKM_ENCRYPTION_DECRYPTION

Change-Id: I1ff9b89b45c643a95521381d676349a3c2408a22

src/ckm/CMakeLists.txt
src/ckm/encryption-decryption-env.cpp [new file with mode: 0644]
src/ckm/encryption-decryption-env.h [new file with mode: 0644]
src/ckm/encryption-decryption.cpp

index 5d67118..2aae5cd 100644 (file)
@@ -52,6 +52,7 @@ SET(CKM_SOURCES
     ${PROJECT_SOURCE_DIR}/src/ckm/clean-env.cpp
     ${PROJECT_SOURCE_DIR}/src/ckm/test-certs.cpp
     ${PROJECT_SOURCE_DIR}/src/ckm/algo-params.cpp
+    ${PROJECT_SOURCE_DIR}/src/ckm/encryption-decryption-env.cpp
     ${PROJECT_SOURCE_DIR}/src/ckm/encryption-decryption.cpp
 )
 
diff --git a/src/ckm/encryption-decryption-env.cpp b/src/ckm/encryption-decryption-env.cpp
new file mode 100644 (file)
index 0000000..fb1aba6
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ *  Copyright (c) 2000 - 2015 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       encryption-decryption-env.cpp
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#include <encryption-decryption-env.h>
+
+using namespace CKM;
+
+EncryptionError SyncApi::encrypt(const ckmc_param_list_s *params,
+                                 const char *key_alias,
+                                 const char *password,
+                                 const ckmc_raw_buffer_s& decrypted,
+                                 ckmc_raw_buffer_s **ppencrypted)
+{
+    return ckmcError2Result(ckmc_encrypt_data(params, key_alias, password, decrypted, ppencrypted));
+}
+
+EncryptionError SyncApi::decrypt(const ckmc_param_list_s *params,
+                                 const char *key_alias,
+                                 const char *password,
+                                 const ckmc_raw_buffer_s& encrypted,
+                                 ckmc_raw_buffer_s **ppdecrypted)
+{
+    return ckmcError2Result(ckmc_decrypt_data(params, key_alias, password, encrypted, ppdecrypted));
+}
+
+EncryptionError SyncApi::ckmcError2Result(int error) {
+    switch (error) {
+    case CKMC_ERROR_NONE:                   return EncryptionError::SUCCESS;
+    case CKMC_ERROR_INVALID_PARAMETER:      return EncryptionError::INVALID_PARAM;
+    case CKMC_ERROR_SERVER_ERROR:           return EncryptionError::SERVER_ERROR;
+    case CKMC_ERROR_DB_ALIAS_UNKNOWN:       return EncryptionError::ALIAS_UNKNOWN;
+    case CKMC_ERROR_AUTHENTICATION_FAILED:  return EncryptionError::AUTH_FAILED;
+    default:                                return EncryptionError::OTHER;
+    }
+}
+
+
+
+void AsyncApi::Observer::ReceivedError(int error) {
+    Finished(error);
+}
+void AsyncApi::Observer::ReceivedEncrypted(RawBuffer && buffer) {
+    m_buffer = std::move(buffer);
+    Finished();
+}
+
+void AsyncApi::Observer::ReceivedDecrypted(RawBuffer && buffer) {
+    m_buffer = std::move(buffer);
+    Finished();
+}
+
+void AsyncApi::Observer::WaitForResponse() {
+    std::unique_lock<std::mutex> lock(m_mutex);
+    m_cv.wait(lock, [this] {return m_finished;});
+}
+void AsyncApi::Observer::Finished(int error)
+{
+    m_error = error;
+    m_finished = true;
+    m_cv.notify_one();
+}
+
+EncryptionError AsyncApi::crypt(cryptoFn operation,
+                                const ckmc_param_list_s *params,
+                                const char *key_alias,
+                                const char *password,
+                                const ckmc_raw_buffer_s& in,
+                                ckmc_raw_buffer_s **ppout)
+{
+    // C++ API doesn't have to check that
+    if(!params || !key_alias || !ppout)
+        return EncryptionError::INVALID_PARAM;
+
+    CKM::ManagerAsync mgr;
+    std::shared_ptr<Observer> obs = std::make_shared<Observer>();
+
+    // params
+    const CryptoAlgorithm* ca = reinterpret_cast<const CryptoAlgorithm*>(params);
+
+    // password
+    Password pass;
+    if (password)
+        pass = password;
+
+    // buffer
+    RawBuffer inBuffer(in.data, in.data + in.size);
+
+    // crypto operation
+    (mgr.*operation)(obs, *ca, key_alias, pass, inBuffer);
+    obs->WaitForResponse();
+    if(obs->m_error != CKM_API_SUCCESS)
+        return ckmError2Result(obs->m_error);
+
+    int ret = ckmc_buffer_new(obs->m_buffer.data(), obs->m_buffer.size(), ppout);
+    if (ret != CKMC_ERROR_NONE)
+        return EncryptionError::OTHER;
+
+    return EncryptionError::SUCCESS;
+}
+
+EncryptionError AsyncApi::encrypt(const ckmc_param_list_s *params,
+                                  const char *key_alias,
+                                  const char *password,
+                                  const ckmc_raw_buffer_s& plain,
+                                  ckmc_raw_buffer_s **ppencrypted)
+{
+    return crypt(&CKM::ManagerAsync::encrypt, params, key_alias, password, plain, ppencrypted);
+}
+
+EncryptionError AsyncApi::decrypt(const ckmc_param_list_s *params,
+                                  const char *key_alias,
+                                  const char *password,
+                                  const ckmc_raw_buffer_s& encrypted,
+                                  ckmc_raw_buffer_s **ppdecrypted)
+{
+    return crypt(&CKM::ManagerAsync::decrypt, params, key_alias, password, encrypted, ppdecrypted);
+}
+
+EncryptionError AsyncApi::ckmError2Result(int error)
+{
+    switch (error) {
+    case CKM_API_SUCCESS:                      return EncryptionError::SUCCESS;
+    case CKM_API_ERROR_INPUT_PARAM:            return EncryptionError::INVALID_PARAM;
+    case CKM_API_ERROR_SERVER_ERROR:           return EncryptionError::SERVER_ERROR;
+    case CKM_API_ERROR_DB_ALIAS_UNKNOWN:       return EncryptionError::ALIAS_UNKNOWN;
+    case CKM_API_ERROR_AUTHENTICATION_FAILED:  return EncryptionError::AUTH_FAILED;
+    default:                                   return EncryptionError::OTHER;
+    }
+}
diff --git a/src/ckm/encryption-decryption-env.h b/src/ckm/encryption-decryption-env.h
new file mode 100644 (file)
index 0000000..ca0ba0d
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *  Copyright (c) 2000 - 2015 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       encryption-decryption-env.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#pragma once
+
+#include <memory>
+#include <mutex>
+#include <condition_variable>
+
+#include <ckmc/ckmc-type.h>
+#include <ckmc/ckmc-manager.h>
+#include <ckm/ckm-manager-async.h>
+
+enum EncryptionError{
+    SUCCESS,
+    INVALID_PARAM,
+    SERVER_ERROR,
+    ALIAS_UNKNOWN,
+    AUTH_FAILED,
+    OTHER,
+};
+
+struct EncryptionApi
+{
+    virtual EncryptionError encrypt(const ckmc_param_list_s *params,
+                                    const char *key_alias,
+                                    const char *password,
+                                    const ckmc_raw_buffer_s& decrypted,
+                                    ckmc_raw_buffer_s **ppencrypted) = 0;
+
+    virtual EncryptionError decrypt(const ckmc_param_list_s *params,
+                                    const char *key_alias,
+                                    const char *password,
+                                    const ckmc_raw_buffer_s& encrypted,
+                                    ckmc_raw_buffer_s **ppdecrypted) = 0;
+};
+
+class SyncApi : public EncryptionApi
+{
+public:
+    virtual EncryptionError encrypt(const ckmc_param_list_s *params,
+                                    const char *key_alias,
+                                    const char *password,
+                                    const ckmc_raw_buffer_s& decrypted,
+                                    ckmc_raw_buffer_s **ppencrypted);
+
+    virtual EncryptionError decrypt(const ckmc_param_list_s *params,
+                                    const char *key_alias,
+                                    const char *password,
+                                    const ckmc_raw_buffer_s& encrypted,
+                                    ckmc_raw_buffer_s **ppdecrypted);
+private:
+    static EncryptionError ckmcError2Result(int error);
+};
+
+struct AsyncApi : public EncryptionApi
+{
+private:
+    struct Observer : public CKM::ManagerAsync::Observer {
+        Observer() : m_finished(false), m_error(CKM_API_SUCCESS) {}
+
+        void ReceivedError(int error);
+        void ReceivedEncrypted(CKM::RawBuffer && buffer);
+        void ReceivedDecrypted(CKM::RawBuffer && buffer);
+        void WaitForResponse();
+        void Finished(int error = CKMC_ERROR_NONE);
+
+        std::mutex m_mutex;
+        std::condition_variable m_cv;
+        bool m_finished;
+        int m_error;
+        CKM::RawBuffer m_buffer;
+    };
+
+public:
+    EncryptionError encrypt(const ckmc_param_list_s *params,
+                            const char *key_alias,
+                            const char *password,
+                            const ckmc_raw_buffer_s& decrypted,
+                            ckmc_raw_buffer_s **ppencrypted);
+
+    EncryptionError decrypt(const ckmc_param_list_s *params,
+                            const char *key_alias,
+                            const char *password,
+                            const ckmc_raw_buffer_s& encrypted,
+                            ckmc_raw_buffer_s **ppdecrypted);
+private:
+    typedef void (CKM::ManagerAsync::*cryptoFn)(const CKM::ManagerAsync::ObserverPtr&,
+                                                const CKM::CryptoAlgorithm&,
+                                                const CKM::Alias&,
+                                                const CKM::Password&,
+                                                const CKM::RawBuffer&);
+
+    EncryptionError crypt(cryptoFn operation,
+                          const ckmc_param_list_s *params,
+                          const char *key_alias,
+                          const char *password,
+                          const ckmc_raw_buffer_s& in,
+                          ckmc_raw_buffer_s **ppout);
+
+    static EncryptionError ckmError2Result(int error);
+};
+
+
+
index 3b752be..8bc1707 100644 (file)
@@ -30,6 +30,9 @@
 #include <ckmc/ckmc-manager.h>
 #include <ckm/ckm-type.h>
 #include <access_provider2.h>
+#include <encryption-decryption-env.h>
+
+using namespace CKM;
 
 namespace {
 
@@ -40,15 +43,58 @@ const size_t CTR_DEFAULT_LEN = 16*8;
 const size_t DEFAULT_IV_LEN = 16;
 const size_t BUF_LEN = 86; // must be less than 1024/8-41 to support RSA OAEP 1024
 
+// Environment
+SyncApi g_syncApi;
+AsyncApi g_asyncApi;
+
+EncryptionApi* g_api = &g_syncApi;
+
+EncryptionError apiEncrypt(const ckmc_param_list_s *params,
+                        const char *key_alias,
+                        const char *password,
+                        const ckmc_raw_buffer_s decrypted,
+                        ckmc_raw_buffer_s **ppencrypted) {
+    return g_api->encrypt(params, key_alias, password, decrypted, ppencrypted);
+}
+
+EncryptionError apiDecrypt(const ckmc_param_list_s *params,
+                        const char *key_alias,
+                        const char *password,
+                        const ckmc_raw_buffer_s encrypted,
+                        ckmc_raw_buffer_s **ppdecrypted) {
+    return g_api->decrypt(params, key_alias, password, encrypted, ppdecrypted);
+}
+
+template <typename F, typename... Args>
+void assert_crypto_result(EncryptionError expected, F&& func, Args... args)
+{
+    EncryptionError ret = func(args...);
+    RUNNER_ASSERT_MSG(ret == expected,
+                      "Expected: " << static_cast<int>(expected) <<
+                      " got: " << static_cast<int>(ret));
+}
+
+template <typename F, typename... Args>
+void assert_crypto_positive(F&& func, Args... args)
+{
+    assert_crypto_result(EncryptionError::SUCCESS, std::move(func), args...);
+}
+
+template <typename F, typename... Args>
+void assert_crypto_invalid_param(F&& func, Args... args)
+{
+    assert_crypto_result(EncryptionError::INVALID_PARAM, std::move(func), args...);
+}
+
 struct TagTest {
     int tagLen;
-    int expected;
+    EncryptionError expected;
 };
 
 struct KeyAliasPair
 {
-    CKM::Alias prv;
-    CKM::Alias pub;
+    Alias prv;
+    Alias pub;
 };
 
 class EncEnv : public RemoveDataEnv<UID> {
@@ -79,6 +125,26 @@ public:
     ScopedAccessProvider* m_sap;
 };
 
+struct SyncEnv : public EncEnv {
+    void init(const std::string& str) {
+        EncEnv::init(str);
+        g_api = &g_syncApi;
+    }
+
+   void finish() { EncEnv::finish(); }
+   static std::string suffix() { return "_sync"; }
+};
+
+struct AsyncEnv : public EncEnv {
+    void init(const std::string& str) {
+        EncEnv::init(str);
+        g_api = &g_asyncApi;
+    }
+
+   void finish() { EncEnv::finish(); }
+   static std::string suffix() { return "_async"; }
+};
+
 struct AlgoBase {
     ckmc_algo_type_e m_type;
     size_t m_keyLen;
@@ -216,8 +282,8 @@ struct EncryptionResult
 {
     RawBufferPtr encrypted;
     ParamListPtr params;
-    CKM::Alias prvKey;
-    CKM::Alias pubKey;
+    Alias prvKey;
+    Alias pubKey;
 };
 
 EncryptionResult encrypt(const AlgoBasePtr& algo,
@@ -232,12 +298,12 @@ EncryptionResult encrypt(const AlgoBasePtr& algo,
     assert_positive(ckmc_generate_params, algo->m_type, ret.params.get());
     setParam(ret.params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN));
 
-    assert_positive(ckmc_encrypt_data,
-                    ret.params.get(),
-                    aliases.pub.c_str(),
-                    pass,
-                    *plain.get(),
-                    &encrypted);
+    assert_crypto_positive(apiEncrypt,
+                           ret.params.get(),
+                           aliases.pub.c_str(),
+                           pass,
+                           *plain.get(),
+                           &encrypted);
 
     ret.encrypted = create_raw_buffer(encrypted);
     ret.prvKey = aliases.prv;
@@ -266,12 +332,12 @@ void testNoIvEnc(Algorithm type)
     // param list with algo type only
     ParamListPtr params = createParamListPtr();
     setParam(params, CKMC_PARAM_ALGO_TYPE, algo->m_type);
-    assert_invalid_param(ckmc_encrypt_data,
-                         params.get(),
-                         aliases.pub.c_str(),
-                         nullptr,
-                         *plain.get(),
-                         &encrypted);
+    assert_crypto_invalid_param(apiEncrypt,
+                                params.get(),
+                                aliases.pub.c_str(),
+                                nullptr,
+                                *plain.get(),
+                                &encrypted);
 }
 
 void testNoIvDec(Algorithm type)
@@ -288,12 +354,12 @@ void testNoIvDec(Algorithm type)
     // param list with algo type only
     ParamListPtr params = createParamListPtr();
     setParam(params, CKMC_PARAM_ALGO_TYPE, algo->m_type);
-    assert_invalid_param(ckmc_decrypt_data,
-                         params.get(),
-                         ret.prvKey.c_str(),
-                         nullptr,
-                         *ret.encrypted.get(),
-                         &decrypted);
+    assert_crypto_invalid_param(apiDecrypt,
+                                params.get(),
+                                ret.prvKey.c_str(),
+                                nullptr,
+                                *ret.encrypted.get(),
+                                &decrypted);
 }
 
 void testInvalidIvEnc(Algorithm type)
@@ -313,12 +379,12 @@ void testInvalidIvEnc(Algorithm type)
 
     // invalid encryption
     auto test = [&](){
-        assert_invalid_param(ckmc_encrypt_data,
-                             params.get(),
-                             aliases.pub.c_str(),
-                             nullptr,
-                             *plain.get(),
-                             &encryptedTmp);
+        assert_crypto_invalid_param(apiEncrypt,
+                                    params.get(),
+                                    aliases.pub.c_str(),
+                                    nullptr,
+                                    *plain.get(),
+                                    &encryptedTmp);
         ckmc_buffer_free(encryptedTmp);
         encryptedTmp = nullptr;
     };
@@ -342,12 +408,12 @@ void testInvalidIvDec(Algorithm type)
 
     // decryption
     auto test2 = [&](){
-        assert_invalid_param(ckmc_decrypt_data,
-                             ret.params.get(),
-                             ret.prvKey.c_str(),
-                             nullptr,
-                             *ret.encrypted.get(),
-                             &decrypted);
+        assert_crypto_invalid_param(apiDecrypt,
+                                    ret.params.get(),
+                                    ret.prvKey.c_str(),
+                                    nullptr,
+                                    *ret.encrypted.get(),
+                                    &decrypted);
         ckmc_buffer_free(decrypted);
         decrypted = nullptr;
     };
@@ -380,21 +446,21 @@ void encryptionWithCustomData(Algorithm type, ckmc_param_name_e name)
     setParam(params, name, createRandomBufferCAPI(64));
 
     // encrypt
-    assert_positive(ckmc_encrypt_data,
-                    params.get(),
-                    aliases.pub.c_str(),
-                    nullptr,
-                    *plain.get(),
-                    &encrypted);
+    assert_crypto_positive(apiEncrypt,
+                           params.get(),
+                           aliases.pub.c_str(),
+                           nullptr,
+                           *plain.get(),
+                           &encrypted);
     RawBufferPtr tmpEnc = create_raw_buffer(encrypted);
 
     // decrypt
-    assert_positive(ckmc_decrypt_data,
-                    params.get(),
-                    aliases.prv.c_str(),
-                    nullptr,
-                    *tmpEnc.get(),
-                    &decrypted);
+    assert_crypto_positive(apiDecrypt,
+                           params.get(),
+                           aliases.prv.c_str(),
+                           nullptr,
+                           *tmpEnc.get(),
+                           &decrypted);
     RawBufferPtr tmpDec = create_raw_buffer(decrypted);
 
     // check
@@ -406,16 +472,18 @@ void encryptionWithCustomData(Algorithm type, ckmc_param_name_e name)
     setParam(params, name, createRandomBufferCAPI(32));
 
     // decrypt
-    assert_result(CKMC_ERROR_SERVER_ERROR,
-                  ckmc_decrypt_data,
-                  params.get(),
-                  aliases.prv.c_str(),
-                  nullptr,
-                  *tmpEnc.get(),
-                  &decrypted);
+    assert_crypto_result(EncryptionError::SERVER_ERROR,
+                         apiDecrypt,
+                         params.get(),
+                         aliases.prv.c_str(),
+                         nullptr,
+                         *tmpEnc.get(),
+                         &decrypted);
 }
 
-void testGcmIvSize(size_t size, const KeyAliasPair& aliases, int error = CKMC_ERROR_NONE)
+void testGcmIvSize(size_t size,
+                   const KeyAliasPair& aliases,
+                   EncryptionError error = EncryptionError::SUCCESS)
 {
     // prepare buffers
     RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN));
@@ -431,25 +499,25 @@ void testGcmIvSize(size_t size, const KeyAliasPair& aliases, int error = CKMC_ER
     setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(size));
 
     // encryption
-    assert_result(error,
-                  ckmc_encrypt_data,
-                  params.get(),
-                  aliases.pub.c_str(),
-                  nullptr,
-                  *plain.get(),
-                  &encryptedTmp);
-
-    if(error != CKMC_ERROR_NONE)
+    assert_crypto_result(error,
+                         apiEncrypt,
+                         params.get(),
+                         aliases.pub.c_str(),
+                         nullptr,
+                         *plain.get(),
+                         &encryptedTmp);
+
+    if(error != EncryptionError::SUCCESS)
         return;
     encrypted = create_raw_buffer(encryptedTmp);
 
     // decryption
-    assert_positive(ckmc_decrypt_data,
-                    params.get(),
-                    aliases.prv.c_str(),
-                    nullptr,
-                    *encrypted.get(),
-                    &decryptedTmp);
+    assert_crypto_positive(apiDecrypt,
+                           params.get(),
+                           aliases.prv.c_str(),
+                           nullptr,
+                           *encrypted.get(),
+                           &decryptedTmp);
     decrypted = create_raw_buffer(decryptedTmp);
 
     assert_buffers_equal(*plain.get(), *decrypted.get());
@@ -470,12 +538,12 @@ void testIntegrity(Algorithm type)
     ret.encrypted->data[BUF_LEN/2]++;
 
     // no data integrity check
-    assert_positive(ckmc_decrypt_data,
-                    ret.params.get(),
-                    ret.prvKey.c_str(),
-                    nullptr,
-                    *ret.encrypted.get(),
-                     &decrypted);
+    assert_crypto_positive(apiDecrypt,
+                           ret.params.get(),
+                           ret.prvKey.c_str(),
+                           nullptr,
+                           *ret.encrypted.get(),
+                           &decrypted);
 
     RawBufferPtr tmp = create_raw_buffer(decrypted);
     assert_buffers_equal(*plain.get(), *decrypted, false);
@@ -499,12 +567,12 @@ void testCtrEncryptionInvalidLength(Algorithm type)
 
     // encryption
     auto test = [&](){
-        assert_invalid_param(ckmc_encrypt_data,
-                             params.get(),
-                             aliases.pub.c_str(),
-                             nullptr,
-                             *plain.get(),
-                             &encryptedTmp);
+        assert_crypto_invalid_param(apiEncrypt,
+                                    params.get(),
+                                    aliases.pub.c_str(),
+                                    nullptr,
+                                    *plain.get(),
+                                    &encryptedTmp);
         ckmc_buffer_free(encryptedTmp);
         encryptedTmp = nullptr;
     };
@@ -535,12 +603,12 @@ void testCtrEncryptionValidLength(Algorithm type)
 
     // encryption
     auto test = [&](){
-        assert_positive(ckmc_encrypt_data,
-                        params.get(),
-                        aliases.pub.c_str(),
-                        nullptr,
-                        *plain.get(),
-                        &encryptedTmp);
+        assert_crypto_positive(apiEncrypt,
+                               params.get(),
+                               aliases.pub.c_str(),
+                               nullptr,
+                               *plain.get(),
+                               &encryptedTmp);
         ckmc_buffer_free(encryptedTmp);
         encryptedTmp = nullptr;
     };
@@ -568,12 +636,12 @@ void testCtrDecryptionInvalidLength(Algorithm type)
 
     // decryption
     auto test = [&](){
-        assert_invalid_param(ckmc_decrypt_data,
-                             ret.params.get(),
-                             ret.prvKey.c_str(),
-                             nullptr,
-                             *ret.encrypted.get(),
-                             &decrypted);
+        assert_crypto_invalid_param(apiDecrypt,
+                                    ret.params.get(),
+                                    ret.prvKey.c_str(),
+                                    nullptr,
+                                    *ret.encrypted.get(),
+                                    &decrypted);
         ckmc_buffer_free(decrypted);
         decrypted = nullptr;
     };
@@ -599,12 +667,12 @@ void testCtrDecryptionValidLength(Algorithm type)
 
     // decryption
     auto test = [&](){
-        assert_positive(ckmc_decrypt_data,
-                             ret.params.get(),
-                             ret.prvKey.c_str(),
-                             nullptr,
-                             *ret.encrypted.get(),
-                             &decrypted);
+        assert_crypto_positive(apiDecrypt,
+                               ret.params.get(),
+                               ret.prvKey.c_str(),
+                               nullptr,
+                               *ret.encrypted.get(),
+                               &decrypted);
         ckmc_buffer_free(decrypted);
         RawBufferPtr tmp = create_raw_buffer(decrypted);
         assert_buffers_equal(*plain.get(), *decrypted);
@@ -638,37 +706,37 @@ void testGcmEncryptionTagLen(Algorithm type)
 
     std::vector<TagTest> testData = {
             // illegal tag lengths
-            { -1,   CKMC_ERROR_INVALID_PARAMETER },
-            { 0,    CKMC_ERROR_INVALID_PARAMETER },
-            { 16,   CKMC_ERROR_INVALID_PARAMETER },
-            { 48,   CKMC_ERROR_INVALID_PARAMETER },
-            { 72,   CKMC_ERROR_INVALID_PARAMETER },
-            { 100,  CKMC_ERROR_INVALID_PARAMETER },
-            { 108,  CKMC_ERROR_INVALID_PARAMETER },
-            { 116,  CKMC_ERROR_INVALID_PARAMETER },
-            { 124,  CKMC_ERROR_INVALID_PARAMETER },
-            { 256,  CKMC_ERROR_INVALID_PARAMETER },
+            { -1,   EncryptionError::INVALID_PARAM },
+            { 0,    EncryptionError::INVALID_PARAM },
+            { 16,   EncryptionError::INVALID_PARAM },
+            { 48,   EncryptionError::INVALID_PARAM },
+            { 72,   EncryptionError::INVALID_PARAM },
+            { 100,  EncryptionError::INVALID_PARAM },
+            { 108,  EncryptionError::INVALID_PARAM },
+            { 116,  EncryptionError::INVALID_PARAM },
+            { 124,  EncryptionError::INVALID_PARAM },
+            { 256,  EncryptionError::INVALID_PARAM },
             // legal tag lengths
-            { 32,   CKMC_ERROR_NONE },
-            { 64,   CKMC_ERROR_NONE },
-            { 96,   CKMC_ERROR_NONE },
-            { 104,  CKMC_ERROR_NONE },
-            { 112,  CKMC_ERROR_NONE },
-            { 120,  CKMC_ERROR_NONE },
-            { 128,  CKMC_ERROR_NONE },
+            { 32,   EncryptionError::SUCCESS },
+            { 64,   EncryptionError::SUCCESS },
+            { 96,   EncryptionError::SUCCESS },
+            { 104,  EncryptionError::SUCCESS },
+            { 112,  EncryptionError::SUCCESS },
+            { 120,  EncryptionError::SUCCESS },
+            { 128,  EncryptionError::SUCCESS },
     };
 
     // encryption
     for(const auto& it : testData)
     {
         setParam(params, CKMC_PARAM_ED_TAG_LEN, it.tagLen);
-        assert_result(it.expected,
-                      ckmc_encrypt_data,
-                      params.get(),
-                      aliases.pub.c_str(),
-                      nullptr,
-                      *plain.get(),
-                      &encryptedTmp);
+        assert_crypto_result(it.expected,
+                             apiEncrypt,
+                             params.get(),
+                             aliases.pub.c_str(),
+                             nullptr,
+                             *plain.get(),
+                             &encryptedTmp);
         ckmc_buffer_free(encryptedTmp);
         encryptedTmp = nullptr;
     }
@@ -687,38 +755,38 @@ void testGcmDecryptionTagLen(Algorithm type)
 
     std::vector<TagTest> testData = {
             // illegal tag lengths
-            { -1,   CKMC_ERROR_INVALID_PARAMETER },
-            { 0,    CKMC_ERROR_INVALID_PARAMETER },
-            { 16,   CKMC_ERROR_INVALID_PARAMETER },
-            { 48,   CKMC_ERROR_INVALID_PARAMETER },
-            { 72,   CKMC_ERROR_INVALID_PARAMETER },
-            { 100,  CKMC_ERROR_INVALID_PARAMETER },
-            { 108,  CKMC_ERROR_INVALID_PARAMETER },
-            { 116,  CKMC_ERROR_INVALID_PARAMETER },
-            { 124,  CKMC_ERROR_INVALID_PARAMETER },
-            { 256,  CKMC_ERROR_INVALID_PARAMETER },
+            { -1,   EncryptionError::INVALID_PARAM },
+            { 0,    EncryptionError::INVALID_PARAM },
+            { 16,   EncryptionError::INVALID_PARAM },
+            { 48,   EncryptionError::INVALID_PARAM },
+            { 72,   EncryptionError::INVALID_PARAM },
+            { 100,  EncryptionError::INVALID_PARAM },
+            { 108,  EncryptionError::INVALID_PARAM },
+            { 116,  EncryptionError::INVALID_PARAM },
+            { 124,  EncryptionError::INVALID_PARAM },
+            { 256,  EncryptionError::INVALID_PARAM },
             // legal tag lengths (EVP_CipherFinal fails but we can't get the error code)
-            { 32,   CKMC_ERROR_SERVER_ERROR },
-            { 64,   CKMC_ERROR_SERVER_ERROR },
-            { 96,   CKMC_ERROR_SERVER_ERROR },
-            { 104,  CKMC_ERROR_SERVER_ERROR },
-            { 112,  CKMC_ERROR_SERVER_ERROR },
-            { 120,  CKMC_ERROR_SERVER_ERROR },
+            { 32,   EncryptionError::SERVER_ERROR },
+            { 64,   EncryptionError::SERVER_ERROR },
+            { 96,   EncryptionError::SERVER_ERROR },
+            { 104,  EncryptionError::SERVER_ERROR },
+            { 112,  EncryptionError::SERVER_ERROR },
+            { 120,  EncryptionError::SERVER_ERROR },
             // legal tag length that was actually used for encryption (default)
-            { 128,  CKMC_ERROR_NONE },
+            { 128,  EncryptionError::SUCCESS },
     };
 
     // decryption
     for(const auto& it : testData)
     {
         setParam(ret.params, CKMC_PARAM_ED_TAG_LEN, it.tagLen);
-        assert_result(it.expected,
-                      ckmc_decrypt_data,
-                      ret.params.get(),
-                      ret.prvKey.c_str(),
-                      nullptr,
-                      *ret.encrypted.get(),
-                      &decrypted);
+        assert_crypto_result(it.expected,
+                             apiDecrypt,
+                             ret.params.get(),
+                             ret.prvKey.c_str(),
+                             nullptr,
+                             *ret.encrypted.get(),
+                             &decrypted);
         ckmc_buffer_free(decrypted);
         decrypted = nullptr;
     }
@@ -739,13 +807,13 @@ void testGcmWrongTag(Algorithm type)
     ret.encrypted->data[ret.encrypted->size-1]++;
 
     // EVP_CipherFinal fails but we can't get error code
-    assert_result(CKMC_ERROR_SERVER_ERROR,
-                  ckmc_decrypt_data,
-                  ret.params.get(),
-                  ret.prvKey.c_str(),
-                  nullptr,
-                  *ret.encrypted.get(),
-                  &decrypted);
+    assert_crypto_result(EncryptionError::SERVER_ERROR,
+                         apiDecrypt,
+                         ret.params.get(),
+                         ret.prvKey.c_str(),
+                         nullptr,
+                         *ret.encrypted.get(),
+                         &decrypted);
 }
 
 void testGcmDifferentIvSizes(Algorithm type)
@@ -755,7 +823,7 @@ void testGcmDifferentIvSizes(Algorithm type)
     // add AES GCM key
     KeyAliasPair aliases = algo->keyGen();
 
-    testGcmIvSize(11,   aliases, CKMC_ERROR_SERVER_ERROR); // 12B is the smallest
+    testGcmIvSize(11,   aliases, EncryptionError::SERVER_ERROR); // 12B is the smallest
     testGcmIvSize(12,  aliases);
     testGcmIvSize(17,  aliases);
     testGcmIvSize(128, aliases);
@@ -772,7 +840,7 @@ void testEncryptDecryptBigData(Algorithm type)
     // encrypt
     auto ret = encrypt(algo, plain);
 
-    assert_positive(ckmc_decrypt_data,
+    assert_positive(apiDecrypt,
                     ret.params.get(),
                     ret.prvKey.c_str(),
                     nullptr,
@@ -799,24 +867,24 @@ void testEncryptDecryptDifferentKeys(Algorithm type, bool success)
 
     if (success) {
         // some algorithms don't verify key validity
-        assert_positive(ckmc_decrypt_data,
-                        ret.params.get(),
-                        differentKeys.prv.c_str(),
-                        nullptr,
-                        *ret.encrypted.get(),
-                        &decrypted);
+        assert_crypto_positive(apiDecrypt,
+                               ret.params.get(),
+                               differentKeys.prv.c_str(),
+                               nullptr,
+                               *ret.encrypted.get(),
+                               &decrypted);
         RawBufferPtr tmp = create_raw_buffer(decrypted);
 
         assert_buffers_equal(*plain.get(), *decrypted, false);
     } else {
         // different key should not be accepted
-        assert_result(CKMC_ERROR_SERVER_ERROR,
-                      ckmc_decrypt_data,
-                      ret.params.get(),
-                      differentKeys.prv.c_str(),
-                      nullptr,
-                      *ret.encrypted.get(),
-                      &decrypted);
+        assert_crypto_result(EncryptionError::SERVER_ERROR,
+                             apiDecrypt,
+                             ret.params.get(),
+                             differentKeys.prv.c_str(),
+                             nullptr,
+                             *ret.encrypted.get(),
+                             &decrypted);
     }
 
     // Cleanup before testing next algorithm. Ignore results because not all keys are present
@@ -836,12 +904,12 @@ void testRsaLongestData(Algorithm type, size_t dataSize)
     // encrypt
     auto ret = encrypt(algo, plain);
 
-    assert_positive(ckmc_decrypt_data,
-                    ret.params.get(),
-                    ret.prvKey.c_str(),
-                    nullptr,
-                    *ret.encrypted.get(),
-                    &decrypted);
+    assert_crypto_positive(apiDecrypt,
+                           ret.params.get(),
+                           ret.prvKey.c_str(),
+                           nullptr,
+                           *ret.encrypted.get(),
+                           &decrypted);
     RawBufferPtr tmp = create_raw_buffer(decrypted);
 
     assert_buffers_equal(*plain.get(), *decrypted);
@@ -860,13 +928,13 @@ void testRsaDataTooLong(Algorithm type, size_t dataSize)
 
     ret.params = createParamListPtr();
     assert_positive(ckmc_generate_params, algo->m_type, ret.params.get());
-    assert_result(CKMC_ERROR_SERVER_ERROR,
-                  ckmc_encrypt_data,
-                  ret.params.get(),
-                  aliases.pub.c_str(),
-                  nullptr,
-                  *plain.get(),
-                  &encrypted);
+    assert_crypto_result(EncryptionError::SERVER_ERROR,
+                         apiEncrypt,
+                         ret.params.get(),
+                         aliases.pub.c_str(),
+                         nullptr,
+                         *plain.get(),
+                         &encrypted);
 }
 
 } // namespace anonymous
@@ -878,7 +946,7 @@ RUNNER_TEST_GROUP_INIT(CKM_ENCRYPTION_DECRYPTION);
 // Generic encryption decryption tests
 /////////////////////////////////////////
 
-RUNNER_TEST(TED_0010_encrypt_invalid_param_list, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0010_encrypt_invalid_param_list, SyncEnv, AsyncEnv)
 {
     testAllAlgorithms([](const AlgoBasePtr& algo){
         // prepare buffers
@@ -889,25 +957,25 @@ RUNNER_TEST(TED_0010_encrypt_invalid_param_list, EncEnv)
         KeyAliasPair aliases = algo->keyGen();
 
         // null param list
-        assert_invalid_param(ckmc_encrypt_data,
-                             nullptr,
-                             aliases.pub.c_str(),
-                             nullptr,
-                             *plain.get(),
-                             &encrypted);
+        assert_crypto_invalid_param(apiEncrypt,
+                                    nullptr,
+                                    aliases.pub.c_str(),
+                                    nullptr,
+                                    *plain.get(),
+                                    &encrypted);
 
         // empty param list
         ParamListPtr params = createParamListPtr();
-        assert_invalid_param(ckmc_encrypt_data,
-                             params.get(),
-                             aliases.pub.c_str(),
-                             nullptr,
-                             *plain.get(),
-                             &encrypted);
+        assert_crypto_invalid_param(apiEncrypt,
+                                    params.get(),
+                                    aliases.pub.c_str(),
+                                    nullptr,
+                                    *plain.get(),
+                                    &encrypted);
     });
 }
 
-RUNNER_TEST(TED_0020_encrypt_missing_key, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0020_encrypt_missing_key, SyncEnv, AsyncEnv)
 {
     testAllAlgorithms([](const AlgoBasePtr& algo){
         // prepare buffers
@@ -919,17 +987,17 @@ RUNNER_TEST(TED_0020_encrypt_missing_key, EncEnv)
         assert_positive(ckmc_generate_params, algo->m_type, params.get());
         setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN));
 
-        assert_result(CKMC_ERROR_DB_ALIAS_UNKNOWN,
-                      ckmc_encrypt_data,
-                      params.get(),
-                      "non-existing-key-alias",
-                      nullptr,
-                      *plain.get(),
-                      &encrypted);
+        assert_crypto_result(EncryptionError::ALIAS_UNKNOWN,
+                             apiEncrypt,
+                             params.get(),
+                             "non-existing-key-alias",
+                             nullptr,
+                             *plain.get(),
+                             &encrypted);
     });
 }
 
-RUNNER_TEST(TED_0030_encrypt_no_plain_text, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0030_encrypt_no_plain_text, SyncEnv, AsyncEnv)
 {
     testAllAlgorithms([](const AlgoBasePtr& algo){
         // prepare buffers
@@ -944,16 +1012,16 @@ RUNNER_TEST(TED_0030_encrypt_no_plain_text, EncEnv)
         assert_positive(ckmc_generate_params, algo->m_type, params.get());
         setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN));
 
-        assert_invalid_param(ckmc_encrypt_data,
-                             params.get(),
-                             aliases.pub.c_str(),
-                             nullptr,
-                             plain,
-                             &encrypted);
+        assert_crypto_invalid_param(apiEncrypt,
+                                    params.get(),
+                                    aliases.pub.c_str(),
+                                    nullptr,
+                                    plain,
+                                    &encrypted);
     });
 }
 
-RUNNER_TEST(TED_0040_encrypt_no_output_buffer, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0040_encrypt_no_output_buffer, SyncEnv, AsyncEnv)
 {
     testAllAlgorithms([](const AlgoBasePtr& algo){
         // prepare buffers
@@ -968,16 +1036,16 @@ RUNNER_TEST(TED_0040_encrypt_no_output_buffer, EncEnv)
         assert_positive(ckmc_generate_params, algo->m_type, params.get());
         setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN));
 
-        assert_invalid_param(ckmc_encrypt_data,
-                             params.get(),
-                             aliases.pub.c_str(),
-                             nullptr,
-                             *plain.get(),
-                             encrypted);
+        assert_crypto_invalid_param(apiEncrypt,
+                                    params.get(),
+                                    aliases.pub.c_str(),
+                                    nullptr,
+                                    *plain.get(),
+                                    encrypted);
     });
 }
 
-RUNNER_TEST(TED_0110_decrypt_invalid_param_list, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0110_decrypt_invalid_param_list, SyncEnv, AsyncEnv)
 {
     testAllAlgorithms([](const AlgoBasePtr& algo){
         // prepare buffers
@@ -988,25 +1056,25 @@ RUNNER_TEST(TED_0110_decrypt_invalid_param_list, EncEnv)
         auto ret = encrypt(algo, plain);
 
         // null param list
-        assert_invalid_param(ckmc_decrypt_data,
-                             nullptr,
-                             ret.prvKey.c_str(),
-                             nullptr,
-                             *ret.encrypted.get(),
-                             &decrypted);
+        assert_crypto_invalid_param(apiDecrypt,
+                                    nullptr,
+                                    ret.prvKey.c_str(),
+                                    nullptr,
+                                    *ret.encrypted.get(),
+                                    &decrypted);
 
         // empty param list
         ParamListPtr params = createParamListPtr();
-        assert_invalid_param(ckmc_decrypt_data,
-                             params.get(),
-                             ret.prvKey.c_str(),
-                             nullptr,
-                             *ret.encrypted.get(),
-                             &decrypted);
+        assert_crypto_invalid_param(apiDecrypt,
+                                    params.get(),
+                                    ret.prvKey.c_str(),
+                                    nullptr,
+                                    *ret.encrypted.get(),
+                                    &decrypted);
     });
 }
 
-RUNNER_TEST(TED_0120_decrypt_missing_key, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0120_decrypt_missing_key, SyncEnv, AsyncEnv)
 {
     testAllAlgorithms([](const AlgoBasePtr& algo){
         // prepare buffers
@@ -1020,17 +1088,17 @@ RUNNER_TEST(TED_0120_decrypt_missing_key, EncEnv)
         assert_positive(ckmc_remove_alias, ret.prvKey.c_str());
 
         // try to decrypt
-        assert_result(CKMC_ERROR_DB_ALIAS_UNKNOWN,
-                      ckmc_decrypt_data,
-                      ret.params.get(),
-                      ret.prvKey.c_str(),
-                      nullptr,
-                      *ret.encrypted.get(),
-                      &decrypted);
+        assert_crypto_result(EncryptionError::ALIAS_UNKNOWN,
+                             apiDecrypt,
+                             ret.params.get(),
+                             ret.prvKey.c_str(),
+                             nullptr,
+                             *ret.encrypted.get(),
+                             &decrypted);
     });
 }
 
-RUNNER_TEST(TED_0130_decrypt_no_encrypted_text, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0130_decrypt_no_encrypted_text, SyncEnv, AsyncEnv)
 {
     testAllAlgorithms([](const AlgoBasePtr& algo){
         // prepare buffers
@@ -1045,16 +1113,16 @@ RUNNER_TEST(TED_0130_decrypt_no_encrypted_text, EncEnv)
         assert_positive(ckmc_generate_params, algo->m_type, params.get());
         setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN));
 
-        assert_invalid_param(ckmc_decrypt_data,
-                             params.get(),
-                             aliases.prv.c_str(),
-                             nullptr,
-                             encrypted,
-                             &decrypted);
+        assert_crypto_invalid_param(apiDecrypt,
+                                    params.get(),
+                                    aliases.prv.c_str(),
+                                    nullptr,
+                                    encrypted,
+                                    &decrypted);
     });
 }
 
-RUNNER_TEST(TED_0140_decrypt_no_output_buffer, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0140_decrypt_no_output_buffer, SyncEnv, AsyncEnv)
 {
     testAllAlgorithms([](const AlgoBasePtr& algo){
         // prepare buffers
@@ -1064,16 +1132,16 @@ RUNNER_TEST(TED_0140_decrypt_no_output_buffer, EncEnv)
         // encrypt
         auto ret = encrypt(algo, plain);
 
-        assert_invalid_param(ckmc_decrypt_data,
-                             ret.params.get(),
-                             ret.prvKey.c_str(),
-                             nullptr,
-                             *ret.encrypted.get(),
-                             decrypted);
+        assert_crypto_invalid_param(apiDecrypt,
+                                    ret.params.get(),
+                                    ret.prvKey.c_str(),
+                                    nullptr,
+                                    *ret.encrypted.get(),
+                                    decrypted);
     });
 }
 
-RUNNER_TEST(TED_0200_encrypt_decrypt_different_keys, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0200_encrypt_decrypt_different_keys, SyncEnv, AsyncEnv)
 {
     testEncryptDecryptDifferentKeys(AES_CBC_128, false);
     testEncryptDecryptDifferentKeys(AES_CBC_192, false);
@@ -1092,7 +1160,7 @@ RUNNER_TEST(TED_0200_encrypt_decrypt_different_keys, EncEnv)
     testEncryptDecryptDifferentKeys(RSA_OAEP_4096, false);
 }
 
-RUNNER_TEST(TED_0210_encrypt_decrypt_different_params, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0210_encrypt_decrypt_different_params, SyncEnv, AsyncEnv)
 {
     testAllAlgorithms([](const AlgoBasePtr& algo){
         // prepare buffers
@@ -1107,16 +1175,16 @@ RUNNER_TEST(TED_0210_encrypt_decrypt_different_params, EncEnv)
         assert_positive(ckmc_generate_params, CKMC_ALGO_RSA_GEN, params.get());
         setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN));
 
-        assert_invalid_param(ckmc_decrypt_data,
-                             params.get(),
-                             ret.prvKey.c_str(),
-                             nullptr,
-                             *ret.encrypted.get(),
-                             &decrypted);
+        assert_crypto_invalid_param(apiDecrypt,
+                                    params.get(),
+                                    ret.prvKey.c_str(),
+                                    nullptr,
+                                    *ret.encrypted.get(),
+                                    &decrypted);
     });
 }
 
-RUNNER_TEST(TED_0300_encrypt_decrypt, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0300_encrypt_decrypt, SyncEnv, AsyncEnv)
 {
     testAllAlgorithms([](const AlgoBasePtr& algo){
         // prepare buffers
@@ -1126,19 +1194,19 @@ RUNNER_TEST(TED_0300_encrypt_decrypt, EncEnv)
         // encrypt
         auto ret = encrypt(algo, plain);
 
-        assert_positive(ckmc_decrypt_data,
-                        ret.params.get(),
-                        ret.prvKey.c_str(),
-                        nullptr,
-                        *ret.encrypted.get(),
-                        &decrypted);
+        assert_crypto_positive(apiDecrypt,
+                               ret.params.get(),
+                               ret.prvKey.c_str(),
+                               nullptr,
+                               *ret.encrypted.get(),
+                               &decrypted);
         RawBufferPtr tmp = create_raw_buffer(decrypted);
 
         assert_buffers_equal(*plain.get(), *decrypted);
     });
 }
 
-RUNNER_TEST(TED_0310_encrypt_decrypt_password, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0310_encrypt_decrypt_password, SyncEnv, AsyncEnv)
 {
     testAllAlgorithms([](const AlgoBasePtr& algo){
         // prepare buffers
@@ -1149,21 +1217,21 @@ RUNNER_TEST(TED_0310_encrypt_decrypt_password, EncEnv)
         auto ret = encrypt(algo, plain, PASSWORD);
 
         // wrong password
-        assert_result(CKMC_ERROR_AUTHENTICATION_FAILED,
-                      ckmc_decrypt_data,
-                      ret.params.get(),
-                      ret.prvKey.c_str(),
-                      "wrong-password",
-                      *ret.encrypted.get(),
-                      &decrypted);
+        assert_crypto_result(EncryptionError::AUTH_FAILED,
+                             apiDecrypt,
+                             ret.params.get(),
+                             ret.prvKey.c_str(),
+                             "wrong-password",
+                             *ret.encrypted.get(),
+                             &decrypted);
 
         // correct password
-        assert_positive(ckmc_decrypt_data,
-                        ret.params.get(),
-                        ret.prvKey.c_str(),
-                        PASSWORD,
-                        *ret.encrypted.get(),
-                        &decrypted);
+        assert_crypto_positive(apiDecrypt,
+                               ret.params.get(),
+                               ret.prvKey.c_str(),
+                               PASSWORD,
+                               *ret.encrypted.get(),
+                               &decrypted);
         RawBufferPtr tmp = create_raw_buffer(decrypted); // guarantees deletion
 
         assert_buffers_equal(*plain.get(), *decrypted);
@@ -1171,62 +1239,62 @@ RUNNER_TEST(TED_0310_encrypt_decrypt_password, EncEnv)
 }
 
 // long test split into smaller ones
-RUNNER_TEST(TED_0400_encrypt_decrypt_big_data_aes_cbc_128, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_cbc_128, SyncEnv, AsyncEnv)
 {
     testEncryptDecryptBigData(AES_CBC_128);
 }
 
-RUNNER_TEST(TED_0400_encrypt_decrypt_big_data_aes_cbc_192, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_cbc_192, SyncEnv, AsyncEnv)
 {
     testEncryptDecryptBigData(AES_CBC_192);
 }
 
-RUNNER_TEST(TED_0400_encrypt_decrypt_big_data_aes_cbc_256, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_cbc_256, SyncEnv, AsyncEnv)
 {
     testEncryptDecryptBigData(AES_CBC_256);
 }
 
-RUNNER_TEST(TED_0400_encrypt_decrypt_big_data_aes_gcm_128, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_gcm_128, SyncEnv, AsyncEnv)
 {
     testEncryptDecryptBigData(AES_GCM_128);
 }
 
-RUNNER_TEST(TED_0400_encrypt_decrypt_big_data_aes_gcm_192, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_gcm_192, SyncEnv, AsyncEnv)
 {
     testEncryptDecryptBigData(AES_GCM_192);
 }
 
-RUNNER_TEST(TED_0400_encrypt_decrypt_big_data_aes_gcm_256, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_gcm_256, SyncEnv, AsyncEnv)
 {
     testEncryptDecryptBigData(AES_GCM_256);
 }
 
-RUNNER_TEST(TED_0400_encrypt_decrypt_big_data_aes_ctr_128, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_ctr_128, SyncEnv, AsyncEnv)
 {
     testEncryptDecryptBigData(AES_CTR_128);
 }
 
-RUNNER_TEST(TED_0400_encrypt_decrypt_big_data_aes_ctr_192, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_ctr_192, SyncEnv, AsyncEnv)
 {
     testEncryptDecryptBigData(AES_CTR_192);
 }
 
-RUNNER_TEST(TED_0400_encrypt_decrypt_big_data_aes_ctr_256, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_ctr_256, SyncEnv, AsyncEnv)
 {
     testEncryptDecryptBigData(AES_CTR_256);
 }
 
-RUNNER_TEST(TED_0400_encrypt_decrypt_big_data_aes_cfb_128, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_cfb_128, SyncEnv, AsyncEnv)
 {
     testEncryptDecryptBigData(AES_CFB_128);
 }
 
-RUNNER_TEST(TED_0400_encrypt_decrypt_big_data_aes_cfb_192, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_cfb_192, SyncEnv, AsyncEnv)
 {
     testEncryptDecryptBigData(AES_CFB_192);
 }
 
-RUNNER_TEST(TED_0400_encrypt_decrypt_big_data_aes_cfb_256, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_cfb_256, SyncEnv, AsyncEnv)
 {
     testEncryptDecryptBigData(AES_CFB_256);
 }
@@ -1235,7 +1303,7 @@ RUNNER_TEST(TED_0400_encrypt_decrypt_big_data_aes_cfb_256, EncEnv)
 // Algorithm specific tests
 /////////////////////////////////////////
 
-RUNNER_TEST(TED_1005_no_iv_enc, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1005_no_iv_enc, SyncEnv, AsyncEnv)
 {
     testNoIvEnc(AES_CTR_128);
     testNoIvEnc(AES_CTR_192);
@@ -1251,7 +1319,7 @@ RUNNER_TEST(TED_1005_no_iv_enc, EncEnv)
     testNoIvEnc(AES_GCM_256);
 }
 
-RUNNER_TEST(TED_1010_invalid_iv_enc, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1010_invalid_iv_enc, SyncEnv, AsyncEnv)
 {
     testInvalidIvEnc(AES_CTR_128);
     testInvalidIvEnc(AES_CTR_192);
@@ -1264,7 +1332,7 @@ RUNNER_TEST(TED_1010_invalid_iv_enc, EncEnv)
     testInvalidIvEnc(AES_CFB_256);
 }
 
-RUNNER_TEST(TED_1015_no_iv_dec, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1015_no_iv_dec, SyncEnv, AsyncEnv)
 {
     testNoIvDec(AES_CTR_128);
     testNoIvDec(AES_CTR_192);
@@ -1280,7 +1348,7 @@ RUNNER_TEST(TED_1015_no_iv_dec, EncEnv)
     testNoIvDec(AES_GCM_256);
 }
 
-RUNNER_TEST(TED_1020_invalid_iv_dec, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1020_invalid_iv_dec, SyncEnv, AsyncEnv)
 {
     testInvalidIvDec(AES_CTR_128);
     testInvalidIvDec(AES_CTR_192);
@@ -1293,7 +1361,7 @@ RUNNER_TEST(TED_1020_invalid_iv_dec, EncEnv)
     testInvalidIvDec(AES_CFB_256);
 }
 
-RUNNER_TEST(TED_1050_data_integrity, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1050_data_integrity, SyncEnv, AsyncEnv)
 {
     testIntegrity(AES_CTR_128);
     testIntegrity(AES_CTR_192);
@@ -1306,14 +1374,14 @@ RUNNER_TEST(TED_1050_data_integrity, EncEnv)
     testIntegrity(AES_CFB_256);
 }
 
-RUNNER_TEST(TED_1100_ctr_encryption_invalid_length, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1100_ctr_encryption_invalid_length, SyncEnv, AsyncEnv)
 {
     testCtrEncryptionInvalidLength(AES_CTR_128);
     testCtrEncryptionInvalidLength(AES_CTR_192);
     testCtrEncryptionInvalidLength(AES_CTR_256);
 }
 
-RUNNER_TEST(TED_1105_ctr_encryption_valid_length, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1105_ctr_encryption_valid_length, SyncEnv, AsyncEnv)
 {
     RUNNER_IGNORED_MSG("Openssl supports only 128-bit AES CTR length");
     testCtrEncryptionValidLength(AES_CTR_128);
@@ -1321,14 +1389,14 @@ RUNNER_TEST(TED_1105_ctr_encryption_valid_length, EncEnv)
     testCtrEncryptionValidLength(AES_CTR_256);
 }
 
-RUNNER_TEST(TED_1110_ctr_decryption_invalid_length, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1110_ctr_decryption_invalid_length, SyncEnv, AsyncEnv)
 {
     testCtrDecryptionInvalidLength(AES_CTR_128);
     testCtrDecryptionInvalidLength(AES_CTR_192);
     testCtrDecryptionInvalidLength(AES_CTR_256);
 }
 
-RUNNER_TEST(TED_1115_ctr_decryption_valid_length, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1115_ctr_decryption_valid_length, SyncEnv, AsyncEnv)
 {
     RUNNER_IGNORED_MSG("Openssl supports only 128-bit AES CTR length");
     testCtrDecryptionValidLength(AES_CTR_128);
@@ -1336,42 +1404,42 @@ RUNNER_TEST(TED_1115_ctr_decryption_valid_length, EncEnv)
     testCtrDecryptionValidLength(AES_CTR_256);
 }
 
-RUNNER_TEST(TED_1200_gcm_encryption_tag_len, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1200_gcm_encryption_tag_len, SyncEnv, AsyncEnv)
 {
     testGcmEncryptionTagLen(AES_GCM_128);
     testGcmEncryptionTagLen(AES_GCM_192);
     testGcmEncryptionTagLen(AES_GCM_256);
 }
 
-RUNNER_TEST(TED_1210_gcm_decryption_tag_len, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1210_gcm_decryption_tag_len, SyncEnv, AsyncEnv)
 {
     testGcmDecryptionTagLen(AES_GCM_128);
     testGcmDecryptionTagLen(AES_GCM_192);
     testGcmDecryptionTagLen(AES_GCM_256);
 }
 
-RUNNER_TEST(TED_1230_gcm_wrong_tag, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1230_gcm_wrong_tag, SyncEnv, AsyncEnv)
 {
     testGcmWrongTag(AES_GCM_128);
     testGcmWrongTag(AES_GCM_192);
     testGcmWrongTag(AES_GCM_256);
 }
 
-RUNNER_TEST(TED_1240_gcm_different_iv_sizes, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1240_gcm_different_iv_sizes, SyncEnv, AsyncEnv)
 {
     testGcmDifferentIvSizes(AES_GCM_128);
     testGcmDifferentIvSizes(AES_GCM_192);
     testGcmDifferentIvSizes(AES_GCM_256);
 }
 
-RUNNER_TEST(TED_1250_gcm_aad, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1250_gcm_aad, SyncEnv, AsyncEnv)
 {
     encryptionWithCustomData(AES_GCM_128, CKMC_PARAM_ED_AAD);
     encryptionWithCustomData(AES_GCM_192, CKMC_PARAM_ED_AAD);
     encryptionWithCustomData(AES_GCM_256, CKMC_PARAM_ED_AAD);
 }
 
-RUNNER_TEST(TED_1300_rsa_label, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1300_rsa_label, SyncEnv, AsyncEnv)
 {
     RUNNER_IGNORED_MSG("RSA-OAEP labels are not supported in openssl");
     encryptionWithCustomData(RSA_OAEP_1024, CKMC_PARAM_ED_LABEL);
@@ -1379,14 +1447,14 @@ RUNNER_TEST(TED_1300_rsa_label, EncEnv)
     encryptionWithCustomData(RSA_OAEP_4096, CKMC_PARAM_ED_LABEL);
 }
 
-RUNNER_TEST(TED_1330_rsa_longest_data, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1330_rsa_longest_data, SyncEnv, AsyncEnv)
 {
     testRsaLongestData(RSA_OAEP_1024, 86);
     testRsaLongestData(RSA_OAEP_2048, 214);
     testRsaLongestData(RSA_OAEP_4096, 470);
 }
 
-RUNNER_TEST(TED_1350_rsa_data_too_long, EncEnv)
+RUNNER_TEST_MULTIPLE(TED_1350_rsa_data_too_long, SyncEnv, AsyncEnv)
 {
     testRsaDataTooLong(RSA_OAEP_1024, 87);
     testRsaDataTooLong(RSA_OAEP_2048, 215);