CKM: Cipher API tests
[platform/core/test/security-tests.git] / src / ckm / unprivileged / encryption-decryption.cpp
index a29c452..cf9e67a 100644 (file)
@@ -46,6 +46,7 @@ const size_t BUF_LEN = 86; // must be less than 1024/8-41 to support RSA OAEP 10
 // Environment
 SyncApi g_syncApi;
 AsyncApi g_asyncApi;
+CipherApi g_cipherApi;
 
 EncryptionApi* g_api = &g_syncApi;
 
@@ -134,6 +135,18 @@ struct AsyncEnv {
     static std::string suffix() { return "_async"; }
 };
 
+struct CipherEnv {
+    void init(const std::string&) {
+        g_api = &g_cipherApi;
+    }
+
+    void finish() {
+        g_api = nullptr;
+    }
+
+    static std::string suffix() { return "_cipher"; }
+};
+
 struct Algo {
     ckmc_algo_type_e type;
     size_t keyLen;
@@ -152,6 +165,7 @@ enum KeyIdx {
 RawBufferPtr PLAIN_DATA;
 RawBufferPtr BIG_DATA;
 ckmc_raw_buffer_s* DEFAULT_IV;
+ckmc_raw_buffer_s* IV1;
 ckmc_raw_buffer_s* IV11;
 ckmc_raw_buffer_s* IV12;
 ckmc_raw_buffer_s* IV15;
@@ -201,9 +215,10 @@ public:
 #ifdef TZ_BACKEND
         BIG_DATA = create_raw_buffer(createRandomBufferCAPI(1000));
 #else
-        BIG_DATA = create_raw_buffer(createRandomBufferCAPI(5000000));
+        BIG_DATA = create_raw_buffer(createRandomBufferCAPI(500000));
 #endif
         DEFAULT_IV = createRandomBufferCAPI(DEFAULT_IV_LEN);
+        IV1 = createRandomBufferCAPI(1);
         IV11 = createRandomBufferCAPI(11);
         IV12 = createRandomBufferCAPI(12);
         IV15 = createRandomBufferCAPI(15);
@@ -276,6 +291,7 @@ public:
         ckmc_buffer_free(IV15);
         ckmc_buffer_free(IV12);
         ckmc_buffer_free(IV11);
+        ckmc_buffer_free(IV1);
         ckmc_buffer_free(DEFAULT_IV);
 
         int ret = ckmc_lock_user_key(UID);
@@ -322,8 +338,7 @@ EncryptionResult encrypt(const Algo& algo,
     return ret;
 }
 
-void testAllAlgorithms(
-        const std::function<void(const Algo& algo)>& test)
+void testAllAlgorithms(const std::function<void(const Algo& algo)>& test)
 {
     test( { CKMC_ALGO_AES_CBC, 128 });
     test( { CKMC_ALGO_AES_CBC, 192 });
@@ -337,9 +352,12 @@ void testAllAlgorithms(
     test( { CKMC_ALGO_AES_CFB, 128 });
     test( { CKMC_ALGO_AES_CFB, 192 });
     test( { CKMC_ALGO_AES_CFB, 256 });
-    test( { CKMC_ALGO_RSA_OAEP, 1024 });
-    test( { CKMC_ALGO_RSA_OAEP, 2048 });
-    test( { CKMC_ALGO_RSA_OAEP, 4096 });
+
+    if (!g_api->symmetricOnly()) {
+        test( { CKMC_ALGO_RSA_OAEP, 1024 });
+        test( { CKMC_ALGO_RSA_OAEP, 2048 });
+        test( { CKMC_ALGO_RSA_OAEP, 4096 });
+    }
 }
 
 void testNoIvEnc(const Algo& algo)
@@ -815,7 +833,8 @@ void testGcmDifferentIvSizes(const Algo& algo)
     // add AES GCM key
     KeyAliasPair aliases = getKey(algo, PRIMARY);
 
-    testGcmIvSize(IV11,  aliases, EncryptionError::SERVER_ERROR); // 12B is the smallest
+    testGcmIvSize(IV1,   aliases);
+    testGcmIvSize(IV11,  aliases);
     testGcmIvSize(IV12,  aliases);
     testGcmIvSize(IV17,  aliases);
     testGcmIvSize(IV128, aliases);
@@ -915,6 +934,19 @@ void testRsaDataTooLong(const Algo& algo, size_t dataSize)
                          &encrypted);
 }
 
+std::pair<Alias, ParamListPtr> defaultGcmCipherSetup()
+{
+    Algo algo = {CKMC_ALGO_AES_GCM, 256};
+    KeyAliasPair aliases = getKey(algo, PRIMARY);
+
+    ckmc_param_list_h handle = NULL;
+    assert_positive(ckmc_generate_new_params, algo.type, &handle);
+    auto params = ParamListPtr(handle, ckmc_param_list_free);
+    setParam(params, CKMC_PARAM_ED_IV, IV12);
+
+    return std::make_pair(aliases.prv, params);
+}
+
 } // namespace anonymous
 
 RUNNER_TEST_GROUP_INIT_ENV(CKM_ENCRYPTION_DECRYPTION, EncGroupFixture);
