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<char*>(PASSWORD), false };
const ckmc_policy_s EXPORTABLE_PW { const_cast<char*>(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:
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);
{
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<ckmc_kdf_prf_e>(0);
+ auto wrongPrf2 = static_cast<ckmc_kdf_prf_e>(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<ckmc_kbkdf_mode_e>(0);
+ auto wrongMode2 = static_cast<ckmc_kbkdf_mode_e>(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<ckmc_kbkdf_counter_location_e>(0);
+ auto wrongLocation2 = static_cast<ckmc_kbkdf_counter_location_e>(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);
+}