From 1cb89ce20d6bfe60844bb51bb0ef4a2ebfa9035f Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 19 Feb 2017 14:45:10 -0500 Subject: [PATCH] set correct curve parameters for GOST R 34.10 --- Crypto.cpp | 22 +++++++++++++++------- Crypto.h | 2 +- Signature.h | 18 ++++++++++-------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index fb3ce16b..4aa6b82d 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -803,17 +803,18 @@ namespace crypto static ENGINE * g_GostEngine = nullptr; static const EVP_MD * g_Gost3411 = nullptr; - - ENGINE * GetGostEngine () + static EVP_PKEY * g_GostPKEY = nullptr; + + const EVP_PKEY * GetGostPKEY () { - return g_GostEngine; - } - + return g_GostPKEY; + } + uint8_t * GOSTR3411 (const uint8_t * buf, size_t len, uint8_t * digest) { if (!g_Gost3411) return nullptr; auto ctx = EVP_MD_CTX_new (); - EVP_DigestInit_ex (ctx, g_Gost3411, GetGostEngine ()); + EVP_DigestInit_ex (ctx, g_Gost3411, g_GostEngine); EVP_DigestUpdate (ctx, buf, len); EVP_DigestFinal_ex (ctx, digest, nullptr); EVP_MD_CTX_free (ctx); @@ -833,13 +834,20 @@ namespace crypto ENGINE_init (g_GostEngine); ENGINE_set_default (g_GostEngine, ENGINE_METHOD_ALL); - ENGINE_ctrl_cmd_string(g_GostEngine, "CRYPT_PARAMS", "id-Gost28147-89-CryptoPro-A-ParamSet", 0); g_Gost3411 = ENGINE_get_digest(g_GostEngine, NID_id_GostR3411_94); + + auto ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, g_GostEngine); + EVP_PKEY_keygen_init (ctx); + EVP_PKEY_CTX_ctrl_str (ctx, "paramset", "A"); // possible values 'A', 'B', 'C', 'XA', 'XB' + EVP_PKEY_keygen (ctx, &g_GostPKEY); // it seems only way to fill with correct params + EVP_PKEY_CTX_free (ctx); return true; } void TerminateGost () { + if (g_GostPKEY) + EVP_PKEY_free (g_GostPKEY); if (g_GostEngine) { ENGINE_finish (g_GostEngine); diff --git a/Crypto.h b/Crypto.h index 24d16ae5..fca7b073 100644 --- a/Crypto.h +++ b/Crypto.h @@ -282,7 +282,7 @@ namespace crypto // GOST bool InitGost (); void TerminateGost (); - ENGINE * GetGostEngine (); + const EVP_PKEY * GetGostPKEY (); uint8_t * GOSTR3411 (const uint8_t * buf, size_t len, uint8_t * digest); // hash void InitCrypto (bool precomputation, bool withGost = false); diff --git a/Signature.h b/Signature.h index 21dccb98..d8c04814 100644 --- a/Signature.h +++ b/Signature.h @@ -453,8 +453,9 @@ namespace crypto GOSTR3410Verifier (const uint8_t * signingKey) { m_PublicKey = EVP_PKEY_new (); - EVP_PKEY_set_type (m_PublicKey, NID_id_GostR3410_2001); - EC_KEY * ecKey = (EC_KEY *)EVP_PKEY_get0 (m_PublicKey); + EC_KEY * ecKey = EC_KEY_new (); + EVP_PKEY_assign (m_PublicKey, NID_id_GostR3410_2001, ecKey); + EVP_PKEY_copy_parameters (m_PublicKey, GetGostPKEY ()); BIGNUM * x = BN_bin2bn (signingKey, GOSTR3410_PUBLIC_KEY_LENGTH/2, NULL); BIGNUM * y = BN_bin2bn (signingKey + GOSTR3410_PUBLIC_KEY_LENGTH/2, GOSTR3410_PUBLIC_KEY_LENGTH/2, NULL); EC_KEY_set_public_key_affine_coordinates (ecKey, x, y); @@ -466,7 +467,7 @@ namespace crypto { uint8_t digest[32]; GOSTR3411 (buf, len, digest); - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new (m_PublicKey, GetGostEngine ()); + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new (m_PublicKey, nullptr); EVP_PKEY_verify_init (ctx); int ret = EVP_PKEY_verify (ctx, signature, GOSTR3410_SIGNATURE_LENGTH, digest, 32); EVP_PKEY_CTX_free (ctx); @@ -488,8 +489,9 @@ namespace crypto GOSTR3410Signer (const uint8_t * signingPrivateKey) { m_PrivateKey = EVP_PKEY_new (); - EVP_PKEY_set_type (m_PrivateKey, NID_id_GostR3410_2001); - EC_KEY * ecKey = (EC_KEY *)EVP_PKEY_get0 (m_PrivateKey); + EC_KEY * ecKey = EC_KEY_new (); + EVP_PKEY_assign (m_PrivateKey, NID_id_GostR3410_2001, ecKey); + EVP_PKEY_copy_parameters (m_PrivateKey, GetGostPKEY ()); EC_KEY_set_private_key (ecKey, BN_bin2bn (signingPrivateKey, GOSTR3410_PUBLIC_KEY_LENGTH/2, NULL)); } ~GOSTR3410Signer () { EVP_PKEY_free (m_PrivateKey); } @@ -498,7 +500,7 @@ namespace crypto { uint8_t digest[32]; GOSTR3411 (buf, len, digest); - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new (m_PrivateKey, GetGostEngine ()); + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new (m_PrivateKey, nullptr); EVP_PKEY_sign_init (ctx); size_t l = GOSTR3410_SIGNATURE_LENGTH; EVP_PKEY_sign (ctx, signature, &l, digest, 32); @@ -512,9 +514,9 @@ namespace crypto inline void CreateGOSTR3410RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) { - auto ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, GetGostEngine ()); + auto ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, nullptr); EVP_PKEY_keygen_init (ctx); - EVP_PKEY_CTX_ctrl_str (ctx, "paramset", "A"); + EVP_PKEY_CTX_ctrl_str (ctx, "paramset", "A"); // TODO should be in one place EVP_PKEY* pkey = nullptr; EVP_PKEY_keygen (ctx, &pkey); const EC_KEY* ecKey = (const EC_KEY*) EVP_PKEY_get0(pkey);