From: Dariusz Michaluk Date: Thu, 22 Jun 2023 07:28:24 +0000 (+0200) Subject: Merge branch 'ckm' into tizen X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=HEAD;hp=c3cea86e7d05eebe2a337a73e732f10d65bf33ac;p=platform%2Fcore%2Ftest%2Fsecurity-tests.git Merge branch 'ckm' into tizen Change-Id: Ia4bb16867447fd4d661a8578e21a7131a2cd16ad --- 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 01c265c..2ceb95b 100644 --- a/src/ckm/ckm-common.cpp +++ b/src/ckm/ckm-common.cpp @@ -387,55 +387,63 @@ void check_alias_list(const CKM::AliasVector& expected) RUNNER_ASSERT_MSG(expected == actual, "Actual list of aliases differ from expected list."); } -void check_alias_info_list_helper(const CKM::AliasPwdVector& expected, const CKM::AliasPwdVector& actual, - const std::string &userSmackLabel) +void check_alias_info_list_helper(const InfoVector& expected, + const InfoMap& actual, + const std::string &userSmackLabel) { std::string errorLogMsg; - std::unordered_map aliasPwdMap; RUNNER_ASSERT_MSG(expected.size() == actual.size(), "Aliases item count differs, expected: " << expected.size() << " actual: " << actual.size()); - for (const auto &it : actual) + for (const auto &expectedIt : expected) { - aliasPwdMap[std::get<0>(it)] = std::get<1>(it); - } - - - for (const auto &it : expected) - { - auto aliasPwd = aliasPwdMap.find(userSmackLabel + std::get<0>(it)); - if (aliasPwd != aliasPwdMap.end()) { - if (aliasPwd->second != std::get<1>(it)) { - errorLogMsg += "Alias: " + std::get<0>(it) + " has wrong encryption status: " - + std::to_string(std::get<1>(it)) + "\n"; + auto actualIt = actual.find(userSmackLabel + expectedIt.alias); + if (actualIt != actual.end()) { + if (actualIt->second.passwordProtected != expectedIt.passwordProtected) { + errorLogMsg += "Alias: " + actualIt->second.alias + " has wrong encryption status: " + + std::to_string(actualIt->second.passwordProtected) + "\n"; + } + if (actualIt->second.backend != expectedIt.backend) { + errorLogMsg += "Alias: " + actualIt->second.alias + " belongs to wrong backend: " + + std::to_string(static_cast(actualIt->second.backend)) + "\n"; } } else { - errorLogMsg += "Expected alias: " + std::get<0>(it) + " not found.\n"; + errorLogMsg += "Expected alias: " + actualIt->second.alias + " not found.\n"; } } if (!errorLogMsg.empty()) { - for (const auto &it : actual) + for (const auto& [alias, info] : actual) { - errorLogMsg += "Actual alias: " + std::get<0>(it) + " status: " - + std::to_string(std::get<1>(it)) + "\n"; + errorLogMsg += "Actual alias: " + alias + + " status: " + std::to_string(info.passwordProtected) + + " backend: " + std::to_string(static_cast(info.backend)) + "\n"; } RUNNER_FAIL_MSG("Actual list of aliases differ from expected list.\n" + errorLogMsg); } } -void check_alias_info_list(const CKM::AliasPwdVector& expected) +CKM::BackendId backend() +{ +#ifdef TZ_BACKEND + return CKM::BackendId::TZ; +#else + return CKM::BackendId::SW; +#endif +} + +void check_alias_info_list(const InfoVector& expected) { ckmc_alias_info_list_s *aliasInfoList = NULL; int ret = ckmc_get_data_alias_info_list(&aliasInfoList); RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Failed to get the list of data aliases. " << ret << " / " << CKMCErrorToString(ret)); - CKM::AliasPwdVector actual; + InfoMap actual; ckmc_alias_info_list_s *plist = aliasInfoList; - char* alias; + char* alias = nullptr; bool isPasswordProtected; unsigned int it = 0; while (plist) @@ -443,11 +451,18 @@ void check_alias_info_list(const CKM::AliasPwdVector& expected) ret = ckmc_alias_info_get_alias(plist->info, &alias); RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Failed to get alias. " << ret << " / " << CKMCErrorToString(ret)); + RUNNER_ASSERT_MSG(alias != nullptr, "Got null alias. Iterator: " << it); + ret = ckmc_alias_info_is_password_protected(plist->info, &isPasswordProtected); RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Failed to get password protection status" << ret << " / " << CKMCErrorToString(ret)); - RUNNER_ASSERT_MSG(alias != nullptr, "Got null alias. Iterator: " << it); - actual.push_back(std::make_pair(alias, isPasswordProtected)); + + ckmc_backend_id_e backend; + ret = ckmc_alias_info_get_backend(plist->info, &backend); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Failed to get backend" << ret << " / " + << CKMCErrorToString(ret)); + + actual.try_emplace(alias, alias, isPasswordProtected, static_cast(backend)); plist = plist->next; it++; } @@ -600,6 +615,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 4d398e5..07cf3cc 100644 --- a/src/ckm/ckm-common.h +++ b/src/ckm/ckm-common.h @@ -145,9 +145,28 @@ void reset_user_data(uid_t user_id, const char *passwd); ckmc_raw_buffer_s prepare_message_buffer(const char * input); void check_alias_list(const CKM::AliasVector& expected); -void check_alias_info_list_helper(const CKM::AliasPwdVector& expected, const CKM::AliasPwdVector& actual, + +struct Info { + Info(const CKM::Alias &alias, + bool passwordProtected, + CKM::BackendId backend = CKM::BackendId::SW) : + alias(alias), + passwordProtected(passwordProtected), + backend(backend) {} + + CKM::Alias alias; + bool passwordProtected; + CKM::BackendId backend; +}; +typedef std::vector InfoVector; +typedef std::unordered_map InfoMap; + +CKM::BackendId backend(); + +void check_alias_info_list_helper(const InfoVector& expected, + const InfoMap& actual, const std::string &userSmackLabel = {}); -void check_alias_info_list(const CKM::AliasPwdVector& expected); +void check_alias_info_list(const InfoVector& expected); typedef enum { ALIAS_KEY, @@ -194,6 +213,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); @@ -203,6 +223,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/privileged/system-db.cpp b/src/ckm/privileged/system-db.cpp index 1a4ee6e..944ada6 100644 --- a/src/ckm/privileged/system-db.cpp +++ b/src/ckm/privileged/system-db.cpp @@ -527,11 +527,11 @@ RUNNER_TEST(T5046_CLIENT_GET_ALIAS_STATUS_NO_PASSWORD, RemoveDataEnv<0>) save_data(TEST_SYSTEM_ALIAS_2.c_str(), TEST_DATA); // [test] - CKM::AliasPwdVector aliasPwdVector; - aliasPwdVector.push_back(std::make_pair(TEST_SYSTEM_ALIAS.c_str(), false)); - aliasPwdVector.push_back(std::make_pair(TEST_SYSTEM_ALIAS_2.c_str(), false)); + InfoVector expected; + expected.emplace_back(TEST_SYSTEM_ALIAS, false, backend()); + expected.emplace_back(TEST_SYSTEM_ALIAS_2, false, backend()); - check_alias_info_list(aliasPwdVector); + check_alias_info_list(expected); } RUNNER_TEST(T5047_CLIENT_GET_ALIAS_STATUS_PASSWORD_PROTECTED, RemoveDataEnv<0>) @@ -551,10 +551,10 @@ RUNNER_TEST(T5047_CLIENT_GET_ALIAS_STATUS_PASSWORD_PROTECTED, RemoveDataEnv<0>) save_data((TEST_SYSTEM_ALIAS_2 + "1").c_str(), TEST_DATA, strlen(TEST_DATA), TEST_PASSWORD); // [test] - CKM::AliasPwdVector aliasPwdVector; - aliasPwdVector.push_back(std::make_pair(TEST_SYSTEM_ALIAS.c_str(), false)); - aliasPwdVector.push_back(std::make_pair(TEST_SYSTEM_ALIAS_2.c_str(), true)); - aliasPwdVector.push_back(std::make_pair((TEST_SYSTEM_ALIAS_2 + "1").c_str(),true)); + InfoVector expected; + expected.emplace_back(TEST_SYSTEM_ALIAS, false, backend()); + expected.emplace_back(TEST_SYSTEM_ALIAS_2, true, backend()); + expected.emplace_back(TEST_SYSTEM_ALIAS_2 + "1", true, backend()); - check_alias_info_list(aliasPwdVector); + check_alias_info_list(expected); } diff --git a/src/ckm/unprivileged/encryption-decryption-env.cpp b/src/ckm/unprivileged/encryption-decryption-env.cpp index 03dc266..7f43bcb 100644 --- a/src/ckm/unprivileged/encryption-decryption-env.cpp +++ b/src/ckm/unprivileged/encryption-decryption-env.cpp @@ -20,6 +20,7 @@ */ #include +#include using namespace CKM; @@ -145,3 +146,196 @@ 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) +{ +#ifdef TZ_BACKEND + ckmc_backend_info_h info; + size_t maxSize; + // All unexportable keys go to TZ if enabled (and all of them are unexportable) + assert_positive(ckmc_get_backend_info, CKMC_BACKEND_TZ, &info); + assert_positive(ckmc_backend_get_max_chunk_size, info, &maxSize); + const size_t CHUNK_SIZE = 80 < maxSize ? 80 : maxSize; +#else + const size_t CHUNK_SIZE = 80; +#endif + 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 a29c452..d8b98b3 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; @@ -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; @@ -199,11 +213,16 @@ public: PLAIN_DATA = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); #ifdef TZ_BACKEND - BIG_DATA = create_raw_buffer(createRandomBufferCAPI(1000)); + ckmc_backend_info_h info; + size_t size; + assert_positive(ckmc_get_backend_info, CKMC_BACKEND_TZ, &info); + assert_positive(ckmc_backend_get_max_chunk_size, info, &size); + BIG_DATA = create_raw_buffer(createRandomBufferCAPI(size)); #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 +295,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 +342,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 }); @@ -337,9 +356,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 +837,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 +938,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); @@ -923,7 +959,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 +987,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 +1058,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 +1086,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 +1149,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 +1160,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 +1189,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 +1221,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 +1285,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 +1301,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 +1314,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 +1330,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 +1343,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 +1356,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 +1371,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 +1386,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 +1489,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); @@ -1459,3 +1498,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); +} diff --git a/src/ckm/unprivileged/main.cpp b/src/ckm/unprivileged/main.cpp index 93ccd11..8f02903 100644 --- a/src/ckm/unprivileged/main.cpp +++ b/src/ckm/unprivileged/main.cpp @@ -280,7 +280,13 @@ RUNNER_TEST(T1014_save_with_label) RUNNER_TEST(T1020_save_big_data) { #ifdef TZ_BACKEND - const size_t BIG_SIZE = 100000; + ckmc_backend_info_h info; + size_t size; + // all data goes to TZ when enabled + assert_positive(ckmc_get_backend_info, CKMC_BACKEND_TZ, &info); + assert_positive(ckmc_backend_get_max_chunk_size, info, &size); + const size_t BIG_SIZE = size; + CKM::PolicyBackend backend = CKM::PolicyBackend::FORCE_HARDWARE; #else const size_t BIG_SIZE = 5000000; @@ -442,7 +448,7 @@ RUNNER_TEST(T1024_app_user_save_keys_get_alias_pwd) const int aliasNameCount = 10; auto manager = CKM::Manager::create(); - CKM::AliasPwdVector expected; + InfoVector expected; CKM::RawBuffer buffer(KEY_PEM.begin(), KEY_PEM.end()); auto key = CKM::Key::create(buffer, CKM::Password()); std::string currentAlias; @@ -453,21 +459,31 @@ RUNNER_TEST(T1024_app_user_save_keys_get_alias_pwd) { CKM::Policy policy = generate_ckm_policy(it); currentAlias = "T1024_appkey" + std::to_string(it); - expected.push_back(std::make_pair(currentAlias, !policy.password.empty())); + expected.emplace_back(currentAlias, !policy.password.empty(), backend()); RUNNER_ASSERT_MSG( CKM_API_SUCCESS == (exitCode = manager->saveKey(currentAlias, key, policy)), "Error=" << CKM::APICodeToString(exitCode)); } - CKM::AliasPwdVector actual; + CKM::AliasInfoVector aliasInfoVector; + InfoMap actual; RUNNER_ASSERT_MSG( - CKM_API_SUCCESS == (exitCode = manager->getKeyAliasPwdVector(actual)), + CKM_API_SUCCESS == (exitCode = manager->getKeyAliasInfoVector(aliasInfoVector)), "Error=" << CKM::APICodeToString(exitCode)); RUNNER_ASSERT_MSG( - actual.size() == (beforeSaveAliasCount + aliasNameCount), - "Wrong aliases count: " << actual.size() << " Expected: " + aliasInfoVector.size() == (beforeSaveAliasCount + aliasNameCount), + "Wrong aliases count: " << aliasInfoVector.size() << " Expected: " << (beforeSaveAliasCount + aliasNameCount)); + + bool status; + for (const auto &info : aliasInfoVector) { + exitCode = manager->getKeyEncryptionStatus(info.alias, status); + RUNNER_ASSERT_MSG(CKM_API_SUCCESS == exitCode, "Error=" << CKM::APICodeToString(exitCode)); + + actual.try_emplace(info.alias, info.alias, status, info.backend); + } + check_alias_info_list_helper(expected, actual, "/User "); remove_user_data(USER_APP); @@ -481,7 +497,7 @@ RUNNER_TEST(T1025_app_user_save_certificates_get_alias_pwd) const int aliasNameCount = 10; auto manager = CKM::Manager::create(); - CKM::AliasPwdVector expected; + InfoVector expected; auto cert = TestData::getTestCertificate(TestData::TEST_LEAF); std::string currentAlias; @@ -490,20 +506,31 @@ RUNNER_TEST(T1025_app_user_save_certificates_get_alias_pwd) { CKM::Policy policy = generate_ckm_policy(it); currentAlias = "T1025_appcert" + std::to_string(it); - expected.push_back(std::make_pair(currentAlias, !policy.password.empty())); + expected.emplace_back(currentAlias, !policy.password.empty(), CKM::BackendId::SW); RUNNER_ASSERT_MSG( CKM_API_SUCCESS == (exitCode = manager->saveCertificate(currentAlias, cert, policy)), "Error=" << CKM::APICodeToString(exitCode)); } - CKM::AliasPwdVector actual; + CKM::AliasInfoVector aliasInfoVector; + InfoMap actual; + RUNNER_ASSERT_MSG( - CKM_API_SUCCESS == (exitCode = manager->getCertificateAliasPwdVector(actual)), + CKM_API_SUCCESS == (exitCode = manager->getCertificateAliasInfoVector(aliasInfoVector)), "Error=" << CKM::APICodeToString(exitCode)); RUNNER_ASSERT_MSG( - actual.size() == (beforeSaveAliasCount + aliasNameCount), - "Wrong aliases count: " << actual.size() << " Expected: " + aliasInfoVector.size() == (beforeSaveAliasCount + aliasNameCount), + "Wrong aliases count: " << aliasInfoVector.size() << " Expected: " << (beforeSaveAliasCount + aliasNameCount)); + + bool status; + for (const auto &info : aliasInfoVector) { + exitCode = manager->getCertificateEncryptionStatus(info.alias, status); + RUNNER_ASSERT_MSG(CKM_API_SUCCESS == exitCode, "Error=" << CKM::APICodeToString(exitCode)); + + actual.try_emplace(info.alias, info.alias, status, info.backend); + } + check_alias_info_list_helper(expected, actual, "/User "); remove_user_data(USER_APP); @@ -517,7 +544,7 @@ RUNNER_TEST(T1026_app_user_save_data_get_alias_pwd) const int aliasNameCount = 10; auto manager = CKM::Manager::create(); - CKM::AliasPwdVector expected; + InfoVector expected; std::string binData = "My bin data"; CKM::RawBuffer buffer(binData.begin(), binData.end()); std::string currentAlias; @@ -527,25 +554,63 @@ RUNNER_TEST(T1026_app_user_save_data_get_alias_pwd) { CKM::Policy policy = generate_ckm_policy(it); currentAlias = "T1026_appdata" + std::to_string(it); - expected.push_back(std::make_pair(currentAlias, !policy.password.empty())); + expected.emplace_back(currentAlias, !policy.password.empty(), backend()); RUNNER_ASSERT_MSG( CKM_API_SUCCESS == (exitCode = manager->saveData(currentAlias, buffer, policy)), "Error=" << CKM::APICodeToString(exitCode)); } - CKM::AliasPwdVector actual; + CKM::AliasInfoVector aliasInfoVector; + InfoMap actual; + RUNNER_ASSERT_MSG( - CKM_API_SUCCESS == (exitCode = manager->getDataAliasPwdVector(actual)), + CKM_API_SUCCESS == (exitCode = manager->getDataAliasInfoVector(aliasInfoVector)), "Error=" << CKM::APICodeToString(exitCode)); RUNNER_ASSERT_MSG( - actual.size() == (beforeSaveAliasCount + aliasNameCount), - "Wrong aliases count: " << actual.size() << " Expected: " + aliasInfoVector.size() == (beforeSaveAliasCount + aliasNameCount), + "Wrong aliases count: " << aliasInfoVector.size() << " Expected: " << (beforeSaveAliasCount + aliasNameCount)); + + bool status; + for (const auto &info : aliasInfoVector) { + exitCode = manager->getDataEncryptionStatus(info.alias, status); + RUNNER_ASSERT_MSG(CKM_API_SUCCESS == exitCode, "Error=" << CKM::APICodeToString(exitCode)); + + actual.try_emplace(info.alias, info.alias, status, info.backend); + } + check_alias_info_list_helper(expected, actual, "/User "); remove_user_data(USER_APP); } +RUNNER_TEST(T1027_backend_info) +{ + //int ckmc_get_backend_info(ckmc_backend_id_e backend, ckmc_backend_info_h* ppinfo) + ckmc_backend_info_h info; + size_t size; + assert_invalid_param(ckmc_get_backend_info, static_cast(-1), &info); + assert_invalid_param(ckmc_get_backend_info, static_cast(2), &info); + assert_invalid_param(ckmc_get_backend_info, CKMC_BACKEND_SW, nullptr); + +#ifdef TZ_BACKEND + assert_positive(ckmc_get_backend_info, CKMC_BACKEND_TZ, &info); + RUNNER_ASSERT_MSG(info != nullptr, "Backend info is null"); + + assert_positive(ckmc_backend_get_max_chunk_size, info, &size); + RUNNER_ASSERT_MSG(size != 0, "Unexpected max chunk size"); +#else + assert_invalid_param(ckmc_get_backend_info, CKMC_BACKEND_TZ, &info); +#endif + + assert_positive(ckmc_get_backend_info, CKMC_BACKEND_SW, &info); + RUNNER_ASSERT_MSG(info != nullptr, "Backend info is null"); + + assert_positive(ckmc_backend_get_max_chunk_size, info, &size); + RUNNER_ASSERT_MSG(size == 0, "Unexpected max chunk size"); +} + + RUNNER_TEST(T1029_deinit) { remove_user_data(USER_APP);