@@ -923,7 +955,7 @@ RUNNER_TEST_GROUP_INIT_ENV(CKM_ENCRYPTION_DECRYPTION, EncGroupFixture);
 // Generic encryption decryption tests
 /////////////////////////////////////////
 
-RUNNER_TEST_MULTIPLE(TED_0010_encrypt_invalid_param_list, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0010_encrypt_invalid_param_list, SyncEnv, AsyncEnv, CipherEnv)
 {
     testAllAlgorithms([](const Algo& algo){
         // prepare buffers
@@ -951,7 +983,7 @@ RUNNER_TEST_MULTIPLE(TED_0010_encrypt_invalid_param_list, SyncEnv, AsyncEnv)
     });
 }
 
-RUNNER_TEST_MULTIPLE(TED_0020_encrypt_missing_key, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0020_encrypt_missing_key, SyncEnv, AsyncEnv, CipherEnv)
 {
     testAllAlgorithms([](const Algo& algo){
         // prepare buffers
@@ -1022,7 +1054,7 @@ RUNNER_TEST_MULTIPLE(TED_0040_encrypt_no_output_buffer, SyncEnv, AsyncEnv)
     });
 }
 
-RUNNER_TEST_MULTIPLE(TED_0110_decrypt_invalid_param_list, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0110_decrypt_invalid_param_list, SyncEnv, AsyncEnv, CipherEnv)
 {
     testAllAlgorithms([](const Algo& algo){
         // prepare buffers
@@ -1050,7 +1082,7 @@ RUNNER_TEST_MULTIPLE(TED_0110_decrypt_invalid_param_list, SyncEnv, AsyncEnv)
     });
 }
 
-RUNNER_TEST_MULTIPLE(TED_0120_decrypt_missing_key, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0120_decrypt_missing_key, SyncEnv, AsyncEnv, CipherEnv)
 {
     testAllAlgorithms([](const Algo& algo){
         // prepare buffers
@@ -1113,7 +1145,7 @@ RUNNER_TEST_MULTIPLE(TED_0140_decrypt_no_output_buffer, SyncEnv, AsyncEnv)
     });
 }
 
-RUNNER_TEST_MULTIPLE(TED_0200_encrypt_decrypt_different_keys, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0200_encrypt_decrypt_different_keys, SyncEnv, AsyncEnv, CipherEnv)
 {
     testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_GCM, 128}, false);
     testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_GCM, 192}, false);
@@ -1124,12 +1156,15 @@ RUNNER_TEST_MULTIPLE(TED_0200_encrypt_decrypt_different_keys, SyncEnv, AsyncEnv)
     testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_CFB, 128}, true);
     testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_CFB, 192}, true);
     testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_CFB, 256}, true);
-    testEncryptDecryptDifferentKeys({CKMC_ALGO_RSA_OAEP, 1024}, false);
-    testEncryptDecryptDifferentKeys({CKMC_ALGO_RSA_OAEP, 2048}, false);
-    testEncryptDecryptDifferentKeys({CKMC_ALGO_RSA_OAEP, 4096}, false);
+
+    if (!g_api->symmetricOnly()) {
+        testEncryptDecryptDifferentKeys({CKMC_ALGO_RSA_OAEP, 1024}, false);
+        testEncryptDecryptDifferentKeys({CKMC_ALGO_RSA_OAEP, 2048}, false);
+        testEncryptDecryptDifferentKeys({CKMC_ALGO_RSA_OAEP, 4096}, false);
+    }
 }
 
