From: Krzysztof Jackiewicz Date: Wed, 24 May 2023 10:31:42 +0000 (+0200) Subject: CKM: Cipher API tests X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Ftest%2Fsecurity-tests.git;a=commitdiff_plain;h=61fe8c39f3dbc09bb97b5dad874cf6fb58028e43 CKM: Cipher API tests Also reduce big data size to speed up the testing Change-Id: I8ea762d4aecdfdc6c57f12f5a708185e68830858 --- diff --git a/packaging/security-tests.spec b/packaging/security-tests.spec index cd7b9c0..0b398af 100644 --- a/packaging/security-tests.spec +++ b/packaging/security-tests.spec @@ -12,6 +12,7 @@ BuildRequires: libattr-devel BuildRequires: pkgconfig(libcap) BuildRequires: pkgconfig(libsmack) BuildRequires: pkgconfig(security-manager) +# TODO update when cipher API is released BuildRequires: pkgconfig(key-manager) >= 0.1.49 BuildRequires: key-manager-initial-values BuildRequires: util-linux diff --git a/src/ckm/ckm-common.cpp b/src/ckm/ckm-common.cpp index 5479eb6..c34aaa2 100644 --- a/src/ckm/ckm-common.cpp +++ b/src/ckm/ckm-common.cpp @@ -606,6 +606,11 @@ RawBufferPtr create_raw_buffer(ckmc_raw_buffer_s* buffer) return RawBufferPtr(buffer, ckmc_buffer_free); } +CipherCtxPtr create_cipher_ctx(ckmc_cipher_ctx_h ctx) +{ + return CipherCtxPtr(ctx, ckmc_cipher_free); +} + CKM::Policy generate_ckm_policy(int iterator_nr) { if (iterator_nr % 2) { // policy with password and with / without extractable flag return CKM::Policy(CKM::Password("test_pwd"), iterator_nr % 4); diff --git a/src/ckm/ckm-common.h b/src/ckm/ckm-common.h index c0578ac..f930657 100644 --- a/src/ckm/ckm-common.h +++ b/src/ckm/ckm-common.h @@ -196,6 +196,7 @@ public: typedef std::shared_ptr RawBufferPtr; typedef std::shared_ptr ParamListPtr; +typedef std::shared_ptr CipherCtxPtr; ParamListPtr createParamListPtr(); void setParam(ParamListPtr& params, ckmc_param_name_e name, ckmc_raw_buffer_s* buffer); @@ -205,6 +206,8 @@ void assert_buffers_equal(const ckmc_raw_buffer_s* b1, const ckmc_raw_buffer_s* RawBufferPtr create_raw_buffer(ckmc_raw_buffer_s* buffer); +CipherCtxPtr create_cipher_ctx(ckmc_cipher_ctx_h ctx); + template void test_no_observer(F&& func, Args... args) diff --git a/src/ckm/unprivileged/encryption-decryption-env.cpp b/src/ckm/unprivileged/encryption-decryption-env.cpp index 03dc266..16017d4 100644 --- a/src/ckm/unprivileged/encryption-decryption-env.cpp +++ b/src/ckm/unprivileged/encryption-decryption-env.cpp @@ -145,3 +145,187 @@ EncryptionError AsyncApi::ckmError2Result(int error) default: return EncryptionError::OTHER; } } + +int CipherApi::crypt(ckmc_cipher_ctx_h ctx, + unsigned char *ptr, + size_t left, + CKM::RawBuffer& output) +{ + const size_t CHUNK_SIZE = 80; + ckmc_raw_buffer_s* out = nullptr; + ckmc_raw_buffer_s* in = nullptr; + size_t size = CHUNK_SIZE; + int ret = CKMC_ERROR_NONE; + + while (left > 0) { + if (left < CHUNK_SIZE) + size = left; + + ret = ckmc_buffer_new(ptr, size, &in); + if (ret != CKMC_ERROR_NONE) + goto crypt_fail; + + ret = ckmc_cipher_update(ctx, *in, &out); + if (ret != CKMC_ERROR_NONE) + goto crypt_fail; + + ckmc_buffer_free(in); + in = nullptr; + if (out != nullptr) + std::copy(out->data, out->data + out->size, std::back_inserter(output)); + + ckmc_buffer_free(out); + out = nullptr; + + left -= size; + ptr += size; + } + +crypt_fail: + ckmc_buffer_free(out); + ckmc_buffer_free(in); + return ret; +} + +EncryptionError CipherApi::encrypt(ckmc_param_list_h params, + const char *key_alias, + const char *password, + const ckmc_raw_buffer_s& plain, + ckmc_raw_buffer_s **ppencrypted) +{ + ckmc_cipher_ctx_h ctx = nullptr; + size_t left = plain.size; + unsigned char* ptr = plain.data; + CKM::RawBuffer encrypted; + ckmc_raw_buffer_s* out = nullptr; + ckmc_raw_buffer_s* encrypted_c = nullptr; + uint64_t algo; + + int ret = ckmc_param_list_get_integer(params, CKMC_PARAM_ALGO_TYPE, &algo); + if (ret != CKMC_ERROR_NONE) + goto encrypt_fail; + + // encrypt + ret = ckmc_cipher_initialize(params, key_alias, password, true, &ctx); + if (ret != CKMC_ERROR_NONE) + goto encrypt_fail; + + ret = crypt(ctx, ptr, left, encrypted); + if (ret != CKMC_ERROR_NONE) + goto encrypt_fail; + + ret = ckmc_cipher_finalize(ctx, nullptr, &out); + if (ret != CKMC_ERROR_NONE) + goto encrypt_fail; + + // make sure finalize returns exactly the tag + if (algo == CKMC_ALGO_AES_GCM) { + uint64_t tagLen = 128; + ret = ckmc_param_list_get_integer(params, CKMC_PARAM_ED_TAG_LEN, &tagLen); + if (ret != CKMC_ERROR_NONE && ret != CKMC_ERROR_INVALID_PARAMETER) + goto encrypt_fail; + + if (tagLen / 8 != out->size) { + ret = CKMC_ERROR_SERVER_ERROR; + goto encrypt_fail; + } + } + + if (out != nullptr) + std::copy(out->data, out->data + out->size, std::back_inserter(encrypted)); + out = nullptr; + + ret = ckmc_buffer_new(encrypted.data(), encrypted.size(), &encrypted_c); + if (ret != CKMC_ERROR_NONE) + goto encrypt_fail; + + *ppencrypted = encrypted_c; + +encrypt_fail: + ckmc_buffer_free(out); + ckmc_cipher_free(ctx); + + return ckmcError2Result(ret); +} + +EncryptionError CipherApi::decrypt(ckmc_param_list_h params, + const char *key_alias, + const char *password, + const ckmc_raw_buffer_s& encrypted, + ckmc_raw_buffer_s **ppdecrypted) +{ + ckmc_cipher_ctx_h ctx = nullptr; + size_t left = encrypted.size; + unsigned char* ptr = encrypted.data; + CKM::RawBuffer decrypted; + ckmc_raw_buffer_s* out = nullptr; + ckmc_raw_buffer_s* decrypted_c = nullptr; + ckmc_raw_buffer_s* tag = nullptr; + uint64_t algo; + + int ret = ckmc_param_list_get_integer(params, CKMC_PARAM_ALGO_TYPE, &algo); + if (ret != CKMC_ERROR_NONE) + goto decrypt_fail; + + // extract the tag to pass in finalize + if (algo == CKMC_ALGO_AES_GCM) { + uint64_t tagLen = 128; + ret = ckmc_param_list_get_integer(params, CKMC_PARAM_ED_TAG_LEN, &tagLen); + if (ret != CKMC_ERROR_NONE && ret != CKMC_ERROR_INVALID_PARAMETER) + goto decrypt_fail; + + tagLen /= 8; + if (tagLen > left) { + ret = CKMC_ERROR_INVALID_PARAMETER; + goto decrypt_fail; + } + + ret = ckmc_buffer_new(encrypted.data + encrypted.size - tagLen, tagLen, &tag); + if (ret != CKMC_ERROR_NONE) + goto decrypt_fail; + + left -= tagLen; + } + + // decrypt + ret = ckmc_cipher_initialize(params, key_alias, password, false, &ctx); + if (ret != CKMC_ERROR_NONE) + goto decrypt_fail; + + ret = crypt(ctx, ptr, left, decrypted); + if (ret != CKMC_ERROR_NONE) + goto decrypt_fail; + + ret = ckmc_cipher_finalize(ctx, tag, &out); + if (ret != CKMC_ERROR_NONE) + goto decrypt_fail; + + if (out != nullptr) + std::copy(out->data, out->data + out->size, std::back_inserter(decrypted)); + out = nullptr; + + ret = ckmc_buffer_new(decrypted.data(), decrypted.size(), &decrypted_c); + if (ret != CKMC_ERROR_NONE) + goto decrypt_fail; + + *ppdecrypted = decrypted_c; + +decrypt_fail: + ckmc_cipher_free(ctx); + ckmc_buffer_free(out); + ckmc_buffer_free(tag); + + return ckmcError2Result(ret); +} + +EncryptionError CipherApi::ckmcError2Result(int error) +{ + switch (error) { + case CKMC_ERROR_NONE: return EncryptionError::SUCCESS; + case CKMC_ERROR_INVALID_PARAMETER: return EncryptionError::INVALID_PARAM; + case CKMC_ERROR_SERVER_ERROR: return EncryptionError::SERVER_ERROR; + case CKMC_ERROR_DB_ALIAS_UNKNOWN: return EncryptionError::ALIAS_UNKNOWN; + case CKMC_ERROR_AUTHENTICATION_FAILED: return EncryptionError::AUTH_FAILED; + default: return EncryptionError::OTHER; + } +} diff --git a/src/ckm/unprivileged/encryption-decryption-env.h b/src/ckm/unprivileged/encryption-decryption-env.h index 1af99e5..ac564f3 100644 --- a/src/ckm/unprivileged/encryption-decryption-env.h +++ b/src/ckm/unprivileged/encryption-decryption-env.h @@ -35,7 +35,7 @@ enum EncryptionError{ SERVER_ERROR, ALIAS_UNKNOWN, AUTH_FAILED, - OTHER, + OTHER }; struct EncryptionApi @@ -51,22 +51,26 @@ struct EncryptionApi const char *password, const ckmc_raw_buffer_s& encrypted, ckmc_raw_buffer_s **ppdecrypted) = 0; + + virtual bool symmetricOnly() const { return false; } + + virtual ~EncryptionApi() {} }; class SyncApi : public EncryptionApi { public: - virtual EncryptionError encrypt(ckmc_param_list_h params, - const char *key_alias, - const char *password, - const ckmc_raw_buffer_s& decrypted, - ckmc_raw_buffer_s **ppencrypted); + EncryptionError encrypt(ckmc_param_list_h params, + const char *key_alias, + const char *password, + const ckmc_raw_buffer_s& decrypted, + ckmc_raw_buffer_s **ppencrypted) override; - virtual EncryptionError decrypt(ckmc_param_list_h params, - const char *key_alias, - const char *password, - const ckmc_raw_buffer_s& encrypted, - ckmc_raw_buffer_s **ppdecrypted); + EncryptionError decrypt(ckmc_param_list_h params, + const char *key_alias, + const char *password, + const ckmc_raw_buffer_s& encrypted, + ckmc_raw_buffer_s **ppdecrypted) override; private: static EncryptionError ckmcError2Result(int error); }; @@ -95,13 +99,13 @@ public: const char *key_alias, const char *password, const ckmc_raw_buffer_s& decrypted, - ckmc_raw_buffer_s **ppencrypted); + ckmc_raw_buffer_s **ppencrypted) override; EncryptionError decrypt(ckmc_param_list_h params, const char *key_alias, const char *password, const ckmc_raw_buffer_s& encrypted, - ckmc_raw_buffer_s **ppdecrypted); + ckmc_raw_buffer_s **ppdecrypted) override; private: typedef void (CKM::ManagerAsync::*cryptoFn)(const CKM::ManagerAsync::ObserverPtr&, const CKM::CryptoAlgorithm&, @@ -119,5 +123,25 @@ private: static EncryptionError ckmError2Result(int error); }; +class CipherApi : public EncryptionApi +{ +public: + EncryptionError encrypt(ckmc_param_list_h params, + const char *key_alias, + const char *password, + const ckmc_raw_buffer_s& decrypted, + ckmc_raw_buffer_s **ppencrypted) override; + + EncryptionError decrypt(ckmc_param_list_h params, + const char *key_alias, + const char *password, + const ckmc_raw_buffer_s& encrypted, + ckmc_raw_buffer_s **ppdecrypted) override; + + bool symmetricOnly() const override { return true; } +private: + int crypt(ckmc_cipher_ctx_h ctx, unsigned char *ptr, size_t left, CKM::RawBuffer& output); + EncryptionError ckmcError2Result(int error); +}; diff --git a/src/ckm/unprivileged/encryption-decryption.cpp b/src/ckm/unprivileged/encryption-decryption.cpp index 037ff08..cf9e67a 100644 --- a/src/ckm/unprivileged/encryption-decryption.cpp +++ b/src/ckm/unprivileged/encryption-decryption.cpp @@ -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; @@ -202,7 +215,7 @@ 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); @@ -325,8 +338,7 @@ EncryptionResult encrypt(const Algo& algo, return ret; } -void testAllAlgorithms( - const std::function& test) +void testAllAlgorithms(const std::function& test) { test( { CKMC_ALGO_AES_CBC, 128 }); test( { CKMC_ALGO_AES_CBC, 192 }); @@ -340,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) @@ -919,6 +934,19 @@ void testRsaDataTooLong(const Algo& algo, size_t dataSize) &encrypted); } +std::pair 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); @@ -927,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 @@ -955,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 @@ -1026,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 @@ -1054,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 @@ -1117,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); @@ -1128,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 @@ -1154,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 @@ -1186,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}); } @@ -1250,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}); @@ -1266,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}); @@ -1279,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}); @@ -1295,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}); @@ -1308,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}); @@ -1321,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}); @@ -1336,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}); @@ -1351,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); @@ -1454,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 threads; threads.reserve(10); @@ -1463,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); +}