diff --git a/Crypto.cpp b/Crypto.cpp index ae0fdd46..6b260ac1 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -8,7 +8,6 @@ #include #include "TunnelBase.h" #include -#include #include "Log.h" #include "Crypto.h" @@ -803,24 +802,40 @@ namespace crypto }*/ static ENGINE * g_GostEngine = nullptr; - static bool InitGost () + static const EVP_MD * g_Gost3411 = nullptr; + + ENGINE * GetGostEngine () + { + return g_GostEngine; + } + + uint8_t * GOSTR3411 (const uint8_t * buf, size_t len, uint8_t * digest) + { + if (!g_Gost3411) return false; + auto ctx = EVP_MD_CTX_new (); + EVP_DigestInit_ex (ctx, g_Gost3411, GetGostEngine ()); + EVP_DigestUpdate (ctx, buf, len); + EVP_DigestFinal_ex (ctx, digest, nullptr); + EVP_MD_CTX_free (ctx); + return digest; + } + + bool InitGost () { - auto g_GostEngine = ENGINE_by_id ("gost"); - if (!g_GostEngine) - { - ENGINE_load_builtin_engines (); #if OPENSSL_API_COMPAT < 0x10100000L - ENGINE_load_dynamic (); + ENGINE_load_builtin_engines (); + ENGINE_load_dynamic (); +#else + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN |, NULL); #endif - g_GostEngine = ENGINE_by_id ("gost"); - if (!g_GostEngine) return false; - } + g_GostEngine = ENGINE_by_id ("gost"); + if (!g_GostEngine) return false; - ENGINE_set_default (g_GostEngine, ENGINE_METHOD_ALL); + g_Gost3411 = ENGINE_get_digest(g_GostEngine, NID_id_GostR3411_94); return true; } - static void TerminateGost () + void TerminateGost () { if (g_GostEngine) { @@ -835,7 +850,6 @@ namespace crypto void InitCrypto (bool precomputation, bool withGost) { SSL_library_init (); - if (withGost) InitGost (); /* auto numLocks = CRYPTO_num_locks(); for (int i = 0; i < numLocks; i++) m_OpenSSLMutexes.emplace_back (new std::mutex); @@ -865,7 +879,6 @@ namespace crypto ); delete[] g_ElggTable; g_ElggTable = nullptr; } - TerminateGost (); /* CRYPTO_set_locking_callback (nullptr); m_OpenSSLMutexes.clear ();*/ } diff --git a/Crypto.h b/Crypto.h index afd4fc0d..24d16ae5 100644 --- a/Crypto.h +++ b/Crypto.h @@ -12,6 +12,7 @@ #include #include #include +#include #include "Base.h" #include "Tag.h" @@ -278,6 +279,12 @@ namespace crypto #endif }; +// GOST + bool InitGost (); + void TerminateGost (); + ENGINE * GetGostEngine (); + uint8_t * GOSTR3411 (const uint8_t * buf, size_t len, uint8_t * digest); // hash + void InitCrypto (bool precomputation, bool withGost = false); void TerminateCrypto (); } @@ -326,6 +333,11 @@ inline void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **pri inline RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) { return pkey->pkey.rsa; } +inline EVP_MD_CTX *EVP_MD_CTX_new () + { return EVP_MD_CTX_create(); } +inline void EVP_MD_CTX_free (EVP_MD_CTX *ctx) + { EVP_MD_CTX_destroy (ctx); } + // ssl #define TLS_method TLSv1_method diff --git a/Signature.h b/Signature.h index 3c45b739..21dccb98 100644 --- a/Signature.h +++ b/Signature.h @@ -464,9 +464,11 @@ namespace crypto bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const { - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new (m_PublicKey, nullptr); + uint8_t digest[32]; + GOSTR3411 (buf, len, digest); + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new (m_PublicKey, GetGostEngine ()); EVP_PKEY_verify_init (ctx); - int ret = EVP_PKEY_verify (ctx, signature, GOSTR3410_SIGNATURE_LENGTH, buf, len); + int ret = EVP_PKEY_verify (ctx, signature, GOSTR3410_SIGNATURE_LENGTH, digest, 32); EVP_PKEY_CTX_free (ctx); return ret == 1; } @@ -494,10 +496,12 @@ namespace crypto void Sign (const uint8_t * buf, int len, uint8_t * signature) const { - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new (m_PrivateKey, nullptr); + uint8_t digest[32]; + GOSTR3411 (buf, len, digest); + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new (m_PrivateKey, GetGostEngine ()); EVP_PKEY_sign_init (ctx); size_t l = GOSTR3410_SIGNATURE_LENGTH; - EVP_PKEY_sign (ctx, signature, &l, buf, len); + EVP_PKEY_sign (ctx, signature, &l, digest, 32); EVP_PKEY_CTX_free (ctx); } @@ -508,7 +512,7 @@ namespace crypto inline void CreateGOSTR3410RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) { - auto ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, nullptr); + auto ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, GetGostEngine ()); EVP_PKEY_keygen_init (ctx); EVP_PKEY_CTX_ctrl_str (ctx, "paramset", "A"); EVP_PKEY* pkey = nullptr;