-RUNNER_TEST_MULTIPLE(TED_0300_encrypt_decrypt, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0300_encrypt_decrypt, SyncEnv, AsyncEnv, CipherEnv)
 {
     testAllAlgorithms([](const Algo& algo){
         // prepare buffers
@@ -1150,7 +1185,7 @@ RUNNER_TEST_MULTIPLE(TED_0300_encrypt_decrypt, SyncEnv, AsyncEnv)
     });
 }
 
-RUNNER_TEST_MULTIPLE(TED_0310_encrypt_decrypt_password, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0310_encrypt_decrypt_password, SyncEnv, AsyncEnv, CipherEnv)
 {
     testAllAlgorithms([](const Algo& algo){
         // prepare buffers
@@ -1182,62 +1217,62 @@ RUNNER_TEST_MULTIPLE(TED_0310_encrypt_decrypt_password, SyncEnv, AsyncEnv)
 }
 
 // long test split into smaller ones
-RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CBC_128, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CBC_128, SyncEnv, AsyncEnv, CipherEnv)
 {
     testEncryptDecryptBigData({CKMC_ALGO_AES_CBC, 128});
 }
 
-RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CBC_192, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CBC_192, SyncEnv, AsyncEnv, CipherEnv)
 {
     testEncryptDecryptBigData({CKMC_ALGO_AES_CBC, 192});
 }
 
-RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CBC_256, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CBC_256, SyncEnv, AsyncEnv, CipherEnv)
 {
     testEncryptDecryptBigData({CKMC_ALGO_AES_CBC, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_GCM_128, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_GCM_128, SyncEnv, AsyncEnv, CipherEnv)
 {
     testEncryptDecryptBigData({CKMC_ALGO_AES_GCM, 128});
 }
 
-RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_GCM_192, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_GCM_192, SyncEnv, AsyncEnv, CipherEnv)
 {
     testEncryptDecryptBigData({CKMC_ALGO_AES_GCM, 192});
 }
 
-RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_GCM_256, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_GCM_256, SyncEnv, AsyncEnv, CipherEnv)
 {
     testEncryptDecryptBigData({CKMC_ALGO_AES_GCM, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CTR_128, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CTR_128, SyncEnv, AsyncEnv, CipherEnv)
 {
     testEncryptDecryptBigData({CKMC_ALGO_AES_CTR, 128});
 }
 
-RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CTR_192, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CTR_192, SyncEnv, AsyncEnv, CipherEnv)
 {
     testEncryptDecryptBigData({CKMC_ALGO_AES_CTR, 192});
 }
 
-RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CTR_256, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CTR_256, SyncEnv, AsyncEnv, CipherEnv)
 {
     testEncryptDecryptBigData({CKMC_ALGO_AES_CTR, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CFB_128, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CFB_128, SyncEnv, AsyncEnv, CipherEnv)
 {
     testEncryptDecryptBigData({CKMC_ALGO_AES_CFB, 128});
 }
 
-RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CFB_192, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CFB_192, SyncEnv, AsyncEnv, CipherEnv)
 {
     testEncryptDecryptBigData({CKMC_ALGO_AES_CFB, 192});
 }
 
-RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CFB_256, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CFB_256, SyncEnv, AsyncEnv, CipherEnv)
 {
     testEncryptDecryptBigData({CKMC_ALGO_AES_CFB, 256});
 }
@@ -1246,7 +1281,7 @@ RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CFB_256, SyncEnv, Asy
 // Algorithm specific tests
 /////////////////////////////////////////
 
