Unit and system tests for YACA using OpenSSL mockup 96/232596/16
authorLukasz Pawelczyk <l.pawelczyk@samsung.com>
Wed, 6 May 2020 12:35:53 +0000 (14:35 +0200)
committerLukasz Pawelczyk <l.pawelczyk@samsung.com>
Wed, 8 Jul 2020 11:42:09 +0000 (13:42 +0200)
Those tests use OpenSSL mockup to test behaviour of YACA when OpenSSL
fails. This code covers remaining ~16% of YACA's code.

Change-Id: I1c22097155dc37a56c397b024abbc04a1c60faba

tests/CMakeLists.txt
tests/common.h
tests/mock_test_crypto.cpp [new file with mode: 0644]
tests/mock_test_digest.cpp [new file with mode: 0644]
tests/mock_test_encrypt.cpp [new file with mode: 0644]
tests/mock_test_key.cpp [new file with mode: 0644]
tests/mock_test_rsa.cpp [new file with mode: 0644]
tests/mock_test_seal.cpp [new file with mode: 0644]
tests/mock_test_sign.cpp [new file with mode: 0644]
tests/mock_test_simple.cpp [new file with mode: 0644]

index ad3eb0dbc424bd51049fbda349fac6a6eddfc7ff..8e81541c2d97b581c6f5d96cd6caf11e5a3ba430 100644 (file)
@@ -34,6 +34,14 @@ SET(TESTS_SOURCES
        test_seal.cpp
        test_sign.cpp
        openssl_mock_impl.c
+       mock_test_crypto.cpp
+       mock_test_key.cpp
+       mock_test_simple.cpp
+       mock_test_rsa.cpp
+       mock_test_digest.cpp
+       mock_test_encrypt.cpp
+       mock_test_seal.cpp
+       mock_test_sign.cpp
        )
 
 FIND_PACKAGE(Boost REQUIRED unit_test_framework)
index 6c661e3dc6e2c7fe7826b36a28aed65c35a7c89d..38d512259ad6beec8e95e02beb630963f9e67b47 100644 (file)
 #include <yaca_error.h>
 #include "../src/debug.h"
 
+#include "openssl_mock_impl.h"
+
+#include <yaca_crypto.h>
+#include <yaca_error.h>
+#include "../src/debug.h"
+
 
 constexpr size_t INPUT_DATA_SIZE = 4096;
 constexpr char INPUT_DATA[INPUT_DATA_SIZE] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus congue semper ipsum, ac convallis magna rhoncus sit amet. Donec pellentesque maximus convallis. Mauris ut egestas sem. Maecenas efficitur suscipit auctor. Nunc malesuada laoreet porttitor. Donec gravida tortor nisi, in mattis lectus porta ut. Integer vehicula eros et tellus placerat, nec fermentum justo aliquet.\
@@ -89,4 +95,46 @@ void call_update_loop(yaca_context_h ctx, const char *input, size_t input_len,
                                          char *output, size_t &output_len, size_t split,
                                          update_fun_5_t *fun);
 
+/* This function automates using mockup infrastructure with the
+ * designated test (passed in the argument). The test is called in a
+ * loop starting with MOCK_fail_nth == 1 increasing it by 1 on every
+ * call. The idea is to fail all mocked up OpenSSL functions that the
+ * test uses one by one. In such cases the test is expected to fail.
+ *
+ * When the value of MOCK_fail_nth surpasses the number of used
+ * OpenSSL functions that are mocked up the test is expected to
+ * succeed and the function quits with a success.
+ *
+ * Every other outcome is considered a failure.
+ *
+ * See HANDLE_FUNCTION() in openssl_mock_impl.c
+ */
+template<typename func>
+void call_mock_test(func F)
+{
+       for (int n = 1; ; ++n) {
+               MOCK_fail_nth = n;
+
+               int ret = F();
+
+               if (MOCK_fail_nth == 0) {
+                       /* The nth OpenSSL function failed. The test is expected
+                        * to fail. Increase the value and carry on.
+                        */
+                       BOOST_REQUIRE_MESSAGE(ret != YACA_ERROR_NONE,
+                                                                 "The code should've failed\n");
+               } else /* if (MOCK_fail_nth > 0) */ {
+                       /* The n seems to be higher than the number of mocked up
+                        * OpenSSL calls. The test is expected to succeed as no
+                        * OpenSSL functions failed in the end. Quit the loop.
+                        */
+                       BOOST_REQUIRE_MESSAGE(ret == YACA_ERROR_NONE,
+                                                                 "The code should've succeeded\n");
+                       MOCK_fail_nth = 0;
+                       break;
+               }
+       }
+}
+
+
 #endif /* COMMON_H */
