#include "sa_engine_common.h"
#if OPENSSL_VERSION_NUMBER > 0x1010106f && OPENSSL_VERSION_NUMBER < 0x30000000
#include "client_test_helpers.h"
#include "digest_util.h"
#include <gtest/gtest.h>
#include <openssl/evp.h>
using namespace client_test_helpers;
TEST_P(SaEnginePkeyMacTest, digestSignWithUpdateFinalTest) {
auto key_type = std::get<0>(GetParam());
auto key_length = std::get<1>(GetParam());
auto digest_algorithm = std::get<2>(GetParam());
auto mac_algorithm = std::get<3>(GetParam());
std::vector<uint8_t> clear_key;
sa_elliptic_curve curve;
auto key = create_sa_key(key_type, key_length, clear_key, curve);
ASSERT_NE(key, nullptr);
if (*key == UNSUPPORTED_KEY)
GTEST_SKIP() << "key type, key size, or curve not supported";
auto data = random(256);
std::vector<uint8_t> mac;
std::shared_ptr<ENGINE> const engine(sa_get_engine(), sa_engine_free);
ASSERT_NE(engine, nullptr);
EVP_PKEY* temp = ENGINE_load_private_key(engine.get(), reinterpret_cast<char*>(key.get()), nullptr, nullptr);
ASSERT_NE(temp, nullptr);
std::shared_ptr<EVP_PKEY> const evp_pkey(temp, EVP_PKEY_free);
const EVP_MD* evp_md;
if (mac_algorithm == SA_MAC_ALGORITHM_HMAC)
evp_md = digest_mechanism(digest_algorithm);
else
evp_md = nullptr;
size_t mac_length = 0;
std::shared_ptr<EVP_MD_CTX> const evp_md_sign_ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free);
ASSERT_NE(evp_md_sign_ctx, nullptr);
EVP_PKEY_CTX* evp_pkey_sign_ctx = nullptr;
ASSERT_EQ(EVP_DigestSignInit(evp_md_sign_ctx.get(), &evp_pkey_sign_ctx, evp_md, engine.get(), evp_pkey.get()),
1);
ASSERT_EQ(EVP_DigestSignUpdate(evp_md_sign_ctx.get(), data.data(), data.size()), 1);
ASSERT_EQ(EVP_DigestSignFinal(evp_md_sign_ctx.get(), nullptr, &mac_length), 1);
mac.resize(mac_length);
ASSERT_EQ(EVP_DigestSignFinal(evp_md_sign_ctx.get(), mac.data(), &mac_length), 1);
mac.resize(mac_length);
std::vector<uint8_t> mac2;
if (mac_algorithm == SA_MAC_ALGORITHM_HMAC)
ASSERT_TRUE(hmac_openssl(mac2, clear_key, data, digest_algorithm));
else
ASSERT_TRUE(cmac_openssl(mac2, clear_key, data));
ASSERT_EQ(mac, mac2);
}
TEST_P(SaEnginePkeyMacTest, digestSignNoUpdateFinalTest) {
auto key_type = std::get<0>(GetParam());
auto key_length = std::get<1>(GetParam());
auto digest_algorithm = std::get<2>(GetParam());
auto mac_algorithm = std::get<3>(GetParam());
std::vector<uint8_t> clear_key;
sa_elliptic_curve curve;
auto key = create_sa_key(key_type, key_length, clear_key, curve);
ASSERT_NE(key, nullptr);
if (*key == UNSUPPORTED_KEY)
GTEST_SKIP() << "key type, key size, or curve not supported";
auto data = random(256);
std::vector<uint8_t> mac;
std::shared_ptr<ENGINE> const engine(sa_get_engine(), sa_engine_free);
ASSERT_NE(engine, nullptr);
EVP_PKEY* temp = ENGINE_load_private_key(engine.get(), reinterpret_cast<char*>(key.get()), nullptr, nullptr);
ASSERT_NE(temp, nullptr);
std::shared_ptr<EVP_PKEY> const evp_pkey(temp, EVP_PKEY_free);
const EVP_MD* evp_md;
if (mac_algorithm == SA_MAC_ALGORITHM_HMAC)
evp_md = digest_mechanism(digest_algorithm);
else
evp_md = nullptr;
size_t mac_length = 0;
std::shared_ptr<EVP_MD_CTX> const evp_md_sign_ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free);
ASSERT_NE(evp_md_sign_ctx, nullptr);
EVP_PKEY_CTX* evp_pkey_sign_ctx = nullptr;
ASSERT_EQ(EVP_DigestSignInit(evp_md_sign_ctx.get(), &evp_pkey_sign_ctx, evp_md, engine.get(), evp_pkey.get()),
1);
ASSERT_EQ(EVP_DigestSign(evp_md_sign_ctx.get(), nullptr, &mac_length, data.data(), data.size()), 1);
mac.resize(mac_length);
ASSERT_EQ(EVP_DigestSign(evp_md_sign_ctx.get(), mac.data(), &mac_length, data.data(), data.size()), 1);
mac.resize(mac_length);
std::vector<uint8_t> mac2;
if (mac_algorithm == SA_MAC_ALGORITHM_HMAC)
ASSERT_TRUE(hmac_openssl(mac2, clear_key, data, digest_algorithm));
else
ASSERT_TRUE(cmac_openssl(mac2, clear_key, data));
ASSERT_EQ(mac, mac2);
}
INSTANTIATE_TEST_SUITE_P(
SaEnginePkeyCmacTests,
SaEnginePkeyMacTest,
::testing::Combine(
::testing::Values(SA_KEY_TYPE_SYMMETRIC),
::testing::Values(SYM_128_KEY_SIZE, SYM_256_KEY_SIZE),
::testing::Values(0),
::testing::Values(SA_MAC_ALGORITHM_CMAC)));
INSTANTIATE_TEST_SUITE_P(
SaEnginePkeyHmacTests,
SaEnginePkeyMacTest,
::testing::Combine(
::testing::Values(SA_KEY_TYPE_SYMMETRIC),
::testing::Values(SYM_128_KEY_SIZE, SYM_160_KEY_SIZE, SYM_256_KEY_SIZE),
::testing::Values(SA_DIGEST_ALGORITHM_SHA1, SA_DIGEST_ALGORITHM_SHA256, SA_DIGEST_ALGORITHM_SHA384,
SA_DIGEST_ALGORITHM_SHA512),
::testing::Values(SA_MAC_ALGORITHM_HMAC)));
#endif