-RUNNER_TEST_MULTIPLE(TED_1005_no_iv_enc, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1005_no_iv_enc, SyncEnv, AsyncEnv, CipherEnv)
 {
     testNoIvEnc({CKMC_ALGO_AES_CTR, 128});
     testNoIvEnc({CKMC_ALGO_AES_CTR, 192});
@@ -1262,7 +1297,7 @@ RUNNER_TEST_MULTIPLE(TED_1005_no_iv_enc, SyncEnv, AsyncEnv)
     testNoIvEnc({CKMC_ALGO_AES_GCM, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1010_invalid_iv_enc, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1010_invalid_iv_enc, SyncEnv, AsyncEnv, CipherEnv)
 {
     testInvalidIvEnc({CKMC_ALGO_AES_CTR, 128});
     testInvalidIvEnc({CKMC_ALGO_AES_CTR, 192});
@@ -1275,7 +1310,7 @@ RUNNER_TEST_MULTIPLE(TED_1010_invalid_iv_enc, SyncEnv, AsyncEnv)
     testInvalidIvEnc({CKMC_ALGO_AES_CFB, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1015_no_iv_dec, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1015_no_iv_dec, SyncEnv, AsyncEnv, CipherEnv)
 {
     testNoIvDec({CKMC_ALGO_AES_CTR, 128});
     testNoIvDec({CKMC_ALGO_AES_CTR, 192});
@@ -1291,7 +1326,7 @@ RUNNER_TEST_MULTIPLE(TED_1015_no_iv_dec, SyncEnv, AsyncEnv)
     testNoIvDec({CKMC_ALGO_AES_GCM, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1020_invalid_iv_dec, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1020_invalid_iv_dec, SyncEnv, AsyncEnv, CipherEnv)
 {
     testInvalidIvDec({CKMC_ALGO_AES_CTR, 128});
     testInvalidIvDec({CKMC_ALGO_AES_CTR, 192});
@@ -1304,7 +1339,7 @@ RUNNER_TEST_MULTIPLE(TED_1020_invalid_iv_dec, SyncEnv, AsyncEnv)
     testInvalidIvDec({CKMC_ALGO_AES_CFB, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1050_data_integrity, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1050_data_integrity, SyncEnv, AsyncEnv, CipherEnv)
 {
     testIntegrity({CKMC_ALGO_AES_CTR, 128});
     testIntegrity({CKMC_ALGO_AES_CTR, 192});
@@ -1317,14 +1352,14 @@ RUNNER_TEST_MULTIPLE(TED_1050_data_integrity, SyncEnv, AsyncEnv)
     testIntegrity({CKMC_ALGO_AES_CFB, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1100_ctr_encryption_invalid_length, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1100_ctr_encryption_invalid_length, SyncEnv, AsyncEnv, CipherEnv)
 {
     testCtrEncryptionInvalidLength({CKMC_ALGO_AES_CTR, 128});
     testCtrEncryptionInvalidLength({CKMC_ALGO_AES_CTR, 192});
     testCtrEncryptionInvalidLength({CKMC_ALGO_AES_CTR, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1105_ctr_encryption_valid_length, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1105_ctr_encryption_valid_length, SyncEnv, AsyncEnv, CipherEnv)
 {
     RUNNER_IGNORED_MSG("Openssl supports only 128-bit AES CTR length");
     testCtrEncryptionValidLength({CKMC_ALGO_AES_CTR, 128});
@@ -1332,14 +1367,14 @@ RUNNER_TEST_MULTIPLE(TED_1105_ctr_encryption_valid_length, SyncEnv, AsyncEnv)
     testCtrEncryptionValidLength({CKMC_ALGO_AES_CTR, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1110_ctr_decryption_invalid_length, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1110_ctr_decryption_invalid_length, SyncEnv, AsyncEnv, CipherEnv)
 {
     testCtrDecryptionInvalidLength({CKMC_ALGO_AES_CTR, 128});
     testCtrDecryptionInvalidLength({CKMC_ALGO_AES_CTR, 192});
     testCtrDecryptionInvalidLength({CKMC_ALGO_AES_CTR, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1115_ctr_decryption_valid_length, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1115_ctr_decryption_valid_length, SyncEnv, AsyncEnv, CipherEnv)
 {
     RUNNER_IGNORED_MSG("Openssl supports only 128-bit AES CTR length");
     testCtrDecryptionValidLength({CKMC_ALGO_AES_CTR, 128});
@@ -1347,35 +1382,35 @@ RUNNER_TEST_MULTIPLE(TED_1115_ctr_decryption_valid_length, SyncEnv, AsyncEnv)
     testCtrDecryptionValidLength({CKMC_ALGO_AES_CTR, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1200_gcm_encryption_tag_len, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1200_gcm_encryption_tag_len, SyncEnv, AsyncEnv, CipherEnv)
 {
     testGcmEncryptionTagLen({CKMC_ALGO_AES_GCM, 128});
     testGcmEncryptionTagLen({CKMC_ALGO_AES_GCM, 192});
     testGcmEncryptionTagLen({CKMC_ALGO_AES_GCM, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1210_gcm_decryption_tag_len, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1210_gcm_decryption_tag_len, SyncEnv, AsyncEnv, CipherEnv)
 {
     testGcmDecryptionTagLen({CKMC_ALGO_AES_GCM, 128});
     testGcmDecryptionTagLen({CKMC_ALGO_AES_GCM, 192});
     testGcmDecryptionTagLen({CKMC_ALGO_AES_GCM, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1230_gcm_wrong_tag, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1230_gcm_wrong_tag, SyncEnv, AsyncEnv, CipherEnv)
 {
     testGcmWrongTag({CKMC_ALGO_AES_GCM, 128});
     testGcmWrongTag({CKMC_ALGO_AES_GCM, 192});
     testGcmWrongTag({CKMC_ALGO_AES_GCM, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1240_gcm_different_iv_sizes, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1240_gcm_different_iv_sizes, SyncEnv, AsyncEnv, CipherEnv)
 {
     testGcmDifferentIvSizes({CKMC_ALGO_AES_GCM, 128});
     testGcmDifferentIvSizes({CKMC_ALGO_AES_GCM, 192});
     testGcmDifferentIvSizes({CKMC_ALGO_AES_GCM, 256});
 }
 
-RUNNER_TEST_MULTIPLE(TED_1250_gcm_aad, SyncEnv, AsyncEnv)
+RUNNER_TEST_MULTIPLE(TED_1250_gcm_aad, SyncEnv, AsyncEnv, CipherEnv)
 {
     encryptionWithCustomData({CKMC_ALGO_AES_GCM, 128}, CKMC_PARAM_ED_AAD);
     encryptionWithCustomData({CKMC_ALGO_AES_GCM, 192}, CKMC_PARAM_ED_AAD);
@@ -1450,7 +1485,7 @@ RUNNER_TEST(TED_2010_dec_no_observer_async, AsyncEnv)
 /////////////////////////////////////////
 // Mulithreaded test for synchronous API
 /////////////////////////////////////////
-RUNNER_TEST(TED_3000_muliple_threads, SyncEnv)
+RUNNER_TEST_MULTIPLE(TED_3000_multiple_threads, SyncEnv, CipherEnv)
 {
     std::vector<std::thread> threads;
     threads.reserve(10);
@@ -1459,3 +1494,154 @@ RUNNER_TEST(TED_3000_muliple_threads, SyncEnv)
     for (auto& thread : threads)
         thread.join();
 }
+
+/////////////////////////////////////////
+// Cipher API only
+/////////////////////////////////////////
+RUNNER_TEST(TED_4000_cipher_missing_arguments)
+{
+    ckmc_raw_buffer_s* encrypted = nullptr;
+
+    auto [alias, params] = defaultGcmCipherSetup();
+
+    ckmc_cipher_ctx_h ctx = nullptr;
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, true, &ctx);
+    auto ctxPtr = create_cipher_ctx(ctx);
+
+    // no AAD
+    assert_invalid_param(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, true, &ctx);
+
+    // missing arguments
+    assert_invalid_param(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, true, nullptr);
+    assert_invalid_param(ckmc_cipher_update, nullptr, *PLAIN_DATA.get(), &encrypted);
+    assert_invalid_param(ckmc_cipher_update, ctx, *PLAIN_DATA.get(), nullptr);
+    assert_invalid_param(ckmc_cipher_finalize, nullptr, nullptr, &encrypted);
+    assert_invalid_param(ckmc_cipher_finalize, nullptr, nullptr, nullptr);
+}
+
+RUNNER_TEST(TED_4010_cipher_reinitialize_without_aad)
+{
+    auto [alias, params] = defaultGcmCipherSetup();
+
+    ckmc_cipher_ctx_h ctx = nullptr;
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, true, &ctx);
+    auto ctxPtr = create_cipher_ctx(ctx);
+
+    // no AAD
+    assert_invalid_param(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, true, &ctx);
+}
+
+RUNNER_TEST(TED_4020_cipher_tag_during_encryption)
+{
+    ckmc_raw_buffer_s* encrypted = nullptr;
+
+    auto [alias, params] = defaultGcmCipherSetup();
+
+    ckmc_cipher_ctx_h ctx = nullptr;
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, true, &ctx);
+    auto ctxPtr = create_cipher_ctx(ctx);
+
+    // tag input during encryption
+    assert_invalid_param(ckmc_cipher_finalize, ctx, PLAIN_DATA.get(), &encrypted);
+}
+
+RUNNER_TEST(TED_4030_cipher_wrong_order)
+{
+    ckmc_raw_buffer_s* encrypted = nullptr;
+
+    auto [alias, params] = defaultGcmCipherSetup();
+
+    ckmc_cipher_ctx_h ctx = nullptr;
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, true, &ctx);
+    auto ctxPtr = create_cipher_ctx(ctx);
+
+    assert_positive(ckmc_cipher_update, ctx, *PLAIN_DATA.get(), &encrypted);
+    ckmc_buffer_free(encrypted);
+
+    // initialize after update
+    setParam(params, CKMC_PARAM_ED_AAD, AAD32);
+    assert_invalid_param(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, true, nullptr);
+
+    assert_positive(ckmc_cipher_finalize, ctx, nullptr, &encrypted);
+    ckmc_buffer_free(encrypted);
+
+    // initialize after finalize
+    assert_invalid_param(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, true, nullptr);
+
+    // update after finalize
+    assert_invalid_param(ckmc_cipher_update, ctx, *PLAIN_DATA.get(), &encrypted);
+}
+
+RUNNER_TEST(TED_4040_cipher_gcm_aad_and_tag)
+{
+    ckmc_raw_buffer_s* encrypted = nullptr;
+
+    auto [alias, params] = defaultGcmCipherSetup();
+    setParam(params, CKMC_PARAM_ED_AAD, AAD32);
+
+    ckmc_cipher_ctx_h ctx = nullptr;
+
+    // encrypt
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, true, &ctx);
+    auto ctxPtr = create_cipher_ctx(ctx);
+
+    // 2 more AAD chunks
+    setParam(params, CKMC_PARAM_ED_AAD, AAD64);
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, true, &ctx);
+    setParam(params, CKMC_PARAM_ED_AAD, AAD32);
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, true, &ctx);
+
+    ckmc_raw_buffer_s* tag = nullptr;
+
+    assert_positive(ckmc_cipher_update, ctx, *PLAIN_DATA.get(), &encrypted);
+    auto encryptedPtr = create_raw_buffer(encrypted);
+    assert_positive(ckmc_cipher_finalize, ctx, nullptr, &tag);
+
+    ctxPtr.reset();
+    ctx = nullptr;
+
+    ckmc_raw_buffer_s* decrypted = nullptr;
+    ckmc_raw_buffer_s* empty = nullptr;
+
+    // decrypt with invalid AAD
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, false, &ctx);
+    ctxPtr = create_cipher_ctx(ctx);
+
+    assert_positive(ckmc_cipher_update, ctx, *encrypted, &decrypted);
+    ckmc_buffer_free(decrypted);
+    assert_invalid_param(ckmc_cipher_finalize, ctx, tag, &empty);
+
+    ctxPtr.reset();
+    ctx = nullptr;
+
+    // decrypt without TAG
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, false, &ctx);
+    ctxPtr = create_cipher_ctx(ctx);
+    setParam(params, CKMC_PARAM_ED_AAD, AAD64);
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, false, &ctx);
+    setParam(params, CKMC_PARAM_ED_AAD, AAD32);
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, false, &ctx);
+
+    assert_positive(ckmc_cipher_update, ctx, *encrypted, &decrypted);
+    ckmc_buffer_free(decrypted);
+    assert_invalid_param(ckmc_cipher_finalize, ctx, nullptr, &empty);
+
+    ctxPtr.reset();
+    ctx = nullptr;
+
+    // correct decrypt
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, false, &ctx);
+    ctxPtr = create_cipher_ctx(ctx);
+    setParam(params, CKMC_PARAM_ED_AAD, AAD64);
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, false, &ctx);
+    setParam(params, CKMC_PARAM_ED_AAD, AAD32);
+    assert_positive(ckmc_cipher_initialize, params.get(), alias.c_str(), nullptr, false, &ctx);
+
+    assert_positive(ckmc_cipher_update, ctx, *encrypted, &decrypted);
+    auto decryptedPtr = create_raw_buffer(decrypted);
+    assert_positive(ckmc_cipher_finalize, ctx, tag, &empty);
+
+    RUNNER_ASSERT(empty == nullptr);
+
+    assert_buffers_equal(PLAIN_DATA.get(), decrypted);
+}