From: Krzysztof Jackiewicz Date: Thu, 23 Feb 2023 09:14:43 +0000 (+0100) Subject: CKM: Add KBKDF tests X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Ftest%2Fsecurity-tests.git;a=commitdiff_plain;h=674533873c00e115c038ad4195290e09afe90ffd CKM: Add KBKDF tests Change-Id: I8af39566757c6f3b4e9ca82184f9f99708c3271a --- diff --git a/src/ckm/unprivileged/key-derivation.cpp b/src/ckm/unprivileged/key-derivation.cpp index 1a8a1fc..9955525 100644 --- a/src/ckm/unprivileged/key-derivation.cpp +++ b/src/ckm/unprivileged/key-derivation.cpp @@ -40,12 +40,34 @@ const KeyAliasPair PEERS2 = { "peer2_ec_private", "peer2_ec_public" }; const KeyAliasPair WRONG = { "wrong_ec_private", "wrong_ec_public" }; const KeyAliasPair RSA = { "rsa_private", "rsa_public" }; const std::string DERIVED = "derived"; +const std::string SECRET = "secret"; const ckmc_policy_s UNEXPORTABLE { nullptr, false }; const ckmc_policy_s EXPORTABLE { nullptr, true }; const ckmc_policy_s UNEXPORTABLE_PW { const_cast(PASSWORD), false }; const ckmc_policy_s EXPORTABLE_PW { const_cast(PASSWORD), true }; +constexpr ckmc_kdf_prf_e HMAC256 = CKMC_KDF_PRF_HMAC_SHA256; +constexpr ckmc_kdf_prf_e HMAC384 = CKMC_KDF_PRF_HMAC_SHA384; +constexpr ckmc_kdf_prf_e HMAC512 = CKMC_KDF_PRF_HMAC_SHA512; +constexpr ckmc_kbkdf_counter_location_e BEFORE = CKMC_KBKDF_COUNTER_BEFORE_FIXED; +constexpr ckmc_kbkdf_counter_location_e AFTER = CKMC_KBKDF_COUNTER_AFTER_FIXED; +constexpr ckmc_kbkdf_counter_location_e MIDDLE = CKMC_KBKDF_COUNTER_MIDDLE_FIXED; +constexpr ckmc_kbkdf_mode_e COUNTER = CKMC_KBKDF_MODE_COUNTER; +constexpr uint64_t U0 = 0; +constexpr uint64_t U1 = 1; +constexpr uint64_t U7 = 7; +constexpr uint64_t U8 = 8; +constexpr uint64_t U16 = 16; +constexpr uint64_t U24 = 24; +constexpr uint64_t U32 = 32; +constexpr uint64_t U64 = 64; + +const RawBufferPtr LAB = create_raw_buffer(createRandomBufferCAPI(16)); +const RawBufferPtr CTX = create_raw_buffer(createRandomBufferCAPI(12)); +const RawBufferPtr FIX = create_raw_buffer(createRandomBufferCAPI(36)); +const RawBufferPtr ONE = create_raw_buffer(createRandomBufferCAPI(1)); + class EcdhGroupFixture: public DPL::Test::TestGroup { private: @@ -167,6 +189,114 @@ void invalidDerive(const ParamListPtr& params) EXPORTABLE); } + +class KbkdfParamTester { +public: + void Ok(const uint64_t* len, + const ckmc_kdf_prf_e* prf, + const ckmc_kbkdf_mode_e* mode, + const ckmc_kbkdf_counter_location_e* location, + const RawBufferPtr context, + const RawBufferPtr label, + const RawBufferPtr fixed, + const uint64_t* rlen, + const uint64_t* llen, + bool noSeparator = false) + { + return Test(true, len, prf, mode, location, context, label, fixed, rlen, llen, noSeparator); + } + + void Fail(const uint64_t* len, + const ckmc_kdf_prf_e* prf, + const ckmc_kbkdf_mode_e* mode, + const ckmc_kbkdf_counter_location_e* location, + const RawBufferPtr context, + const RawBufferPtr label, + const RawBufferPtr fixed, + const uint64_t* rlen, + const uint64_t* llen, + bool noSeparator = false) + { + return Test( + false, len, prf, mode, location, context, label, fixed, rlen, llen, noSeparator); + } +private: + void Test(bool ok, + const uint64_t* len, + const ckmc_kdf_prf_e* prf, + const ckmc_kbkdf_mode_e* mode, + const ckmc_kbkdf_counter_location_e* location, + const RawBufferPtr context, + const RawBufferPtr label, + const RawBufferPtr fixed, + const uint64_t* rlen, + const uint64_t* llen, + bool noSeparator = false) + { + auto derive = createParamListPtr(); + setParam(derive, CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_KBKDF); + if (len) + setParam(derive, CKMC_PARAM_KDF_LEN, *len); + if (prf) + setParam(derive, CKMC_PARAM_KDF_PRF, *prf); + if (mode) + setParam(derive, CKMC_PARAM_KBKDF_MODE, *mode); + if (location) + setParam(derive, CKMC_PARAM_KBKDF_COUNTER_LOCATION, *location); + if (context) + setParam(derive, CKMC_PARAM_KBKDF_CONTEXT, context.get()); + if (label) + setParam(derive, CKMC_PARAM_KBKDF_LABEL, label.get()); + if (fixed) + setParam(derive, CKMC_PARAM_KBKDF_FIXED_INPUT, fixed.get()); + if (rlen) + setParam(derive, CKMC_PARAM_KBKDF_RLEN, *rlen); + if (llen) + setParam(derive, CKMC_PARAM_KBKDF_LLEN, *llen); + if (noSeparator) + setParam(derive, CKMC_PARAM_KBKDF_NO_SEPARATOR, 1); + + if (ok) { + assert_positive(ckmc_key_derive, + derive.get(), + SECRET.c_str(), + "", + DERIVED.c_str(), + EXPORTABLE); + + ckmc_key_s *derived = nullptr; + assert_positive(ckmc_get_key, DERIVED.c_str(), "", &derived); + size_t derived_size = derived->key_size; + ckmc_key_free(derived); + + RUNNER_ASSERT(derived_size == *len); + + assert_positive(ckmc_remove_alias, DERIVED.c_str()); + } else { + assert_result(CKMC_ERROR_INVALID_PARAMETER, + ckmc_key_derive, + derive.get(), + SECRET.c_str(), + "", + DERIVED.c_str(), + EXPORTABLE); + } + } +}; + +ParamListPtr getDefaultKBKDFParams() +{ + auto kbkdfParams = createParamListPtr(); + setParam(kbkdfParams, CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_KBKDF); + setParam(kbkdfParams, CKMC_PARAM_KDF_LEN, 32); + setParam(kbkdfParams, CKMC_PARAM_KDF_PRF, CKMC_KDF_PRF_HMAC_SHA256); + setParam(kbkdfParams, CKMC_PARAM_KBKDF_MODE, CKMC_KBKDF_MODE_COUNTER); + setParam(kbkdfParams, CKMC_PARAM_KBKDF_LABEL, LAB.get()); + setParam(kbkdfParams, CKMC_PARAM_KBKDF_CONTEXT, CTX.get()); + setParam(kbkdfParams, CKMC_PARAM_KBKDF_COUNTER_LOCATION, CKMC_KBKDF_COUNTER_BEFORE_FIXED); + return kbkdfParams; +} + } // namespace anonymous RUNNER_TEST_GROUP_INIT_ENV(CKM_DERIVE_ECDH, EcdhGroupFixture); @@ -347,3 +477,226 @@ RUNNER_TEST(TECDH_0230_wrong_key_types, DerivedFixture) { deriveEcdh(RSA.prv, "", RSA.pub, DERIVED, UNEXPORTABLE, CKMC_ERROR_INVALID_PARAMETER); } + + +class KbkdfGroupFixture: public DPL::Test::TestGroup +{ +public: + void Init() override + { + remove_user_data(UID); + assert_positive(ckmc_unlock_user_key, UID, "db-pass"); + + ckmc_raw_buffer_s* secret = createRandomBufferCAPI(12); + + assert_positive(ckmc_save_data, SECRET.c_str(), *secret, UNEXPORTABLE); + } + + void Finish() override + { + int ret = ckmc_lock_user_key(UID); + if (ret != CKMC_ERROR_NONE) + RUNNER_ERROR_MSG("DB lock failed: " << CKMCErrorToString(ret)); + remove_user_data(UID); + } +}; + +RUNNER_TEST_GROUP_INIT_ENV(CKM_DERIVE_KBKDF, KbkdfGroupFixture); + +RUNNER_TEST(TKBKDF_0010_positive, DerivedFixture) +{ + KbkdfParamTester test; + + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + + test.Ok(&U16, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + test.Ok(&U24, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + + test.Ok(&U32, &HMAC384, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + test.Ok(&U32, &HMAC512, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + + test.Ok(&U32, &HMAC256, &COUNTER, &AFTER, CTX, LAB, nullptr, nullptr, nullptr); + test.Ok(&U32, &HMAC256, &COUNTER, &MIDDLE, CTX, LAB, nullptr, nullptr, nullptr); + + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, ONE, LAB, nullptr, nullptr, nullptr); + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, ONE, nullptr, nullptr, nullptr); + + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, nullptr, nullptr, FIX, nullptr, nullptr); + test.Ok(&U32, &HMAC256, &COUNTER, &AFTER, nullptr, nullptr, FIX, nullptr, nullptr); + + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, nullptr, nullptr, ONE, nullptr, nullptr); + + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, &U32, nullptr); + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, &U24, nullptr); + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, &U16, nullptr); + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, &U8, nullptr); + + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, &U32); + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, &U24); + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, &U16); + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, &U8); + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, &U0); + + test.Ok(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr, true); + test.Ok(&U32, &HMAC256, &COUNTER, &MIDDLE, CTX, LAB, nullptr, nullptr, nullptr, true); +} + +RUNNER_TEST(TKBKDF_0020_derive_from_derived, DerivedFixture) +{ + auto kbkdfParams = getDefaultKBKDFParams(); + assert_positive(ckmc_key_derive, + kbkdfParams.get(), + SECRET.c_str(), + "", + DERIVED.c_str(), + UNEXPORTABLE); + + assert_positive(ckmc_key_derive, + kbkdfParams.get(), + DERIVED.c_str(), + "", + "derived2", + EXPORTABLE); + + ckmc_key_s *derived2 = nullptr; + assert_positive(ckmc_get_key, "derived2", "", &derived2); + ckmc_key_free(derived2); +} + +RUNNER_TEST(TKBKDF_0030_unknown_alias, DerivedFixture) +{ + auto kbkdfParams = getDefaultKBKDFParams(); + assert_result(CKMC_ERROR_DB_ALIAS_UNKNOWN, + ckmc_key_derive, + kbkdfParams.get(), + "nonexistent-alias", + "", + DERIVED.c_str(), + EXPORTABLE); +} + +RUNNER_TEST(TKBKDF_0040_wrong_password, DerivedFixture) +{ + auto kbkdfParams = getDefaultKBKDFParams(); + assert_result(CKMC_ERROR_AUTHENTICATION_FAILED, + ckmc_key_derive, + kbkdfParams.get(), + SECRET.c_str(), + "wrong-password", + DERIVED.c_str(), + EXPORTABLE); +} + +RUNNER_TEST(TKBKDF_0050_alias_exists, DerivedFixture) +{ + auto kbkdfParams = getDefaultKBKDFParams(); + assert_positive(ckmc_key_derive, + kbkdfParams.get(), + SECRET.c_str(), + "", + DERIVED.c_str(), + EXPORTABLE); + + assert_result(CKMC_ERROR_DB_ALIAS_EXISTS, + ckmc_key_derive, + kbkdfParams.get(), + SECRET.c_str(), + "", + DERIVED.c_str(), + EXPORTABLE); +} + +RUNNER_TEST(TKBKDF_0060_derived_password, DerivedFixture) +{ + auto kbkdfParams = getDefaultKBKDFParams(); + assert_positive(ckmc_key_derive, + kbkdfParams.get(), + SECRET.c_str(), + "", + DERIVED.c_str(), + EXPORTABLE); + + ckmc_key_s *derived = nullptr; + assert_result( + CKMC_ERROR_AUTHENTICATION_FAILED, ckmc_get_key, DERIVED.c_str(), PASSWORD, &derived); + + assert_positive(ckmc_remove_alias, DERIVED.c_str()); + + assert_positive(ckmc_key_derive, + kbkdfParams.get(), + SECRET.c_str(), + "", + DERIVED.c_str(), + EXPORTABLE_PW); + + assert_result( + CKMC_ERROR_AUTHENTICATION_FAILED, ckmc_get_key, DERIVED.c_str(), "", &derived); + assert_positive(ckmc_get_key, DERIVED.c_str(), PASSWORD, &derived); + ckmc_key_free(derived); +} + +RUNNER_TEST(TKBKDF_0070_unexportable, DerivedFixture) +{ + auto kbkdfParams = getDefaultKBKDFParams(); + assert_positive(ckmc_key_derive, + kbkdfParams.get(), + SECRET.c_str(), + "", + DERIVED.c_str(), + UNEXPORTABLE); + + ckmc_key_s *derived = nullptr; + assert_result(CKMC_ERROR_NOT_EXPORTABLE, ckmc_get_key, DERIVED.c_str(), "", &derived); +} + +RUNNER_TEST(TKBKDF_0100_wrong_params, DerivedFixture) +{ + KbkdfParamTester test; + + // missing parameters + test.Fail(nullptr, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + test.Fail(&U32, nullptr, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + test.Fail(&U32, &HMAC256, nullptr, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + test.Fail(&U32, &HMAC256, &COUNTER, nullptr, CTX, LAB, nullptr, nullptr, nullptr); + test.Fail(&U32, &HMAC256, &COUNTER, &BEFORE, nullptr, LAB, nullptr, nullptr, nullptr); + test.Fail(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, nullptr, nullptr, nullptr, nullptr); + + // conflicting parameters + test.Fail(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, FIX, nullptr, nullptr); + test.Fail(&U32, &HMAC256, &COUNTER, &BEFORE, nullptr, LAB, FIX, nullptr, nullptr); + test.Fail(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, nullptr, FIX, nullptr, nullptr); + test.Fail(&U32, &HMAC256, &COUNTER, &MIDDLE, nullptr, nullptr, FIX, nullptr, nullptr); + test.Fail(&U32, &HMAC256, &COUNTER, &MIDDLE, nullptr, nullptr, FIX, nullptr, &U32); + test.Fail(&U32, &HMAC256, &COUNTER, &MIDDLE, nullptr, nullptr, FIX, nullptr, &U0); + test.Fail(&U32, &HMAC256, &COUNTER, &MIDDLE, nullptr, nullptr, FIX, nullptr, nullptr, true); + + // invalid values + test.Fail(&U0, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + test.Fail(&U1, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + test.Fail(&U8, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + test.Fail(&U64, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + + auto wrongPrf1 = static_cast(0); + auto wrongPrf2 = static_cast(4); + test.Fail(&U32, &wrongPrf1, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + test.Fail(&U32, &wrongPrf2, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + + auto wrongMode1 = static_cast(0); + auto wrongMode2 = static_cast(2); + test.Fail(&U32, &HMAC256, &wrongMode1, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + test.Fail(&U32, &HMAC256, &wrongMode2, &BEFORE, CTX, LAB, nullptr, nullptr, nullptr); + + auto wrongLocation1 = static_cast(0); + auto wrongLocation2 = static_cast(4); + test.Fail(&U32, &HMAC256, &COUNTER, &wrongLocation1, CTX, LAB, nullptr, nullptr, nullptr); + test.Fail(&U32, &HMAC256, &COUNTER, &wrongLocation2, CTX, LAB, nullptr, nullptr, nullptr); + + test.Fail(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, &U0, nullptr); + test.Fail(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, &U1, nullptr); + test.Fail(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, &U7, nullptr); + test.Fail(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, &U64, nullptr); + + test.Fail(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, &U1); + test.Fail(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, &U7); + test.Fail(&U32, &HMAC256, &COUNTER, &BEFORE, CTX, LAB, nullptr, nullptr, &U64); +}