diff --git a/tests/mock_test_crypto.cpp b/tests/mock_test_crypto.cpp
new file mode 100644 (file)
index 0000000..93deb81
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ *  Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ *
+ *  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    mock_test_crypto.cpp
+ * @author  Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ * @brief   Base crypto API unit tests using mockup.
+ */
+
+#include <boost/test/unit_test.hpp>
+
+#include <openssl/rand.h>
+#include <sys/syscall.h>
+
+#include <yaca_crypto.h>
+#include <yaca_error.h>
+
+#include "common.h"
+#include "openssl_mock_impl.h"
+
+
+namespace {
+
+const size_t DATA_SIZE = 10;
+
+}
+
+BOOST_AUTO_TEST_SUITE(MOCK_TESTS_CRYPTO)
+
+BOOST_FIXTURE_TEST_CASE(T1101__mock__negative__malloc, InitFixture)
+{
+       int ret;
+       char *alloc;
+
+       MOCK_fail_OPENSSL_malloc = 1;
+       ret = yaca_malloc(DATA_SIZE, (void**)&alloc);
+       BOOST_REQUIRE(ret == YACA_ERROR_OUT_OF_MEMORY);
+}
+
+
+BOOST_FIXTURE_TEST_CASE(T1102__mock__negative__zalloc, InitFixture)
+{
+       int ret;
+       char *alloc;
+
+       MOCK_fail_OPENSSL_malloc = 1;
+       ret = yaca_zalloc(DATA_SIZE, (void**)&alloc);
+       BOOST_REQUIRE(ret == YACA_ERROR_OUT_OF_MEMORY);
+}
+
+
+BOOST_FIXTURE_TEST_CASE(T1103__mock__negative__realloc, InitFixture)
+{
+       int ret;
+       char *alloc;
+
+       ret = yaca_zalloc(DATA_SIZE, (void**)&alloc);
+       BOOST_REQUIRE(ret == YACA_ERROR_NONE);
+
+       MOCK_fail_OPENSSL_realloc = 1;
+       ret = yaca_realloc(DATA_SIZE * 2, (void**)&alloc);
+       BOOST_REQUIRE(ret == YACA_ERROR_OUT_OF_MEMORY);
+
+       yaca_free(alloc);
+}
+
+BOOST_FIXTURE_TEST_CASE(T1104__mock__negative__randomize_bytes, InitFixture)
+{
+       int ret;
+       char buf[DATA_SIZE] = {};
+
+       MOCK_fail_RAND_bytes = 1;
+       ret = yaca_randomize_bytes(buf, DATA_SIZE);
+       BOOST_REQUIRE(ret == YACA_ERROR_INTERNAL);
+}
+
+#ifndef SYS_getrandom
+BOOST_AUTO_TEST_CASE(T1105__mock__negative__sys_init)
+{
+       int ret;
+
+       MOCK_fail_open = 1;
+       ret = yaca_initialize();
+       BOOST_REQUIRE(ret == YACA_ERROR_INTERNAL);
+}
+
+BOOST_FIXTURE_TEST_CASE(T1106__mock__negative__sys_randomize_bytes, InitFixture)
+{
+       int ret;
+       char data[DATA_SIZE];
+
+       MOCK_fail_read = 1;
+       ret = yaca_randomize_bytes(data, DATA_SIZE);
+       BOOST_REQUIRE(ret == YACA_ERROR_INTERNAL);
+}
+#endif
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/mock_test_digest.cpp b/tests/mock_test_digest.cpp
new file mode 100644 (file)
index 0000000..24ba81f
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ *
+ *  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    test_digest.cpp
+ * @author  Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ * @brief   Digest API unit tests.
+ */
+
+#include <boost/test/unit_test.hpp>
+#include <vector>
+
+#include <yaca_crypto.h>
+#include <yaca_digest.h>
+#include <yaca_encrypt.h>
+#include <yaca_key.h>
+#include <yaca_error.h>
+
+#include "common.h"
+
+
+BOOST_AUTO_TEST_SUITE(MOCK_TESTS_DIGEST)
+
+BOOST_FIXTURE_TEST_CASE(T1501__mock__negative__yaca_digest, InitFixture)
+{
+       struct digest_args {
+               yaca_digest_algorithm_e algo = YACA_DIGEST_SHA256;
+       };
+
+       const std::vector<struct digest_args> dargs = {
+               {yaca_digest_algorithm_e::YACA_DIGEST_MD5},
+               {yaca_digest_algorithm_e::YACA_DIGEST_SHA224}
+       };
+
+       for (const auto &da: dargs) {
+               auto test_code = [&da]() -> int
+                       {
+                               int ret;
+                               yaca_context_h ctx = YACA_CONTEXT_NULL;
+                               char *digest = NULL;
+                               size_t digest_len;
+
+                               ret = yaca_digest_initialize(&ctx, da.algo);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_digest_update(ctx, INPUT_DATA, INPUT_DATA_SIZE);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_context_get_output_length(ctx, 0, &digest_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_malloc(digest_len, (void**)&digest);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_digest_finalize(ctx, digest, &digest_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                       exit:
+                               yaca_context_destroy(ctx);
+                               yaca_free(digest);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/mock_test_encrypt.cpp b/tests/mock_test_encrypt.cpp
new file mode 100644 (file)
index 0000000..e2657b5
--- /dev/null
@@ -0,0 +1,684 @@
+/*
+ *  Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ *
+ *  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    test_encrypt.cpp
+ * @author  Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ * @brief   Encrypt API unit tests.
+ */
+
+#include <boost/test/unit_test.hpp>
+#include <vector>
+#include <cstring>
+
+#include <yaca_crypto.h>
+#include <yaca_encrypt.h>
+#include <yaca_key.h>
+#include <yaca_digest.h>
+#include <yaca_error.h>
+
+#include "common.h"
+
+
+BOOST_AUTO_TEST_SUITE(MOCK_TESTS_ENCRYPT)
+
+BOOST_FIXTURE_TEST_CASE(T1601__mock__negative__encrypt_decrypt, InitFixture)
+{
+       struct encrypt_args {
+               yaca_encrypt_algorithm_e algo;
+               yaca_block_cipher_mode_e bcm;
+               size_t key_bit_len;
+               yaca_padding_e padding;
+       };
+
+       const std::vector<encrypt_args> eargs = {
+               {YACA_ENCRYPT_AES,               YACA_BCM_CBC,  128, YACA_PADDING_NONE   },
+               {YACA_ENCRYPT_UNSAFE_DES,        YACA_BCM_OFB,   64, YACA_INVALID_PADDING},
+               {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CBC,  128, YACA_PADDING_PKCS7  },
+               {YACA_ENCRYPT_3DES_3TDEA,        YACA_BCM_CFB1, 192, YACA_INVALID_PADDING},
+               {YACA_ENCRYPT_UNSAFE_RC4,        YACA_BCM_NONE, 256, YACA_INVALID_PADDING},
+               {YACA_ENCRYPT_CAST5,             YACA_BCM_ECB,  128, YACA_PADDING_NONE   }
+       };
+
+       for (const auto &ea: eargs) {
+               auto test_code = [&ea]()
+                       {
+                               int ret;
+                               yaca_context_h ctx = YACA_CONTEXT_NULL;
+                               yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL;
+
+                               size_t iv_bit_len, len1 = 0, len2 = 0;
+
+                               char *encrypted = NULL, *decrypted = NULL;
+                               size_t encrypted_len = 0, decrypted_len = 0;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_encrypt_get_iv_bit_length(ea.algo, ea.bcm, ea.key_bit_len, &iv_bit_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               if (iv_bit_len > 0) {
+                                       ret = yaca_key_generate(YACA_KEY_TYPE_IV, iv_bit_len, &iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                               }
+
+                               /* ENCRYPT */
+                               {
+                                       ret = yaca_encrypt_initialize(&ctx, ea.algo, ea.bcm, key, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len = written;
+
+                                       if (ea.padding != YACA_INVALID_PADDING) {
+                                               ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &ea.padding,
+                                                                                                               sizeof(yaca_padding_e));
+                                               if (ret != YACA_ERROR_NONE) goto exit;
+                                       }
+
+                                       ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len += written;
+
+                                       ret = yaca_realloc(encrypted_len, (void **)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                               /* DECRYPT */
+                               {
+                                       ret = yaca_decrypt_initialize(&ctx, ea.algo, ea.bcm, key, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       if (ea.padding != YACA_INVALID_PADDING) {
+                                               ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &ea.padding,
+                                                                                                               sizeof(yaca_padding_e));
+                                               if (ret != YACA_ERROR_NONE) goto exit;
+                                       }
+
+                                       ret = yaca_context_get_output_length(ctx, encrypted_len, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&decrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       decrypted_len = written;
+
+                                       ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                       exit:
+                               yaca_context_destroy(ctx);
+                               yaca_key_destroy(key);
+                               yaca_key_destroy(iv);
+                               yaca_free(encrypted);
+                               yaca_free(decrypted);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1602__mock__negative__encrypt_decrypt_wrap, InitFixture)
+{
+       struct encrypt_args {
+               yaca_encrypt_algorithm_e algo;
+               size_t key_bit_len;
+               size_t key_material_len;
+       };
+
+       const std::vector<encrypt_args> eargs = {
+               {YACA_ENCRYPT_AES,        128, 192 / 8},
+               {YACA_ENCRYPT_3DES_3TDEA, 192, 128 / 8},
+       };
+
+       for (const auto &ea: eargs) {
+               auto test_code = [&ea]()
+                       {
+                               int ret;
+                               yaca_context_h ctx = YACA_CONTEXT_NULL;
+                               yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL;
+                               char *key_material = NULL;
+
+                               size_t iv_bit_len, len1, len2;
+
+                               char *encrypted = NULL, *decrypted = NULL;
+                               size_t encrypted_len, decrypted_len;
+
+                               ret = yaca_zalloc(ea.key_material_len, (void**)&key_material);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+                               ret = yaca_randomize_bytes(key_material, ea.key_material_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_encrypt_get_iv_bit_length(ea.algo, YACA_BCM_WRAP, ea.key_bit_len, &iv_bit_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               if (iv_bit_len > 0) {
+                                       ret = yaca_key_generate(YACA_KEY_TYPE_IV, iv_bit_len, &iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                               }
+
+                               /* ENCRYPT */
+                               {
+                                       ret = yaca_encrypt_initialize(&ctx, ea.algo, YACA_BCM_WRAP, key, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, ea.key_material_len, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_encrypt_update(ctx, key_material, ea.key_material_len,
+                                                                                         encrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len = written;
+
+                                       ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len += written;
+
+                                       ret = yaca_realloc(encrypted_len, (void **)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                               /* DECRYPT */
+                               {
+                                       ret = yaca_decrypt_initialize(&ctx, ea.algo, YACA_BCM_WRAP, key, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, encrypted_len, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&decrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       decrypted_len = written;
+
+                                       ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                       exit:
+                               yaca_context_destroy(ctx);
+                               yaca_key_destroy(key);
+                               yaca_key_destroy(iv);
+                               yaca_free(key_material);
+                               yaca_free(encrypted);
+                               yaca_free(decrypted);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1603__mock__negative__encrypt_decrypt_rc2, InitFixture)
+{
+       struct encrypt_args {
+               yaca_block_cipher_mode_e bcm;
+               size_t key_bit_len;
+               yaca_padding_e padding;
+               size_t effective_key_bits;
+       };
+
+       const std::vector<encrypt_args> eargs = {
+               {YACA_BCM_CBC, 224, YACA_INVALID_PADDING, 1},
+               {YACA_BCM_CBC, 192, YACA_PADDING_NONE,   64},
+               {YACA_BCM_CBC, 272, YACA_PADDING_PKCS7,   8},
+       };
+
+       for (const auto &ea: eargs) {
+               auto test_code = [&ea]()
+                       {
+                               int ret;
+                               yaca_context_h ctx = YACA_CONTEXT_NULL;
+                               yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL;
+
+                               size_t iv_bit_len, len1 = 0, len2 = 0;
+
+                               char *encrypted = NULL, *decrypted = NULL;
+                               size_t encrypted_len = 0, decrypted_len = 0;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_encrypt_get_iv_bit_length(YACA_ENCRYPT_UNSAFE_RC2, ea.bcm, ea.key_bit_len, &iv_bit_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               if (iv_bit_len > 0) {
+                                       ret = yaca_key_generate(YACA_KEY_TYPE_IV, iv_bit_len, &iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                               }
+
+                               /* ENCRYPT */
+                               {
+                                       ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, ea.bcm, key, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       if (ea.padding != YACA_INVALID_PADDING) {
+                                               ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING,
+                                                                                                               &ea.padding, sizeof(yaca_padding_e));
+                                               if (ret != YACA_ERROR_NONE) goto exit;
+                                       }
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS,
+                                                                                                       &ea.effective_key_bits, sizeof(size_t));
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len = written;
+
+                                       ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len += written;
+
+                                       ret = yaca_realloc(encrypted_len, (void **)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                               /* DECRYPT */
+                               {
+                                       ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_UNSAFE_RC2, ea.bcm, key, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       if (ea.padding != YACA_INVALID_PADDING) {
+                                               ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING,
+                                                                                                               &ea.padding, sizeof(yaca_padding_e));
+                                               if (ret != YACA_ERROR_NONE) goto exit;
+                                       }
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS,
+                                                                                                       &ea.effective_key_bits, sizeof(size_t));
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, encrypted_len, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&decrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       decrypted_len = written;
+
+                                       ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                       exit:
+                               yaca_context_destroy(ctx);
+                               yaca_key_destroy(key);
+                               yaca_key_destroy(iv);
+                               yaca_free(encrypted);
+                               yaca_free(decrypted);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1604__mock__negative__encrypt_decrypt_ccm, InitFixture)
+{
+       struct encrypt_args {
+               size_t key_bit_len;
+               size_t ccm_tag_len;
+               size_t aad_len;
+               size_t iv_bit_len;
+       };
+
+       const std::vector<encrypt_args> eargs = {
+               {128, 12, 19, 64},
+               {192, 10, 34, 96}
+       };
+
+       for (const auto &ea: eargs) {
+               auto test_code = [&ea]()
+                       {
+                               int ret;
+                               yaca_context_h ctx = YACA_CONTEXT_NULL;
+                               yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL;
+
+                               size_t len1, len2;
+
+                               char *tag = NULL, *aad = NULL;
+                               size_t tag_len;
+
+                               char *encrypted = NULL, *decrypted = NULL;
+                               size_t encrypted_len, decrypted_len;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_IV, ea.iv_bit_len, &iv);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               /* ENCRYPT */
+                               {
+                                       ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       tag_len = ea.ccm_tag_len;
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG_LEN,
+                                                                                                       &tag_len, sizeof(tag_len));
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_malloc(ea.aad_len, (void**)&aad);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_randomize_bytes(aad, ea.aad_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_encrypt_update(ctx, NULL, INPUT_DATA_SIZE,
+                                                                                         NULL, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD,
+                                                                                                       aad, ea.aad_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len = written;
+
+                                       ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len += written;
+
+                                       ret = yaca_realloc(encrypted_len, (void **)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_property(ctx, YACA_PROPERTY_CCM_TAG, (void**)&tag, &tag_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                               /* DECRYPT */
+                               {
+                                       ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_CCM, key, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, encrypted_len, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&decrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_decrypt_update(ctx, NULL, encrypted_len,
+                                                                                         NULL, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD,
+                                                                                                       aad, ea.aad_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       decrypted_len = written;
+
+                                       ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                       exit:
+                               yaca_context_destroy(ctx);
+                               yaca_key_destroy(key);
+                               yaca_key_destroy(iv);
+                               yaca_free(encrypted);
+                               yaca_free(decrypted);
+                               yaca_free(tag);
+                               yaca_free(aad);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1605__mock__negative__encrypt_decrypt_gcm, InitFixture)
+{
+       struct encrypt_args {
+               size_t key_bit_len;
+               size_t gcm_tag_len;
+               size_t aad_len;
+               size_t iv_bit_len;
+       };
+
+       const std::vector<encrypt_args> eargs = {
+               {128, 13, 22,  64},
+               {256, 14, 12, 128}
+       };
+
+       for (const auto &ea: eargs) {
+               auto test_code = [&ea]()
+                       {
+                               int ret;
+                               yaca_context_h ctx = YACA_CONTEXT_NULL;
+                               yaca_key_h key = YACA_KEY_NULL, iv = YACA_KEY_NULL;
+
+                               size_t len1 = 0, len2 = 0;
+
+                               char *encrypted = NULL, *decrypted = NULL;
+                               size_t encrypted_len = 0, decrypted_len = 0;
+
+                               char *tag = NULL, *aad = NULL;
+                               size_t tag_len;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_IV, ea.iv_bit_len, &iv);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               /* ENCRYPT */
+                               {
+                                       ret = yaca_encrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_malloc(ea.aad_len, (void**)&aad);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_randomize_bytes(aad, ea.aad_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD,
+                                                                                                       aad, ea.aad_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_encrypt_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len = written;
+
+                                       ret = yaca_encrypt_finalize(ctx, encrypted + encrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len += written;
+
+                                       ret = yaca_realloc(encrypted_len, (void **)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       tag_len = ea.gcm_tag_len;
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG_LEN,
+                                                                                                       &tag_len, sizeof(tag_len));
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_property(ctx, YACA_PROPERTY_GCM_TAG,
+                                                                                                       (void**)&tag, &tag_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                               /* DECRYPT */
+                               {
+                                       ret = yaca_decrypt_initialize(&ctx, YACA_ENCRYPT_AES, YACA_BCM_GCM, key, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, encrypted_len, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&decrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD,
+                                                                                                       aad, ea.aad_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       decrypted_len = written;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG,
+                                                                                                       tag, tag_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                       exit:
+                               yaca_context_destroy(ctx);
+                               yaca_key_destroy(key);
+                               yaca_key_destroy(iv);
+                               yaca_free(encrypted);
+                               yaca_free(decrypted);
+                               yaca_free(tag);
+                               yaca_free(aad);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/mock_test_key.cpp b/tests/mock_test_key.cpp
new file mode 100644 (file)
index 0000000..2c94c4d
--- /dev/null
@@ -0,0 +1,573 @@
+/*
+ *  Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ *
+ *  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    test_key.cpp
+ * @author  Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ * @brief   Key API unit tests.
+ */
+
+#include <boost/test/unit_test.hpp>
+#include <vector>
+
+#include <yaca_crypto.h>
+#include <yaca_encrypt.h>
+#include <yaca_key.h>
+#include <yaca_simple.h>
+#include <yaca_error.h>
+
+#include "common.h"
+
+
+namespace {
+
+int import_export(yaca_key_h key, yaca_key_type_e type, const char *password,
+                                 yaca_key_format_e format, yaca_key_file_format_e file_format)
+{
+       int ret;
+       yaca_key_h imported = YACA_KEY_NULL;
+
+       char *data = NULL;
+       size_t data_len = 0;
+       yaca_key_type_e key_type;
+       size_t key_length;
+
+       ret = yaca_key_export(key, format, file_format,
+                                                 password, &data, &data_len);
+       if (ret != YACA_ERROR_NONE) goto exit;
+
+       ret = yaca_key_import(type, password, data, data_len, &imported);
+       if (ret != YACA_ERROR_NONE) goto exit;
+
+       ret = yaca_key_get_type(imported, &key_type);
+       if (ret != YACA_ERROR_NONE) goto exit;
+       ret = yaca_key_get_bit_length(imported, &key_length);
+       if (ret != YACA_ERROR_NONE) goto exit;
+
+exit:
+       yaca_key_destroy(imported);
+       yaca_free(data);
+       return ret;
+}
+
+} // namespace
+
+
+BOOST_AUTO_TEST_SUITE(MOCK_TESTS_KEY)
+
+BOOST_FIXTURE_TEST_CASE(T1201__mock__negative__key_symmetric_all, InitFixture)
+{
+       struct key_args {
+               yaca_key_type_e type;
+               yaca_key_bit_length_e len;
+       };
+
+       const std::vector<struct key_args> kargs = {
+               {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT},
+               {YACA_KEY_TYPE_DES,       YACA_KEY_LENGTH_192BIT},
+               {YACA_KEY_TYPE_IV,        YACA_KEY_LENGTH_IV_64BIT}
+       };
+
+       for (const auto &ka: kargs) {
+               auto test_code = [&ka]()
+                       {
+                               int ret;
+                               yaca_key_h key = YACA_KEY_NULL;
+
+                               ret = yaca_key_generate(ka.type, ka.len, &key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = import_export(key, ka.type, "",
+                                                                       YACA_KEY_FORMAT_DEFAULT,
+                                                                       YACA_KEY_FILE_FORMAT_RAW);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = import_export(key, ka.type, "",
+                                                                       YACA_KEY_FORMAT_DEFAULT,
+                                                                       YACA_KEY_FILE_FORMAT_BASE64);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                       exit:
+                               yaca_key_destroy(key);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1202__mock__negative__key_asymmetric_generate_all, InitFixture)
+{
+       struct key_args {
+               yaca_key_type_e type_priv;
+               yaca_key_type_e type_pub;
+               yaca_key_type_e type_params;
+               yaca_key_bit_length_e len;
+       };
+
+       const std::vector<struct key_args> kargs = {
+               {YACA_KEY_TYPE_RSA_PRIV,
+                YACA_KEY_TYPE_RSA_PUB,
+                YACA_INVALID_KEY_TYPE,
+                YACA_KEY_LENGTH_512BIT},
+               {YACA_KEY_TYPE_DSA_PRIV,
+                YACA_KEY_TYPE_DSA_PUB,
+                YACA_KEY_TYPE_DSA_PARAMS,
+                YACA_KEY_LENGTH_512BIT},
+               {YACA_KEY_TYPE_DH_PRIV,
+                YACA_KEY_TYPE_DH_PUB,
+                YACA_KEY_TYPE_DH_PARAMS,
+                (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_1024_160},
+               {YACA_KEY_TYPE_EC_PRIV,
+                YACA_KEY_TYPE_EC_PUB,
+                YACA_KEY_TYPE_EC_PARAMS,
+                (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME192V1}
+       };
+
+       for (const auto &ka: kargs) {
+               auto test_code = [&ka]()
+                       {
+                               int ret;
+                               yaca_key_h priv = YACA_KEY_NULL;
+                               yaca_key_h priv2 = YACA_KEY_NULL;
+                               yaca_key_h pub = YACA_KEY_NULL;
+                               yaca_key_h params = YACA_KEY_NULL;
+                               yaca_key_h params2 = YACA_KEY_NULL;
+
+                               ret = yaca_key_generate(ka.type_priv, ka.len, &priv);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_key_extract_public(priv, &pub);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               if (ka.type_params != YACA_INVALID_KEY_TYPE) {
+                                       ret = yaca_key_generate(ka.type_params, ka.len, &params);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_key_generate_from_parameters(params, &priv2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_key_extract_parameters(pub, &params2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                               }
+
+                       exit:
+                               yaca_key_destroy(params);
+                               yaca_key_destroy(params2);
+                               yaca_key_destroy(priv);
+                               yaca_key_destroy(priv2);
+                               yaca_key_destroy(pub);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1204__mock__negative__key_asymmetric_import_export, InitFixture)
+{
+       struct key_args {
+               yaca_key_type_e type_priv;
+               yaca_key_type_e type_pub;
+               yaca_key_type_e type_params;
+               yaca_key_bit_length_e len;
+       };
+
+       const std::vector<struct key_args> kargs = {
+               {YACA_KEY_TYPE_RSA_PRIV,
+                YACA_KEY_TYPE_RSA_PUB,
+                YACA_INVALID_KEY_TYPE,
+                YACA_KEY_LENGTH_512BIT},
+               {YACA_KEY_TYPE_DSA_PRIV,
+                YACA_KEY_TYPE_DSA_PUB,
+                YACA_KEY_TYPE_DSA_PARAMS,
+                YACA_KEY_LENGTH_512BIT},
+               {YACA_KEY_TYPE_EC_PRIV,
+                YACA_KEY_TYPE_EC_PUB,
+                YACA_KEY_TYPE_EC_PARAMS,
+                (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME192V1},
+               {YACA_KEY_TYPE_DH_PRIV,
+                YACA_KEY_TYPE_DH_PUB,
+                YACA_KEY_TYPE_DH_PARAMS,
+                (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_1024_160},
+       };
+
+       for (const auto &ka: kargs) {
+               auto test_code = [&ka]()
+                       {
+                               int ret;
+                               yaca_key_h key_priv = YACA_KEY_NULL;
+                               yaca_key_h key_pub = YACA_KEY_NULL;
+                               yaca_key_h key_params = YACA_KEY_NULL;
+
+                               ret = yaca_key_generate(ka.type_priv, ka.len, &key_priv);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = import_export(key_priv, ka.type_priv, NULL,
+                                                                       YACA_KEY_FORMAT_DEFAULT,
+                                                                       YACA_KEY_FILE_FORMAT_DER);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = import_export(key_priv, ka.type_priv, NULL,
+                                                                       YACA_KEY_FORMAT_DEFAULT,
+                                                                       YACA_KEY_FILE_FORMAT_PEM);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_key_extract_public(key_priv, &key_pub);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = import_export(key_pub, ka.type_pub, "",
+                                                                       YACA_KEY_FORMAT_DEFAULT,
+                                                                       YACA_KEY_FILE_FORMAT_DER);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = import_export(key_pub, ka.type_pub, "",
+                                                                       YACA_KEY_FORMAT_DEFAULT,
+                                                                       YACA_KEY_FILE_FORMAT_PEM);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               if (ka.type_params != YACA_INVALID_KEY_TYPE) {
+                                       ret = yaca_key_extract_parameters(key_priv, &key_params);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = import_export(key_params, ka.type_params, NULL,
+                                                                               YACA_KEY_FORMAT_DEFAULT,
+                                                                               YACA_KEY_FILE_FORMAT_DER);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = import_export(key_params, ka.type_params, NULL,
+                                                                               YACA_KEY_FORMAT_DEFAULT,
+                                                                               YACA_KEY_FILE_FORMAT_PEM);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                               }
+
+                       exit:
+                               yaca_key_destroy(key_params);
+                               yaca_key_destroy(key_priv);
+                               yaca_key_destroy(key_pub);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1205__mock__negative__key_encrypted_import_export, InitFixture)
+{
+       static const char *PASSWORD = "ExamplE_PassworD";
+
+       struct default_args {
+               yaca_key_type_e type;
+               yaca_key_bit_length_e len;
+       };
+
+       const std::vector<struct default_args> dargs = {
+               {YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT},
+               {YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_512BIT}
+       };
+
+       for (const auto &da: dargs) {
+               auto test_code = [&da]()
+                       {
+                               int ret;
+                               yaca_key_h key = YACA_KEY_NULL;
+
+                               ret = yaca_key_generate(da.type, da.len, &key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = import_export(key, da.type, PASSWORD,
+                                                                       YACA_KEY_FORMAT_DEFAULT,
+                                                                       YACA_KEY_FILE_FORMAT_PEM);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                       exit:
+                               yaca_key_destroy(key);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+
+       struct pkcs8_args {
+               yaca_key_type_e type;
+               yaca_key_bit_length_e len;
+       };
+
+       const std::vector<struct pkcs8_args> pargs {
+               {YACA_KEY_TYPE_RSA_PRIV,
+                YACA_KEY_LENGTH_512BIT},
+               {YACA_KEY_TYPE_DSA_PRIV,
+                YACA_KEY_LENGTH_512BIT},
+               {YACA_KEY_TYPE_EC_PRIV,
+                (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME256V1},
+               {YACA_KEY_TYPE_DH_PRIV,
+                (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_1024_160},
+       };
+
+       for (const auto &pa: pargs) {
+               auto test_code2 = [&pa]()
+                       {
+                               int ret;
+                               yaca_key_h key = YACA_KEY_NULL;
+
+                               ret = yaca_key_generate(pa.type, pa.len, &key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = import_export(key, pa.type, PASSWORD,
+                                                                       YACA_KEY_FORMAT_PKCS8,
+                                                                       YACA_KEY_FILE_FORMAT_DER);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = import_export(key, pa.type, PASSWORD,
+                                                                       YACA_KEY_FORMAT_PKCS8,
+                                                                       YACA_KEY_FILE_FORMAT_PEM);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                       exit:
+                               yaca_key_destroy(key);
+                               return ret;
+                       };
+
+               call_mock_test(test_code2);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1206__mock__negative__key_derive_dh, InitFixture)
+{
+       struct key_args {
+               yaca_key_type_e type;
+               yaca_key_bit_length_e len;
+       };
+
+       const std::vector<struct key_args> kargs = {
+               {YACA_KEY_TYPE_DH_PRIV,
+                (yaca_key_bit_length_e)YACA_KEY_LENGTH_DH_RFC_1024_160},
+               {YACA_KEY_TYPE_EC_PRIV,
+                (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_SECP256K1}
+       };
+
+       for (const auto &ka: kargs) {
+               auto test_code = [&ka]()
+                       {
+                               int ret;
+                               yaca_key_h priv1 = YACA_KEY_NULL, pub1 = YACA_KEY_NULL;
+                               yaca_key_h priv2 = YACA_KEY_NULL, pub2 = YACA_KEY_NULL;
+                               char *secret1 = NULL, *secret2 = NULL;
+                               size_t secret1_len, secret2_len;
+
+                               ret = yaca_key_generate(ka.type, ka.len, &priv1);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+                               ret = yaca_key_generate(ka.type, ka.len, &priv2);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+                               ret = yaca_key_extract_public(priv1, &pub1);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+                               ret = yaca_key_extract_public(priv2, &pub2);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_key_derive_dh(priv1, pub2, &secret1, &secret1_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+                               ret = yaca_key_derive_dh(priv2, pub1, &secret2, &secret2_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                       exit:
+                               yaca_key_destroy(priv1);
+                               yaca_key_destroy(priv2);
+                               yaca_key_destroy(pub1);
+                               yaca_key_destroy(pub2);
+                               yaca_free(secret1);
+                               yaca_free(secret2);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1207__mock__negative__key_derive_kdf, InitFixture)
+{
+       static const size_t SECRET_LEN = 128;
+       static const size_t MATERIAL_LEN = 256;
+
+       struct kdf_args {
+               yaca_kdf_e kdf;
+               yaca_digest_algorithm_e digest;
+       };
+
+       const std::vector<struct kdf_args> kargs = {
+               {YACA_KDF_X942, YACA_DIGEST_SHA1},
+               {YACA_KDF_X962, YACA_DIGEST_MD5}
+       };
+
+       int ret;
+       char secret[SECRET_LEN];
+
+       ret = yaca_randomize_bytes(secret, SECRET_LEN);
+       BOOST_REQUIRE(ret == YACA_ERROR_NONE);
+
+       for (const auto &ka: kargs) {
+               auto test_code = [&ka, &secret]()
+                       {
+                               int ret;
+                               char *key_material = NULL;;
+
+                               ret = yaca_key_derive_kdf(ka.kdf, ka.digest, secret, SECRET_LEN,
+                                                                                 NULL, 0, MATERIAL_LEN, &key_material);
+
+                               yaca_free(key_material);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1208__mock__negative__key_derive_pbkdf2, InitFixture)
+{
+       static const char *PASSWORD = "Password_ExamplE";
+       static const size_t SALT_LEN = 64;
+
+       struct pbkdf2_args {
+               yaca_digest_algorithm_e digest;
+               size_t iter;
+               size_t bit_len;
+       };
+
+       const std::vector<struct pbkdf2_args> pargs = {
+               {YACA_DIGEST_MD5,     1, 256},
+               {YACA_DIGEST_SHA512, 50, 512}
+       };
+
+       int ret;
+       char salt[SALT_LEN];
+
+       ret = yaca_randomize_bytes(salt, SALT_LEN);
+       BOOST_REQUIRE(ret == YACA_ERROR_NONE);
+
+       for (const auto &pa: pargs) {
+               auto test_code = [&pa, &salt]()
+                       {
+                               int ret;
+                               yaca_key_h key = YACA_KEY_NULL;
+
+                               ret = yaca_key_derive_pbkdf2(PASSWORD, salt, SALT_LEN, pa.iter,
+                                                                                        pa.digest, pa.bit_len, &key);
+
+                               yaca_key_destroy(key);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1209__mock__negative__import_x509_cert, InitFixture)
+{
+       static const char data_pem[] = "-----BEGIN CERTIFICATE-----\n\
+MIIC9jCCAl+gAwIBAgIUaWM7DVy/evvsrKz8gkz3qWZKw7EwDQYJKoZIhvcNAQEL\n\
+BQAwgYwxCzAJBgNVBAYTAlBMMRQwEgYDVQQIDAtNYXpvd2llY2tpZTERMA8GA1UE\n\
+BwwIV2Fyc3phd2ExEDAOBgNVBAoMB1NhbXN1bmcxCzAJBgNVBAsMAklUMRQwEgYD\n\
+VQQDDAtzYW1zdW5nLmNvbTEfMB0GCSqGSIb3DQEJARYQbm9uZUBzYW1zdW5nLmNv\n\
+bTAeFw0yMDA0MDkxNzUzMDlaFw0yNTA0MDgxNzUzMDlaMIGMMQswCQYDVQQGEwJQ\n\
+TDEUMBIGA1UECAwLTWF6b3dpZWNraWUxETAPBgNVBAcMCFdhcnN6YXdhMRAwDgYD\n\
+VQQKDAdTYW1zdW5nMQswCQYDVQQLDAJJVDEUMBIGA1UEAwwLc2Ftc3VuZy5jb20x\n\
+HzAdBgkqhkiG9w0BCQEWEG5vbmVAc2Ftc3VuZy5jb20wgZ8wDQYJKoZIhvcNAQEB\n\
+BQADgY0AMIGJAoGBAMrx4VdcBEWSXdOa7nJr6Vh53TDfnqhgOGRUC8c+kGUu45Cp\n\
+hcGU7q44zfqvEdgkVBK+Y6GBMrbB0TALo2zK4RVDIgTc8UskbiBjiP4cHB+Zl460\n\
+kU/0vKZPWt7yWq9g87lppEr/f0RTGrKkkcVadCxmKILr4ZtS9563xXH+kKAlAgMB\n\
+AAGjUzBRMB0GA1UdDgQWBBQBroKxSi+l6RqOD5jQGRYyoM0I1jAfBgNVHSMEGDAW\n\
+gBQBroKxSi+l6RqOD5jQGRYyoM0I1jAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3\n\
+DQEBCwUAA4GBAC1f+n4ly876nTXMjdINH8qmxrHOH55vt7v1KYWqCVFSJbqtQMlT\n\
+E9+bqRGN2LpzMBkDdNkGSrCesI1l/FUStjqdpBGMi1fqFDNDyBXkLJDH5HAMR3ei\n\
+hajHIasdGWcAfj+Cyuk1KcTIEkBfdYR6a8C4g04Vbg6M0qEjFl5UTMwm\n\
+-----END CERTIFICATE-----";
+
+       /* THIS CHUNK OF BYTES IS AUTOMATICALLY GENERATED */
+       static const unsigned char data_der[] = {
+               0x30, 0x82, 0x02, 0xf2, 0x30, 0x82, 0x02, 0x5b, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x3e,
+               0x03, 0xd9, 0x79, 0x86, 0xae, 0xa4, 0x85, 0x59, 0xd6, 0x2b, 0x53, 0x29, 0xee, 0xfd, 0x2c, 0x26,
+               0xe8, 0x72, 0x57, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+               0x05, 0x00, 0x30, 0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+               0x50, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0b, 0x4d, 0x61, 0x7a,
+               0x6f, 0x77, 0x69, 0x65, 0x63, 0x6b, 0x69, 0x65, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04,
+               0x07, 0x0c, 0x06, 0x57, 0x61, 0x72, 0x73, 0x61, 0x77, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55,
+               0x04, 0x0a, 0x0c, 0x07, 0x53, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x31, 0x0b, 0x30, 0x09, 0x06,
+               0x03, 0x55, 0x04, 0x0b, 0x0c, 0x02, 0x49, 0x54, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04,
+               0x03, 0x0c, 0x0b, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x1f,
+               0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e,
+               0x6f, 0x6e, 0x65, 0x40, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
+               0x1e, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x34, 0x31, 0x34, 0x31, 0x35, 0x32, 0x33, 0x30, 0x37, 0x5a,
+               0x17, 0x0d, 0x32, 0x31, 0x30, 0x34, 0x31, 0x34, 0x31, 0x35, 0x32, 0x33, 0x30, 0x37, 0x5a, 0x30,
+               0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x50, 0x4c, 0x31,
+               0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0b, 0x4d, 0x61, 0x7a, 0x6f, 0x77, 0x69,
+               0x65, 0x63, 0x6b, 0x69, 0x65, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x06,
+               0x57, 0x61, 0x72, 0x73, 0x61, 0x77, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
+               0x07, 0x53, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+               0x0b, 0x0c, 0x02, 0x49, 0x54, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0b,
+               0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06,
+               0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x6e, 0x6f, 0x6e, 0x65,
+               0x40, 0x73, 0x61, 0x6d, 0x73, 0x75, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30,
+               0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81,
+               0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xc9, 0x73, 0x11, 0x8f, 0x63, 0x4d, 0xaa,
+               0x8e, 0xc5, 0xb5, 0x6d, 0x9c, 0xea, 0x30, 0x43, 0xb5, 0x5d, 0xd3, 0xb2, 0x9c, 0x59, 0x23, 0xdf,
+               0xa8, 0x69, 0xe6, 0x0d, 0xfe, 0x0a, 0xdb, 0xce, 0x22, 0x64, 0x15, 0x02, 0xf6, 0xa4, 0xe9, 0x22,
+               0x04, 0xce, 0x73, 0x9e, 0x89, 0x1e, 0x87, 0x93, 0x31, 0x07, 0x91, 0x0e, 0xbd, 0x98, 0x45, 0x3d,
+               0x66, 0xe9, 0x59, 0x02, 0xfc, 0x2f, 0xd9, 0x11, 0x71, 0xc4, 0x11, 0x3f, 0x20, 0xf3, 0x49, 0xb6,
+               0x59, 0x26, 0xb2, 0x8c, 0x9f, 0x74, 0xe0, 0x09, 0x3b, 0x4f, 0xdd, 0xf4, 0x13, 0x8b, 0x91, 0x48,
+               0x1e, 0x1b, 0xf5, 0x86, 0xca, 0xe6, 0xd6, 0x1d, 0x29, 0x74, 0x1d, 0xb6, 0x84, 0x0b, 0x48, 0xe7,
+               0x40, 0x14, 0x60, 0x65, 0xb2, 0x35, 0xf0, 0x48, 0xe9, 0x93, 0xea, 0x77, 0x63, 0x77, 0x53, 0x77,
+               0xaf, 0xbb, 0xac, 0xc2, 0x86, 0x40, 0xc7, 0xb0, 0x0b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53,
+               0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd0, 0xb1, 0x78,
+               0xed, 0xee, 0xb4, 0x57, 0x7b, 0x4f, 0xed, 0x45, 0xba, 0x0b, 0x5a, 0x32, 0xe5, 0xe1, 0x32, 0xee,
+               0x83, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xd0, 0xb1,
+               0x78, 0xed, 0xee, 0xb4, 0x57, 0x7b, 0x4f, 0xed, 0x45, 0xba, 0x0b, 0x5a, 0x32, 0xe5, 0xe1, 0x32,
+               0xee, 0x83, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
+               0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+               0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x2e, 0xf4, 0x42, 0x8b, 0xde, 0xfe, 0x36, 0x79, 0x6d, 0xaa,
+               0x51, 0x85, 0x65, 0xe3, 0x0f, 0x89, 0x1f, 0x84, 0xce, 0x5c, 0x34, 0x03, 0x0d, 0x59, 0x2a, 0xad,
+               0xfb, 0x09, 0xd2, 0xcd, 0xbc, 0xac, 0x51, 0x4a, 0xe3, 0xcb, 0x9e, 0xe5, 0x75, 0x26, 0x36, 0x5e,
+               0xe7, 0xc6, 0x86, 0x6b, 0xf8, 0xc4, 0x96, 0x99, 0x43, 0xb6, 0x53, 0xcc, 0x6a, 0x14, 0x57, 0xcd,
+               0x08, 0xad, 0x53, 0x11, 0x5f, 0x17, 0x97, 0xb3, 0x2f, 0x36, 0xbe, 0xd6, 0x5c, 0x03, 0x32, 0xe3,
+               0x2a, 0x4f, 0x69, 0x85, 0xf6, 0xf0, 0x14, 0x13, 0x2b, 0xfc, 0xa6, 0x64, 0x67, 0x4d, 0x7b, 0xab,
+               0xb9, 0xd0, 0x06, 0x00, 0xce, 0xc6, 0x85, 0x08, 0x45, 0xfb, 0xca, 0x70, 0x1b, 0xb4, 0x8f, 0x4e,
+               0x49, 0x2e, 0xfe, 0x94, 0xd7, 0x7b, 0xf1, 0xc6, 0x60, 0x24, 0xa6, 0x79, 0x5a, 0xeb, 0x92, 0xed,
+               0xd7, 0x07, 0x42, 0x65, 0xd3, 0x31
+       };
+
+       auto test_code = []()
+               {
+                       int ret;
+                       yaca_key_h key_pem = YACA_KEY_NULL, key_der = YACA_KEY_NULL;
+
+                       ret = yaca_key_import(YACA_KEY_TYPE_RSA_PUB, NULL, data_pem,
+                                                                 sizeof(data_pem), &key_pem);
+                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                       ret = yaca_key_import(YACA_KEY_TYPE_RSA_PUB, NULL, (char*)data_der,
+                                                                 sizeof(data_der), &key_der);
+                       if (ret != YACA_ERROR_NONE) goto exit;
+
+               exit:
+                       yaca_key_destroy(key_pem);
+                       yaca_key_destroy(key_der);
+                       return ret;
+               };
+
+       call_mock_test(test_code);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/mock_test_rsa.cpp b/tests/mock_test_rsa.cpp
new file mode 100644 (file)
index 0000000..0fd2afb
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ *  Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ *
+ *  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    test_rsa.c
+ * @author  Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ * @brief   RSA API unit tests.
+ */
+
+#include <boost/test/unit_test.hpp>
+#include <vector>
+
+#include <yaca_crypto.h>
+#include <yaca_rsa.h>
+#include <yaca_key.h>
+#include <yaca_error.h>
+
+#include "common.h"
+
+
+BOOST_AUTO_TEST_SUITE(MOCK_TESTS_RSA)
+
+BOOST_FIXTURE_TEST_CASE(T1401__mock__negative__private_encrypt, InitFixture)
+{
+       struct rsa_args {
+               yaca_padding_e pad;
+               yaca_key_bit_length_e bit_len;
+               size_t shorter;
+       };
+
+       const std::vector<struct rsa_args> rargs = {
+               {YACA_PADDING_NONE,         YACA_KEY_LENGTH_512BIT,   0},
+               {YACA_PADDING_PKCS1,        YACA_KEY_LENGTH_512BIT,  11},
+       };
+
+       for (const auto &ra: rargs) {
+               auto test_code = [&ra]()
+                       {
+                               int ret;
+                               yaca_key_h rsa_prv = YACA_KEY_NULL, rsa_pub = YACA_KEY_NULL;
+                               size_t input_len = ra.bit_len / 8 - ra.shorter;
+                               char *encrypted = NULL, *decrypted = NULL;
+                               size_t encrypted_len, decrypted_len;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, ra.bit_len, &rsa_prv);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+                               ret = yaca_key_extract_public(rsa_prv, &rsa_pub);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_rsa_private_encrypt(ra.pad, rsa_prv, INPUT_DATA, input_len,
+                                                                                          &encrypted, &encrypted_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_rsa_public_decrypt(ra.pad, rsa_pub, encrypted, encrypted_len,
+                                                                                         &decrypted, &decrypted_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                       exit:
+                               yaca_key_destroy(rsa_prv);
+                               yaca_key_destroy(rsa_pub);
+                               yaca_free(encrypted);
+                               yaca_free(decrypted);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1402__mock__negative__public_encrypt, InitFixture)
+{
+       struct rsa_args {
+               yaca_padding_e pad;
+               yaca_key_bit_length_e bit_len;
+               size_t shorter;
+       };
+
+       const std::vector<struct rsa_args> rargs = {
+               {YACA_PADDING_NONE,         YACA_KEY_LENGTH_512BIT,   0},
+               {YACA_PADDING_PKCS1,        YACA_KEY_LENGTH_1024BIT, 11},
+               {YACA_PADDING_PKCS1_OAEP,   YACA_KEY_LENGTH_2048BIT, 42},
+       };
+
+       for (const auto &ra: rargs) {
+               auto test_code = [&ra]()
+                       {
+                               int ret;
+                               yaca_key_h rsa_prv = YACA_KEY_NULL, rsa_pub = YACA_KEY_NULL;
+                               size_t input_len = ra.bit_len / 8 - ra.shorter;
+                               char *encrypted = NULL, *decrypted = NULL;
+                               size_t encrypted_len, decrypted_len;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, ra.bit_len, &rsa_prv);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+                               ret = yaca_key_extract_public(rsa_prv, &rsa_pub);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_rsa_public_encrypt(ra.pad, rsa_pub, INPUT_DATA, input_len,
+                                                                                         &encrypted, &encrypted_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_rsa_private_decrypt(ra.pad, rsa_prv, encrypted, encrypted_len,
+                                                                                          &decrypted, &decrypted_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                       exit:
+                               yaca_key_destroy(rsa_prv);
+                               yaca_key_destroy(rsa_pub);
+                               yaca_free(encrypted);
+                               yaca_free(decrypted);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/mock_test_seal.cpp b/tests/mock_test_seal.cpp
new file mode 100644 (file)
index 0000000..cccc7e1
--- /dev/null
@@ -0,0 +1,558 @@
+/*
+ *  Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ *
+ *  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    test_seal.cpp
+ * @author  Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ * @brief   Seal API unit tests.
+ */
+
+#include <boost/test/unit_test.hpp>
+#include <vector>
+
+#include <yaca_crypto.h>
+#include <yaca_seal.h>
+#include <yaca_key.h>
+#include <yaca_encrypt.h>
+#include <yaca_error.h>
+
+#include "common.h"
+
+
+BOOST_AUTO_TEST_SUITE(MOCK_TESTS_SEAL)
+
+BOOST_FIXTURE_TEST_CASE(T1701__mock__negative__seal_open, InitFixture)
+{
+       struct seal_args {
+               yaca_encrypt_algorithm_e algo;
+               yaca_block_cipher_mode_e bcm;
+               size_t key_bit_len;
+               yaca_padding_e padding;
+       };
+
+       const std::vector<seal_args> sargs = {
+               {YACA_ENCRYPT_AES,               YACA_BCM_CBC,  128, YACA_PADDING_NONE   },
+               {YACA_ENCRYPT_UNSAFE_DES,        YACA_BCM_ECB,   64, YACA_PADDING_PKCS7  },
+               {YACA_ENCRYPT_UNSAFE_3DES_2TDEA, YACA_BCM_CFB,  128, YACA_INVALID_PADDING},
+               {YACA_ENCRYPT_3DES_3TDEA,        YACA_BCM_CBC,  192, YACA_PADDING_PKCS7  },
+               {YACA_ENCRYPT_UNSAFE_RC4,        YACA_BCM_NONE, 256, YACA_INVALID_PADDING},
+               {YACA_ENCRYPT_CAST5,             YACA_BCM_CBC,  128, YACA_PADDING_NONE   },
+       };
+
+       for (const auto &sa: sargs) {
+               auto test_code = [&sa]()
+                       {
+                               int ret;
+                               yaca_context_h ctx = YACA_CONTEXT_NULL;
+                               yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL;
+                               yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL;
+
+                               size_t len1 = 0, len2 = 0;
+
+                               char *encrypted = NULL, *decrypted = NULL;
+                               size_t encrypted_len = 0, decrypted_len = 0;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_prv);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+                               ret = yaca_key_extract_public(key_prv, &key_pub);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               /* SEAL */
+                               {
+                                       ret = yaca_seal_initialize(&ctx, key_pub, sa.algo, sa.bcm,
+                                                                                          sa.key_bit_len, &key_sym, &iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len = written;
+
+                                       if (sa.padding != YACA_INVALID_PADDING) {
+                                               ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &sa.padding,
+                                                                                                               sizeof(yaca_padding_e));
+                                               if (ret != YACA_ERROR_NONE) goto exit;
+                                       }
+
+                                       ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len += written;
+
+                                       ret = yaca_realloc(encrypted_len, (void **)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                               /* OPEN */
+                               {
+                                       ret = yaca_open_initialize(&ctx, key_prv, sa.algo, sa.bcm,
+                                                                                          sa.key_bit_len, key_sym, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       if (sa.padding != YACA_INVALID_PADDING) {
+                                               ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &sa.padding,
+                                                                                                               sizeof(yaca_padding_e));
+                                               if (ret != YACA_ERROR_NONE) goto exit;
+                                       }
+
+                                       ret = yaca_context_get_output_length(ctx, encrypted_len, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&decrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       decrypted_len = written;
+
+                                       ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                       exit:
+                               yaca_context_destroy(ctx);
+                               yaca_key_destroy(key_prv);
+                               yaca_key_destroy(key_pub);
+                               yaca_key_destroy(key_sym);
+                               yaca_key_destroy(iv);
+                               yaca_free(encrypted);
+                               yaca_free(decrypted);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1702__mock__negative__seal_open_rc2, InitFixture)
+{
+       struct seal_args {
+               yaca_block_cipher_mode_e bcm;
+               size_t key_bit_len;
+               size_t effective_key_bits;
+       };
+
+       const std::vector<seal_args> sargs = {
+               {YACA_BCM_CBC, 192,   1024},
+               {YACA_BCM_CFB, 192,    333}
+       };
+
+       for (const auto &sa: sargs) {
+               auto test_code = [&sa]()
+                       {
+                               int ret;
+                               yaca_context_h ctx = YACA_CONTEXT_NULL;
+                               yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL;
+                               yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL;
+
+                               size_t len1 = 0, len2 = 0;
+
+                               char *encrypted = NULL, *decrypted = NULL;
+                               size_t encrypted_len = 0, decrypted_len = 0;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_prv);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+                               ret = yaca_key_extract_public(key_prv, &key_pub);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               /* SEAL */
+                               {
+                                       ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_UNSAFE_RC2, sa.bcm,
+                                                                                          sa.key_bit_len, &key_sym, &iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS,
+                                                                                                       &sa.effective_key_bits, sizeof(size_t));
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len = written;
+
+                                       ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len += written;
+
+                                       ret = yaca_realloc(encrypted_len, (void **)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                               /* OPEN */
+                               {
+                                       ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_UNSAFE_RC2, sa.bcm,
+                                                                                          sa.key_bit_len, key_sym, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_RC2_EFFECTIVE_KEY_BITS,
+                                                                                                       &sa.effective_key_bits, sizeof(size_t));
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, encrypted_len, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&decrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       decrypted_len = written;
+
+                                       ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                       exit:
+                               yaca_context_destroy(ctx);
+                               yaca_key_destroy(key_prv);
+                               yaca_key_destroy(key_pub);
+                               yaca_key_destroy(key_sym);
+                               yaca_key_destroy(iv);
+                               yaca_free(encrypted);
+                               yaca_free(decrypted);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1703__mock__negative__open_seal_ccm, InitFixture)
+{
+       struct seal_args {
+               size_t key_bit_len;
+               size_t ccm_tag_len;
+               size_t aad_len;
+       };
+
+       const std::vector<seal_args> sargs = {
+               {128,  6, 23},
+               {256, 12, 33}
+       };
+
+       for (const auto &sa: sargs) {
+               auto test_code = [&sa]()
+                       {
+                               int ret;
+                               yaca_context_h ctx = YACA_CONTEXT_NULL;
+                               yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL;
+                               yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL;
+
+                               size_t len1, len2;
+
+                               char *tag = NULL, *aad = NULL;
+                               size_t tag_len;
+
+                               char *encrypted = NULL, *decrypted = NULL;
+                               size_t encrypted_len, decrypted_len;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_prv);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+                               ret = yaca_key_extract_public(key_prv, &key_pub);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               /* SEAL */
+                               {
+                                       ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_AES, YACA_BCM_CCM,
+                                                                                          sa.key_bit_len, &key_sym, &iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       tag_len = sa.ccm_tag_len;
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG_LEN,
+                                                                                                       &tag_len, sizeof(tag_len));
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_malloc(sa.aad_len, (void**)&aad);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_randomize_bytes(aad, sa.aad_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_seal_update(ctx, NULL, INPUT_DATA_SIZE,
+                                                                                  NULL, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD,
+                                                                                                       aad, sa.aad_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len = written;
+
+                                       ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len += written;
+
+                                       ret = yaca_realloc(encrypted_len, (void **)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_property(ctx, YACA_PROPERTY_CCM_TAG, (void**)&tag, &tag_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                               /* OPEN */
+                               {
+                                       ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_CCM,
+                                                                                          sa.key_bit_len, key_sym, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, encrypted_len, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&decrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_TAG, tag, tag_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_open_update(ctx, NULL, encrypted_len,
+                                                                                  NULL, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD,
+                                                                                                       aad, sa.aad_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       decrypted_len = written;
+
+                                       ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                       exit:
+                               yaca_context_destroy(ctx);
+                               yaca_key_destroy(key_prv);
+                               yaca_key_destroy(key_pub);
+                               yaca_key_destroy(key_sym);
+                               yaca_key_destroy(iv);
+                               yaca_free(encrypted);
+                               yaca_free(decrypted);
+                               yaca_free(tag);
+                               yaca_free(aad);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1704__mock__negative__seal_open_gcm, InitFixture)
+{
+       struct seal_args {
+               size_t key_bit_len;
+               size_t gcm_tag_len;
+               size_t aad_len;
+       };
+
+       const std::vector<seal_args> sargs = {
+               {128, 13, 22},
+               {192, 15, 33}
+       };
+
+       for (const auto &sa: sargs) {
+               auto test_code = [&sa]()
+                       {
+                               int ret;
+                               yaca_context_h ctx = YACA_CONTEXT_NULL;
+                               yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL;
+                               yaca_key_h key_sym = YACA_KEY_NULL, iv = YACA_KEY_NULL;
+
+                               size_t len1 = 0, len2 = 0;
+
+                               char *encrypted = NULL, *decrypted = NULL;
+                               size_t encrypted_len = 0, decrypted_len = 0;
+
+                               char *tag = NULL, *aad = NULL;
+                               size_t tag_len;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, &key_prv);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+                               ret = yaca_key_extract_public(key_prv, &key_pub);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               /* SEAL */
+                               {
+                                       ret = yaca_seal_initialize(&ctx, key_pub, YACA_ENCRYPT_AES, YACA_BCM_GCM,
+                                                                                          sa.key_bit_len, &key_sym, &iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, INPUT_DATA_SIZE, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_malloc(sa.aad_len, (void**)&aad);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_randomize_bytes(aad, sa.aad_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD,
+                                                                                                       aad, sa.aad_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_seal_update(ctx, INPUT_DATA, INPUT_DATA_SIZE, encrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len = written;
+
+                                       ret = yaca_seal_finalize(ctx, encrypted + encrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       encrypted_len += written;
+
+                                       ret = yaca_realloc(encrypted_len, (void **)&encrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       tag_len = sa.gcm_tag_len;
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG_LEN,
+                                                                                                       &tag_len, sizeof(tag_len));
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_property(ctx, YACA_PROPERTY_GCM_TAG,
+                                                                                                       (void**)&tag, &tag_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                               /* OPEN */
+                               {
+                                       ret = yaca_open_initialize(&ctx, key_prv, YACA_ENCRYPT_AES, YACA_BCM_GCM,
+                                                                                          sa.key_bit_len, key_sym, iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, encrypted_len, &len1);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       ret = yaca_context_get_output_length(ctx, 0, &len2);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       size_t total = len1 + len2;
+                                       size_t written;
+
+                                       ret = yaca_zalloc(total, (void**)&decrypted);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_AAD,
+                                                                                                       aad, sa.aad_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_open_update(ctx, encrypted, encrypted_len, decrypted, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                                       decrypted_len = written;
+
+                                       ret = yaca_context_set_property(ctx, YACA_PROPERTY_GCM_TAG,
+                                                                                                       tag, tag_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_open_finalize(ctx, decrypted + decrypted_len, &written);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                       exit:
+                               yaca_context_destroy(ctx);
+                               yaca_key_destroy(key_prv);
+                               yaca_key_destroy(key_pub);
+                               yaca_key_destroy(key_sym);
+                               yaca_key_destroy(iv);
+                               yaca_free(encrypted);
+                               yaca_free(decrypted);
+                               yaca_free(tag);
+                               yaca_free(aad);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/mock_test_sign.cpp b/tests/mock_test_sign.cpp
new file mode 100644 (file)
index 0000000..59aad1e
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ *  Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ *
+ *  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    test_sign.cpp
+ * @author  Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ * @brief   Signature API unit tests.
+ */
+
+#include <boost/test/unit_test.hpp>
+#include <vector>
+
+#include <yaca_crypto.h>
+#include <yaca_sign.h>
+#include <yaca_key.h>
+#include <yaca_digest.h>
+#include <yaca_error.h>
+
+#include "common.h"
+
+
+BOOST_AUTO_TEST_SUITE(MOCK_TESTS_SIGN)
+
+BOOST_FIXTURE_TEST_CASE(T1801__mock__negative__sign_verify, InitFixture)
+{
+       struct sign_args {
+               yaca_key_type_e type_prv;
+               yaca_key_type_e type_pub;
+               yaca_key_bit_length_e len;
+               yaca_digest_algorithm_e digest;
+               yaca_padding_e pad;
+       };
+
+       const std::vector<sign_args> sargs = {
+               {YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_TYPE_RSA_PUB, YACA_KEY_LENGTH_512BIT,
+                YACA_DIGEST_SHA1, YACA_PADDING_X931},
+               {YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_TYPE_DSA_PUB, YACA_KEY_LENGTH_512BIT,
+                YACA_DIGEST_SHA224, YACA_INVALID_PADDING},
+               {YACA_KEY_TYPE_EC_PRIV, YACA_KEY_TYPE_EC_PUB,
+                (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME192V1,
+                YACA_DIGEST_SHA384, YACA_INVALID_PADDING}
+       };
+
+       for (const auto &sa: sargs) {
+               auto test_code = [&sa]() -> int
+                       {
+                               int ret;
+                               yaca_context_h ctx = YACA_CONTEXT_NULL;
+                               yaca_key_h key_prv = YACA_KEY_NULL, key_pub = YACA_KEY_NULL;
+
+                               char *signature = NULL;
+                               size_t signature_len;
+
+                               ret = yaca_key_generate(sa.type_prv, sa.len, &key_prv);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+                               ret = yaca_key_extract_public(key_prv, &key_pub);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               /* SIGN */
+                               {
+                                       ret = yaca_sign_initialize(&ctx, sa.digest, key_prv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       if (sa.pad != YACA_INVALID_PADDING) {
+                                               ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING,
+                                                                                                               &sa.pad, sizeof(sa.pad));
+                                               if (ret != YACA_ERROR_NONE) goto exit;
+                                       }
+
+                                       ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_context_get_output_length(ctx, 0, &signature_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_malloc(signature_len, (void **)&signature);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_sign_finalize(ctx, signature, &signature_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                               /* VERIFY */
+                               {
+                                       ret = yaca_verify_initialize(&ctx, sa.digest, key_pub);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       if (sa.pad != YACA_INVALID_PADDING) {
+                                               ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING,
+                                                                                                               &sa.pad, sizeof(sa.pad));
+                                               if (ret != YACA_ERROR_NONE) goto exit;
+                                       }
+
+                                       ret = yaca_verify_update(ctx, INPUT_DATA, INPUT_DATA_SIZE);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       ret = yaca_verify_finalize(ctx, signature, signature_len);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+
+                                       yaca_context_destroy(ctx);
+                                       ctx = YACA_CONTEXT_NULL;
+                               }
+
+                       exit:
+                               yaca_context_destroy(ctx);
+                               yaca_key_destroy(key_prv);
+                               yaca_key_destroy(key_pub);
+                               yaca_free(signature);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1802__mock__negative__sign_cmac, InitFixture)
+{
+       struct cmac_args {
+               yaca_key_type_e type;
+               yaca_key_bit_length_e len;
+               yaca_encrypt_algorithm_e algo;
+       };
+
+       const std::vector<cmac_args> cargs = {
+               {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_UNSAFE_64BIT,
+                YACA_ENCRYPT_UNSAFE_DES},
+               {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_192BIT,
+                YACA_ENCRYPT_3DES_3TDEA}
+       };
+
+       for (const auto &ca: cargs) {
+               auto test_code = [&ca]() -> int
+                       {
+                               int ret;
+                               yaca_context_h ctx = YACA_CONTEXT_NULL;
+                               yaca_key_h key = YACA_KEY_NULL;
+
+                               char *signature = NULL;
+                               size_t signature_len;
+
+                               ret = yaca_key_generate(ca.type, ca.len, &key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_sign_initialize_cmac(&ctx, ca.algo, key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_context_get_output_length(ctx, 0, &signature_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_malloc(signature_len, (void **)&signature);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_sign_finalize(ctx, signature, &signature_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                       exit:
+                               yaca_context_destroy(ctx);
+                               yaca_key_destroy(key);
+                               yaca_free(signature);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1803__mock__negative__sign_hmac, InitFixture)
+{
+       struct hmac_args {
+               yaca_key_type_e type;
+               yaca_key_bit_length_e len;
+               yaca_digest_algorithm_e digest;
+       };
+
+       const std::vector<hmac_args> hargs = {
+               {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_UNSAFE_128BIT,
+                YACA_DIGEST_SHA1},
+               {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_128BIT,
+                YACA_DIGEST_SHA224}
+       };
+
+       for (const auto &ha: hargs) {
+               auto test_code = [&ha]() -> int
+                       {
+                               int ret;
+                               yaca_context_h ctx = YACA_CONTEXT_NULL;
+                               yaca_key_h key = YACA_KEY_NULL;
+
+                               char *signature = NULL;
+                               size_t signature_len;
+
+                               ret = yaca_key_generate(ha.type, ha.len, &key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_sign_initialize_hmac(&ctx, ha.digest, key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_context_get_output_length(ctx, 0, &signature_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_malloc(signature_len, (void **)&signature);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_sign_finalize(ctx, signature, &signature_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                       exit:
+                               yaca_context_destroy(ctx);
+                               yaca_key_destroy(key);
+                               yaca_free(signature);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/mock_test_simple.cpp b/tests/mock_test_simple.cpp
new file mode 100644 (file)
index 0000000..8dc2bc3
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ *  Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ *
+ *  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    test_simple.cpp
+ * @author  Lukasz Pawelczyk <l.pawelczyk@samsung.com>
+ * @brief   Simple API unit tests.
+ */
+
+#include <boost/test/unit_test.hpp>
+#include <vector>
+
+#include <yaca_crypto.h>
+#include <yaca_encrypt.h>
+#include <yaca_key.h>
+#include <yaca_simple.h>
+#include <yaca_error.h>
+
+#include "common.h"
+
+
+BOOST_AUTO_TEST_SUITE(MOCK_TESTS_SIMPLE)
+
+BOOST_FIXTURE_TEST_CASE(T1301__mock__negative__positive__simple_encrypt_decrypt, InitFixture)
+{
+       struct encrypt_args {
+               yaca_encrypt_algorithm_e algo;
+               yaca_block_cipher_mode_e bcm;
+               size_t key_bit_len;
+       };
+
+       const std::vector<struct encrypt_args> eargs = {
+               {YACA_ENCRYPT_AES,        YACA_BCM_CBC, YACA_KEY_LENGTH_256BIT       },
+               {YACA_ENCRYPT_3DES_3TDEA, YACA_BCM_ECB, YACA_KEY_LENGTH_192BIT       },
+               {YACA_ENCRYPT_CAST5,      YACA_BCM_OFB, YACA_KEY_LENGTH_UNSAFE_128BIT}
+       };
+
+       for (const auto &ea: eargs) {
+               auto test_case = [&ea]() -> int
+                       {
+                               int ret;
+                               yaca_key_h sym = YACA_KEY_NULL, iv = YACA_KEY_NULL;
+                               size_t iv_bit_len;
+                               char *encrypted = NULL, *decrypted = NULL;
+                               size_t encrypted_len, decrypted_len;
+
+                               ret = yaca_encrypt_get_iv_bit_length(ea.algo, ea.bcm, ea.key_bit_len, &iv_bit_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, ea.key_bit_len, &sym);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               if (iv_bit_len > 0) {
+                                       ret = yaca_key_generate(YACA_KEY_TYPE_IV, iv_bit_len, &iv);
+                                       if (ret != YACA_ERROR_NONE) goto exit;
+                               }
+
+                               ret = yaca_simple_encrypt(ea.algo, ea.bcm, sym, iv, INPUT_DATA, INPUT_DATA_SIZE,
+                                                                                 &encrypted, &encrypted_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_simple_decrypt(ea.algo, ea.bcm, sym, iv, encrypted, encrypted_len,
+                                                                                 &decrypted, &decrypted_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                       exit:
+                               yaca_key_destroy(sym);
+                               yaca_key_destroy(iv);
+                               yaca_free(encrypted);
+                               yaca_free(decrypted);
+                               return ret;
+                       };
+
+               call_mock_test(test_case);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1302__mock__negative__simple_calculate_digest, InitFixture)
+{
+       struct digest_args {
+               yaca_digest_algorithm_e algo = YACA_DIGEST_SHA256;
+       };
+
+       const std::vector<struct digest_args> dargs = {
+               {YACA_DIGEST_MD5},
+               {YACA_DIGEST_SHA256}
+       };
+
+       for (const auto &da: dargs) {
+               auto test_code = [&da]() -> int
+                       {
+                               int ret;
+                               char *digest = NULL;
+                               size_t digest_len;
+
+                               ret = yaca_simple_calculate_digest(da.algo, INPUT_DATA, INPUT_DATA_SIZE,
+                                                                                                  &digest, &digest_len);
+                               yaca_free(digest);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1303__mock__negative__simple_calculate_verify_signature, InitFixture)
+{
+       struct signature_args {
+               yaca_key_type_e type;
+               yaca_key_bit_length_e len;
+               yaca_digest_algorithm_e algo;
+       };
+
+       const std::vector<struct signature_args> sargs = {
+               {YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_512BIT, YACA_DIGEST_MD5},
+               {YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_LENGTH_512BIT, YACA_DIGEST_SHA256},
+               {YACA_KEY_TYPE_EC_PRIV, (yaca_key_bit_length_e)YACA_KEY_LENGTH_EC_PRIME192V1,
+                YACA_DIGEST_SHA224}
+       };
+
+       for (const auto &sa: sargs) {
+               auto test_code = [&sa]() -> int
+                       {
+                               int ret;
+                               yaca_key_h key_priv = YACA_KEY_NULL;
+                               yaca_key_h key_pub = YACA_KEY_NULL;
+
+                               char *signature = NULL;
+                               size_t signature_len;
+
+                               ret = yaca_key_generate(sa.type, sa.len, &key_priv);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_key_extract_public(key_priv, &key_pub);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_simple_calculate_signature(sa.algo, key_priv,
+                                                                                                         INPUT_DATA, INPUT_DATA_SIZE,
+                                                                                                         &signature, &signature_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_simple_verify_signature(sa.algo, key_pub,
+                                                                                                  INPUT_DATA, INPUT_DATA_SIZE,
+                                                                                                  signature, signature_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                       exit:
+                               yaca_key_destroy(key_priv);
+                               yaca_key_destroy(key_pub);
+                               yaca_free(signature);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1304__mock__negative__simple_calculate_hmac, InitFixture)
+{
+       struct hmac_args {
+               yaca_key_type_e type;
+               yaca_key_bit_length_e len;
+               yaca_digest_algorithm_e algo;
+       };
+
+       const std::vector<struct hmac_args> hargs = {
+               {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_192BIT, YACA_DIGEST_MD5},
+               {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_128BIT, YACA_DIGEST_SHA1}
+       };
+
+       for (const auto &ha: hargs) {
+               auto test_code = [&ha]() -> int
+                       {
+                               int ret;
+                               yaca_key_h key = YACA_KEY_NULL;
+                               char *mac = NULL;
+                               size_t mac_len;
+
+                               ret = yaca_key_generate(ha.type, ha.len, &key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_simple_calculate_hmac(ha.algo, key,
+                                                                                                INPUT_DATA, INPUT_DATA_SIZE,
+                                                                                                &mac, &mac_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                       exit:
+                               yaca_key_destroy(key);
+                               yaca_free(mac);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_FIXTURE_TEST_CASE(T1305__mock__negative__simple_calculate_cmac, InitFixture)
+{
+       struct cmac_args {
+               yaca_key_type_e type;
+               yaca_key_bit_length_e len;
+               yaca_encrypt_algorithm_e algo;
+       };
+
+       const std::vector<struct cmac_args> cargs = {
+               {YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_192BIT, YACA_ENCRYPT_AES},
+               {YACA_KEY_TYPE_DES, YACA_KEY_LENGTH_UNSAFE_64BIT, YACA_ENCRYPT_UNSAFE_DES}
+       };
+
+       for (const auto &ca: cargs) {
+               auto test_code = [&ca]() -> int
+                       {
+                               int ret;
+                               yaca_key_h key = YACA_KEY_NULL;
+                               char *mac = NULL;
+                               size_t mac_len;
+
+                               ret = yaca_key_generate(ca.type, ca.len, &key);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                               ret = yaca_simple_calculate_cmac(ca.algo, key,
+                                                                                                INPUT_DATA, INPUT_DATA_SIZE,
+                                                                                                &mac, &mac_len);
+                               if (ret != YACA_ERROR_NONE) goto exit;
+
+                       exit:
+                               yaca_key_destroy(key);
+                               yaca_free(mac);
+                               return ret;
+                       };
+
+               call_mock_test(test_code);
+       }
+}
+
+BOOST_AUTO_TEST_SUITE_END()