From c0c157ecef9f4035039bb4399c99e0818e639771 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 11 Mar 2017 16:48:54 -0500 Subject: [PATCH] use common context for ElGamal encrypt/decrypt --- Crypto.cpp | 8 ++------ Crypto.h | 4 ++-- Garlic.cpp | 13 ++++++++++--- Garlic.h | 8 +++++--- I2NPProtocol.cpp | 5 +++-- Tunnel.cpp | 4 +++- TunnelConfig.h | 4 ++-- 7 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index 791968d3..04126cb6 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -272,9 +272,8 @@ namespace crypto } // ElGamal - void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding) + void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) { - BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); // everything, but a, because a might come from table BIGNUM * k = BN_CTX_get (ctx); @@ -324,13 +323,11 @@ namespace crypto } BN_free (a); BN_CTX_end (ctx); - BN_CTX_free (ctx); } bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, - uint8_t * data, bool zeroPadding) + uint8_t * data, BN_CTX * ctx, bool zeroPadding) { - BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); BIGNUM * x = BN_CTX_get (ctx), * a = BN_CTX_get (ctx), * b = BN_CTX_get (ctx); BN_bin2bn (key, 256, x); @@ -343,7 +340,6 @@ namespace crypto uint8_t m[255]; bn2buf (b, m, 255); BN_CTX_end (ctx); - BN_CTX_free (ctx); uint8_t hash[32]; SHA256 (m + 33, 222, hash); if (memcmp (m + 1, hash, 32)) diff --git a/Crypto.h b/Crypto.h index 748a7f48..691bb716 100644 --- a/Crypto.h +++ b/Crypto.h @@ -48,8 +48,8 @@ namespace crypto }; // ElGamal - void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding = false); - bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, bool zeroPadding = false); + void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); + bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false); void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub); // HMAC diff --git a/Garlic.cpp b/Garlic.cpp index 51fa6c3b..5b5fd71b 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -187,7 +187,8 @@ namespace garlic RAND_bytes (elGamal.preIV, 32); // Pre-IV uint8_t iv[32]; // IV is first 16 bytes SHA256(elGamal.preIV, 32, iv); - i2p::crypto::ElGamalEncrypt (m_Destination->GetEncryptionPublicKey (), (uint8_t *)&elGamal, buf, true); + i2p::crypto::ElGamalEncrypt (m_Destination->GetEncryptionPublicKey (), + (uint8_t *)&elGamal, buf, m_Owner->GetBNContext (), true); m_Encryption.SetIV (iv); buf += 514; len += 514; @@ -388,9 +389,15 @@ namespace garlic return size; } - + + GarlicDestination::GarlicDestination (): m_NumTags (32) // 32 tags by default + { + m_Ctx = BN_CTX_new (); + } + GarlicDestination::~GarlicDestination () { + BN_CTX_free (m_Ctx); } void GarlicDestination::CleanUp () @@ -446,7 +453,7 @@ namespace garlic { // tag not found. Use ElGamal ElGamalBlock elGamal; - if (length >= 514 && i2p::crypto::ElGamalDecrypt (GetEncryptionPrivateKey (), buf, (uint8_t *)&elGamal, true)) + if (length >= 514 && i2p::crypto::ElGamalDecrypt (GetEncryptionPrivateKey (), buf, (uint8_t *)&elGamal, m_Ctx, true)) { auto decryption = std::make_shared(); decryption->SetKey (elGamal.sessionKey); diff --git a/Garlic.h b/Garlic.h index b5dcd1eb..6b05df42 100644 --- a/Garlic.h +++ b/Garlic.h @@ -153,11 +153,12 @@ namespace garlic { public: - GarlicDestination (): m_NumTags (32) {}; // 32 tags by default + GarlicDestination (); ~GarlicDestination (); void CleanUp (); - void SetNumTags (int numTags) { m_NumTags = numTags; }; + void SetNumTags (int numTags) { m_NumTags = numTags; }; + BN_CTX * GetBNContext () const { return m_Ctx; }; std::shared_ptr GetRoutingSession (std::shared_ptr destination, bool attachLeaseSet); void CleanupExpiredTags (); void RemoveDeliveryStatusSession (uint32_t msgID); @@ -188,7 +189,8 @@ namespace garlic void HandleGarlicPayload (uint8_t * buf, size_t len, std::shared_ptr from); private: - + + BN_CTX * m_Ctx; // outgoing sessions int m_NumTags; std::mutex m_SessionsMutex; diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 0a5031e7..4e4ca7c3 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -326,8 +326,9 @@ namespace i2p if (!memcmp (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)i2p::context.GetRouterInfo ().GetIdentHash (), 16)) { LogPrint (eLogDebug, "I2NP: Build request record ", i, " is ours"); - - i2p::crypto::ElGamalDecrypt (i2p::context.GetEncryptionPrivateKey (), record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText); + BN_CTX * ctx = BN_CTX_new (); + i2p::crypto::ElGamalDecrypt (i2p::context.GetEncryptionPrivateKey (), record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText, ctx); + BN_CTX_free (ctx); // replace record to reply if (i2p::context.AcceptsTunnels () && i2p::tunnel::tunnels.GetTransitTunnels ().size () <= g_MaxNumTransitTunnels && diff --git a/Tunnel.cpp b/Tunnel.cpp index 390c64ac..798d7198 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -51,6 +51,7 @@ namespace tunnel uint8_t * records = msg->GetPayload () + 1; TunnelHopConfig * hop = m_Config->GetFirstHop (); int i = 0; + BN_CTX * ctx = BN_CTX_new (); while (hop) { uint32_t msgID; @@ -59,7 +60,7 @@ namespace tunnel else msgID = replyMsgID; int idx = recordIndicies[i]; - hop->CreateBuildRequestRecord (records + idx*TUNNEL_BUILD_RECORD_SIZE, msgID); + hop->CreateBuildRequestRecord (records + idx*TUNNEL_BUILD_RECORD_SIZE, msgID, ctx); hop->recordIndex = idx; i++; #ifdef WITH_EVENTS @@ -67,6 +68,7 @@ namespace tunnel #endif hop = hop->next; } + BN_CTX_free (ctx); #ifdef WITH_EVENTS EmitTunnelEvent("tunnel.build", this, peers); #endif diff --git a/TunnelConfig.h b/TunnelConfig.h index c131059c..10e980ad 100644 --- a/TunnelConfig.h +++ b/TunnelConfig.h @@ -83,7 +83,7 @@ namespace tunnel } } - void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID) const + void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) const { uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; htobe32buf (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); @@ -101,7 +101,7 @@ namespace tunnel htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ()); htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); - i2p::crypto::ElGamalEncrypt (ident->GetEncryptionPublicKey (), clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET); + i2p::crypto::ElGamalEncrypt (ident->GetEncryptionPublicKey (), clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } };