diff --git a/Crypto.cpp b/Crypto.cpp index b42dafa6..0ec0f020 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -146,6 +146,10 @@ namespace crypto } // DH/ElGamal + + const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226; + const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048; + #define elgp GetCryptoConstants ().elgp #define elgg GetCryptoConstants ().elgg @@ -169,6 +173,10 @@ namespace crypto { if (m_DH->priv_key) { BN_free (m_DH->priv_key); m_DH->priv_key = NULL; }; if (m_DH->pub_key) { BN_free (m_DH->pub_key); m_DH->pub_key = NULL; }; +#if !defined(__x86_64__) // use short exponent for non x64 + m_DH->priv_key = BN_new (); + BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1); +#endif DH_generate_key (m_DH); if (priv) bn2buf (m_DH->priv_key, priv, 256); if (pub) bn2buf (m_DH->pub_key, pub, 256); @@ -201,9 +209,9 @@ namespace crypto // select random k BIGNUM * k = BN_new (); #if defined(__x86_64__) - BN_rand (k, 2048, -1, 1); // full exponent for x64 + BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64 #else - BN_rand (k, 226, -1, 1); // short exponent of 226 bits + BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits #endif // caulculate a a = BN_new (); @@ -282,6 +290,14 @@ namespace crypto { #if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER) RAND_bytes (priv, 256); +#else + // lower 226 bits (28 bytes and 2 bits) only. short exponent + auto numBytes = (ELGAMAL_SHORT_EXPONENT_NUM_BITS)/8 + 1; // 29 + auto numZeroBytes = 256 - numBytes; + RAND_bytes (priv + numZeroBytes, numBytes); + memset (priv, 0, numZeroBytes); + priv[numZeroBytes] &= 0x03; +#endif BN_CTX * ctx = BN_CTX_new (); BIGNUM * p = BN_new (); BN_bin2bn (priv, 256, p); @@ -289,11 +305,6 @@ namespace crypto bn2buf (p, pub, 256); BN_free (p); BN_CTX_free (ctx); -#else - DHKeys dh; - dh.GenerateKeys (priv, pub); - -#endif } // HMAC diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 8db9d330..06fabc31 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -777,20 +777,20 @@ namespace util s << "Client Tunnels:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetClientTunnels ()) { - s << it.second->GetName () << " ⇐ "; auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); s << ""; + s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } s << "
\r\nServer Tunnels:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetServerTunnels ()) { - s << it.second->GetName () << " ⇒ "; auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); s << ""; + s << it.second->GetName () << " ⇒ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << ":" << it.second->GetLocalPort (); s << "
\r\n"<< std::endl; diff --git a/Identity.cpp b/Identity.cpp index 0ca9567a..f221dd04 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -311,18 +311,18 @@ namespace data switch (keyType) { case SIGNING_KEY_TYPE_DSA_SHA1: - m_Verifier.reset (new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey)); + UpdateVerifier (new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey)); break; case SIGNING_KEY_TYPE_ECDSA_SHA256_P256: { size_t padding = 128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64 - m_Verifier.reset (new i2p::crypto::ECDSAP256Verifier (m_StandardIdentity.signingKey + padding)); + UpdateVerifier (new i2p::crypto::ECDSAP256Verifier (m_StandardIdentity.signingKey + padding)); break; } case SIGNING_KEY_TYPE_ECDSA_SHA384_P384: { size_t padding = 128 - i2p::crypto::ECDSAP384_KEY_LENGTH; // 32 = 128 - 96 - m_Verifier.reset (new i2p::crypto::ECDSAP384Verifier (m_StandardIdentity.signingKey + padding)); + UpdateVerifier (new i2p::crypto::ECDSAP384Verifier (m_StandardIdentity.signingKey + padding)); break; } case SIGNING_KEY_TYPE_ECDSA_SHA512_P521: @@ -331,7 +331,7 @@ namespace data memcpy (signingKey, m_StandardIdentity.signingKey, 128); size_t excessLen = i2p::crypto::ECDSAP521_KEY_LENGTH - 128; // 4 = 132- 128 memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - m_Verifier.reset (new i2p::crypto::ECDSAP521Verifier (signingKey)); + UpdateVerifier (new i2p::crypto::ECDSAP521Verifier (signingKey)); break; } case SIGNING_KEY_TYPE_RSA_SHA256_2048: @@ -340,7 +340,7 @@ namespace data memcpy (signingKey, m_StandardIdentity.signingKey, 128); size_t excessLen = i2p::crypto::RSASHA2562048_KEY_LENGTH - 128; // 128 = 256- 128 memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - m_Verifier.reset (new i2p::crypto:: RSASHA2562048Verifier (signingKey)); + UpdateVerifier (new i2p::crypto:: RSASHA2562048Verifier (signingKey)); break; } case SIGNING_KEY_TYPE_RSA_SHA384_3072: @@ -349,7 +349,7 @@ namespace data memcpy (signingKey, m_StandardIdentity.signingKey, 128); size_t excessLen = i2p::crypto::RSASHA3843072_KEY_LENGTH - 128; // 256 = 384- 128 memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - m_Verifier.reset (new i2p::crypto:: RSASHA3843072Verifier (signingKey)); + UpdateVerifier (new i2p::crypto:: RSASHA3843072Verifier (signingKey)); break; } case SIGNING_KEY_TYPE_RSA_SHA512_4096: @@ -358,20 +358,28 @@ namespace data memcpy (signingKey, m_StandardIdentity.signingKey, 128); size_t excessLen = i2p::crypto::RSASHA5124096_KEY_LENGTH - 128; // 384 = 512- 128 memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - m_Verifier.reset (new i2p::crypto:: RSASHA5124096Verifier (signingKey)); + UpdateVerifier (new i2p::crypto:: RSASHA5124096Verifier (signingKey)); break; } case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: { size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32 - m_Verifier.reset (new i2p::crypto::EDDSA25519Verifier (m_StandardIdentity.signingKey + padding)); + UpdateVerifier (new i2p::crypto::EDDSA25519Verifier (m_StandardIdentity.signingKey + padding)); break; } default: LogPrint (eLogError, "Identity: Signing key type ", (int)keyType, " is not supported"); } } - + + void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const + { + if (!m_Verifier || !verifier) + m_Verifier.reset (verifier); + else + delete verifier; + } + void IdentityEx::DropVerifier () const { // TODO: potential race condition with Verify diff --git a/Identity.h b/Identity.h index 27da190d..d8abd6f4 100644 --- a/Identity.h +++ b/Identity.h @@ -95,6 +95,7 @@ namespace data private: void CreateVerifier () const; + void UpdateVerifier (i2p::crypto::Verifier * verifier) const; private: